+
+if ( ! function_exists( 'json_last_error_msg' ) ) :
+ /**
+ * Retrieves the error string of the last json_encode() or json_decode() call.
+ *
+ * @since 4.4.0
+ *
+ * @internal This is a compatibility function for PHP <5.5
+ *
+ * @return bool|string Returns the error message on success, "No Error" if no error has occurred,
+ * or false on failure.
+ */
+ function json_last_error_msg() {
+ // See https://core.trac.wordpress.org/ticket/27799.
+ if ( ! function_exists( 'json_last_error' ) ) {
+ return false;
+ }
+
+ $last_error_code = json_last_error();
+
+ // Just in case JSON_ERROR_NONE is not defined.
+ $error_code_none = defined( 'JSON_ERROR_NONE' ) ? JSON_ERROR_NONE : 0;
+
+ switch ( true ) {
+ case $last_error_code === $error_code_none:
+ return 'No error';
+
+ case defined( 'JSON_ERROR_DEPTH' ) && JSON_ERROR_DEPTH === $last_error_code:
+ return 'Maximum stack depth exceeded';
+
+ case defined( 'JSON_ERROR_STATE_MISMATCH' ) && JSON_ERROR_STATE_MISMATCH === $last_error_code:
+ return 'State mismatch (invalid or malformed JSON)';
+
+ case defined( 'JSON_ERROR_CTRL_CHAR' ) && JSON_ERROR_CTRL_CHAR === $last_error_code:
+ return 'Control character error, possibly incorrectly encoded';
+
+ case defined( 'JSON_ERROR_SYNTAX' ) && JSON_ERROR_SYNTAX === $last_error_code:
+ return 'Syntax error';
+
+ case defined( 'JSON_ERROR_UTF8' ) && JSON_ERROR_UTF8 === $last_error_code:
+ return 'Malformed UTF-8 characters, possibly incorrectly encoded';
+
+ case defined( 'JSON_ERROR_RECURSION' ) && JSON_ERROR_RECURSION === $last_error_code:
+ return 'Recursion detected';
+
+ case defined( 'JSON_ERROR_INF_OR_NAN' ) && JSON_ERROR_INF_OR_NAN === $last_error_code:
+ return 'Inf and NaN cannot be JSON encoded';
+
+ case defined( 'JSON_ERROR_UNSUPPORTED_TYPE' ) && JSON_ERROR_UNSUPPORTED_TYPE === $last_error_code:
+ return 'Type is not supported';
+
+ default:
+ return 'An unknown error occurred';
+ }
+ }
+endif;
+
+if ( ! interface_exists( 'JsonSerializable' ) ) {
+ define( 'WP_JSON_SERIALIZE_COMPATIBLE', true );
+ /**
+ * JsonSerializable interface.
+ *
+ * Compatibility shim for PHP <5.4
+ *
+ * @link https://secure.php.net/jsonserializable
+ *
+ * @since 4.4.0
+ */
+ interface JsonSerializable {
+ public function jsonSerialize();
+ }
+}
+
+// random_int was introduced in PHP 7.0
+if ( ! function_exists( 'random_int' ) ) {
+ require ABSPATH . WPINC . '/random_compat/random.php';
+}
+
+if ( ! function_exists( 'array_replace_recursive' ) ) :
+ /**
+ * PHP-agnostic version of {@link array_replace_recursive()}.
+ *
+ * The array_replace_recursive() function is a PHP 5.3 function. WordPress
+ * currently supports down to PHP 5.2, so this method is a workaround
+ * for PHP 5.2.
+ *
+ * Note: array_replace_recursive() supports infinite arguments, but for our use-
+ * case, we only need to support two arguments.
+ *
+ * Subject to removal once WordPress makes PHP 5.3.0 the minimum requirement.
+ *
+ * @since 4.5.3
+ *
+ * @see http://php.net/manual/en/function.array-replace-recursive.php#109390
+ *
+ * @param array $base Array with keys needing to be replaced.
+ * @param array $replacements Array with the replaced keys.
+ *
+ * @return array
+ */
+ function array_replace_recursive( $base = array(), $replacements = array() ) {
+ foreach ( array_slice( func_get_args(), 1 ) as $replacements ) {
+ $bref_stack = array( &$base );
+ $head_stack = array( $replacements );
+
+ do {
+ end( $bref_stack );
+
+ $bref = &$bref_stack[ key( $bref_stack ) ];
+ $head = array_pop( $head_stack );
+
+ unset( $bref_stack[ key( $bref_stack ) ] );
+
+ foreach ( array_keys( $head ) as $key ) {
+ if ( isset( $key, $bref ) &&
+ isset( $bref[ $key ] ) && is_array( $bref[ $key ] ) &&
+ isset( $head[ $key ] ) && is_array( $head[ $key ] )
+ ) {
+ $bref_stack[] = &$bref[ $key ];
+ $head_stack[] = $head[ $key ];
+ } else {
+ $bref[ $key ] = $head[ $key ];
+ }
+ }
+ } while ( count( $head_stack ) );
+ }
+
+ return $base;
+ }
+endif;
+
+// SPL can be disabled on PHP 5.2
+if ( ! function_exists( 'spl_autoload_register' ) ):
+ $_wp_spl_autoloaders = array();
+
+ /**
+ * Autoloader compatibility callback.
+ *
+ * @since 4.6.0
+ *
+ * @param string $classname Class to attempt autoloading.
+ */
+ function __autoload( $classname ) {
+ global $_wp_spl_autoloaders;
+ foreach ( $_wp_spl_autoloaders as $autoloader ) {
+ if ( ! is_callable( $autoloader ) ) {
+ // Avoid the extra warning if the autoloader isn't callable.
+ continue;
+ }
+
+ call_user_func( $autoloader, $classname );
+
+ // If it has been autoloaded, stop processing.
+ if ( class_exists( $classname, false ) ) {
+ return;
+ }
+ }
+ }
+
+ /**
+ * Registers a function to be autoloaded.
+ *
+ * @since 4.6.0
+ *
+ * @param callable $autoload_function The function to register.
+ * @param bool $throw Optional. Whether the function should throw an exception
+ * if the function isn't callable. Default true.
+ * @param bool $prepend Whether the function should be prepended to the stack.
+ * Default false.
+ */
+ function spl_autoload_register( $autoload_function, $throw = true, $prepend = false ) {
+ if ( $throw && ! is_callable( $autoload_function ) ) {
+ // String not translated to match PHP core.
+ throw new Exception( 'Function not callable' );
+ }
+
+ global $_wp_spl_autoloaders;
+
+ // Don't allow multiple registration.
+ if ( in_array( $autoload_function, $_wp_spl_autoloaders ) ) {
+ return;
+ }
+
+ if ( $prepend ) {
+ array_unshift( $_wp_spl_autoloaders, $autoload_function );
+ } else {
+ $_wp_spl_autoloaders[] = $autoload_function;
+ }
+ }
+
+ /**
+ * Unregisters an autoloader function.
+ *
+ * @since 4.6.0
+ *
+ * @param callable $function The function to unregister.
+ * @return bool True if the function was unregistered, false if it could not be.
+ */
+ function spl_autoload_unregister( $function ) {
+ global $_wp_spl_autoloaders;
+ foreach ( $_wp_spl_autoloaders as &$autoloader ) {
+ if ( $autoloader === $function ) {
+ unset( $autoloader );
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Retrieves the registered autoloader functions.
+ *
+ * @since 4.6.0
+ *
+ * @return array List of autoloader functions.
+ */
+ function spl_autoload_functions() {
+ return $GLOBALS['_wp_spl_autoloaders'];
+ }
+endif;