EntityState::mergeWith()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
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 4
rs 10
1
<?php
2
declare(strict_types=1);
3
4
namespace Stratadox\EntityState;
5
6
use Stratadox\EntityState\RepresentsEntity as TheOther;
7
8
/**
9
 * Represents the state of an entity.
10
 *
11
 * @author Stratadox
12
 */
13
final class EntityState implements RepresentsEntity
14
{
15
    private $class;
16
    private $id;
17
    private $properties;
18
19
    private function __construct(
20
        string $class,
21
        ?string $id,
22
        ListsPropertyStates $properties
23
    ) {
24
        $this->class = $class;
25
        $this->id = $id;
26
        $this->properties = $properties;
27
    }
28
29
    /**
30
     * Produces an entity representation.
31
     *
32
     * @param string              $class      The fully qualified class name.
33
     * @param null|string         $id         The id of the entity.
34
     * @param ListsPropertyStates $properties The property state representations.
35
     * @return RepresentsEntity               The entity state representation.
36
     */
37
    public static function ofThe(
38
        string $class,
39
        ?string $id,
40
        ListsPropertyStates $properties
41
    ): RepresentsEntity {
42
        return new self($class, $id, $properties);
43
    }
44
45
    /** @inheritdoc */
46
    public function class(): string
47
    {
48
        return $this->class;
49
    }
50
51
    /** @inheritdoc */
52
    public function hasTheSameIdentityAs(RepresentsEntity $entity): bool
53
    {
54
        return $this->class === $entity->class()
55
            && $this->id === $entity->id();
56
    }
57
58
    /** @inheritdoc */
59
    public function id(): ?string
60
    {
61
        return $this->id;
62
    }
63
64
    /** @inheritdoc */
65
    public function properties(): ListsPropertyStates
66
    {
67
        return $this->properties;
68
    }
69
70
    /** @inheritdoc */
71
    public function isDifferentFrom(TheOther $entity): bool
72
    {
73
        return !$this->hasTheSameIdentityAs($entity)
74
            || $this->properties->areDifferentFrom($entity->properties());
75
    }
76
77
    /** @inheritdoc */
78
    public function subsetThatDiffersFrom(
79
        ListsEntityStates $entityStates
80
    ): RepresentsEntity {
81
        foreach ($entityStates as $entity) {
82
            if ($this->hasTheSameIdentityAs($entity)) {
83
                return $this->subsetThatDiffersFromThe($entity);
84
            }
85
        }
86
        return $this;
87
    }
88
89
    /** @inheritdoc */
90
    public function mergeWith(TheOther $entityState): RepresentsEntity
91
    {
92
        return $this->with(
93
            $this->properties->merge($entityState->properties())
94
        );
95
    }
96
97
    private function subsetThatDiffersFromThe(
98
        RepresentsEntity $otherEntity
99
    ): RepresentsEntity {
100
        $properties = [];
101
        foreach ($this->properties as $myProperty) {
102
            if ($myProperty->isDifferentInThe($otherEntity->properties())) {
103
                $properties[] = $myProperty;
104
            }
105
        }
106
        return $this->with(PropertyStates::list(...$properties));
107
    }
108
109
    private function with(ListsPropertyStates $properties): RepresentsEntity
110
    {
111
        return EntityState::ofThe($this->class, $this->id, $properties);
112
    }
113
}
114