Passed
Push — master ( 8afc73...99d80c )
by Edward
04:17
created

ContainsValueComparator::compare()   B

Complexity

Conditions 7
Paths 4

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 7
eloc 7
c 1
b 0
f 1
nc 4
nop 2
dl 0
loc 13
rs 8.8333
1
<?php
2
declare(strict_types=1);
3
4
namespace Remorhaz\JSON\Data\Comparator;
5
6
use Collator;
7
use Remorhaz\JSON\Data\Value\ArrayValueInterface;
8
use Remorhaz\JSON\Data\Value\ObjectValueInterface;
9
use Remorhaz\JSON\Data\Value\ScalarValueInterface;
10
use Remorhaz\JSON\Data\Value\ValueInterface;
11
12
final class ContainsValueComparator implements ComparatorInterface
13
{
14
15
    private $collator;
16
17
    private $equalComparator;
18
19
    public function __construct(Collator $collator)
20
    {
21
        $this->collator = $collator;
22
        $this->equalComparator = new EqualValueComparator($this->collator);
23
    }
24
25
    public function compare(ValueInterface $leftValue, ValueInterface $rightValue): bool
26
    {
27
        if ($leftValue instanceof ScalarValueInterface && $rightValue instanceof ScalarValueInterface) {
28
            return $this->equalComparator->compare($leftValue, $rightValue);
29
        }
30
        if ($leftValue instanceof ArrayValueInterface && $rightValue instanceof ArrayValueInterface) {
31
            return $this->equalComparator->compare($leftValue, $rightValue);
32
        }
33
        if ($leftValue instanceof ObjectValueInterface && $rightValue instanceof ObjectValueInterface) {
34
            return $this->objectContains($leftValue, $rightValue);
35
        }
36
37
        return false;
38
    }
39
40
    private function objectContains(ObjectValueInterface $leftValue, ObjectValueInterface $rightValue): bool
41
    {
42
        $leftValueIterator = $leftValue->createChildIterator();
43
        $rightValueIterator = $rightValue->createChildIterator();
44
        $valuesByProperty = [];
45
        while ($leftValueIterator->valid()) {
46
            $property = $leftValueIterator->key();
47
            if (isset($valuesByProperty[$property])) {
48
                return false;
49
            }
50
            $valuesByProperty[$property] = $leftValueIterator->current();
51
            $leftValueIterator->next();
52
        }
53
        while ($rightValueIterator->valid()) {
54
            $property = $rightValueIterator->key();
55
            if (!isset($valuesByProperty[$property])) {
56
                return false;
57
            }
58
            if (!$this->compare($valuesByProperty[$property], $rightValueIterator->current())) {
59
                return false;
60
            }
61
            $rightValueIterator->next();
62
        }
63
64
        return true;
65
    }
66
}
67