diff -r 5e7a0fedabdf -r 877f952ae2bd web/lib/Zend/Json.php --- a/web/lib/Zend/Json.php Thu Mar 21 17:31:31 2013 +0100 +++ b/web/lib/Zend/Json.php Thu Mar 21 19:50:53 2013 +0100 @@ -14,9 +14,9 @@ * * @category Zend * @package Zend_Json - * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id: Json.php 20615 2010-01-25 19:54:12Z matthew $ + * @version $Id: Json.php 24593 2012-01-05 20:35:02Z matthew $ */ /** @@ -33,7 +33,7 @@ * @category Zend * @package Zend_Json * @uses Zend_Json_Expr - * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License */ class Zend_Json @@ -125,8 +125,12 @@ */ public static function encode($valueToEncode, $cycleCheck = false, $options = array()) { - if (is_object($valueToEncode) && method_exists($valueToEncode, 'toJson')) { - return $valueToEncode->toJson(); + if (is_object($valueToEncode)) { + if (method_exists($valueToEncode, 'toJson')) { + return $valueToEncode->toJson(); + } elseif (method_exists($valueToEncode, 'toArray')) { + return self::encode($valueToEncode->toArray(), $cycleCheck, $options); + } } // Pre-encoding look for Zend_Json_Expr objects and replacing by tmp ids @@ -179,12 +183,15 @@ * NOTE: This method is used internally by the encode method. * * @see encode - * @param mixed $valueToCheck a string - object property to be encoded + * @param array|object|Zend_Json_Expr $value a string - object property to be encoded + * @param array $javascriptExpressions + * @param null $currentKey + * + * @internal param mixed $valueToCheck * @return void */ - protected static function _recursiveJsonExprFinder( - &$value, array &$javascriptExpressions, $currentKey = null - ) { + protected static function _recursiveJsonExprFinder(&$value, array &$javascriptExpressions, $currentKey = null) + { if ($value instanceof Zend_Json_Expr) { // TODO: Optimize with ascii keys, if performance is bad $magicKey = "____" . $currentKey . "_" . (count($javascriptExpressions)); @@ -208,6 +215,104 @@ } /** + * Return the value of an XML attribute text or the text between + * the XML tags + * + * In order to allow Zend_Json_Expr from xml, we check if the node + * matchs the pattern that try to detect if it is a new Zend_Json_Expr + * if it matches, we return a new Zend_Json_Expr instead of a text node + * + * @param SimpleXMLElement $simpleXmlElementObject + * @return Zend_Json_Expr|string + */ + protected static function _getXmlValue($simpleXmlElementObject) { + $pattern = '/^[\s]*new Zend_Json_Expr[\s]*\([\s]*[\"\']{1}(.*)[\"\']{1}[\s]*\)[\s]*$/'; + $matchings = array(); + $match = preg_match ($pattern, $simpleXmlElementObject, $matchings); + if ($match) { + return new Zend_Json_Expr($matchings[1]); + } else { + return (trim(strval($simpleXmlElementObject))); + } + } + /** + * _processXml - Contains the logic for xml2json + * + * The logic in this function is a recursive one. + * + * The main caller of this function (i.e. fromXml) needs to provide + * only the first two parameters i.e. the SimpleXMLElement object and + * the flag for ignoring or not ignoring XML attributes. The third parameter + * will be used internally within this function during the recursive calls. + * + * This function converts the SimpleXMLElement object into a PHP array by + * calling a recursive (protected static) function in this class. Once all + * the XML elements are stored in the PHP array, it is returned to the caller. + * + * Throws a Zend_Json_Exception if the XML tree is deeper than the allowed limit. + * + * @param SimpleXMLElement $simpleXmlElementObject + * @param boolean $ignoreXmlAttributes + * @param integer $recursionDepth + * @return array + */ + protected static function _processXml($simpleXmlElementObject, $ignoreXmlAttributes, $recursionDepth=0) + { + // Keep an eye on how deeply we are involved in recursion. + if ($recursionDepth > self::$maxRecursionDepthAllowed) { + // XML tree is too deep. Exit now by throwing an exception. + require_once 'Zend/Json/Exception.php'; + throw new Zend_Json_Exception( + "Function _processXml exceeded the allowed recursion depth of " . + self::$maxRecursionDepthAllowed); + } // End of if ($recursionDepth > self::$maxRecursionDepthAllowed) + + $children = $simpleXmlElementObject->children(); + $name = $simpleXmlElementObject->getName(); + $value = self::_getXmlValue($simpleXmlElementObject); + $attributes = (array) $simpleXmlElementObject->attributes(); + + if (count($children) == 0) { + if (!empty($attributes) && !$ignoreXmlAttributes) { + foreach ($attributes['@attributes'] as $k => $v) { + $attributes['@attributes'][$k]= self::_getXmlValue($v); + } + if (!empty($value)) { + $attributes['@text'] = $value; + } + return array($name => $attributes); + } else { + return array($name => $value); + } + } else { + $childArray= array(); + foreach ($children as $child) { + $childname = $child->getName(); + $element = self::_processXml($child,$ignoreXmlAttributes,$recursionDepth+1); + if (array_key_exists($childname, $childArray)) { + if (empty($subChild[$childname])) { + $childArray[$childname] = array($childArray[$childname]); + $subChild[$childname] = true; + } + $childArray[$childname][] = $element[$childname]; + } else { + $childArray[$childname] = $element[$childname]; + } + } + if (!empty($attributes) && !$ignoreXmlAttributes) { + foreach ($attributes['@attributes'] as $k => $v) { + $attributes['@attributes'][$k] = self::_getXmlValue($v); + } + $childArray['@attributes'] = $attributes['@attributes']; + } + if (!empty($value)) { + $childArray['@text'] = $value; + } + return array($name => $childArray); + } + } + + /** * fromXml - Converts XML to JSON * * Converts a XML formatted string into a JSON formatted string. @@ -233,7 +338,8 @@ * @return mixed - JSON formatted string on success * @throws Zend_Json_Exception */ - public static function fromXml ($xmlStringContents, $ignoreXmlAttributes=true) { + public static function fromXml($xmlStringContents, $ignoreXmlAttributes=true) + { // Load the XML formatted string into a Simple XML Element object. $simpleXmlElementObject = simplexml_load_string($xmlStringContents); @@ -252,120 +358,16 @@ // It is just that simple. $jsonStringOutput = self::encode($resultArray); return($jsonStringOutput); - } // End of function fromXml. + } + + /** - * _processXml - Contains the logic for xml2json - * - * The logic in this function is a recursive one. - * - * The main caller of this function (i.e. fromXml) needs to provide - * only the first two parameters i.e. the SimpleXMLElement object and - * the flag for ignoring or not ignoring XML attributes. The third parameter - * will be used internally within this function during the recursive calls. - * - * This function converts the SimpleXMLElement object into a PHP array by - * calling a recursive (protected static) function in this class. Once all - * the XML elements are stored in the PHP array, it is returned to the caller. - * - * Throws a Zend_Json_Exception if the XML tree is deeper than the allowed limit. + * Pretty-print JSON string * - * @static - * @access protected - * @param SimpleXMLElement $simpleXmlElementObject XML element to be converted - * @param boolean $ignoreXmlAttributes Include or exclude XML attributes in - * the xml2json conversion process. - * @param int $recursionDepth Current recursion depth of this function - * @return mixed - On success, a PHP associative array of traversed XML elements - * @throws Zend_Json_Exception - */ - protected static function _processXml ($simpleXmlElementObject, $ignoreXmlAttributes, $recursionDepth=0) { - // Keep an eye on how deeply we are involved in recursion. - if ($recursionDepth > self::$maxRecursionDepthAllowed) { - // XML tree is too deep. Exit now by throwing an exception. - require_once 'Zend/Json/Exception.php'; - throw new Zend_Json_Exception( - "Function _processXml exceeded the allowed recursion depth of " . - self::$maxRecursionDepthAllowed); - } // End of if ($recursionDepth > self::$maxRecursionDepthAllowed) - - if ($recursionDepth == 0) { - // Store the original SimpleXmlElementObject sent by the caller. - // We will need it at the very end when we return from here for good. - $callerProvidedSimpleXmlElementObject = $simpleXmlElementObject; - } // End of if ($recursionDepth == 0) - - if ($simpleXmlElementObject instanceof SimpleXMLElement) { - // Get a copy of the simpleXmlElementObject - $copyOfSimpleXmlElementObject = $simpleXmlElementObject; - // Get the object variables in the SimpleXmlElement object for us to iterate. - $simpleXmlElementObject = get_object_vars($simpleXmlElementObject); - } // End of if (get_class($simpleXmlElementObject) == "SimpleXMLElement") - - // It needs to be an array of object variables. - if (is_array($simpleXmlElementObject)) { - // Initialize a result array. - $resultArray = array(); - // Is the input array size 0? Then, we reached the rare CDATA text if any. - if (count($simpleXmlElementObject) <= 0) { - // Let us return the lonely CDATA. It could even be - // an empty element or just filled with whitespaces. - return (trim(strval($copyOfSimpleXmlElementObject))); - } // End of if (count($simpleXmlElementObject) <= 0) - - // Let us walk through the child elements now. - foreach($simpleXmlElementObject as $key=>$value) { - // Check if we need to ignore the XML attributes. - // If yes, you can skip processing the XML attributes. - // Otherwise, add the XML attributes to the result array. - if(($ignoreXmlAttributes == true) && (is_string($key)) && ($key == "@attributes")) { - continue; - } // End of if(($ignoreXmlAttributes == true) && ($key == "@attributes")) - - // Let us recursively process the current XML element we just visited. - // Increase the recursion depth by one. - $recursionDepth++; - $resultArray[$key] = self::_processXml ($value, $ignoreXmlAttributes, $recursionDepth); - - // Decrease the recursion depth by one. - $recursionDepth--; - } // End of foreach($simpleXmlElementObject as $key=>$value) { - - if ($recursionDepth == 0) { - // That is it. We are heading to the exit now. - // Set the XML root element name as the root [top-level] key of - // the associative array that we are going to return to the original - // caller of this recursive function. - $tempArray = $resultArray; - $resultArray = array(); - $resultArray[$callerProvidedSimpleXmlElementObject->getName()] = $tempArray; - } // End of if ($recursionDepth == 0) - - return($resultArray); - } else { - // We are now looking at either the XML attribute text or - // the text between the XML tags. - - // In order to allow Zend_Json_Expr from xml, we check if the node - // matchs the pattern that try to detect if it is a new Zend_Json_Expr - // if it matches, we return a new Zend_Json_Expr instead of a text node - $pattern = '/^[\s]*new Zend_Json_Expr[\s]*\([\s]*[\"\']{1}(.*)[\"\']{1}[\s]*\)[\s]*$/'; - $matchings = array(); - $match = preg_match ($pattern, $simpleXmlElementObject, $matchings); - if ($match) { - return new Zend_Json_Expr($matchings[1]); - } else { - return (trim(strval($simpleXmlElementObject))); - } - - } // End of if (is_array($simpleXmlElementObject)) - } // End of function _processXml. - - /** - * Pretty-print JSON string - * - * Use 'indent' option to select indentation string - by default it's a tab - * + * Use 'format' option to select output format - currently html and txt supported, txt is default + * Use 'indent' option to override the indentation string set in the format - by default for the 'txt' format it's a tab + * * @param string $json Original JSON string * @param array $options Encoding options * @return string @@ -373,32 +375,62 @@ public static function prettyPrint($json, $options = array()) { $tokens = preg_split('|([\{\}\]\[,])|', $json, -1, PREG_SPLIT_DELIM_CAPTURE); - $result = ""; + $result = ''; $indent = 0; - + + $format= 'txt'; + $ind = "\t"; - if(isset($options['indent'])) { + + if (isset($options['format'])) { + $format = $options['format']; + } + + switch ($format) { + case 'html': + $lineBreak = '
'; + $ind = '    '; + break; + default: + case 'txt': + $lineBreak = "\n"; + $ind = "\t"; + break; + } + + // override the defined indent setting with the supplied option + if (isset($options['indent'])) { $ind = $options['indent']; } - + + $inLiteral = false; foreach($tokens as $token) { - if($token == "") continue; - + if($token == '') { + continue; + } + $prefix = str_repeat($ind, $indent); - if($token == "{" || $token == "[") { + if (!$inLiteral && ($token == '{' || $token == '[')) { $indent++; - if($result != "" && $result[strlen($result)-1] == "\n") { + if (($result != '') && ($result[(strlen($result)-1)] == $lineBreak)) { $result .= $prefix; } - $result .= "$token\n"; - } else if($token == "}" || $token == "]") { + $result .= $token . $lineBreak; + } elseif (!$inLiteral && ($token == '}' || $token == ']')) { $indent--; $prefix = str_repeat($ind, $indent); - $result .= "\n$prefix$token"; - } else if($token == ",") { - $result .= "$token\n"; + $result .= $lineBreak . $prefix . $token; + } elseif (!$inLiteral && $token == ',') { + $result .= $token . $lineBreak; } else { - $result .= $prefix.$token; + $result .= ( $inLiteral ? '' : $prefix ) . $token; + + // Count # of unescaped double-quotes in token, subtract # of + // escaped double-quotes and if the result is odd then we are + // inside a string literal + if ((substr_count($token, "\"")-substr_count($token, "\\\"")) % 2 != 0) { + $inLiteral = !$inLiteral; + } } } return $result;