EntityStates::list()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
1
<?php
2
declare(strict_types=1);
3
4
namespace Stratadox\EntityState;
5
6
use Stratadox\ImmutableCollection\ImmutableCollection;
7
8
/**
9
 * Collection of entity representations.
10
 *
11
 * @author Stratadox
12
 */
13
final class EntityStates extends ImmutableCollection implements ListsEntityStates
14
{
15
    private function __construct(RepresentsEntity ...$entities)
16
    {
17
        parent::__construct(...$entities);
18
    }
19
20
    /**
21
     * Packs a number of entities in a collection.
22
     *
23
     * @param RepresentsEntity ...$entities The entities to collect.
24
     * @return ListsEntityStates            The collection of entities.
25
     */
26
    public static function list(RepresentsEntity ...$entities): ListsEntityStates
27
    {
28
        return new EntityStates(...$entities);
29
    }
30
31
    /** @inheritdoc */
32
    public function current(): RepresentsEntity
33
    {
34
        return parent::current();
35
    }
36
37
    /** @inheritdoc */
38
    public function offsetGet($position): RepresentsEntity
39
    {
40
        return parent::offsetGet($position);
41
    }
42
43
    /** @inheritdoc */
44
    public function add(RepresentsEntity $entityState): ListsEntityStates
45
    {
46
        if ($this->hasThe($entityState)) {
47
            return $this->mergeThe($entityState);
48
        }
49
50
        $entityStates = $this->items();
51
        $entityStates[] = $entityState;
52
        return EntityStates::list(...$entityStates);
53
    }
54
55
    /** @inheritdoc */
56
    public function hasThe(RepresentsEntity $entity): bool
57
    {
58
        foreach ($this as $candidate) {
59
            if ($candidate->hasTheSameIdentityAs($entity)) {
60
                return true;
61
            }
62
        }
63
        return false;
64
    }
65
66
    /** @inheritdoc */
67
    public function hasADifferent(RepresentsEntity $entity): bool
68
    {
69
        foreach ($this as $candidate) {
70
            if ($candidate->hasTheSameIdentityAs($entity)) {
71
                return $candidate->isDifferentFrom($entity);
72
            }
73
        }
74
        return false;
75
    }
76
77
    /** @inheritdoc */
78
    public function entitiesThatAreNotIn(ListsEntityStates $otherEntities): ListsEntityStates
79
    {
80
        $entities = [];
81
        foreach ($this as $entity) {
82
            if (!$otherEntities->hasThe($entity)) {
83
                $entities[] = $entity;
84
            }
85
        }
86
        return EntityStates::list(...$entities);
87
    }
88
89
    /** @inheritdoc */
90
    public function entityStateThatDiffersFrom(
91
        ListsEntityStates $otherState
92
    ): ListsEntityStates {
93
        $entities = [];
94
        foreach ($this as $state) {
95
            if ($otherState->hasADifferent($state)) {
96
                $entities[] = $state->subsetThatDiffersFrom($otherState);
97
            }
98
        }
99
        return EntityStates::list(...$entities);
100
    }
101
102
    /** @inheritdoc */
103
    public function changesSince(ListsEntityStates $previousState): TellsWhatChanged
104
    {
105
        return Changes::wereMade(
106
            $this->entitiesThatAreNotIn($previousState),
107
            $this->entityStateThatDiffersFrom($previousState),
108
            $previousState->entitiesThatAreNotIn($this)
109
        );
110
    }
111
112
    private function mergeThe(RepresentsEntity $newState): ListsEntityStates
113
    {
114
        $entities = $this->items();
115
        foreach ($this as $i => $entityState) {
116
            if ($entityState->hasTheSameIdentityAs($newState)) {
117
                $entities[$i] = $entityState->mergeWith($newState);
118
            }
119
        }
120
        return EntityStates::list(...$entities);
121
    }
122
}
123