Esempio n. 1
0
 protected static function recurseValueBeforeFiltering($value, $inputFilterOrFilterCollection, &$success, $currDepth)
 {
     assert('$inputFilterOrFilterCollection instanceof CInputFilter || ' . 'is_collection($inputFilterOrFilterCollection)', vs(isset($this), get_defined_vars()));
     if ($currDepth == self::$ms_maxRecursionDepth) {
         $success = false;
         return;
     }
     $currDepth++;
     if (!is_cmap($value)) {
         // Only interested in PHP arrays.
         return $value;
     }
     if (is_carray($inputFilterOrFilterCollection)) {
         // The output value is expected to be a CArray; the keys in the arrived PHP array should be sequential.
         if (!CMap::areKeysSequential($value)) {
             $success = false;
             return;
         }
         $value = CArray::fromPArray($value);
         $len = CArray::length($value);
         if ($len != CArray::length($inputFilterOrFilterCollection)) {
             $success = false;
             return;
         }
         for ($i = 0; $i < $len; $i++) {
             $inputValue = $value[$i];
             $inputFilterElement = $inputFilterOrFilterCollection[$i];
             $inputValue = self::recurseValueBeforeFiltering($inputValue, $inputFilterElement, $success, $currDepth);
             if (!$success) {
                 return;
             }
             $value[$i] = $inputValue;
         }
     } else {
         if (is_cmap($inputFilterOrFilterCollection)) {
             // The output value is expected to be a CMap; already got one.
             foreach ($value as $inputKey => &$inputValue) {
                 if (!CMap::hasKey($inputFilterOrFilterCollection, $inputKey)) {
                     $success = false;
                     return;
                 }
                 $inputFilterElement = $inputFilterOrFilterCollection[$inputKey];
                 $inputValue = self::recurseValueBeforeFiltering($inputValue, $inputFilterElement, $success, $currDepth);
                 if (!$success) {
                     return;
                 }
             }
             unset($inputValue);
         } else {
             $success = false;
             return;
         }
     }
     return $value;
 }
Esempio n. 2
0
 /**
  * Determines if the URL in a specified string is valid.
  *
  * @param  string $url The URL string to be looked into.
  * @param  bool $ignoreProtocolAbsence **OPTIONAL. Default is** `false`. Tells whether the URL in the string may
  * still be considered valid even if it does not indicate any protocol.
  *
  * @return bool `true` if the URL in the string is valid, `false` otherwise.
  */
 public static function isValid($url, $ignoreProtocolAbsence = false)
 {
     assert('is_cstring($url) && is_bool($ignoreProtocolAbsence)', vs(isset($this), get_defined_vars()));
     $parsedUrl = parse_url($url);
     if (!is_cmap($parsedUrl)) {
         return false;
     }
     if ($ignoreProtocolAbsence && !CMap::hasKey($parsedUrl, "scheme")) {
         // No protocol seems to be specified, try with the default one.
         $url = self::DEFAULT_PROTOCOL . "://{$url}";
         $parsedUrl = parse_url($url);
         if (!is_cmap($parsedUrl)) {
             return false;
         }
         if (!CMap::hasKey($parsedUrl, "scheme")) {
             return false;
         }
     }
     if (is_cstring(filter_var($url, FILTER_VALIDATE_URL))) {
         return true;
     } else {
         if (CMap::hasKey($parsedUrl, "host")) {
             // The `filter_var` function could fail to recognize an IPv6 as the URL's host (enclosed in square
             // brackets), so, in case of a valid IPv6 being the host, replace it with an IPv4 and give the URL another
             // try.
             $host = $parsedUrl["host"];
             if (CRegex::find($host, "/^\\[.*\\]\\z/")) {
                 $host = CString::substr($host, 1, CString::length($host) - 2);
                 if (CIp::isValidV6($host)) {
                     // Should not influence the validity if the string is present anywhere else.
                     $url = CString::replace($url, "[{$host}]", "127.0.0.1");
                     if (is_cstring(filter_var($url, FILTER_VALIDATE_URL)) && is_cmap(parse_url($url))) {
                         return true;
                     }
                 }
             }
         }
     }
     return false;
 }
Esempio n. 3
0
 /**
  * Returns the keyword-value pairs of a locale.
  *
  * @return CMapObject The locale's keyword-value pairs, with values of type `CUStringObject`.
  */
 public function keywords()
 {
     assert('$this->hasKeywords()', vs(isset($this), get_defined_vars()));
     $keywords = Locale::getKeywords($this->m_name);
     return oop_m(is_cmap($keywords) ? $keywords : CMap::make());
 }
