Completed
Push — master ( ab1ce3...fbad15 )
by Viacheslav
10:10 queued 20s
created

JsonHash   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 70
Duplicated Lines 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
wmc 17
eloc 38
c 1
b 1
f 0
dl 0
loc 70
rs 10

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
C xorHash() 0 56 16
1
<?php
2
3
namespace Swaggest\JsonDiff;
4
5
class JsonHash
6
{
7
    private $options = 0;
8
9
    public function __construct($options = 0)
10
    {
11
        $this->options = $options;
12
    }
13
14
    /**
15
     * @param mixed $data
16
     * @param string $path
17
     * @return string
18
     */
19
    public function xorHash($data, $path = '')
20
    {
21
        $xorHash = '';
22
23
        if (!$data instanceof \stdClass && !is_array($data)) {
24
            $s = $path . (string)$data;
25
            if (strlen($xorHash) < strlen($s)) {
26
                $xorHash = str_pad($xorHash, strlen($s));
27
            }
28
            $xorHash ^= $s;
29
30
            return $xorHash;
31
        }
32
33
        if ($this->options & JsonDiff::TOLERATE_ASSOCIATIVE_ARRAYS) {
34
            if (is_array($data) && !empty($data) && !array_key_exists(0, $data)) {
35
                $data = (object)$data;
36
            }
37
        }
38
39
        if (is_array($data)) {
40
            if ($this->options & JsonDiff::REARRANGE_ARRAYS) {
41
                foreach ($data as $key => $item) {
42
                    $itemPath = $path . '/' . $key;
43
                    $itemHash = $path . $this->xorHash($item, $itemPath);
44
                    if (strlen($xorHash) < strlen($itemHash)) {
45
                        $xorHash = str_pad($xorHash, strlen($itemHash));
46
                    }
47
                    $xorHash ^= $itemHash;
48
                }
49
            } else {
50
                foreach ($data as $key => $item) {
51
                    $itemPath = $path . '/' . $key;
52
                    $itemHash = md5($itemPath . $this->xorHash($item, $itemPath), true);
53
                    if (strlen($xorHash) < strlen($itemHash)) {
54
                        $xorHash = str_pad($xorHash, strlen($itemHash));
55
                    }
56
                    $xorHash ^= $itemHash;
57
                }
58
            }
59
60
            return $xorHash;
61
        }
62
63
        $dataKeys = get_object_vars($data);
64
        foreach ($dataKeys as $key => $value) {
65
            $propertyPath = $path . '/' .
66
                JsonPointer::escapeSegment($key, (bool)($this->options & JsonDiff::JSON_URI_FRAGMENT_ID));
67
            $propertyHash = $propertyPath . $this->xorHash($value, $propertyPath);
68
            if (strlen($xorHash) < strlen($propertyHash)) {
69
                $xorHash = str_pad($xorHash, strlen($propertyHash));
70
            }
71
            $xorHash ^= $propertyHash;
72
        }
73
74
        return $xorHash;
75
    }
76
}