Passed
Push — master ( 99d80c...db9e79 )
by Edward
02:29
created

ContainsValueComparator::objectContains()   A

Complexity

Conditions 6
Paths 6

Size

Total Lines 20
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

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