Passed
Push — master ( 373c52...ed53b1 )
by Thorsten
03:30
created

Entity::toNative()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 4
cts 4
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 0
crap 1
1
<?php
2
/**
3
 * This file is part of the daikon-cqrs/entity project.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
9
declare(strict_types=1);
10
11
namespace Daikon\Entity\Entity;
12
13
use Daikon\Entity\Assert\Assertion;
14
use Daikon\Entity\Entity\Path\ValuePathParser;
15
use Daikon\Entity\Exception\InvalidPath;
16
use Daikon\Entity\Exception\UnknownAttribute;
17
use Daikon\Entity\ValueObject\ValueObjectInterface;
18
19
abstract class Entity implements EntityInterface
20
{
21
    /**
22
     * @var ValueObjectMap
23
     */
24
    private $valueObjectMap;
25
26
    /**
27
     * @param ValuePathParser
28
     */
29
    private $pathParser;
30
31
    /**
32
     * @param mixed[] array
33
     * @return EntityInterface
34
     */
35 10
    public static function fromNative($nativeState): EntityInterface
36
    {
37 10
        return new static($nativeState);
38
    }
39
40 1
    public function toNative(): array
41
    {
42 1
        $entityState = $this->valueObjectMap->toNative();
43 1
        $entityState[self::TYPE_KEY] = static::class;
44 1
        return $entityState;
45
    }
46
47 1
    public function isSameAs(EntityInterface $entity): bool
48
    {
49 1
        Assertion::isInstanceOf($entity, static::class);
50 1
        return $this->getIdentity()->equals($entity->getIdentity());
51
    }
52
53 1
    public function withValue(string $attributeName, $value): EntityInterface
54
    {
55 1
        $copy = clone $this;
56 1
        $copy->valueObjectMap = $this->valueObjectMap->withValue($attributeName, $value);
57 1
        return $copy;
58
    }
59
60 1
    public function withValues(array $values): EntityInterface
61
    {
62 1
        $copy = clone $this;
63 1
        $copy->valueObjectMap = $this->valueObjectMap->withValues($values);
64 1
        return $copy;
65
    }
66
67 3
    public function has(string $attributeName): bool
68
    {
69 3
        if (!$this->getAttributeMap()->has($attributeName)) {
70 1
            throw new UnknownAttribute(sprintf(
71 1
                'Attribute "%s" is not known to the entity %s',
72 1
                $attributeName,
73 1
                static::class
74
            ));
75
        }
76 2
        return $this->valueObjectMap->has($attributeName);
77
    }
78
79 6
    public function get(string $valuePath): ?ValueObjectInterface
80
    {
81 6
        if (mb_strpos($valuePath, '.')) {
82 2
            return $this->evaluatePath($valuePath);
83
        }
84 6
        if (!$this->getAttributeMap()->has($valuePath)) {
85 1
            throw new UnknownAttribute(sprintf(
86 1
                'Attribute "%s" is unknown to entity "%s"',
87 1
                $valuePath,
88 1
                static::class
89
            ));
90
        }
91 5
        return $this->valueObjectMap->has($valuePath) ? $this->valueObjectMap->get($valuePath) : null;
92
    }
93
94
    public function equals(ValueObjectInterface $entity): bool
95
    {
96
        if (!$entity instanceof static) {
97
            return false;
98
        }
99
        return (new EntityDiff)($this, $entity)->isEmpty();
100
    }
101
102
    public function __toString(): string
103
    {
104
        return sprintf('%s:%s', static::class, $this->getIdentity());
105
    }
106
107 10
    private function __construct(array $values = [])
0 ignored issues
show
introduced by
Something seems to be off here. Are you sure you want to declare the constructor as private, and the class as abstract?
Loading history...
108
    {
109 10
        $this->valueObjectMap = ValueObjectMap::forEntity($this, $values);
110 10
        $this->pathParser = ValuePathParser::create();
111 10
    }
112
113 2
    private function evaluatePath($valuePath): ?ValueObjectInterface
114
    {
115 2
        $value = null;
116 2
        $entity = $this;
117 2
        foreach ($this->pathParser->parse($valuePath) as $pathPart) {
118 2
            $value = $entity->get($pathPart->getAttributeName());
119 1
            if ($value && $pathPart->hasPosition()) {
120 1
                if (!$value instanceof EntityListInterface) {
121
                    throw new InvalidPath('Trying to traverse non-entity value');
122
                }
123 1
                $entity = $value->get($pathPart->getPosition());
124 1
                $value = $entity;
125
            }
126
        }
127 1
        return $value;
128
    }
129
}
130