Esempio n. 4
0
 /**
  * Returns all the values assigned to a specified long option with which the script was run,
  * e.g. "--option=value1 --option=value2".
  *
  * @param  string $optionName The name of the option, excluding "-".
  *
  * @return CArrayObject The values of the option specified, where each value is of type `CUStringObject`.
  */
 public static function valuesForLongOption($optionName)
 {
     assert('is_cstring($optionName)', vs(isset($this), get_defined_vars()));
     assert('self::hasLongOptionWithValue($optionName)', vs(isset($this), get_defined_vars()));
     $opt = getopt("", ["{$optionName}:"]);
     $values = $opt[$optionName];
     return oop_a(is_cmap($values) ? CArray::fromPArray($values) : CArray::fromElements($values));
 }
Esempio n. 5
0
 /**
  * Sends a message to the recipient(s).
  *
  * @param  reference $failedAddresses **OPTIONAL. OUTPUT.** After the method is called with this parameter
  * provided, the parameter's value, which is of type `CArrayObject`, is an array containing the email addresses of
  * the recipients who failed to receive the message.
  *
  * @return int The number of recipients who have successfully received the message.
  */
 public function send(&$failedAddresses = null)
 {
     assert('isset($this->m_swiftMailer) && isset($this->m_swiftMessage)', vs(isset($this), get_defined_vars()));
     assert('(isset($this->m_from) || isset($this->m_sender) || isset($this->m_returnAddress)) && ' . '(isset($this->m_to) || isset($this->m_cc) || isset($this->m_bcc))', vs(isset($this), get_defined_vars()));
     $message = $this->m_swiftMessage;
     if (isset($this->m_from)) {
         $message->setFrom($this->m_from);
     }
     if (isset($this->m_to)) {
         $message->setTo($this->m_to);
     }
     if (isset($this->m_cc)) {
         $message->setCc($this->m_cc);
     }
     if (isset($this->m_bcc)) {
         $message->setBcc($this->m_bcc);
     }
     if (isset($this->m_sender)) {
         $message->setSender($this->m_sender);
     }
     if (isset($this->m_returnAddress)) {
         $message->setReturnPath($this->m_returnAddress);
     }
     if (isset($this->m_replyAddress)) {
         $message->setReplyTo($this->m_replyAddress);
     }
     if (isset($this->m_body)) {
         if (CString::equals($this->m_bodyType, CMimeType::PLAIN_TEXT)) {
             $this->m_body = $this->maybeWrapText($this->m_body);
         }
         $message->setBody($this->m_body, $this->m_bodyType);
     }
     if (isset($this->m_altBodiesAndTypes)) {
         $len = CArray::length($this->m_altBodiesAndTypes);
         for ($i = 0; $i < $len; $i++) {
             $bodyAndType = $this->m_altBodiesAndTypes[$i];
             $body = $bodyAndType[0];
             $type = $bodyAndType[1];
             if (CString::equals($type, CMimeType::PLAIN_TEXT)) {
                 $body = $this->maybeWrapText($body);
             }
             $message->addPart($body, $type);
         }
     }
     $paFailedAddresses;
     $res = $this->m_swiftMailer->send($message, $paFailedAddresses);
     if (is_cmap($paFailedAddresses)) {
         $failedAddresses = oop_a(CArray::fromPArray($paFailedAddresses));
     }
     $res = is_int($res) ? $res : 0;
     return $res;
 }
