forked from swaggest/json-diff
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathJsonValueReplace.php
79 lines (65 loc) · 2.13 KB
/
JsonValueReplace.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
<?php
namespace Swaggest\JsonDiff;
class JsonValueReplace
{
private $search;
private $replace;
private $pathFilterRegex;
private $path = '';
private $pathItems = array();
public $affectedPaths = array();
/**
* JsonReplace constructor.
* @param mixed $search
* @param mixed $replace
* @param null|string $pathFilter Regular expression to check path
*/
public function __construct($search, $replace, $pathFilter = null)
{
$this->search = $search;
$this->replace = $replace;
$this->pathFilterRegex = $pathFilter;
}
/**
* Recursively replaces all nodes equal to `search` value with `replace` value.
* @param mixed $data
* @return mixed
* @throws Exception
*/
public function process($data)
{
$check = true;
if ($this->pathFilterRegex && !preg_match($this->pathFilterRegex, $this->path)) {
$check = false;
}
if (!is_array($data) && !is_object($data)) {
if ($check && $data === $this->search) {
$this->affectedPaths[] = $this->path;
return $this->replace;
} else {
return $data;
}
}
/** @var string[] $originalKeys */
$originalKeys = $data instanceof \stdClass ? get_object_vars($data) : $data;
if ($check) {
$diff = new JsonDiff($data, $this->search, JsonDiff::STOP_ON_DIFF);
if ($diff->getDiffCnt() === 0) {
$this->affectedPaths[] = $this->path;
return $this->replace;
}
}
$result = array();
foreach ($originalKeys as $key => $originalValue) {
$path = $this->path;
$pathItems = $this->pathItems;
$actualKey = $key;
$this->path .= '/' . JsonPointer::escapeSegment($actualKey);
$this->pathItems[] = $actualKey;
$result[$key] = $this->process($originalValue);
$this->path = $path;
$this->pathItems = $pathItems;
}
return $data instanceof \stdClass ? (object)$result : $result;
}
}