Exemplo n.º 1
0
 /**
  * Returns the Metaphone key "heard" from a string.
  *
  * The algorithm used to render the [Metaphone](http://en.wikipedia.org/wiki/Metaphone) key is the first-generation
  * one.
  *
  * @param  string $string The source string.
  * @param  bool $transliterate **OPTIONAL. Default is** `true`. Tells whether to transliterate the string into the
  * Latin script and then flatten it to ASCII before generating the key. Since the Metaphone algorithm is not
  * Unicode-aware, the touch of transliteration is something that any arbitrary Unicode string would wish for. For
  * example, "こんにちは" is transliterated to "kon'nichiha".
  *
  * @return string The Metaphone key of the string.
  */
 public static function metaphoneKey($string, $transliterate = true)
 {
     assert('is_cstring($string) && is_bool($transliterate)', vs(isset($this), get_defined_vars()));
     $string = CEString::flattenUnicodeToAscii($string, $transliterate);
     return CString::metaphoneKey($string);
 }
Exemplo n.º 2
0
 /**
  * Decodes the JSON-encoded string provided earlier to the decoder and returns the result.
  *
  * @param  reference $success **OPTIONAL. OUTPUT.** After the method is called with this parameter provided, the
  * parameter's value tells whether the decoding was successful.
  *
  * @return mixed The decoded value of type `CMapObject` or `CArrayObject`.
  */
 public function decode(&$success = null)
 {
     assert('is_cstring($this->m_source)', vs(isset($this), get_defined_vars()));
     $success = true;
     $source = $this->m_source;
     if ($this->m_decodingStrictness == self::LENIENT && !CUString::isValid($source)) {
         // Change the character encoding or try fixing it.
         if (CEString::looksLikeLatin1($source)) {
             $source = CEString::convertLatin1ToUtf8($source);
         } else {
             $source = CEString::fixUtf8($source);
         }
     }
     if ($this->m_decodingStrictness == self::STRICT_WITH_COMMENTS || $this->m_decodingStrictness == self::LENIENT) {
         if (CRegex::find($source, "/\\/\\/|\\/\\*/u")) {
             // Remove "//..." and "/*...*/" comments.
             $source = CRegex::remove($source, "/(?<!\\\\)\"(?:[^\\\\\"]++|\\\\{2}|\\\\\\C)*\"(*SKIP)(*FAIL)|" . "\\/\\/.*|\\/\\*\\C*?\\*\\//u");
         }
     }
     if ($this->m_decodingStrictness == self::LENIENT) {
         if (CRegex::find($source, "/[:\\[,]\\s*'([^\\\\']++|\\\\{2}|\\\\\\C)*'(?=\\s*[,}\\]])/u")) {
             // Convert single-quoted string values into double-quoted, taking care of double quotes within such
             // strings before and single quotes after. This needs to go in front of the rest of the leniency fixes.
             while (true) {
                 $prevSource = $source;
                 $source = CRegex::replace($source, "/(?<!\\\\)\"(?:[^\\\\\"]++|\\\\{2}|\\\\\\C)*\"(*SKIP)(*FAIL)|" . "([:\\[,]\\s*'(?:[^\\\\'\"]++|\\\\{2}|\\\\\\C)*)\"((?:[^\\\\']++|\\\\{2}|\\\\\\C)*')/u", "\$1\\\"\$2");
                 if (CString::equals($source, $prevSource) || is_null($source)) {
                     break;
                 }
             }
             if (is_null($source)) {
                 $source = "";
             }
             $source = CRegex::replace($source, "/(?<!\\\\)\"(?:[^\\\\\"]++|\\\\{2}|\\\\\\C)*\"(*SKIP)(*FAIL)|" . "([:\\[,]\\s*)'((?:[^\\\\']++|\\\\{2}|\\\\\\C)*)'(?=\\s*[,}\\]])/u", "\$1\"\$2\"");
             while (true) {
                 $prevSource = $source;
                 $source = CRegex::replace($source, "/([:\\[,]\\s*\"(?:[^\\\\\"]++|\\\\{2}|\\\\[^'])*)\\\\'((?:[^\\\\\"]++|\\\\{2}|\\\\\\C)*\")" . "(?=\\s*[,}\\]])/u", "\$1'\$2");
                 if (CString::equals($source, $prevSource) || is_null($source)) {
                     break;
                 }
             }
             if (is_null($source)) {
                 $source = "";
             }
         }
         if (CRegex::find($source, "/[{,]\\s*[\\w\\-.]+\\s*:/u")) {
             // Put property names in double quotes.
             $source = CRegex::replace($source, "/(?<!\\\\)\"(?:[^\\\\\"]++|\\\\{2}|\\\\\\C)*\"(*SKIP)(*FAIL)|" . "([{,]\\s*)([\\w\\-.]+)(\\s*:)/u", "\$1\"\$2\"\$3");
         }
         if (CRegex::find($source, "/[{,]\\s*'[\\w\\-.]+'\\s*:/u")) {
             // Put property names that are in single quotes in double quotes.
             $source = CRegex::replace($source, "/(?<!\\\\)\"(?:[^\\\\\"]++|\\\\{2}|\\\\\\C)*\"(*SKIP)(*FAIL)|" . "([{,]\\s*)'([\\w\\-.]+)'(\\s*:)/u", "\$1\"\$2\"\$3");
         }
         if (CRegex::find($source, "/,\\s*[}\\]]/u")) {
             // Remove trailing commas.
             $source = CRegex::remove($source, "/(?<!\\\\)\"(?:[^\\\\\"]++|\\\\{2}|\\\\\\C)*\"(*SKIP)(*FAIL)|" . ",(?=\\s*[}\\]])/u");
         }
         // Within string values, convert byte values for BS, FF, LF, CR, and HT, which are prohibited in JSON,
         // to their escaped equivalents.
         $stringValueSubjectRe = "/(?<!\\\\)\"(?:[^\\\\\"]++|\\\\{2}|\\\\\\C)*\"/u";
         $source = CRegex::replaceWithCallback($source, $stringValueSubjectRe, function ($matches) {
             return CRegex::replace($matches[0], "/\\x{0008}/u", "\\b");
         });
         $source = CRegex::replaceWithCallback($source, $stringValueSubjectRe, function ($matches) {
             return CRegex::replace($matches[0], "/\\x{000C}/u", "\\f");
         });
         $source = CRegex::replaceWithCallback($source, $stringValueSubjectRe, function ($matches) {
             return CRegex::replace($matches[0], "/\\x{000A}/u", "\\n");
         });
         $source = CRegex::replaceWithCallback($source, $stringValueSubjectRe, function ($matches) {
             return CRegex::replace($matches[0], "/\\x{000D}/u", "\\r");
         });
         $source = CRegex::replaceWithCallback($source, $stringValueSubjectRe, function ($matches) {
             return CRegex::replace($matches[0], "/\\x{0009}/u", "\\t");
         });
     }
     $decodedValue = @json_decode($source, false, self::$ms_maxRecursionDepth);
     if (is_null($decodedValue)) {
         if ($this->m_decodingStrictness == self::STRICT || $this->m_decodingStrictness == self::STRICT_WITH_COMMENTS) {
             $success = false;
         } else {
             if (CRegex::find($source, "/^\\s*[\\w.]+\\s*\\(/u")) {
                 // The source string appears to be a JSONP. Extract the function's argument and try decoding again.
                 $source = CRegex::replace($source, "/^\\s*[\\w.]+\\s*\\((\\C+)\\)/u", "\$1");
                 $decodedValue = @json_decode($source, false, self::$ms_maxRecursionDepth);
                 if (is_null($decodedValue)) {
                     $success = false;
                 }
             }
         }
     }
     if (!$success) {
         return;
     }
     if ($this->m_decodingStrictness == self::STRICT || $this->m_decodingStrictness == self::STRICT_WITH_COMMENTS) {
         if (!is_object($decodedValue) && !is_array($decodedValue)) {
             $success = false;
             return;
         }
     }
     // Recursively convert any object into a CMapObject/CMap and any PHP array into a CArrayObject/CArray.
     $decodedValue = self::recurseValueAfterDecoding($decodedValue, 0);
     return $decodedValue;
 }