src/Library/Utils/Other/Other.php line 123

Open in your IDE?
  1. <?php
  2. namespace App\Library\Utils\Other;
  3. use App\Library\Utils\Dev\ReflectionUtils\ReflectionUtils;
  4. use App\Library\Utils\StringUtils;
  5. use Doctrine\ORM\EntityManagerInterface;
  6. use Symfony\Component\Console\Input\InputInterface;
  7. use Symfony\Component\Console\Output\OutputInterface;
  8. use Symfony\Component\Console\Question\Question;
  9. use Symfony\Component\HttpFoundation\Request;
  10. class Other
  11. {
  12.     public function __construct(EntityManagerInterface $em)
  13.     {
  14.         $this->em $em;
  15.     }
  16.     /**
  17.      * @param InputInterface $input
  18.      * @param OutputInterface $output
  19.      * @param string $defaultAnswerMsg
  20.      * @return array|mixed|string|string[]|null
  21.      */
  22.     public static function askUser(InputInterface $inputOutputInterface $output$helper$questionTxt, &$replaceAll null,
  23.                                                   $defaultAnswerMsg null$noMsg null$stopMsg null,
  24.                                    array $answers null$defaultAnswer "yes"$useYesNoAllAnswers true$allowAnyInput false,
  25.                                                   $stopInputOnEmptyAnswer false, array $generateMenu null)
  26.     {
  27.         $answer null;
  28.         $yesNoAllAnswers = ['y''n''a''s''yes''no''all'];
  29.         if ($answers === null$answers = [];
  30.         $answers array_merge(
  31.             ($useYesNoAllAnswers $yesNoAllAnswers : []),
  32.             ($answers $answers : []),
  33.             ($stopInputOnEmptyAnswer ? ["stop"] : [])
  34.         );
  35.         if ($stopInputOnEmptyAnswer$defaultAnswer "stop";
  36.         if (!in_array($defaultAnswer$answers)) {
  37.             $defaultAnswer null;
  38.         }
  39.         $answerShortcuts = ['s''y''n''a'];
  40.         $answerShortcutReplacements = ['stop''yes''no''all'];
  41.         if ($generateMenu) {
  42.             $menuItemNumber 0;
  43.             foreach ($generateMenu as $menuItemData) {
  44.                 $menuCaption = ($menuItemData[1] ? $menuItemData[1] : $menuItemData[2]);
  45.                 $answerReplacement $menuItemData[2];
  46.                 if (!$answerReplacement) continue;
  47.                 $menuItemNumber++;
  48.                 $answerStr = ($menuItemData[0] ? $menuItemData[0] : strval($menuItemNumber));
  49.                 $questionTxt .= "\n" $answerStr ". " $menuCaption " ";
  50.                 $answers array_merge($answers, [$answerStr$answerReplacement]);
  51.                 if (strlen($answerStr) == 1) {
  52.                     $answerShortcuts array_merge($answerShortcuts, [$answerStr]);
  53.                     $answerShortcutReplacements array_merge($answerShortcutReplacements, [$answerReplacement]);
  54.                 }
  55.             }
  56.         }
  57.         if ($defaultAnswer$questionTxt .= "\nPress Enter - " . ($defaultAnswerMsg $defaultAnswerMsg $defaultAnswer) . ' ';
  58.         while (!$replaceAll && (!$answer || (!$allowAnyInput && !in_array($answer$answers)))) {
  59.             $question = new Question($questionTxt'[DEFAULT]');
  60.             $answer $helper->ask($input$output$question);
  61.             if ($answer == '[DEFAULT]'$answer $defaultAnswer;
  62.             if (strlen($answer) == '1') {
  63.                 $answer str_replace($answerShortcuts$answerShortcutReplacements$answer);
  64.             }
  65.         }
  66.         if ($answer == 'no') {
  67.             if ($noMsg) echo $noMsg;
  68.         } else if ($answer == 'yes' || $answer == 'all') {
  69.             if ($answer == 'all'$replaceAll true;
  70.         } else if ($answer == 'stop') {
  71.             if ($stopMsg) echo $stopMsg;
  72.             return null;
  73.         }
  74.         return $answer;
  75.     }
  76.     public static function findParentPathWithDir($path$childDirNames)
  77.     {
  78.         if (!is_array($childDirNames)) {
  79.             $childDirNames = [$childDirNames];
  80.         }
  81.         while (true) {
  82.             $path realpath($path "/..");
  83.             $continueSearch false;
  84.             foreach ($childDirNames as $childDirName) {
  85.                 if (($continueSearch = !is_dir($path "/" $childDirName))) break;
  86.             }
  87.             if (!$continueSearch) break;
  88.         }
  89.         return $path;
  90.     }
  91.     static public function getPathStructure($path)
  92.     {
  93.         $result = [
  94.             'segments' => explode("/"$path),
  95.         ];
  96.         $result['fileNameWithExtension'] = $result['segments'][array_key_last($result['segments'])];
  97.         $fileNameWithExtensionArr explode("."$result['fileNameWithExtension']);
  98.         $result['extension'] = $fileNameWithExtensionArr[array_key_last($fileNameWithExtensionArr)];
  99.         unset($fileNameWithExtensionArr[array_key_last($fileNameWithExtensionArr)]);
  100.         $result['fileNameWithoutExtension'] = implode("."$fileNameWithExtensionArr);
  101.         $result['lastSegment'] = $result['segments'][array_key_last($result['segments'])];
  102.         $pathWithoutLastSegment $result['segments'];
  103.         unset($pathWithoutLastSegment[array_key_last($pathWithoutLastSegment)]);
  104.         $pathWithoutLastSegment implode("/"$pathWithoutLastSegment);
  105.         $result['pathWithoutLastSegment'] = $pathWithoutLastSegment;
  106.         return $result;
  107.     }
  108.     public static function getAllSubdirs($path$asString falsebool $addFilesString$_dirLevel ""$recursively true)
  109.     {
  110.         $dirStructure = [];
  111.         $strDirStructure "";
  112.         foreach (scandir($path) as $objName) {
  113.             if ($objName != "." && $objName != ".." is_dir($path DIRECTORY_SEPARATOR $objName)) {
  114.                 if ($asString) {
  115.                     $filesString "";
  116.                     if ($addFilesString) {
  117.                         $addFilesCount 3;
  118.                         foreach (glob("$path/$objName/*") as $filePath) {
  119.                             if (is_dir($filePath)) {
  120.                                 continue;
  121.                             }
  122.                             if ($addFilesCount == 0) {
  123.                                 $filesString .= ($filesString ", " "") . "...";
  124.                                 break;
  125.                             }
  126.                             $filesString .= ($filesString ", " "") . self::getPathStructure($filePath)['lastSegment'];
  127.                             $addFilesCount--;
  128.                         }
  129.                         if (strlen($filesString) > 150) {
  130.                             $filesString substr($filesString0150) . "...";
  131.                         }
  132.                         if ($filesString) {
  133.                             $filesString "     ($filesString)";
  134.                         }
  135.                     }
  136.                     $strDirStructure .= $_dirLevel '- ' $objName $filesString "\r\n" .
  137.                         self::getAllSubdirs($path DIRECTORY_SEPARATOR $objNametrue$addFilesString$_dirLevel "     "true);
  138.                 } else {
  139.                     $dirStructure[$objName] = ($recursively self::getAllSubdirs($path DIRECTORY_SEPARATOR $objNamefalse$addFilesString""true) :
  140.                         $path DIRECTORY_SEPARATOR $objName);
  141.                 }
  142.             }
  143.         }
  144.         if ($asString) {
  145.             return $strDirStructure;
  146.         } else {
  147.             return $dirStructure;
  148.         }
  149.     }
  150.     public static function createGuid(int $length 16)
  151.     {
  152.         $guid bin2hex(openssl_random_pseudo_bytes($length));
  153.         return $guid;
  154.     }
  155.     public static function createToken(): string
  156.     {
  157.         return self::createGuid(32);
  158.     }
  159.     /**
  160.      * @param array|string $addDataBefore
  161.      * @param array|string|mixed $data
  162.      * @param $fileNameWithoutExtension
  163.      */
  164.     public static function appendLog($data$fileNameWithoutExtension 'tests'$addDataBefore null$toOneLine true)
  165.     {
  166.         try {
  167.             $path null;
  168.             if (is_file($fileNameWithoutExtension)) {
  169.                 $path $fileNameWithoutExtension;
  170.             } else {
  171.                 $path self::findParentPathWithDir(__DIR__, ['src''var']) . '/var/log/' $fileNameWithoutExtension ".log";
  172.             }
  173.             if (is_array($data)) {
  174. //            $data = json_encode($data);
  175.                 $data = ($toOneLine StringUtils::arrayToOneLineString($data) : var_export($datatrue));
  176.             }
  177.             if ($addDataBefore) {
  178.                 if (is_array($addDataBefore)) {
  179.                     $addDataBeforeArr $addDataBefore;
  180.                     $addDataBefore "";
  181.                     foreach ($addDataBeforeArr as $dataLable => $dataTmp) {
  182.                         if (is_object($dataTmp) && (ReflectionUtils::hasParentClass($dataTmp, [\Exception::class, \Error::class]))) {
  183.                             if (is_numeric($dataLable)) {
  184.                                 $dataLable get_class($dataTmp);
  185.                             }
  186.                             $dataTmp $dataTmp->getMessage() . ". (File: " $dataTmp->getFile() . ":" $dataTmp->getLine() .
  187.                                 ". Trace: " var_export(self::getBacktrace($dataTmp->getTrace()), true) . ")";
  188.                         }
  189.                         if (!is_numeric($dataLable)) {
  190.                             $dataLable ucfirst($dataLable);
  191.                         }
  192.                         $addNext "";
  193.                         if (is_numeric($dataLable) && is_string($dataTmp)) {
  194.                             $addNext ucfirst($dataTmp);
  195.                         } else {
  196.                             if (is_bool($dataTmp) || is_null($dataTmp)) {
  197.                                 $dataTmp json_encode($dataTmp);
  198.                             }
  199.                             $addNext "{$dataLable}: " $dataTmp;
  200.                         }
  201.                         $addDataBefore .= ($addDataBefore ". " "") . $addNext;
  202.                     }
  203.                 }
  204.                 $data $addDataBefore $data "\r\n";
  205.             }
  206.             self::writeTxtToFile($data$pathnullfalsenullnull,
  207.                 falsetruetrue);
  208.         } catch (\Exception $exception) {
  209.             try {
  210.                 self::writeTxtToFile("Cant append log. Exception: {$exception->getMessage()}{$exception->getFile()}:{$exception->getLine()}$path,
  211.                     nullfalsenullnull,
  212.                     falsetruetrue);
  213.             } catch (\Exception $exception) {
  214.             }
  215.         }
  216.     }
  217.     public static function canAddDebugLog(): bool
  218.     {
  219.         return isset($_ENV["DEBUG_LOG"]) && $_ENV["DEBUG_LOG"] == 1;
  220.     }
  221.     public static function appendTestLog($data$addDataBefore null$toOneLine true)
  222.     {
  223.         self::appendLog($data'tests'$addDataBefore$toOneLine);
  224.     }
  225.     public static function appendQueryLog($data$addDataBefore null$toOneLine true)
  226.     {
  227.         self::appendLog($data'queryLog'$addDataBefore$toOneLine);
  228.     }
  229.     public static function appendPyTgStderrLog($data$addDataBefore null$toOneLine true)
  230.     {
  231.         self::appendLog($data'pyTgStderrLog'$addDataBefore$toOneLine);
  232.     }
  233.     public static function appendSuccessRoomAccessLog($data$addDataBefore null$toOneLine true)
  234.     {
  235.         self::appendLog($data'successRoomAccess'$addDataBefore$toOneLine);
  236.     }
  237.     public static function appendUserStartedStreamLog($data$addDataBefore null$toOneLine true)
  238.     {
  239.         self::appendLog($data'userStartedStream'$addDataBefore$toOneLine);
  240.     }
  241.     public static function appendAuthLog($data$addDataBefore null$toOneLine true)
  242.     {
  243.         self::appendLog($data'authLog'$addDataBefore$toOneLine);
  244.     }
  245.     /**
  246.      * {@inheritdoc}
  247.      * @return null
  248.      */
  249.     static function writeTxtToFile($data$fileName 'logs.txt'string $findRootDirName nullbool $jsonEncode false,
  250.                                    $caption null$do_var_export false$is_all_defined_vars false$addDate false,
  251.                                    bool $append false)
  252.     {
  253.         if ($findRootDirName) {
  254.             $logDirPath "./";
  255.             $logDirRealPath null;
  256.             $dirLevel 0;
  257.             while (!str_ends_with(($logDirRealPath realpath($logDirPath)), "/" $findRootDirName)) {
  258.                 $logDirPath .= "../";
  259.                 $dirLevel++;
  260.                 if ($dirLevel == 500) {
  261.                     throw new \Exception('Cant\'t find root dir.');
  262.                 }
  263.             }
  264.             $fileName $logDirRealPath "/" $fileName;
  265.         }
  266.         try {
  267.             if ($is_all_defined_vars) {
  268.                 if ($caption == null) {
  269.                     $caption "all_defined_vars";
  270.                 }
  271.                 $allVars = [];
  272.                 foreach ($data as $varName => $varData) {
  273.                     $isClassObj = !is_bool($varData) && !is_int($varData) && !is_float($varData) && !is_string($varData) && !is_array($varData);
  274.                     if ($isClassObj) {
  275.                         $allVars[$varName] = get_class($varData);
  276.                     } else {
  277.                         $allVars[$varName] = $varData;
  278.                     }
  279.                     if (is_array($varData)) {
  280.                         $allVars[$varName] = array_keys($varData);
  281.                     }
  282.                 }
  283.                 $data $allVars;
  284.             }
  285.         } catch (\Exception $ex) {
  286.             $data "error: " $ex->getMessage();
  287.         }
  288.         if ($do_var_export) {
  289.             $data var_export($datatrue);
  290.         }
  291.         if ($caption) {
  292. //            $data = $caption . "-->\n" . $data . "\n<--" . $caption;
  293.             $data $caption ": " $data;
  294.         }
  295.         if ($addDate) {
  296.             $data = (new \DateTime())->format('d.m.Y H:i:s') . ": " $data;
  297.         }
  298.         $flags 0;
  299.         if ($append) {
  300.             $flags FILE_APPEND LOCK_EX;
  301.         }
  302.         if ($jsonEncode) {
  303.             $data json_encode($dataJSON_PRETTY_PRINT);
  304.         }
  305.         $myfile file_put_contents($fileName$data PHP_EOL$flags);
  306.     }
  307.     public static function getHostUrl($slashAtEnd true): string
  308.     {
  309.         $url $_SERVER["REQUEST_SCHEME"] . "://" $_SERVER['SERVER_NAME'] .
  310.             (isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] ? ":" $_SERVER['SERVER_PORT'] : "") .
  311.             ($slashAtEnd "/" "");
  312.         return $url;
  313.     }
  314.     public static function filterArray($array$callback null$childElementMethodName null$childElementMethodResult null): array
  315.     {
  316.         $array array_filter($array, function ($curElement) use ($callback$childElementMethodName$childElementMethodResult) {
  317.             $result = (!$callback || ($callback($curElement)) &&
  318.                 (!$childElementMethodName || call_user_func([$curElement$childElementMethodName]) == $childElementMethodResult));
  319.             return $result;
  320.         });
  321.         return $array;
  322.     }
  323.     public static function getBacktrace(array $backtrace null): ?array
  324.     {
  325.         if (!$backtrace) {
  326.             $backtrace debug_backtrace();
  327.         }
  328.         foreach ($backtrace as &$trace) {
  329.             if (isset($trace['file']) && isset($trace["line"]) && isset($trace["function"])) {
  330.                 $trace "{$trace['file']}:{$trace["line"]} (->{$trace["function"]})";
  331.             } else {
  332.                 $trace "...";
  333.             }
  334.         }
  335.         return $backtrace;
  336.     }
  337.     public static function removeKey(array $arraystring $key): array
  338.     {
  339.         unset($array[$key]);
  340.         return $array;
  341.     }
  342.     /**
  343.      * @param null|array|mixed $object
  344.      * @param array|mixed $data
  345.      * @param \Closure|null $createObjectCallback
  346.      */
  347.     public function setObjectDataFromArray($object null$data$includedDataKeys null,
  348.                                            \Closure $createObjectCallback null,
  349.         $beforeObjectPersistCallback null)
  350.     {
  351.         if ($object && !is_array($object)) {
  352.             $object = [$object];
  353.         }
  354.         if (!is_array($data)) {
  355.             $data = [$data];
  356.         }
  357.         $objectIndex = -1;
  358.         foreach ($data as $currentData) {
  359.             $objectIndex++;
  360.             $currentObject null;
  361.             if (!$object) {
  362.                 $currentObject $createObjectCallback();
  363.             } else {
  364.                 $currentObject $object[$objectIndex];
  365.             }
  366.             foreach ($currentData as $setMethod => $dataElement) {
  367.                 if ($includedDataKeys && !in_array($setMethod$includedDataKeys)) {
  368.                     continue;
  369.                 }
  370.                 $setMethod 'set' ucfirst($setMethod);
  371.                 if (method_exists($currentObject$setMethod)) {
  372.                     $currentObject->{$setMethod}($dataElement);
  373.                 }
  374.             }
  375.             if (!$object) {
  376.                 if (!$beforeObjectPersistCallback || $beforeObjectPersistCallback($currentObject$currentData)) {
  377.                     $this->em->persist($currentObject);
  378.                     $this->em->flush();
  379.                 }
  380.             }
  381.         }
  382.     }
  383.     /**
  384.      * @param mixed|array $object
  385.      */
  386.     public static function objectToArray($object$includedDataKeys$onDataCreateCallback null,
  387.                                          array $overrideKeyNames null): array
  388.     {
  389.         $objects $object;
  390.         if (!is_array($objects)) {
  391.             $objects = [$object];
  392.         }
  393.         $objectsData = [];
  394.         $objectsDataIndex = -1;
  395.         foreach ($objects as $currentObject) {
  396.             $objectsDataIndex++;
  397.             $currentObjectData = [];
  398.             foreach ($includedDataKeys as $dataKey) {
  399.                 $getMethod 'get' ucfirst($dataKey);
  400.                 if ($overrideKeyNames) {
  401.                     if (in_array($dataKeyarray_keys($overrideKeyNames))) {
  402.                         $dataKey $overrideKeyNames[$dataKey];
  403.                     }
  404.                 }
  405.                 $currentObjectData[$dataKey] = $currentObject->{$getMethod}();
  406.             }
  407.             if ($onDataCreateCallback) {
  408.                 $currentObjectData $onDataCreateCallback($currentObject$currentObjectData);
  409.             }
  410.             if ($currentObjectData) {
  411.                 $objectsData[$objectsDataIndex] = $currentObjectData;
  412.             }
  413.         }
  414.         if (is_array($object)) {
  415.             return $objectsData;
  416.         } else {
  417.             return $objectsData[0];
  418.         }
  419.     }
  420.     /**
  421.      * @param mixed|array $object
  422.      */
  423.     public static function objectToId($object)
  424.     {
  425.         $objects $object;
  426.         $isArray is_array($objects);
  427.         if (!$isArray) {
  428.             $objects = [$object];
  429.         }
  430.         $result = [];
  431.         foreach ($objects as $object) {
  432.             $result[] = $object->getId();
  433.         }
  434.         if ($isArray) {
  435.             return $result;
  436.         } else {
  437.             return $result[0];
  438.         }
  439.     }
  440.     public static function objectToStringId($object): string
  441.     {
  442.         return implode(","self::objectToId($object));
  443.     }
  444.     public static function sumObjectField($object$field)
  445.     {
  446.         $objects $object;
  447.         $isArray is_array($objects);
  448.         if (!$isArray) {
  449.             $objects = [$object];
  450.         }
  451.         $result 0;
  452.         $field "get" ucfirst($field);
  453.         foreach ($objects as $object) {
  454.             $result += $object->$field();
  455.         }
  456.         return $result;
  457.     }
  458.     /**
  459.      *
  460.      * $callback = function($curElement, $elementIndex, $key) {};
  461.      *
  462.      * @param $array
  463.      * @param null $callback
  464.      * @param null $childElementName
  465.      * @param null $childElementValue
  466.      * @param null $element
  467.      * @param null $skipElement
  468.      * @param null $childArraysElementValueRegex
  469.      * @param bool $returnDetailedResult
  470.      * @return array|int
  471.      */
  472.     static public function findIndexInArray($array$callback null$childElementName null$childElementValue null$element null,
  473.                                             $skipElement null$childArraysElementValueRegex nullbool $returnDetailedResult false,
  474.                                             $childElementMethodName null$childElementMethodResult null$childArraysElementValue null)
  475.     {
  476.         $elementIndex 0;
  477.         $foundIndex = -1;
  478.         $foundKey null;
  479.         $detailedResult = [];
  480.         foreach ($array as $key => $curElement) {
  481.             $found = (!$skipElement || $skipElement != $curElement) &&
  482.                 ((!$callback || $callback($curElement$elementIndex$key)) &&
  483.                     (!$childElementName || (isset($curElement[$childElementName]) && (!$childElementValue || $curElement[$childElementName] == $childElementValue))) &&
  484.                     (!$element || $element == $curElement) &&
  485.                     (!$childElementMethodName || call_user_func([$curElement$childElementMethodName]) == $childElementMethodResult));
  486.             if ($found && ($childArraysElementValueRegex || $childArraysElementValue)) {
  487.                 $found false;
  488.                 $detailedResult['foundChildElementValue'] = null;
  489.                 $tmpArray = ($childElementName $curElement[$childElementName] : $curElement);
  490.                 foreach ($tmpArray as $childKey => $curChildElement) {
  491.                     if ((!$childArraysElementValueRegex || preg_match($childArraysElementValueRegex$curChildElement)) &&
  492.                         (!$childArraysElementValue || $curChildElement == $childArraysElementValue))
  493.                     {
  494.                         $detailedResult['foundChildElementValue'] = $curChildElement;
  495.                         $found true;
  496.                         break;
  497.                     }
  498.                 }
  499.             }
  500.             if ($found) {
  501.                 $foundIndex $elementIndex;
  502.                 $foundKey $key;
  503.                 break;
  504.             }
  505.             $elementIndex++;
  506.         }
  507.         if ($returnDetailedResult) {
  508.             $detailedResult['index'] = $foundIndex;
  509.             $detailedResult['key'] = $foundKey;
  510.             return $detailedResult;
  511.         } else {
  512.             return $foundIndex;
  513.         }
  514.     }
  515.     /**
  516.      * @return array|int
  517.      */
  518.     static public function findIndexInArrayByElement($array$element null)
  519.     {
  520.         return self::findIndexInArray($arraynullnullnull$element);
  521.     }
  522.     public static function findInArrayByChildArrayElementValue($array$childArrayElementValue$childElementName null,
  523.                                                                bool $returnDetailedResult false)
  524.     {
  525.         return self::findInArray($arraynull$childElementNamenullnullnull,
  526.             nullnull$returnDetailedResultnull,
  527.             null$childArrayElementValue);
  528.     }
  529.     static public function findInArray($array$callback null$childElementName null$childElementValue null$element null,
  530.                                        $skipElement null$getResultElementValueWithName null,
  531.                                        $childArraysElementValueRegex null,
  532.                                        bool $returnDetailedResult false$childElementMethodName null$childElementMethodResult null,
  533.         $childArraysElementValue null)
  534.     {
  535.         $result self::findIndexInArray($array$callback$childElementName$childElementValue$element$skipElement$childArraysElementValueRegex,
  536.             $returnDetailedResult$childElementMethodName$childElementMethodResult$childArraysElementValue);
  537.         $index = ($returnDetailedResult $result['index'] : $result);
  538.         $subResult $index;
  539.         if ($index > -|| is_string($index)) {
  540.             $foundKey array_keys($array)[$index];
  541.             if ($getResultElementValueWithName) {
  542.                 $subResult $array[$foundKey][$getResultElementValueWithName];
  543.             } else {
  544.                 $subResult $array[$foundKey];
  545.             }
  546.         } else {
  547.             $subResult null;
  548.         }
  549.         if ($returnDetailedResult) {
  550.             $result['result'] = $subResult;
  551.         } else {
  552.             $result $subResult;
  553.         }
  554.         return $result;
  555.     }
  556.     public static function findInArrayByElementMethodResult($array$childElementMethodName$childElementMethodResult)
  557.     {
  558.         return self::findInArray($arraynullnullnullnullnull,
  559.             nullnullfalse$childElementMethodName,
  560.             $childElementMethodResult);
  561.     }
  562.     public static function convertArray(array $array$elementMethodName null)
  563.     {
  564.         foreach ($array as $key => $value) {
  565.             if ($elementMethodName) {
  566.                 $array[$key] = call_user_func([$value$elementMethodName]);
  567.             }
  568.         }
  569.         return $array;
  570.     }
  571.     public static function sumArray($array$elementMethodName null, array $keys null): float
  572.     {
  573.         if ($keys) {
  574.             return Other::sumArray(array_intersect_key($arrayarray_flip($keys)));
  575.         }
  576.         /** @var float $sum */
  577.         $sum 0.0;
  578.         foreach ($array as $key => $value) {
  579.             if ($elementMethodName) {
  580.                 $sum += (float)call_user_func([$value$elementMethodName]);
  581.             } else {
  582.                 $sum += (float)$value;
  583.             }
  584.         }
  585.         return $sum;
  586.     }
  587.     public static function getVarPath(?string $subPath null): string
  588.     {
  589.         $path self::getRootPath'/var/' . ($subPath ?: "")) ;
  590.         return $path;
  591.     }
  592.     public static function getRootPath(?string $subPath null): string
  593.     {
  594.         $path self::findParentPathWithDir(__DIR__, ['src''var']) . ($subPath ?: "");
  595.         return $path;
  596.     }
  597.     public static function setSettings(array $settings nullstring $settingName null$settingValue null$fileName "settings.json"$isAbsolutePath false)
  598.     {
  599.         if (!$isAbsolutePath) {
  600.             $fileName self::getVarPath($fileName);
  601.         }
  602.         if ($settingName) {
  603.             $settings = [$settingName => $settingValue];
  604.         }
  605.         $currentSettings = [];
  606.         if (is_file($fileName)) {
  607.             $currentSettings json_decode(file_get_contents($fileName), true);
  608.         }
  609.         foreach ($settings as $key => $value) {
  610.             $currentSettings[$key] = $value;
  611.         }
  612.         self::writeTxtToFile($currentSettings$fileNamenulltrue);
  613.     }
  614.     /**
  615.      * @param string|null $settingName
  616.      * @param bool $nullIfNotExists
  617.      * @param $fileName
  618.      * @return array|mixed|null
  619.      * @throws \Exception
  620.      */
  621.     public static function getSettings(string $settingName nullbool $nullIfNotExists false$fileName "settings.json"$isAbsolutePath false)
  622.     {
  623.         if (!$isAbsolutePath) {
  624.             $fileName self::getVarPath($fileName);
  625.         }
  626.         $settings = [];
  627.         if (is_file($fileName)) {
  628.             $settings json_decode(file_get_contents($fileName), true);
  629.         }
  630.         if ($settingName) {
  631.             if (!isset($settings[$settingName])) {
  632.                 if ($nullIfNotExists) {
  633.                     return null;
  634.                 } else {
  635.                     throw new \Exception((is_file($fileName) ? "Setting not exists: $settingName"Settings file not exists: $fileName"));
  636.                 }
  637.             }
  638.             return $settings[$settingName];
  639.         } else {
  640.             return $settings;
  641.         }
  642.     }
  643.     public static function findInChildArray($array$childArrayKey$childArrayValue): ?array
  644.     {
  645.         foreach ($array as $key => $element) {
  646.             if (isset($element[$childArrayKey]) && $element[$childArrayKey] == $childArrayValue) {
  647.                 return ["key" => $key"childKey" => $childArrayKey"value" => $childArrayValue"childArray" => $element];
  648.             }
  649.         }
  650.         return null;
  651.     }
  652.     public static function getIdIndexedEntityArray(array $entities): array
  653.     {
  654.         $arr = [];
  655.         foreach ($entities as $item) {
  656.             $arr[$item->getId()] = $item;
  657.         }
  658.         return $arr;
  659.     }
  660.     public static function removeFilesByRegex($directory$regex) {
  661.         $files glob($directory '/*');
  662.         $removeFiles = [];
  663.         if ($files !== false) {
  664.             foreach ($files as $file) {
  665.                 if (preg_match($regexbasename($file))) {
  666.                     $removeFiles[] = $file;
  667.                 }
  668.             }
  669.             foreach ($removeFiles as $file) {
  670.                 unlink($file);
  671.             }
  672.         }
  673.     }
  674.     public static function getRequestAttributes(Request $request)
  675.     {
  676.         return array_intersect_key($request->attributes->all(),
  677.             array_flip(array_filter(array_keys($request->attributes->all()),
  678.                 function ($key) {return !str_starts_with($key"_");})));
  679.     }
  680.     public static function sleepMs($milliseconds) {
  681.         $microseconds $milliseconds 1000;
  682.         usleep($microseconds);
  683.     }
  684.     public static function filterArrayNotNull(array $arr): array
  685.     {
  686.         return array_filter($arr, function ($value) {
  687.             return $value !== null;
  688.         });
  689.     }
  690.     public static function assertObjectHydrated($objectbool $hydrateFlag null)
  691.     {
  692.         if (!$object && !$hydrateFlag) {
  693.             throw new \Exception("Object not hydrated");
  694.         }
  695.     }
  696.     /**
  697.      * @param array|mixed $value
  698.      * @param $callback
  699.      * @return void
  700.      */
  701.     public static function forEach($value$callback): void
  702.     {
  703.         if (is_array($value)) {
  704.             foreach ($value as $element) {
  705.                 $callback($element);
  706.             }
  707.         } else {
  708.             $callback($value);
  709.         }
  710.     }
  711.     public static function runProcess(string $namestring $args$throwOnNonZeroExitCode falsebool $async false): array
  712.     {
  713. //        $command = "$name " . escapeshellarg($args);
  714.         $command = ($async "nohup " "") . "$name $args. ($async " > " $_ENV['PYTHON_TELEGRAM_PATH'] . "/var/log/aaa 2>&1 & echo $!" "");
  715. //        if (strpos($command, "python3")) {
  716. //            throw new \Exception("$command");
  717. //        }
  718.         if ($async) {
  719.             exec($command$output);
  720.             $pid = (int)$output[0];
  721.             return [
  722.                 'pid' => $pid,
  723.             ];
  724.         }
  725.         // Open a process for the Python script
  726.         $descriptorspec = [
  727.             => ['pipe''r'], // stdin is a pipe that the child will read from
  728.             => ['pipe''w'], // stdout is a pipe that the child will write to
  729.             => ['pipe''w']  // stderr is a pipe that the child will write to
  730.         ];
  731.         $process proc_open($command$descriptorspec$pipes);
  732.         if (is_resource($process)) {
  733.             $status proc_get_status($process);
  734.             $pid $status['pid'] ?? null;
  735.             fclose($pipes[0]);
  736.             $stdout stream_get_contents($pipes[1]);
  737.             fclose($pipes[1]);
  738.             $stderr stream_get_contents($pipes[2]);
  739.             fclose($pipes[2]);
  740.             $exitCode proc_close($process);
  741.             // Output any errors
  742. //            if (!empty($stderr)) {
  743. //                throw new \Exception("Errors:\n" . $stderr) ;
  744. //            }
  745.             $result = [
  746.                 'stdout' => trim($stdout),
  747.                 'stderr' => $stderr,
  748.                 'exitCode' => $exitCode,
  749.                 "pid" => $pid,
  750.             ];
  751.             if ($throwOnNonZeroExitCode && $exitCode !== 0) {
  752.                 throw new \Exception("Exit code is not 0: " $stderr);
  753.             }
  754.             return $result;
  755.         } else {
  756.             throw new \Exception("Failed to open process.") ;
  757.         }
  758.     }
  759. }