Esempio n. 6
0
 /**
  * Determines the order in which two values should appear in a place where it matters, assuming the ascending
  * order.
  *
  * If the values are objects of your custom class, the class should conform to the
  * [IEqualityAndOrder](IEqualityAndOrder.html) interface.
  *
  * @param  mixed $value0 The first value for comparison.
  * @param  mixed $value1 The second value for comparison.
  *
  * @return int A negative value (typically `-1`) if the first value should go before the second value, a positive
  * value (typically `1`) if the other way around, and `0` if the two values are equal.
  *
  * @link   IEqualityAndOrder.html IEqualityAndOrder
  */
 public static function orderAsc($value0, $value1)
 {
     if (CDebug::isDebugModeOn()) {
         if (!(is_cstring($value0) && is_cstring($value1) || is_carray($value0) && is_carray($value1) || is_cmap($value0) && is_cmap($value1))) {
             // With the above exceptions, the two values should be both either scalars or objects of the same
             // class.
             assert('is_object($value0) == is_object($value1)', vs(isset($this), get_defined_vars()));
             assert('!is_object($value0) || CString::equals(get_class($value0), get_class($value1))', vs(isset($this), get_defined_vars()));
         }
     }
     $className;
     if (!phred_classify_duo($value0, $value1, $className)) {
         // Compare the values as scalars.
         assert('(is_scalar($value0) || is_null($value0)) && (is_scalar($value1) || is_null($value1))', vs(isset($this), get_defined_vars()));
         return $value0 === $value1 ? 0 : ($value0 < $value1 ? -1 : 1);
     } else {
         // Compare the values as objects that may conform to one of the comparison interfaces.
         $reflClass = new ReflectionClass($className);
         if ($reflClass->implementsInterface("IEqualityAndOrderStatic")) {
             $res = call_user_func([$className, "compare"], $value0, $value1);
             assert('is_int($res)', vs(isset($this), get_defined_vars()));
             return $res;
         }
         if ($reflClass->implementsInterface("IEqualityAndOrder")) {
             $res = call_user_func([$value0, "compare"], $value1);
             assert('is_int($res)', vs(isset($this), get_defined_vars()));
             return $res;
         }
         // The class of the objects being compared does not implement any applicable comparison interfaces.
         assert('false', vs(isset($this), get_defined_vars()));
     }
 }
Esempio n. 7
0
 protected static function recurseMergingMaps(&$thisMap, $thatMap)
 {
     if (!is_array($thisMap)) {
         $thisMap =& $thisMap->toPArray();
     }
     $thatMap = parray($thatMap);
     foreach ($thatMap as $thatKey => $thatValue) {
         $goDeeper = false;
         $thisValue;
         if (is_cmap($thatValue) && self::hasKey($thisMap, $thatKey)) {
             $thisValue =& $thisMap[$thatKey];
             if (is_cmap($thisValue)) {
                 $goDeeper = true;
             }
         }
         if ($goDeeper) {
             self::recurseMergingMaps($thisValue, $thatValue);
         } else {
             $thisMap[$thatKey] = $thatValue;
         }
     }
 }
Esempio n. 8
0
 /**
  * Returns the names of the time zones that are known for a specified country.
  *
  * If the country's code is not recognized for any reason, the entire list of the known time zone names is
  * returned.
  *
  * @param  string $countryCode The two-letter code of the country, as provided by ISO 3166.
  *
  * @return CArrayObject The known time zone names for the country specified, of type `CUStringObject`.
  */
 public static function knownNamesForCountry($countryCode)
 {
     assert('is_cstring($countryCode)', vs(isset($this), get_defined_vars()));
     $paNames = DateTimeZone::listIdentifiers(DateTimeZone::PER_COUNTRY, $countryCode);
     $paNames = CMap::filter($paNames, "CTimeZone::isNameIcuCompatible");
     $names = CArray::fromPArray($paNames);
     if (is_cmap($paNames) && !CArray::isEmpty($names)) {
         return oop_a($names);
     } else {
         return oop_a(self::knownNames());
     }
 }
Esempio n. 9
0
 /**
  * @ignore
  */
 public function onRequestCompleteOk()
 {
     // Collect summary information for the request and the response.
     $requestSummary = curl_getinfo($this->m_curl);
     if (is_cmap($requestSummary)) {
         $this->m_requestSummary = $requestSummary;
     }
     if ($this->isHttp()) {
         // Put the response's HTTP headers into an associative array.
         $len = CArray::length($this->m_responseHeaders);
         for ($i = 0; $i < $len; $i++) {
             $foundGroups;
             CRegex::findGroups($this->m_responseHeaders[$i], "/^(.+?):\\h*(.*)/", $foundGroups);
             // internal
             $headerNameLc = CString::toLowerCase($foundGroups[0]);
             $this->m_responseHeadersLcKeys[$headerNameLc] = $foundGroups[1];
         }
     }
     // Finalize.
     $this->finalize();
 }
Esempio n. 10
0
/**
 * @ignore
 */
