%PDF- %PDF-
Direktori : /var/www/projetos/suporte.iigd.com.br.old/vendor/swaggest/json-diff/src/ |
Current File : //var/www/projetos/suporte.iigd.com.br.old/vendor/swaggest/json-diff/src/JsonPointer.php |
<?php namespace Swaggest\JsonDiff; class JsonPointer { /** * Create intermediate keys if they don't exist */ const RECURSIVE_KEY_CREATION = 1; /** * Disallow converting empty array to object for key creation */ const STRICT_MODE = 2; /** * Skip action if holder already has a non-null value at path */ const SKIP_IF_ISSET = 4; /** * Allow associative arrays to mimic JSON objects (not recommended) */ const TOLERATE_ASSOCIATIVE_ARRAYS = 8; /** * @param string $key * @param bool $isURIFragmentId * @return string */ public static function escapeSegment($key, $isURIFragmentId = false) { if ($isURIFragmentId) { return str_replace(array('%7E', '%2F'), array('~0', '~1'), urlencode($key)); } else { return str_replace(array('~', '/'), array('~0', '~1'), $key); } } /** * @param string[] $pathItems * @param bool $isURIFragmentId * @return string */ public static function buildPath(array $pathItems, $isURIFragmentId = false) { $result = $isURIFragmentId ? '#' : ''; foreach ($pathItems as $pathItem) { $result .= '/' . self::escapeSegment($pathItem, $isURIFragmentId); } return $result; } /** * @param string $path * @return string[] * @throws Exception */ public static function splitPath($path) { $pathItems = explode('/', $path); $first = array_shift($pathItems); if ($first === '#') { return self::splitPathURIFragment($pathItems); } else { if ($first !== '') { throw new Exception('Path must start with "/": ' . $path); } return self::splitPathJsonString($pathItems); } } private static function splitPathURIFragment(array $pathItems) { $result = array(); foreach ($pathItems as $key) { $key = str_replace(array('~1', '~0'), array('/', '~'), urldecode($key)); $result[] = $key; } return $result; } private static function splitPathJsonString(array $pathItems) { $result = array(); foreach ($pathItems as $key) { $key = str_replace(array('~1', '~0'), array('/', '~'), $key); $result[] = $key; } return $result; } /** * @param mixed $holder * @param string[] $pathItems * @param mixed $value * @param int $flags * @throws Exception */ public static function add(&$holder, $pathItems, $value, $flags = self::RECURSIVE_KEY_CREATION) { $ref = &$holder; while (null !== $key = array_shift($pathItems)) { if ($ref instanceof \stdClass || is_object($ref)) { if (PHP_VERSION_ID < 70100 && '' === $key) { throw new Exception('Empty property name is not supported by PHP <7.1', Exception::EMPTY_PROPERTY_NAME_UNSUPPORTED); } if ($flags & self::RECURSIVE_KEY_CREATION) { $ref = &$ref->$key; } else { if (!isset($ref->$key) && count($pathItems)) { throw new Exception('Non-existent path item: ' . $key); } else { $ref = &$ref->$key; } } } else { // null or array $intKey = filter_var($key, FILTER_VALIDATE_INT); if ($ref === null && (false === $intKey || $intKey !== 0)) { $key = (string)$key; if ($flags & self::RECURSIVE_KEY_CREATION) { $ref = new \stdClass(); $ref = &$ref->{$key}; } else { throw new Exception('Non-existent path item: ' . $key); } } elseif ([] === $ref && 0 === ($flags & self::STRICT_MODE) && false === $intKey && '-' !== $key) { $ref = new \stdClass(); $ref = &$ref->{$key}; } else { if ($flags & self::RECURSIVE_KEY_CREATION && $ref === null) $ref = array(); if ('-' === $key) { $ref = &$ref[count($ref)]; } else { if (false === $intKey) { if (0 === ($flags & self::TOLERATE_ASSOCIATIVE_ARRAYS)) { throw new Exception('Invalid key for array operation'); } $ref = &$ref[$key]; continue; } if (is_array($ref) && array_key_exists($key, $ref) && empty($pathItems)) { array_splice($ref, $intKey, 0, array($value)); } if (0 === ($flags & self::TOLERATE_ASSOCIATIVE_ARRAYS)) { if ($intKey > count($ref) && 0 === ($flags & self::RECURSIVE_KEY_CREATION)) { throw new Exception('Index is greater than number of items in array'); } elseif ($intKey < 0) { throw new Exception('Negative index'); } } $ref = &$ref[$intKey]; } } } } if ($ref !== null && $flags & self::SKIP_IF_ISSET) { return; } $ref = $value; } private static function arrayKeyExists($key, array $a) { if (array_key_exists($key, $a)) { return true; } $key = (string)$key; foreach ($a as $k => $v) { if ((string)$k === $key) { return true; } } return false; } private static function arrayGet($key, array $a) { $key = (string)$key; foreach ($a as $k => $v) { if ((string)$k === $key) { return $v; } } return false; } /** * @param mixed $holder * @param string[] $pathItems * @return bool|mixed * @throws Exception */ public static function get($holder, $pathItems) { $ref = $holder; while (null !== $key = array_shift($pathItems)) { if ($ref instanceof \stdClass) { if (PHP_VERSION_ID < 70100 && '' === $key) { throw new Exception('Empty property name is not supported by PHP <7.1', Exception::EMPTY_PROPERTY_NAME_UNSUPPORTED); } $vars = (array)$ref; if (self::arrayKeyExists($key, $vars)) { $ref = self::arrayGet($key, $vars); } else { throw new Exception('Key not found: ' . $key); } } elseif (is_array($ref)) { if (self::arrayKeyExists($key, $ref)) { $ref = $ref[$key]; } else { throw new Exception('Key not found: ' . $key); } } elseif (is_object($ref)) { if (isset($ref->$key)) { $ref = $ref->$key; } else { throw new Exception('Key not found: ' . $key); } } else { throw new Exception('Key not found: ' . $key); } } return $ref; } /** * @param mixed $holder * @param string $pointer * @return bool|mixed * @throws Exception */ public static function getByPointer($holder, $pointer) { return self::get($holder, self::splitPath($pointer)); } /** * @param mixed $holder * @param string[] $pathItems * @param int $flags * @return mixed * @throws Exception */ public static function remove(&$holder, $pathItems, $flags = 0) { $ref = &$holder; while (null !== $key = array_shift($pathItems)) { $parent = &$ref; $refKey = $key; if ($ref instanceof \stdClass) { if (property_exists($ref, $key)) { $ref = &$ref->$key; } else { throw new Exception('Key not found: ' . $key); } } elseif (is_object($ref)) { if (isset($ref->$key)) { $ref = &$ref->$key; } else { throw new Exception('Key not found: ' . $key); } } else { if (array_key_exists($key, $ref)) { $ref = &$ref[$key]; } else { throw new Exception('Key not found: ' . $key); } } } if (isset($parent) && isset($refKey)) { if ($parent instanceof \stdClass || is_object($parent)) { unset($parent->$refKey); } else { $isAssociative = false; if ($flags & self::TOLERATE_ASSOCIATIVE_ARRAYS) { $i = 0; foreach ($parent as $index => $value) { if ($i !== $index) { $isAssociative = true; break; } } } unset($parent[$refKey]); if (!$isAssociative && (int)$refKey !== count($parent)) { $parent = array_values($parent); } } } return $ref; } }