Passed
Push — master ( 7ad944...9954d6 )
by Viacheslav
02:21
created

JsonPatch::import()   C

Complexity

Conditions 16
Paths 68

Size

Total Lines 57
Code Lines 43

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 57
c 0
b 0
f 0
rs 6.5273
cc 16
eloc 43
nc 68
nop 1

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Swaggest\JsonDiff;
4
5
use Swaggest\JsonDiff\JsonPatch\Add;
6
use Swaggest\JsonDiff\JsonPatch\Copy;
7
use Swaggest\JsonDiff\JsonPatch\Move;
8
use Swaggest\JsonDiff\JsonPatch\OpPath;
9
use Swaggest\JsonDiff\JsonPatch\OpPathFrom;
10
use Swaggest\JsonDiff\JsonPatch\OpPathValue;
11
use Swaggest\JsonDiff\JsonPatch\Remove;
12
use Swaggest\JsonDiff\JsonPatch\Replace;
13
use Swaggest\JsonDiff\JsonPatch\Test;
14
15
/**
16
 * JSON Patch is specified in [RFC 6902](http://tools.ietf.org/html/rfc6902) from the IETF.
17
 *
18
 * Class JsonPatch
19
 */
20
class JsonPatch implements \JsonSerializable
21
{
22
    /** @var OpPath[] */
23
    private $operations = array();
24
25
    /**
26
     * @param array $data
27
     * @return JsonPatch
28
     * @throws Exception
29
     */
30
    public static function import($data)
31
    {
32
        if (!is_array($data)) {
0 ignored issues
show
introduced by
The condition ! is_array($data) can never be true.
Loading history...
33
            throw new Exception('Array expected in JsonPatch::import');
34
        }
35
        $result = new JsonPatch();
36
        foreach ($data as $operation) {
37
            /** @var OpPath|OpPathValue|OpPathFrom $operation */
38
            if (is_array($operation)) {
39
                $operation = (object)$operation;
40
            }
41
42
            if (!isset($operation->op)) {
43
                throw new Exception('Missing "op" in operation data');
44
            }
45
            if (!isset($operation->path)) {
46
                throw new Exception('Missing "path" in operation data');
47
            }
48
49
            $op = null;
50
            switch ($operation->op) {
51
                case Add::OP:
52
                    $op = new Add();
53
                    break;
54
                case Copy::OP:
55
                    $op = new Copy();
56
                    break;
57
                case Move::OP:
58
                    $op = new Move();
59
                    break;
60
                case Remove::OP:
61
                    $op = new Remove();
62
                    break;
63
                case Replace::OP:
64
                    $op = new Replace();
65
                    break;
66
                case Test::OP:
67
                    $op = new Test();
68
                    break;
69
                default:
70
                    throw new Exception('Unknown "op": ' . $operation->op);
71
            }
72
            $op->path = $operation->path;
73
            if ($op instanceof OpPathValue) {
74
                if (!array_key_exists('value', (array)$operation)) {
75
                    throw new Exception('Missing "value" in operation data');
76
                }
77
                $op->value = $operation->value;
78
            } elseif ($op instanceof OpPathFrom) {
79
                if (!isset($operation->from)) {
80
                    throw new Exception('Missing "from" in operation data');
81
                }
82
                $op->from = $operation->from;
83
            }
84
            $result->operations[] = $op;
85
        }
86
        return $result;
87
    }
88
89
    public static function export(JsonPatch $patch)
90
    {
91
        $result = array();
92
        foreach ($patch->operations as $operation) {
93
            $result[] = (object)(array)$operation;
94
        }
95
96
        return $result;
97
    }
98
99
    public function op(OpPath $op)
100
    {
101
        $this->operations[] = $op;
102
        return $this;
103
    }
104
105
    public function jsonSerialize()
106
    {
107
        return self::export($this);
108
    }
109
110
    /**
111
     * @param $original
112
     * @throws Exception
113
     */
114
    public function apply(&$original)
115
    {
116
        foreach ($this->operations as $operation) {
117
            $pathItems = JsonPointer::splitPath($operation->path);
118
            switch (true) {
119
                case $operation instanceof Add:
120
                    JsonPointer::add($original, $pathItems, $operation->value);
121
                    break;
122
                case $operation instanceof Copy:
123
                    $fromItems = JsonPointer::splitPath($operation->from);
124
                    $value = JsonPointer::get($original, $fromItems);
125
                    JsonPointer::add($original, $pathItems, $value);
126
                    break;
127
                case $operation instanceof Move:
128
                    $fromItems = JsonPointer::splitPath($operation->from);
129
                    $value = JsonPointer::get($original, $fromItems);
130
                    JsonPointer::add($original, $pathItems, $value);
131
                    JsonPointer::remove($original, $fromItems);
132
                    break;
133
                case $operation instanceof Remove:
134
                    JsonPointer::remove($original, $pathItems);
135
                    break;
136
                case $operation instanceof Replace:
137
                    JsonPointer::get($original, $pathItems);
138
                    JsonPointer::add($original, $pathItems, $operation->value);
139
                    break;
140
                case $operation instanceof Test:
141
                    $value = JsonPointer::get($original, $pathItems);
142
                    $diff = new JsonDiff($operation->value, $value,
143
                        JsonDiff::STOP_ON_DIFF);
144
                    if ($diff->getDiffCnt() !== 0) {
145
                        throw new Exception('Test operation ' . json_encode($operation) . ' failed: ' . json_encode($value));
146
                    }
147
                    break;
148
            }
149
        }
150
    }
151
}