Edit file File name : SnapJson.php Content :<?php /** * * @package Duplicator * @copyright (c) 2022, Snap Creek LLC */ namespace Duplicator\Libs\Snap; // phpcs:disable require_once(__DIR__ . '/JsonSerializable.php'); // phpcs:enable class SnapJson { /** * Encode a variable into JSON, with some sanity checks. * * @since 4.1.0 * * @param mixed $data Variable (usually an array or object) to encode as JSON. * @param int $options Optional. Options to be passed to json_encode(). Default 0. * @param int $depth Optional. Maximum depth to walk through $data. Must be * greater than 0. Default 512. * * @return string|false The JSON encoded string, or false if it cannot be encoded. */ public static function jsonEncode($data, $options = 0, $depth = 512) { if (function_exists('wp_json_encode')) { return wp_json_encode($data, $options, $depth); } /* * json_encode() has had extra params added over the years. * $options was added in 5.3, and $depth in 5.5. * We need to make sure we call it with the correct arguments. */ if (version_compare(PHP_VERSION, '5.5', '>=')) { $args = array($data, $options, $depth); } elseif (version_compare(PHP_VERSION, '5.3', '>=')) { $args = array($data, $options); } else { $args = array($data); } $preparedData = self::jsonPrepareData($data); // Prepare the data for JSON serialization. $args[0] = $preparedData; $json = @call_user_func_array('json_encode', $args); // If json_encode() was successful, no need to do more sanity checking. // ... unless we're in an old version of PHP, and json_encode() returned // a string containing 'null'. Then we need to do more sanity checking. if (false !== $json && ( version_compare(PHP_VERSION, '5.5', '>=') || false === strpos($json, 'null') )) { return $json; } try { $args[0] = self::jsonSanityCheck($preparedData, $depth); } catch (\Exception $e) { return false; } return call_user_func_array('json_encode', $args); } /** * wp_json_encode with pretty print if define exists * * @param mixed $data Variable (usually an array or object) to encode as JSON. * @param int $options Optional. Options to be passed to json_encode(). Default 0. * @param int $depth Optional. Maximum depth to walk through $data. Must be * greater than 0. Default 512. * * @return string|false The JSON encoded string, or false if it cannot be encoded. */ public static function jsonEncodePPrint($data, $options = 0, $depth = 512) { if (defined('JSON_PRETTY_PRINT')) { // phpcs:ignore PHPCompatibility.Constants.NewConstants.json_pretty_printFound return self::jsonEncode($data, JSON_PRETTY_PRINT | $options, $depth); } else { return self::jsonEncode($data, $options, $depth); } } /** * Prepares response data to be serialized to JSON. * * This supports the JsonSerializable interface for PHP 5.2-5.3 as well. * * @param mixed $data Native representation. * * @return bool|int|float|null|string|mixed[] Data ready for `json_encode()`. */ private static function jsonPrepareData($data) { if ( !defined('WP_JSON_SERIALIZE_COMPATIBLE') || WP_JSON_SERIALIZE_COMPATIBLE === false ) { return $data; } switch (gettype($data)) { case 'boolean': case 'integer': case 'double': case 'string': case 'NULL': // These values can be passed through. return $data; case 'array': // Arrays must be mapped in case they also return objects. return array_map(array(__CLASS__, 'jsonPrepareData'), $data); case 'object': // If this is an incomplete object (__PHP_Incomplete_Class), bail. if (!is_object($data)) { return null; } if ($data instanceof \JsonSerializable) { $data = $data->jsonSerialize(); } else { $data = get_object_vars($data); } // Now, pass the array (or whatever was returned from jsonSerialize through). return self::jsonPrepareData($data); default: return null; } } /** * Perform sanity checks on data that shall be encoded to JSON. * * @ignore * @since 4.1.0 * @access private * * @see wp_json_encode() * * @param mixed $data Variable (usually an array or object) to encode as JSON. * @param int $depth Maximum depth to walk through $data. Must be greater than 0. * * @return mixed The sanitized data that shall be encoded to JSON. */ private static function jsonSanityCheck($data, $depth) { if ($depth < 0) { throw new \Exception('Reached depth limit'); } if ($data instanceof \JsonSerializable) { $data = $data->jsonSerialize(); } if (is_array($data)) { $output = array(); foreach ($data as $id => $el) { // Don't forget to sanitize the ID! if (is_string($id)) { $clean_id = self::jsonConvertString($id); } else { $clean_id = $id; } // Check the element type, so that we're only recursing if we really have to. if (is_array($el) || is_object($el)) { $output[$clean_id] = self::jsonSanityCheck($el, $depth - 1); } elseif (is_string($el)) { $output[$clean_id] = self::jsonConvertString($el); } else { $output[$clean_id] = $el; } } } elseif (is_object($data)) { $output = new \stdClass(); foreach ($data as $id => $el) { if (is_string($id)) { $clean_id = self::jsonConvertString($id); } else { $clean_id = $id; } if (is_array($el) || is_object($el)) { $output->$clean_id = self::jsonSanityCheck($el, $depth - 1); } elseif (is_string($el)) { $output->$clean_id = self::jsonConvertString($el); } else { $output->$clean_id = $el; } } } elseif (is_string($data)) { return self::jsonConvertString($data); } else { return $data; } return $output; } /** * Return json string * * @param string $string data * * @return string */ private static function jsonConvertString($string) { static $use_mb = null; if (is_null($use_mb)) { $use_mb = function_exists('mb_convert_encoding'); } if ($use_mb) { $encoding = mb_detect_encoding($string, mb_detect_order(), true); if ($encoding) { return mb_convert_encoding($string, 'UTF-8', $encoding); } else { return mb_convert_encoding($string, 'UTF-8', 'UTF-8'); } } else { return self::checkInvalidUTF8($string, true); } } /** * Checks for invalid UTF8 in a string. * * @param string $string The text which is to be checked. * @param bool $strip Optional. Whether to attempt to strip out invalid UTF8. Default is false. * * @return string The checked text. */ public static function checkInvalidUTF8($string, $strip = false) { $string = (string) $string; if (0 === strlen($string)) { return ''; } // Check for support for utf8 in the installed PCRE library once and store the result in a static static $utf8_pcre = null; if (!isset($utf8_pcre)) { $utf8_pcre = @preg_match('/^./u', 'a'); } // We can't demand utf8 in the PCRE installation, so just return the string in those cases if (!$utf8_pcre) { return $string; } // preg_match fails when it encounters invalid UTF8 in $string if (1 === @preg_match('/^./us', $string)) { return $string; } // Attempt to strip the bad chars if requested (not recommended) if ($strip && function_exists('iconv')) { return iconv('utf-8', 'utf-8', $string); } return ''; } /** * todo remove esc_attr wp function * * @param mixed $val object to be encoded * * @return string escaped json string */ public static function jsonEncodeEscAttr($val) { return esc_attr(json_encode($val)); } /** * this function return a json encoded string without quotes at the beginning and the end * * @param string $string json string * * @return string */ public static function getJsonWithoutQuotes($string) { if (!is_string($string)) { throw new \Exception('the function getJsonStringWithoutQuotes take only strings'); } return substr(self::jsonEncode($string), 1, -1); } } Save