function _from_oop_tp($value)
{
    // Only used with OOP wrapping for third-party components.
    if (is_carray($value)) {
        $value = splarray($value);
        $len = CArray::length($value);
        for ($i = 0; $i < $len; $i++) {
            $value[$i] = _from_oop_tp($value[$i]);
        }
        return $value->toArray();
    }
    if (is_cmap($value)) {
        $value = parray($value);
        foreach ($value as &$mapValue) {
            $mapValue = _from_oop_tp($mapValue);
        }
        unset($mapValue);
        return $value;
    }
    return $value;
}
Esempio n. 11
0
 protected static function recurseQueryValueAfterParsing($value, $currDepth)
 {
     if ($currDepth == self::$ms_maxRecursionDepth) {
         return $value;
     }
     $currDepth++;
     if (!is_cmap($value)) {
         // Only interested in PHP's associative arrays.
         return $value;
     }
     if (CMap::areKeysSequential($value)) {
         $value = CArray::fromPArray($value);
         $len = CArray::length($value);
         for ($i = 0; $i < $len; $i++) {
             $value[$i] = self::recurseQueryValueAfterParsing($value[$i], $currDepth);
         }
         return oop_a($value);
     } else {
         foreach ($value as &$mapValue) {
             $mapValue = self::recurseQueryValueAfterParsing($mapValue, $currDepth);
         }
         unset($mapValue);
         return oop_m($value);
     }
 }
Esempio n. 12
0
 protected static function recurseCollectionFiltering($inputCollection, $filterOrFilterCollection, &$success, $currDepth)
 {
     assert('is_a($filterOrFilterCollection, get_called_class()) || is_collection($filterOrFilterCollection)', vs(isset($this), get_defined_vars()));
     if ($currDepth == self::$ms_maxRecursionDepth) {
         $success = false;
         return;
     }
     $currDepth++;
     if (is_carray($inputCollection)) {
         if (!is_carray($filterOrFilterCollection)) {
             $success = false;
             return;
         }
         $len = CArray::length($inputCollection);
         if ($len != CArray::length($filterOrFilterCollection)) {
             $success = false;
             return;
         }
         for ($i = 0; $i < $len; $i++) {
             $inputValue = $inputCollection[$i];
             $filterElement = $filterOrFilterCollection[$i];
             if (!is_collection($inputValue)) {
                 $strInputValue = self::collectionElementToString($inputValue, $success);
                 if (!$success) {
                     return;
                 }
                 if (!is_a($filterElement, get_called_class())) {
                     $success = false;
                     return;
                 }
                 $inputValue = $filterElement->filter($strInputValue, $success);
                 if (!$success) {
                     return;
                 }
             } else {
                 $inputValue = self::recurseCollectionFiltering($inputValue, $filterElement, $success, $currDepth);
                 if (!$success) {
                     return;
                 }
             }
             $inputCollection[$i] = $inputValue;
         }
     } else {
         if (!is_cmap($filterOrFilterCollection)) {
             $success = false;
             return;
         }
         foreach ($inputCollection as $inputKey => &$inputValue) {
             if (!CMap::hasKey($filterOrFilterCollection, $inputKey)) {
                 $success = false;
                 return;
             }
             $filterElement = $filterOrFilterCollection[$inputKey];
             if (!is_collection($inputValue)) {
                 $strInputValue = self::collectionElementToString($inputValue, $success);
                 if (!$success) {
                     return;
                 }
                 if (!is_a($filterElement, get_called_class())) {
                     $success = false;
                     return;
                 }
                 $inputValue = $filterElement->filter($strInputValue, $success);
                 if (!$success) {
                     return;
                 }
             } else {
                 $inputValue = self::recurseCollectionFiltering($inputValue, $filterElement, $success, $currDepth);
                 if (!$success) {
                     return;
                 }
             }
         }
         unset($inputValue);
     }
     return $inputCollection;
 }
Esempio n. 13
0
 protected static function recurseValueBeforeEncoding($value, $currDepth)
 {
     if ($currDepth == self::$ms_maxRecursionDepth) {
         return $value;
     }
     $currDepth++;
     if (is_cstring($value)) {
         return $value;
     }
     if (is_cmap($value)) {
         $value = parray($value);
         foreach ($value as &$valueInMap) {
             $valueInMap = self::recurseValueBeforeEncoding($valueInMap, $currDepth);
         }
         unset($valueInMap);
         $value = (object) $value;
     } else {
         if (is_carray($value)) {
             $value = splarray($value);
             $len = CArray::length($value);
             for ($i = 0; $i < $len; $i++) {
                 $value[$i] = self::recurseValueBeforeEncoding($value[$i], $currDepth);
             }
             $value = CArray::toPArray($value);
         }
     }
     return $value;
 }
Esempio n. 14
-1
 /**
  * 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();
 }