ContainsValueComparator::objectContains()   A
last analyzed

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