Passed
Push — master ( a714a7...2bb7f4 )
by Thorsten
02:02
created

Entity::getValueObjectMap()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
3
namespace Daikon\Entity\Entity;
4
5
use Daikon\Entity\Assert\Assertion;
6
use Daikon\Entity\EntityType\EntityTypeInterface;
7
use Daikon\Entity\Entity\Path\ValuePathParser;
8
use Daikon\Entity\Exception\UnexpectedType;
9
use Daikon\Entity\Exception\UnknownAttribute;
10
use Daikon\Entity\ValueObject\Nil;
11
use Daikon\Entity\ValueObject\ValueObjectInterface;
12
13
abstract class Entity implements EntityInterface
14
{
15
    /**
16
     * @var EntityTypeInterface
17
     */
18
    private $type;
19
20
    /**
21
     * @var EntityInterface
22
     */
23
    private $parent;
24
25
    /**
26
     * @var ValueObjectMap
27
     */
28
    private $valueObjectMap;
29
30
    /**
31
     * @param ValuePathParser
32
     */
33
    private $pathParser;
34
35
    /**
36
     * @param mixed[] array
37
     * @return EntityInterface
38
     */
39 31
    public static function fromNative($nativeState): EntityInterface
40
    {
41 31
        $entityType = $nativeState[self::TYPE_KEY];
42 31
        Assertion::isInstanceOf($entityType, EntityTypeInterface::class);
43 31
        $parent = null;
44 31
        if (isset($nativeState[self::PARENT_KEY])) {
45 25
            $parent = $nativeState[self::PARENT_KEY];
46 25
            Assertion::isInstanceOf($parent, EntityInterface::class);
47 25
            unset($nativeState[self::PARENT_KEY]);
48
        }
49 31
        return new static($entityType, $nativeState, $parent);
50
    }
51
52 7
    public function toNative(): array
53
    {
54 7
        $entityState = $this->valueObjectMap->toNative();
55 7
        $entityState[self::TYPE_KEY] = $this->getEntityType()->getName();
56 7
        return $entityState;
57
    }
58
59 1
    public function isSameAs(EntityInterface $entity): bool
60
    {
61 1
        Assertion::isInstanceOf($entity, static::class);
62 1
        return $this->getIdentity()->equals($entity->getIdentity());
63
    }
64
65 13
    public function withValue(string $attributeName, $value): EntityInterface
66
    {
67 13
        $copy = clone $this;
68 13
        $copy->valueObjectMap = $this->valueObjectMap->withValue($attributeName, $value);
69 13
        return $copy;
70
    }
71
72 1
    public function withValues(array $values): EntityInterface
73
    {
74 1
        $copy = clone $this;
75 1
        $copy->valueObjectMap = $this->valueObjectMap->withValues($values);
76 1
        return $copy;
77
    }
78
79 6
    public function has(string $attributeName): bool
80
    {
81 6
        if (!$this->type->hasAttribute($attributeName)) {
82 1
            throw new UnknownAttribute(sprintf('Attribute "%s" is not known to the entity value-map.', $attributeName));
83
        }
84 5
        return $this->valueObjectMap->has($attributeName);
85
    }
86
87 14
    public function get(string $valuePath): ?ValueObjectInterface
88
    {
89 14
        if (mb_strpos($valuePath, '.')) {
90 3
            return $this->evaluatePath($valuePath);
91
        }
92 14
        if (!$this->type->hasAttribute($valuePath)) {
93 1
            throw new UnknownAttribute(sprintf(
94 1
                'Attribute "%s" is unknown to type "%s"',
95 1
                $valuePath,
96 1
                $this->getEntityType()->getName()
97
            ));
98
        }
99 13
        return $this->valueObjectMap->has($valuePath) ? $this->valueObjectMap->get($valuePath) : null;
100
    }
101
102 1
    public function getEntityRoot(): EntityInterface
103
    {
104 1
        $tmpParent = $this->getEntityParent();
105 1
        $root = $tmpParent;
106 1
        while ($tmpParent) {
107 1
            $root = $tmpParent;
108 1
            $tmpParent = $tmpParent->getEntityParent();
109
        }
110 1
        return $root ?? $this;
111
    }
112
113 2
    public function getEntityParent(): ?EntityInterface
114
    {
115 2
        return $this->parent;
116
    }
117
118 31
    public function getEntityType(): EntityTypeInterface
119
    {
120 31
        return $this->type;
121
    }
122
123 31
    protected function __construct(EntityTypeInterface $type, array $values = [], EntityInterface $parent = null)
124
    {
125 31
        $this->type = $type;
126 31
        $this->parent = $parent;
127 31
        $this->valueObjectMap = ValueObjectMap::forEntity($this, $values);
128 31
        $this->pathParser = ValuePathParser::create();
129 31
    }
130
131 3
    private function evaluatePath($valuePath): ?ValueObjectInterface
132
    {
133 3
        $value = null;
134 3
        $entity = $this;
135 3
        foreach ($this->pathParser->parse($valuePath) as $pathPart) {
136
            /* @var EntityInterface $value */
137 3
            $value = $entity->get($pathPart->getAttributeName());
138 2
            if ($pathPart->hasPosition()) {
139 2
                $entity = $value->get($pathPart->getPosition());
140 2
                $value = $entity;
141
            }
142
        }
143 2
        return $value;
144
    }
145
}
146