/** * @param string $targetDocument * * @throws \Rs\Json\Patch\InvalidOperationException * @throws \Rs\Json\Pointer\InvalidJsonException * @throws \Rs\Json\Pointer\InvalidPointerException * @throws \Rs\Json\Pointer\NonWalkableJsonException * @throws \RuntimeException * @return boolean */ public function perform($targetDocument) { $pointer = new Pointer($targetDocument); try { $get = $pointer->get($this->getPath()); // Pointer::get() method can return mixed result, we should force type to array for json string if ($this->isValidJsonString($get)) { $get = json_decode($get); } } catch (NonexistentValueReferencedException $e) { $get = null; } $value = $this->getValue(); /** * to remain backwards compatible, we support testing a $value of array with non-numeric indexes * to a $get of object.. in that case, we cast $value to object */ if (is_array($value) && !empty($value)) { // in if to remain php 5.4 compatible $keys = array_keys($value); if (!ctype_digit((string) $keys[0])) { $value = (object) $value; } } if (is_array($value) && is_array($get)) { return $this->arraysAreIdentical($value, $get); } if (is_object($value) && is_object($get)) { return $get == $value; } return $get === $value; }
/** * @param string $targetDocument * * @throws \Rs\Json\Patch\InvalidOperationException * @throws \Rs\Json\Pointer\InvalidJsonException * @throws \Rs\Json\Pointer\InvalidPointerException * @throws \Rs\Json\Pointer\NonWalkableJsonException * @throws \RuntimeException * @return string */ public function perform($targetDocument) { $pointer = new Pointer($targetDocument); try { $get = $pointer->get($this->getPath()); } catch (NonexistentValueReferencedException $e) { return $targetDocument; } $targetDocument = json_decode($targetDocument); $this->replace($targetDocument, $this->getPointerParts(), $this->getValue()); return json_encode($targetDocument, JSON_UNESCAPED_UNICODE); }
/** * @param string $targetDocument * * @return string */ public function perform($targetDocument) { $pointer = new Pointer($targetDocument); try { $get = $pointer->get($this->getPath()); } catch (NonexistentValueReferencedException $e) { return $targetDocument; } $targetDocument = json_decode($targetDocument, true); $this->remove($targetDocument, $this->getPointerParts()); return json_encode($targetDocument); }
/** * @param string $targetDocument * * @throws \Rs\Json\Patch\InvalidOperationException * @throws \Rs\Json\Pointer\InvalidJsonException * @throws \Rs\Json\Pointer\InvalidPointerException * @throws \Rs\Json\Pointer\NonWalkableJsonException * @throws \RuntimeException * @return string */ public function perform($targetDocument) { $pointer = new Pointer($targetDocument); try { $get = $pointer->get($this->getFrom()); } catch (NonexistentValueReferencedException $e) { return $targetDocument; } if ($this->getFrom() === $this->getPath()) { return $targetDocument; } $operation = new \stdClass(); $operation->path = $this->getPath(); $operation->value = $get; $add = new Add($operation); return $add->perform($targetDocument); }
/** * @param string $targetDocument * * @return boolean */ public function perform($targetDocument) { $pointer = new Pointer($targetDocument); try { $get = $pointer->get($this->getPath()); // Pointer::get() method can return mixed result, we should force type to array for json string if ($this->isValidJsonString($get)) { $get = json_decode($get, true); } } catch (NonexistentValueReferencedException $e) { $get = null; } $value = is_object($this->getValue()) ? (array) $this->getValue() : $this->getValue(); if (is_array($value) && is_array($get)) { asort($get); asort($value); return json_encode($get) === json_encode($value); } return $get === $this->getValue(); }
/** * @param string $targetDocument * * @return boolean */ public function perform($targetDocument) { $pointer = new Pointer($targetDocument); try { $get = $pointer->get($this->getPath()); } catch (NonexistentValueReferencedException $e) { $get = null; } if (is_string($this->getValue())) { $value = json_decode($this->getValue(), true); } else { $value = $this->getValue(); } if (is_array($value) && is_array($get)) { asort($get); asort($value); return json_encode($get) === json_encode($value); } return $get === $this->getValue(); }
/** * @param string $targetDocument JSON of target document * @param string $jsonPatch * @return boolean */ public function validate($targetDocument, $jsonPatch) { $operations = json_decode($jsonPatch, true); $pointer = new Pointer($targetDocument); foreach ($operations as $op) { try { $pointer->get($op['path']); } catch (InvalidPointerException $e) { // Basic validation failed $this->setException($e); return false; } catch (NonexistentValueReferencedException $e) { $pathParts = explode('/', $op['path']); $lastPart = end($pathParts); if (is_numeric($lastPart)) { /** * JSON Pointer library throws an Exception when INDEX is equal to number of elements in array * But JSON Patch allow this as described in RFC * * http://tools.ietf.org/html/rfc6902#section-4.1 * "The specified index MUST NOT be greater than the number of elements in the array." */ // Try to check previous element array_pop($pathParts); array_push($pathParts, $lastPart - 1); try { $pointer->get(implode('/', $pathParts)); } catch (NonexistentValueReferencedException $e) { $this->setException($e); return false; } } } } return true; }
/** * @param string $targetDocument * * @return string */ public function perform($targetDocument) { $pointer = new Pointer($targetDocument); try { $get = $pointer->get($this->getPath()); } catch (NonexistentValueReferencedException $e) { $get = null; } $pointerParts = $this->getPointerParts(); $rootPointer = $pointerParts[0]; if (count($pointerParts) >= 2) { try { $rootGet = $pointer->get(Pointer::POINTER_CHAR . $rootPointer); } catch (NonexistentValueReferencedException $e) { return $targetDocument; } } $targetDocument = json_decode($targetDocument, true); $lastPointerPart = $pointerParts[count($pointerParts) - 1]; if ($get === null && $lastPointerPart !== Pointer::LAST_ARRAY_ELEMENT_CHAR) { if (ctype_digit($lastPointerPart) && $lastPointerPart > count($rootGet)) { return json_encode($targetDocument); } if (count($pointerParts) === 1) { $targetDocument[$pointerParts[0]] = $this->getValue(); } elseif (count($pointerParts) > 1) { $augmentedDocument =& $targetDocument; foreach ($pointerParts as $pointerPart) { $augmentedDocument =& $augmentedDocument[$pointerPart]; } $augmentedDocument = $this->getValue(); } } else { $additionIndex = array_pop($pointerParts); $arrayEntryPath = '/' . implode('/', $pointerParts); try { $targetArray = $pointer->get($arrayEntryPath); } catch (NonexistentValueReferencedException $e) { $targetArray = null; } if (is_array($targetArray)) { if ($lastPointerPart === Pointer::LAST_ARRAY_ELEMENT_CHAR) { $targetArray[] = $this->getValue(); } else { if (is_numeric($additionIndex)) { $replacement = is_array($this->getValue()) || is_object($this->getValue()) ? array($this->getValue()) : $this->getValue(); array_splice($targetArray, $additionIndex, 0, $replacement); } else { $targetArray[$additionIndex] = $this->getValue(); } } $augmentedDocument =& $targetDocument; foreach ($pointerParts as $pointerPart) { $augmentedDocument =& $augmentedDocument[$pointerPart]; } $augmentedDocument = $targetArray; } if ($targetArray === null) { $targetDocument[$additionIndex] = $this->getValue(); } } return json_encode($targetDocument); }