Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
Json.php
Go to the documentation of this file.
1 <?php
27 #require_once 'Zend/Json/Expr.php';
28 
30 #require_once 'Zend/Xml/Security.php';
31 
41 class Zend_Json
42 {
48  const TYPE_ARRAY = 1;
49  const TYPE_OBJECT = 0;
50 
56  public static $maxRecursionDepthAllowed=25;
57 
61  public static $useBuiltinEncoderDecoder = false;
62 
74  public static function decode($encodedValue, $objectDecodeType = Zend_Json::TYPE_ARRAY)
75  {
76  $encodedValue = (string) $encodedValue;
77  if (function_exists('json_decode') && self::$useBuiltinEncoderDecoder !== true) {
78  $decode = json_decode($encodedValue, $objectDecodeType);
79 
80  // php < 5.3
81  if (!function_exists('json_last_error')) {
82  if (strtolower($encodedValue) === 'null') {
83  return null;
84  } elseif ($decode === null) {
85  #require_once 'Zend/Json/Exception.php';
86  throw new Zend_Json_Exception('Decoding failed');
87  }
88  // php >= 5.3
89  } elseif (($jsonLastErr = json_last_error()) != JSON_ERROR_NONE) {
90  #require_once 'Zend/Json/Exception.php';
91  switch ($jsonLastErr) {
92  case JSON_ERROR_DEPTH:
93  throw new Zend_Json_Exception('Decoding failed: Maximum stack depth exceeded');
94  case JSON_ERROR_CTRL_CHAR:
95  throw new Zend_Json_Exception('Decoding failed: Unexpected control character found');
96  case JSON_ERROR_SYNTAX:
97  throw new Zend_Json_Exception('Decoding failed: Syntax error');
98  default:
99  throw new Zend_Json_Exception('Decoding failed');
100  }
101  }
102 
103  return $decode;
104  }
105 
106  #require_once 'Zend/Json/Decoder.php';
107  return Zend_Json_Decoder::decode($encodedValue, $objectDecodeType);
108  }
109 
130  public static function encode($valueToEncode, $cycleCheck = false, $options = array())
131  {
132  if (is_object($valueToEncode)) {
133  if (method_exists($valueToEncode, 'toJson')) {
134  return $valueToEncode->toJson();
135  } elseif (method_exists($valueToEncode, 'toArray')) {
136  return self::encode($valueToEncode->toArray(), $cycleCheck, $options);
137  }
138  }
139 
140  // Pre-encoding look for Zend_Json_Expr objects and replacing by tmp ids
141  $javascriptExpressions = array();
142  if(isset($options['enableJsonExprFinder'])
143  && ($options['enableJsonExprFinder'] == true)
144  ) {
148  #require_once "Zend/Json/Encoder.php";
149  $valueToEncode = self::_recursiveJsonExprFinder($valueToEncode, $javascriptExpressions);
150  }
151 
152  // Encoding
153  if (function_exists('json_encode') && self::$useBuiltinEncoderDecoder !== true) {
154  $encodedResult = json_encode($valueToEncode);
155  } else {
156  #require_once 'Zend/Json/Encoder.php';
157  $encodedResult = Zend_Json_Encoder::encode($valueToEncode, $cycleCheck, $options);
158  }
159 
160  //only do post-proccessing to revert back the Zend_Json_Expr if any.
161  if (count($javascriptExpressions) > 0) {
162  $count = count($javascriptExpressions);
163  for($i = 0; $i < $count; $i++) {
164  $magicKey = $javascriptExpressions[$i]['magicKey'];
165  $value = $javascriptExpressions[$i]['value'];
166 
167  $encodedResult = str_replace(
168  //instead of replacing "key:magicKey", we replace directly magicKey by value because "key" never changes.
169  '"' . $magicKey . '"',
170  $value,
171  $encodedResult
172  );
173  }
174  }
175 
176  return $encodedResult;
177  }
178 
197  protected static function _recursiveJsonExprFinder(&$value, array &$javascriptExpressions, $currentKey = null)
198  {
199  if ($value instanceof Zend_Json_Expr) {
200  // TODO: Optimize with ascii keys, if performance is bad
201  $magicKey = "____" . $currentKey . "_" . (count($javascriptExpressions));
202  $javascriptExpressions[] = array(
203 
204  //if currentKey is integer, encodeUnicodeString call is not required.
205  "magicKey" => (is_int($currentKey)) ? $magicKey : Zend_Json_Encoder::encodeUnicodeString($magicKey),
206  "value" => $value->__toString(),
207  );
208  $value = $magicKey;
209  } elseif (is_array($value)) {
210  foreach ($value as $k => $v) {
211  $value[$k] = self::_recursiveJsonExprFinder($value[$k], $javascriptExpressions, $k);
212  }
213  } elseif (is_object($value)) {
214  foreach ($value as $k => $v) {
215  $value->$k = self::_recursiveJsonExprFinder($value->$k, $javascriptExpressions, $k);
216  }
217  }
218  return $value;
219  }
220 
232  protected static function _getXmlValue($simpleXmlElementObject) {
233  $pattern = '/^[\s]*new Zend_Json_Expr[\s]*\([\s]*[\"\']{1}(.*)[\"\']{1}[\s]*\)[\s]*$/';
234  $matchings = array();
235  $match = preg_match ($pattern, $simpleXmlElementObject, $matchings);
236  if ($match) {
237  return new Zend_Json_Expr($matchings[1]);
238  } else {
239  return (trim(strval($simpleXmlElementObject)));
240  }
241  }
263  protected static function _processXml($simpleXmlElementObject, $ignoreXmlAttributes, $recursionDepth=0)
264  {
265  // Keep an eye on how deeply we are involved in recursion.
266  if ($recursionDepth > self::$maxRecursionDepthAllowed) {
267  // XML tree is too deep. Exit now by throwing an exception.
268  #require_once 'Zend/Json/Exception.php';
269  throw new Zend_Json_Exception(
270  "Function _processXml exceeded the allowed recursion depth of " .
271  self::$maxRecursionDepthAllowed);
272  } // End of if ($recursionDepth > self::$maxRecursionDepthAllowed)
273 
274  $children = $simpleXmlElementObject->children();
275  $name = $simpleXmlElementObject->getName();
276  $value = self::_getXmlValue($simpleXmlElementObject);
277  $attributes = (array) $simpleXmlElementObject->attributes();
278 
279  if (count($children) == 0) {
280  if (!empty($attributes) && !$ignoreXmlAttributes) {
281  foreach ($attributes['@attributes'] as $k => $v) {
282  $attributes['@attributes'][$k]= self::_getXmlValue($v);
283  }
284  if (!empty($value)) {
285  $attributes['@text'] = $value;
286  }
287  return array($name => $attributes);
288  } else {
289  return array($name => $value);
290  }
291  } else {
292  $childArray= array();
293  foreach ($children as $child) {
294  $childname = $child->getName();
295  $element = self::_processXml($child,$ignoreXmlAttributes,$recursionDepth+1);
296  if (array_key_exists($childname, $childArray)) {
297  if (empty($subChild[$childname])) {
298  $childArray[$childname] = array($childArray[$childname]);
299  $subChild[$childname] = true;
300  }
301  $childArray[$childname][] = $element[$childname];
302  } else {
303  $childArray[$childname] = $element[$childname];
304  }
305  }
306  if (!empty($attributes) && !$ignoreXmlAttributes) {
307  foreach ($attributes['@attributes'] as $k => $v) {
308  $attributes['@attributes'][$k] = self::_getXmlValue($v);
309  }
310  $childArray['@attributes'] = $attributes['@attributes'];
311  }
312  if (!empty($value)) {
313  $childArray['@text'] = $value;
314  }
315  return array($name => $childArray);
316  }
317  }
318 
345  public static function fromXml($xmlStringContents, $ignoreXmlAttributes=true)
346  {
347  // Load the XML formatted string into a Simple XML Element object.
348  $simpleXmlElementObject = Zend_Xml_Security::scan($xmlStringContents);
349 
350  // If it is not a valid XML content, throw an exception.
351  if ($simpleXmlElementObject == null) {
352  #require_once 'Zend/Json/Exception.php';
353  throw new Zend_Json_Exception('Function fromXml was called with an invalid XML formatted string.');
354  } // End of if ($simpleXmlElementObject == null)
355 
356  $resultArray = null;
357 
358  // Call the recursive function to convert the XML into a PHP array.
359  $resultArray = self::_processXml($simpleXmlElementObject, $ignoreXmlAttributes);
360 
361  // Convert the PHP array to JSON using Zend_Json encode method.
362  // It is just that simple.
363  $jsonStringOutput = self::encode($resultArray);
364  return($jsonStringOutput);
365  }
366 
367 
368 
379  public static function prettyPrint($json, $options = array())
380  {
381  $tokens = preg_split('|([\{\}\]\[,])|', $json, -1, PREG_SPLIT_DELIM_CAPTURE);
382  $result = '';
383  $indent = 0;
384 
385  $format= 'txt';
386 
387  $ind = "\t";
388 
389  if (isset($options['format'])) {
390  $format = $options['format'];
391  }
392 
393  switch ($format) {
394  case 'html':
395  $lineBreak = '<br />';
396  $ind = '&nbsp;&nbsp;&nbsp;&nbsp;';
397  break;
398  default:
399  case 'txt':
400  $lineBreak = "\n";
401  $ind = "\t";
402  break;
403  }
404 
405  // override the defined indent setting with the supplied option
406  if (isset($options['indent'])) {
407  $ind = $options['indent'];
408  }
409 
410  $inLiteral = false;
411  foreach($tokens as $token) {
412  if($token == '') {
413  continue;
414  }
415 
416  $prefix = str_repeat($ind, $indent);
417  if (!$inLiteral && ($token == '{' || $token == '[')) {
418  $indent++;
419  if (($result != '') && ($result[(strlen($result)-1)] == $lineBreak)) {
420  $result .= $prefix;
421  }
422  $result .= $token . $lineBreak;
423  } elseif (!$inLiteral && ($token == '}' || $token == ']')) {
424  $indent--;
425  $prefix = str_repeat($ind, $indent);
426  $result .= $lineBreak . $prefix . $token;
427  } elseif (!$inLiteral && $token == ',') {
428  $result .= $token . $lineBreak;
429  } else {
430  $result .= ( $inLiteral ? '' : $prefix ) . $token;
431 
432  // Count # of unescaped double-quotes in token, subtract # of
433  // escaped double-quotes and if the result is odd then we are
434  // inside a string literal
435  if ((substr_count($token, "\"")-substr_count($token, "\\\"")) % 2 != 0) {
436  $inLiteral = !$inLiteral;
437  }
438  }
439  }
440  return $result;
441  }
442 }
static decode($encodedValue, $objectDecodeType=Zend_Json::TYPE_ARRAY)
Definition: Json.php:74
elseif(isset( $params[ 'redirect_parent']))
Definition: iframe.phtml:17
static scan($xml, DOMDocument $dom=null)
Definition: Security.php:71
$pattern
Definition: website.php:22
static encodeUnicodeString($value)
Definition: Encoder.php:450
$count
Definition: recent.phtml:13
static $useBuiltinEncoderDecoder
Definition: Json.php:61
static prettyPrint($json, $options=array())
Definition: Json.php:379
static _recursiveJsonExprFinder(&$value, array &$javascriptExpressions, $currentKey=null)
Definition: Json.php:197
$prefix
Definition: name.phtml:25
$value
Definition: gender.phtml:16
$format
Definition: list.phtml:12
const TYPE_ARRAY
Definition: Json.php:48
$attributes
Definition: matrix.phtml:13
static fromXml($xmlStringContents, $ignoreXmlAttributes=true)
Definition: Json.php:345
static _getXmlValue($simpleXmlElementObject)
Definition: Json.php:232
$children
Definition: actions.phtml:11
static _processXml($simpleXmlElementObject, $ignoreXmlAttributes, $recursionDepth=0)
Definition: Json.php:263
const TYPE_OBJECT
Definition: Json.php:49
static encode($valueToEncode, $cycleCheck=false, $options=array())
Definition: Json.php:130
$i
Definition: gallery.phtml:31
static encode($value, $cycleCheck=false, $options=array())
Definition: Encoder.php:74
static decode($source=null, $objectDecodeType=Zend_Json::TYPE_ARRAY)
Definition: Decoder.php:144
static $maxRecursionDepthAllowed
Definition: Json.php:56
$tokens
Definition: cards_list.phtml:9
if(!isset($_GET['name'])) $name
Definition: log.php:14
$element
Definition: element.phtml:12