MediaWiki  1.23.0
FormatJson.php
Go to the documentation of this file.
1 <?php
26 class FormatJson {
34  const UTF8_OK = 1;
35 
46  const XMLMETA_OK = 2;
47 
55  const ALL_OK = 3;
56 
66  const WS_CLEANUP_REGEX = '/(?<=[\[{])\n\s*+(?=[\]}])/';
67 
74  private static $badChars = array(
75  "\xe2\x80\xa8", // U+2028 LINE SEPARATOR
76  "\xe2\x80\xa9", // U+2029 PARAGRAPH SEPARATOR
77  );
78 
82  private static $badCharsEscaped = array(
83  '\u2028', // U+2028 LINE SEPARATOR
84  '\u2029', // U+2029 PARAGRAPH SEPARATOR
85  );
86 
104  public static function encode( $value, $pretty = false, $escaping = 0 ) {
105  if ( !is_string( $pretty ) ) {
106  $pretty = $pretty ? ' ' : false;
107  }
108 
109  if ( defined( 'JSON_UNESCAPED_UNICODE' ) ) {
110  return self::encode54( $value, $pretty, $escaping );
111  }
112 
113  return self::encode53( $value, $pretty, $escaping );
114  }
115 
126  public static function decode( $value, $assoc = false ) {
127  return json_decode( $value, $assoc );
128  }
129 
138  private static function encode54( $value, $pretty, $escaping ) {
139  // PHP escapes '/' to prevent breaking out of inline script blocks using '</script>',
140  // which is hardly useful when '<' and '>' are escaped (and inadequate), and such
141  // escaping negatively impacts the human readability of URLs and similar strings.
142  $options = JSON_UNESCAPED_SLASHES;
143  $options |= $pretty !== false ? JSON_PRETTY_PRINT : 0;
144  $options |= ( $escaping & self::UTF8_OK ) ? JSON_UNESCAPED_UNICODE : 0;
145  $options |= ( $escaping & self::XMLMETA_OK ) ? 0 : ( JSON_HEX_TAG | JSON_HEX_AMP );
146  $json = json_encode( $value, $options );
147  if ( $json === false ) {
148  return false;
149  }
150 
151  if ( $pretty !== false ) {
152  // Remove whitespace inside empty arrays/objects; different JSON encoders
153  // vary on this, and we want our output to be consistent across implementations.
154  $json = preg_replace( self::WS_CLEANUP_REGEX, '', $json );
155  if ( $pretty !== ' ' ) {
156  // Change the four-space indent to a tab indent
157  $json = str_replace( "\n ", "\n\t", $json );
158  while ( strpos( $json, "\t " ) !== false ) {
159  $json = str_replace( "\t ", "\t\t", $json );
160  }
161 
162  if ( $pretty !== "\t" ) {
163  // Change the tab indent to the provided indent
164  $json = str_replace( "\t", $pretty, $json );
165  }
166  }
167  }
168  if ( $escaping & self::UTF8_OK ) {
169  $json = str_replace( self::$badChars, self::$badCharsEscaped, $json );
170  }
171 
172  return $json;
173  }
174 
184  private static function encode53( $value, $pretty, $escaping ) {
185  $options = ( $escaping & self::XMLMETA_OK ) ? 0 : ( JSON_HEX_TAG | JSON_HEX_AMP );
186  $json = json_encode( $value, $options );
187  if ( $json === false ) {
188  return false;
189  }
190 
191  // Emulate JSON_UNESCAPED_SLASHES. Because the JSON contains no unescaped slashes
192  // (only escaped slashes), a simple string replacement works fine.
193  $json = str_replace( '\/', '/', $json );
194 
195  if ( $escaping & self::UTF8_OK ) {
196  // JSON hex escape sequences follow the format \uDDDD, where DDDD is four hex digits
197  // indicating the equivalent UTF-16 code unit's value. To most efficiently unescape
198  // them, we exploit the JSON extension's built-in decoder.
199  // * We escape the input a second time, so any such sequence becomes \\uDDDD.
200  // * To avoid interpreting escape sequences that were in the original input,
201  // each double-escaped backslash (\\\\) is replaced with \\\u005c.
202  // * We strip one of the backslashes from each of the escape sequences to unescape.
203  // * Then the JSON decoder can perform the actual unescaping.
204  $json = str_replace( "\\\\\\\\", "\\\\\\u005c", addcslashes( $json, '\"' ) );
205  $json = json_decode( preg_replace( "/\\\\\\\\u(?!00[0-7])/", "\\\\u", "\"$json\"" ) );
206  $json = str_replace( self::$badChars, self::$badCharsEscaped, $json );
207  }
208 
209  if ( $pretty !== false ) {
210  return self::prettyPrint( $json, $pretty );
211  }
212 
213  return $json;
214  }
215 
224  private static function prettyPrint( $json, $indentString ) {
225  $buf = '';
226  $indent = 0;
227  $json = strtr( $json, array( '\\\\' => '\\\\', '\"' => "\x01" ) );
228  for ( $i = 0, $n = strlen( $json ); $i < $n; $i += $skip ) {
229  $skip = 1;
230  switch ( $json[$i] ) {
231  case ':':
232  $buf .= ': ';
233  break;
234  case '[':
235  case '{':
236  ++$indent;
237  // falls through
238  case ',':
239  $buf .= $json[$i] . "\n" . str_repeat( $indentString, $indent );
240  break;
241  case ']':
242  case '}':
243  $buf .= "\n" . str_repeat( $indentString, --$indent ) . $json[$i];
244  break;
245  case '"':
246  $skip = strcspn( $json, '"', $i + 1 ) + 2;
247  $buf .= substr( $json, $i, $skip );
248  break;
249  default:
250  $skip = strcspn( $json, ',]}"', $i + 1 ) + 1;
251  $buf .= substr( $json, $i, $skip );
252  }
253  }
254  $buf = preg_replace( self::WS_CLEANUP_REGEX, '', $buf );
255 
256  return str_replace( "\x01", '\"', $buf );
257  }
258 }
php
skin txt MediaWiki includes four core it has been set as the default in MediaWiki since the replacing Monobook it had been been the default skin since before being replaced by Vector largely rewritten in while keeping its appearance Several legacy skins were removed in the as the burden of supporting them became too heavy to bear Those in etc for skin dependent CSS etc for skin dependent JavaScript These can also be customised on a per user by etc This feature has led to a wide variety of user styles becoming that gallery is a good place to ending in php
Definition: skin.txt:62
FormatJson\XMLMETA_OK
const XMLMETA_OK
Skip escaping the characters '<', '>', and '&', which have special meanings in HTML and XML.
Definition: FormatJson.php:46
FormatJson\$badChars
static $badChars
Characters problematic in JavaScript.
Definition: FormatJson.php:74
$n
$n
Definition: RandomTest.php:76
FormatJson\encode53
static encode53( $value, $pretty, $escaping)
JSON encoder wrapper for PHP 5.3, which lacks native support for some encoding options.
Definition: FormatJson.php:184
FormatJson\ALL_OK
const ALL_OK
Skip escaping as many characters as reasonably possible.
Definition: FormatJson.php:55
FormatJson\UTF8_OK
const UTF8_OK
Skip escaping most characters above U+007F for readability and compactness.
Definition: FormatJson.php:34
FormatJson\decode
static decode( $value, $assoc=false)
Decodes a JSON string.
Definition: FormatJson.php:126
FormatJson\encode
static encode( $value, $pretty=false, $escaping=0)
Returns the JSON representation of a value.
Definition: FormatJson.php:104
FormatJson
JSON formatter wrapper class.
Definition: FormatJson.php:26
FormatJson\prettyPrint
static prettyPrint( $json, $indentString)
Adds non-significant whitespace to an existing JSON representation of an object.
Definition: FormatJson.php:224
FormatJson\WS_CLEANUP_REGEX
const WS_CLEANUP_REGEX
Regex that matches whitespace inside empty arrays and objects.
Definition: FormatJson.php:66
FormatJson\$badCharsEscaped
static $badCharsEscaped
Escape sequences for characters listed in FormatJson::$badChars.
Definition: FormatJson.php:82
array
the array() calling protocol came about after MediaWiki 1.4rc1.
List of Api Query prop modules.
$options
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped & $options
Definition: hooks.txt:1530
$value
$value
Definition: styleTest.css.php:45
FormatJson\encode54
static encode54( $value, $pretty, $escaping)
JSON encoder wrapper for PHP >= 5.4, which supports useful encoding options.
Definition: FormatJson.php:138