* @license http://www.apache.org/licenses/LICENSE-2.0 * @link http://phpsx.org * @see https://github.com/mikemccabe/json-patch-php * @see https://tools.ietf.org/html/rfc6902 */ class Patch { protected $operations; public function __construct(array $operations) { $this->operations = $operations; } public function patch($data) { foreach ($this->operations as $operation) { $op = isset($operation->op) ? $operation->op : null; $path = isset($operation->path) ? $operation->path : null; $value = isset($operation->value) ? $operation->value : null; $from = isset($operation->from) ? $operation->from : null; switch ($op) { case 'add': case 'append': case 'replace': if (!property_exists($operation, 'value')) { throw new InvalidArgumentException('Value not available'); } $pointer = new Pointer($path); $data = $this->doOperation($data, $pointer->getParts(), $op, $path, $value); break; case 'remove': $pointer = new Pointer($path); $data = $this->doOperation($data, $pointer->getParts(), $op, $path, null); break; case 'test': if (!property_exists($operation, 'value')) { throw new InvalidArgumentException('Value not available'); } $pointer = new Pointer($path); $actual = $pointer->evaluate($data); if (!Comparator::compare($value, $actual)) { throw new InvalidArgumentException('Test value is different'); } break; case 'copy': if (!property_exists($operation, 'from')) { throw new InvalidArgumentException('From not available'); } $pointer = new Pointer($from); $value = $pointer->evaluate($data); $pointer = new Pointer($path); $data = $this->doOperation($data, $pointer->getParts(), 'add', $path, $value); break; case 'move': if (!property_exists($operation, 'from')) { throw new InvalidArgumentException('From not available'); } $pointer = new Pointer($from); $value = $pointer->evaluate($data); $data = $this->doOperation($data, $pointer->getParts(), 'remove', $path, null); $pointer = new Pointer($path); $data = $this->doOperation($data, $pointer->getParts(), 'add', $path, $value); break; default: throw new InvalidArgumentException('Invalid operator'); break; } } return $data; } protected function doOperation($data, array $parts, $op, $path, $value) { if (count($parts) == 0) { if ($op == 'add' || $op == 'replace') { return $value; } } $part = array_shift($parts); if (count($parts) > 0) { if (is_array($data)) { if (array_key_exists($part, $data)) { $data[$part] = $this->doOperation($data[$part], $parts, $op, $path, $value); } else { throw new InvalidArgumentException('Property ' . $part . ' does not exist at /' . implode('/', $parts)); } } elseif ($data instanceof \stdClass) { if (property_exists($data, $part)) { $data->$part = $this->doOperation($data->$part, $parts, $op, $path, $value); } else { throw new InvalidArgumentException('Property ' . $part . ' does not exist at /' . implode('/', $parts)); } } elseif ($data instanceof RecordInterface) { if ($data->hasProperty($part)) { $data->setProperty($part, $this->doOperation($data->getProperty($part), $parts, $op, $path, $value)); } else { throw new InvalidArgumentException('Property ' . $part . ' does not exist at /' . implode('/', $parts)); } } else { throw new InvalidArgumentException('Invalid path ' . $path); } return $data; } if (is_array($data)) { if ($part == '-' || preg_match('/^(0|[1-9][0-9]*)$/', $part)) { if ($op == 'add' || $op == 'append') { if ($part == '-') { $data[] = $value; } else { $index = intval($part); if ($index >= 0 && $index <= count($data)) { array_splice($data, $index, 0, [$value]); } else { throw new InvalidArgumentException('Key ' . $index . ' does not exist at /' . implode('/', $parts)); } } } elseif ($op == 'replace') { if (array_key_exists($part, $data)) { $data[$part] = $value; } } elseif ($op == 'remove') { if (array_key_exists($part, $data)) { unset($data[$part]); $data = array_values($data); } else { throw new InvalidArgumentException('Property ' . $part . ' does not exist at /' . implode('/', $parts)); } } } else { throw new InvalidArgumentException('Invalid key at /' . implode('/', $parts)); } } elseif ($data instanceof \stdClass) { if ($part !== '') { if ($op == 'add' || $op == 'append') { $data->$part = $value; } elseif ($op == 'replace') { if (property_exists($data, $part)) { $data->$part = $value; } } elseif ($op == 'remove') { if (property_exists($data, $part)) { unset($data->$part); } else { throw new InvalidArgumentException('Property ' . $part . ' does not exist at /' . implode('/', $parts)); } } } } elseif ($data instanceof RecordInterface) { if ($part !== '') { if ($op == 'add' || $op == 'append') { $data->setProperty($part, $value); } elseif ($op == 'replace') { if ($data->hasProperty($part)) { $data->setProperty($part, $value); } } elseif ($op == 'remove') { if ($data->hasProperty($part)) { $data->removeProperty($part); } else { throw new InvalidArgumentException('Property ' . $part . ' does not exist at /' . implode('/', $parts)); } } } } return $data; } } __halt_compiler();----SIGNATURE:----gXSMrDdFIhGnD+s2ImcVjGii+z0T/kvoP1kVTDgGH7W23aN0ZzX1qpiOj2ofS3dBLDoPQaURIgUt2lgGC5nWkJ6qQAzj21CB7AA5iOaclSyFRdnWi1HPwdAqEunAJXH5QqmOYy1nybivU2ubSxDm3n45OEu0oAdKJUj1f/V68FOH3BdDi6tTK1oJqKsG6gOSxTbpEVdeoHvl6skzrRDTp3r8qXPclRgUutZXm59Bkbdn34FYAa4qcF3m/uNVx3NqfnBIbbyWdqe0Rc83KnB105A7x3a86havEQ2yjwpn6g7QTDHfMSD58OvP2FL7pkKdpbNZqoM9W6Yqus/IAmO0lkRKCj5W3lzKYssZMeZc4VHkvsScrpsrt9aKHqaeF6XTpX62GNiLNpHPL7LvNqf4d4PDoMq8mpNA28J4mTIG953Q4sCr81xD60z33g9+FrHQQhHKzmKe0zz0iJXoDOGRKuwBTqj63wP6JbPKuvtNSYa5PM58rXmy1ibESDXYw+mmQTTWO/Gx4pqoLm0tDx2kwUs4Ks2FuL73QLx8UNI37VnWmj5PLtMFhoKgfNQ/U61ZE6QNUuOIz6bJBRo4MLENsT0BknLj3RHl1fEIKeIBidl1wjaZnVn6eoHPhECGufiDotJvKc2UuH1qTT9sz3xANH8GBJrCWIlKABZjnNrUbC0=----ATTACHMENT:----NzIzMjk1ODIyNDQ0NTIxNSA5NDA1NzIxNzIyNjEzNjg0IDUzMTI2NTMyMzg5MzQ3OA==