Passed
Push — master ( f96c2a...76a901 )
by BENOIT
02:17
created

IterablePropertyChangeset::diff()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 2
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace BenTools\DoctrineWatcher\Changeset;
4
5
final class IterablePropertyChangeset extends PropertyChangeset
6
{
7
8
    /**
9
     * IterableChangeset constructor.
10
     * @param object        $entity
11
     * @param string        $property
12
     * @param iterable|null $oldValue
13
     * @param iterable|null $newValue
14
     */
15
    public function __construct($entity, string $property, ?iterable $oldValue = null, ?iterable $newValue = null)
16
    {
17
        parent::__construct($entity, $property);
18
19
        $this->oldValue = $oldValue;
20
        $this->newValue = $newValue;
21
22
        $old = iterable_to_array($oldValue ?? []);
23
        $new = iterable_to_array($newValue ?? []);
24
25
        if (!$this->isSequential($old) && !$this->isSequential($new)) {
26
            $this->additions = $this->diff($new, $old);
27
            $this->removals = $this->diff($old, $new);
28
            return;
29
        }
30
        $this->additions = array_values($this->diff($new, $old));
31
        $this->removals = array_values($this->diff($old, $new));
32
    }
33
34
    /**
35
     * @inheritDoc
36
     */
37
    public function hasChanges(): bool
38
    {
39
        return $this->hasAdditions() || $this->hasRemovals();
40
    }
41
42
    /**
43
     * @return string
44
     */
45
    public function getType(): string
46
    {
47
        return self::CHANGESET_ITERABLE;
48
    }
49
50
    /**
51
     * @param array $array
52
     * @return bool
53
     */
54
    private function isSequential(array $array): bool
55
    {
56
        return isset($array[0]) && array_keys($array) === range(0, count($array) - 1);
57
    }
58
59
    /**
60
     * @param array $a
61
     * @param array $b
62
     * @return array
63
     */
64
    private function diff(array $a, array $b): array
65
    {
66
        return array_filter($a, function ($item) use ($b) {
67
            return !in_array($item, $b, true);
68
        });
69
    }
70
}
71