/** * @ignore */ public static function onThirdPartyUpdateByPackageManager() { if (!self::isInCliMode()) { // This method can be run in CLI mode only. assert('false', vs(isset($this), get_defined_vars())); } $timeoutPause = new CTimeoutPause(); CShell::speak("Processing third-party components ..."); $tpDps = CFile::listDirectories(CFilePath::absolute($GLOBALS["PHRED_PATH_TO_THIRD_PARTY"])); $ignorePackages = CConfiguration::option("upd.thirdPartyOopWrappingIgnorePackages"); $ignorePackagesL2 = CArray::filter($ignorePackages, function ($package) { return CString::find($package, "/"); }); $newTpDps = CArray::make(); $len = CArray::length($tpDps); for ($i = 0; $i < $len; $i++) { $tpDp = $tpDps[$i]; $dirName = CFilePath::name($tpDp); if (!CArray::find($ignorePackages, $dirName)) { $dpHasL2DirsToIgnore = CArray::find($ignorePackagesL2, $dirName, function ($packageL2, $dirName) { return CString::equals(CFilePath::directory($packageL2), $dirName); }); if (!$dpHasL2DirsToIgnore) { CArray::push($newTpDps, $tpDp); } else { $tpSubDps = CFile::listDirectories($tpDp); $tpSubDps = CArray::filter($tpSubDps, function ($subDp) use($ignorePackagesL2) { return !CArray::find($ignorePackagesL2, $subDp, function ($packageL2, $subDp) { return CString::endsWith($subDp, $packageL2); }); }); CArray::pushArray($newTpDps, $tpSubDps); } } } $tpDps = $newTpDps; $wrapProtectedMethods = CConfiguration::option("upd.thirdPartyOopWrappingInProtectedMethods"); $wrapPrivateMethods = CConfiguration::option("upd.thirdPartyOopWrappingInPrivateMethods"); static $s_stdPhpTag = "<?php"; static $s_progressResolution = 0.05; $prevProgressDivR = 0; $tpDpsLen = CArray::length($tpDps); for ($i0 = 0; $i0 < $tpDpsLen; $i0++) { $tpFps = CFile::reFindFilesRecursive($tpDps[$i0], "/\\.php\\d?\\z/"); $tpFpsLen = CArray::length($tpFps); for ($i1 = 0; $i1 < $tpFpsLen; $i1++) { $fileCode = CFile::read($tpFps[$i1]); if (!CString::find($fileCode, self::$ms_thirdPartyAlreadyOopWrappedMark)) { $parser = new PhpParser\Parser(new PhpParser\Lexer()); try { // Parse the code. $statements = $parser->parse($fileCode); // Wrap the code into OOP. $traverser = new PhpParser\NodeTraverser(); $mainVisitor = new CMainVisitor($wrapProtectedMethods, $wrapPrivateMethods); $traverser->addVisitor($mainVisitor); $statements = $traverser->traverse($statements); $wrappedCode = (new PhpParser\PrettyPrinter\Standard())->prettyPrint($statements); $phpTagPos = CString::indexOf($wrappedCode, $s_stdPhpTag); if ($phpTagPos == -1) { $wrappedCode = "{$s_stdPhpTag}\n\n{$wrappedCode}"; $phpTagPos = 0; } $wrappedCode = CString::insert($wrappedCode, $phpTagPos + CString::length($s_stdPhpTag), "\n\n" . self::$ms_thirdPartyAlreadyOopWrappedMark); // Save. CFile::write($tpFps[$i1], $wrappedCode); } catch (PhpParser\Error $parserError) { CShell::say("\nPhpParser: " . $tpFps[$i1] . ", at line " . $parserError->getRawLine() . ": " . $parserError->getRawMessage()); } } $progress = (double) ($i0 / $tpDpsLen + 1 / $tpDpsLen * $i1 / $tpFpsLen); $progressDivR = CMathi::floor($progress / $s_progressResolution); if ($progressDivR != $prevProgressDivR) { $perc = CMathi::round($progressDivR * $s_progressResolution * 100); CShell::speak("{$perc}%"); } $prevProgressDivR = $progressDivR; } } CShell::speak("100%"); CShell::say("Done."); $timeoutPause->end(); }
public function testFindBinary() { $array = CArray::fromElements("oua", "vnf", "fnf", "aod", "tvi", "nbt", "jny", "vor", "rfd", "cvm", "hyh", "kng", "ggo", "uea", "hkb", "qbk", "xla", "uod", "jzi", "chw", "ssy", "olr", "bzl", "oux", "ltk", "bah", "khu", "msr", "pqv", "npb", "mtb", "eku", "vcv", "vbv", "wuo", "lrw", "bkw", "ezz", "jtc", "dwk", "dsq", "kzu", "oey", "vbi", "seh", "klz", "asj", "gzg", "ccs", "qop"); $arrayOrig = CArray::makeCopy($array); $len = CArray::length($arrayOrig); // Sort the array first. CArray::sort($array, CComparator::ORDER_ASC); // Using the default comparators. for ($i = 0; $i < $len; $i += 3) { $string = $arrayOrig[$i]; $foundAtPos0; CArray::find($array, $string, CComparator::EQUALITY, $foundAtPos0); $foundAtPos1; $found = CArray::findBinary($array, $string, CComparator::ORDER_ASC, $foundAtPos1); $this->assertTrue($found); $this->assertTrue($foundAtPos1 == $foundAtPos0); } // Using custom comparators. $comparatorEquality = function ($string0, $string1) { return CString::toLowerCase($string0) === CString::toLowerCase($string1); }; $comparatorOrderAsc = function ($string0, $string1) { return CString::compare(CString::toLowerCase($string0), CString::toLowerCase($string1)); }; for ($i = 0; $i < $len; $i += 5) { $string = CString::toUpperCase($arrayOrig[$i]); $foundAtPos0; CArray::find($array, $string, $comparatorEquality, $foundAtPos0); $foundAtPos1; $found = CArray::findBinary($array, $string, $comparatorOrderAsc, $foundAtPos1); $this->assertTrue($found); $this->assertTrue($foundAtPos1 == $foundAtPos0); } // Special cases. $array = CArray::fromElements("a", "b"); $found = CArray::findBinary($array, "a"); $this->assertTrue($found); $found = CArray::findBinary($array, "b"); $this->assertTrue($found); $found = CArray::findBinary($array, "c"); $this->assertFalse($found); $array = CArray::fromElements("a"); $found = CArray::findBinary($array, "a"); $this->assertTrue($found); $array = CArray::make(); $found = CArray::findBinary($array, "a"); $this->assertFalse($found); }
protected function hasHeader($headerName) { $headerName = CString::trim($headerName); return CArray::find($this->m_requestHeaders, $headerName, function ($element0, $element1) { return CRegex::find($element0, "/^\\h*" . CRegex::enterTd($element1) . "\\h*:/i"); }); }
/** * Determines if an array contains an element with a specified value, using linear search. * * You can use your own comparator for the search, but the default comparator has got you covered when searching * for scalar values, such as `string`, `int`, `float`, and `bool`. And the default comparator is smart enough to * know how to compare objects of those classes that conform to the IEquality or IEqualityAndOrder interface * (static or not), including CUStringObject, CArrayObject, CMapObject, CTime etc. See the * [CComparator](CComparator.html) class for more on this. * * @param mixed $whatElement The value of the searched element. * @param callable $comparator **OPTIONAL. Default is** `CComparator::EQUALITY`. The function or method to be * used for the comparison of element values while searching. If this parameter is provided, the comparator should * take two parameters, with the first parameter being an element from the array and the second parameter being the * searched element, and return `true` if the two elements are equal and `false` otherwise. * @param reference $foundAtPos **OPTIONAL. OUTPUT.** If an element has been found after the method was called * with this parameter provided, the parameter's value, which is of type `int`, indicates the position of the first * found element, i.e. the element at the leftmost position if the array contains more than one of such elements. * * @return bool `true` if such element was found in the array, `false` otherwise. * * @link CComparator.html CComparator */ public function find($whatElement, $comparator = CComparator::EQUALITY, &$foundAtPos = null) { return CArray::find($this->m_splArray, $whatElement, $comparator, $foundAtPos); }
/** * Starts a session by sending out the added requests. * * @param reference $success **OPTIONAL. OUTPUT.** After the method is called with this parameter provided, the * parameter's value tells whether the session was successful. * * @return void */ public function start(&$success = null) { $success = true; if ($this->m_hasError) { $success = false; return; } if (CArray::isEmpty($this->m_requestRecordsQueue)) { // Nothing to do. return; } // Current policy is to disable HTTP pipelining. $res = curl_multi_setopt($this->m_multiCurl, CURLMOPT_PIPELINING, 0); if (!$res) { // Should never get in here as long as cURL options are being set correctly, hence the assertion. assert('false', vs(isset($this), get_defined_vars())); $this->m_hasError = true; $this->m_errorMessage = "The 'curl_multi_setopt' function failed."; $success = false; $this->finalize(); return; } $anySuccessfulRequests = false; // Disable the script's execution timeout before getting into the session. $timeoutPause = new CTimeoutPause(); $numRunningRequests = 0; // also the index of the next request to send while (true) { // From the request queue, add as many normal cURL handles to the multi cURL handle as it is allowed by the // maximum number of concurrent requests, priorly setting internal options for every request. while ($numRunningRequests < CArray::length($this->m_requestRecordsQueue) && $numRunningRequests < $this->m_maxNumConcurrentRequests) { $requestRecord = $this->m_requestRecordsQueue[$numRunningRequests]; $request = $requestRecord[0]; $onCompleteCallback = $requestRecord[1]; $newCookieSession = $requestRecord[2]; $requestCurl = $request->curl(); // Set cURL options for the normal cURL handle, having created a temporary file for cookie storage if // needed. $requestSetOptSuccess; if ($this->m_cookiesAreEnabled && $request->isHttp()) { if (!isset($this->m_cookiesFp)) { $this->m_cookiesFp = CFile::createTemporary(); } $request->setInternalOptions($requestSetOptSuccess, $this->m_cookiesFp, $newCookieSession); } else { $request->setInternalOptions($requestSetOptSuccess); } if (!$requestSetOptSuccess) { if (isset($onCompleteCallback)) { call_user_func($onCompleteCallback, false, "", $request, $this); } CArray::remove($this->m_requestRecordsQueue, $numRunningRequests); continue; } // Add the normal cURL handle to the multi cURL handle. $res = curl_multi_add_handle($this->m_multiCurl, $requestCurl); if ($res != 0) { $this->m_hasError = true; $curlError = curl_multi_strerror($res); $this->m_errorMessage = is_cstring($curlError) && !CString::isEmpty($curlError) ? $curlError : "The 'curl_multi_add_handle' function failed."; $success = false; $timeoutPause->end(); $this->finalize(); return; } $numRunningRequests++; } if ($numRunningRequests == 0) { break; } // Process the currently added requests until complete or no more data is available. Although // `CURLM_CALL_MULTI_PERFORM` is deprecated since libcurl 7.20, keep it for compatibility reasons. $numRunningTransfers; do { $multiExecRes = curl_multi_exec($this->m_multiCurl, $numRunningTransfers); } while ($multiExecRes == CURLM_CALL_MULTI_PERFORM); if ($multiExecRes != CURLM_OK) { $this->m_hasError = true; $curlError = curl_multi_strerror($multiExecRes); $this->m_errorMessage = is_cstring($curlError) && !CString::isEmpty($curlError) ? $curlError : "The 'curl_multi_exec' function failed."; $success = false; $timeoutPause->end(); $this->finalize(); return; } // Check for completed requests, call the callback function for any completed one (if such a function is // defined), finalize completed requests, and remove completed requests from the queue. while (true) { $completedRequestInfo = curl_multi_info_read($this->m_multiCurl); if (!is_cmap($completedRequestInfo)) { break; } // A request has completed. assert('$completedRequestInfo["msg"] == CURLMSG_DONE', vs(isset($this), get_defined_vars())); $requestCurl = $completedRequestInfo["handle"]; $requestRes = $completedRequestInfo["result"]; $requestRecordPos; $found = CArray::find($this->m_requestRecordsQueue, $requestCurl, function ($requestRecord, $requestCurl) { $request = $requestRecord[0]; return $request->curl() == $requestCurl; }, $requestRecordPos); assert('$found', vs(isset($this), get_defined_vars())); $requestRecord = $this->m_requestRecordsQueue[$requestRecordPos]; $request = $requestRecord[0]; $onCompleteCallback = $requestRecord[1]; // Remove the normal cURL handle from the multi cURL handle. $res = curl_multi_remove_handle($this->m_multiCurl, $requestCurl); if ($res != 0) { $this->m_hasError = true; $curlError = curl_multi_strerror($res); $this->m_errorMessage = is_cstring($curlError) && !CString::isEmpty($curlError) ? $curlError : "The 'curl_multi_remove_handle' function failed."; $success = false; $timeoutPause->end(); $this->finalize(); return; } if ($requestRes == CURLE_OK) { // The request has succeeded. if (isset($onCompleteCallback)) { $response; if ($request->isReturnTransferSet()) { $response = curl_multi_getcontent($requestCurl); assert('is_cstring($response)', vs(isset($this), get_defined_vars())); } else { $response = ""; } $request->onRequestCompleteOk(); // also close the normal cURL handle call_user_func($onCompleteCallback, true, $response, $request, $this); } else { $request->onRequestCompleteOk(); // also close the normal cURL handle } $anySuccessfulRequests = true; } else { // The request has failed. $curlError = curl_strerror($requestRes); if (!is_cstring($curlError)) { $curlError = ""; } $request->onRequestCompleteWithError($curlError); // also close the normal cURL handle if (isset($onCompleteCallback)) { call_user_func($onCompleteCallback, false, "", $request, $this); } } CArray::remove($this->m_requestRecordsQueue, $requestRecordPos); $numRunningRequests--; } assert('$numRunningRequests == $numRunningTransfers', vs(isset($this), get_defined_vars())); if ($numRunningTransfers > 0) { // Some requests are still being processed (by remote machines). Wait for more data to appear on // sockets, without getting hard on the CPU. do { $multiSelectRes = curl_multi_select($this->m_multiCurl); } while ($multiSelectRes == -1); } else { // No requests are being processed. Check if any requests are pending. if (CArray::isEmpty($this->m_requestRecordsQueue)) { // No requests are pending. break; } } } // Set the script's execution time limit like the session has never happened. $timeoutPause->end(); if (!$anySuccessfulRequests) { $this->m_hasError = true; $this->m_errorMessage = "None of the session's requests succeeded."; $success = false; } $this->finalize(); }