Passed
Push — master ( 819f30...8ceff2 )
by Thorsten
02:22
created

NestedEntityAttribute   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 84
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 8

Test Coverage

Coverage 97.14%

Importance

Changes 0
Metric Value
wmc 14
lcom 2
cbo 8
dl 0
loc 84
ccs 34
cts 35
cp 0.9714
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A define() 0 8 1
A getValueType() 0 4 1
B makeValue() 0 13 5
A getName() 0 4 1
A getEntityType() 0 4 1
A getParent() 0 4 1
A __construct() 0 11 2
A makeEntity() 0 11 2
1
<?php
2
3
namespace Daikon\Entity\EntityType;
4
5
use Daikon\Entity\Assert\Assertion;
6
use Daikon\Entity\Entity\EntityInterface;
7
use Daikon\Entity\Entity\NestedEntity;
8
use Daikon\Entity\Entity\TypedEntityInterface;
9
use Daikon\Entity\Error\CorruptValues;
10
use Daikon\Entity\Error\MissingImplementation;
11
use Daikon\Entity\Error\UnexpectedValue;
12
use Daikon\Entity\ValueObject\Nil;
13
use Daikon\Entity\ValueObject\ValueObjectInterface;
14
15
class NestedEntityAttribute implements AttributeInterface
16
{
17
    /**
18
     * @var string
19
     */
20
    private $name;
21
22
    /**
23
     * @var EntityTypeInterface
24
     */
25
    private $entityType;
26
27
    /**
28
     * @var EntityTypeMap
29
     */
30
    private $allowedTypes;
31
32 54
    public static function define(
33
        string $name,
34
        $entityTypeClasses,
35
        EntityTypeInterface $entityType
36
    ): AttributeInterface {
37 54
        Assertion::isArray($entityTypeClasses);
38 54
        return new static($name, $entityType, $entityTypeClasses);
39
    }
40
41 19
    public function getValueType(): EntityTypeMap
42
    {
43 19
        return $this->allowedTypes;
44
    }
45
46 23
    public function makeValue($value = null, EntityInterface $parent = null): ValueObjectInterface
47
    {
48 23
        if ($value instanceof NestedEntity) {
49 2
            foreach ($this->getValueType() as $type) {
50 2
                if ($type === $value->getEntityType()) {
51 2
                    return $value;
52
                }
53
            }
54
            throw new UnexpectedValue("Given entity-type is not allowed for attribute ".$this->getName());
55
        }
56 21
        Assertion::nullOrisArray($value);
57 20
        return is_array($value) ? $this->makeEntity($value, $parent) : Nil::fromNative($value);
0 ignored issues
show
Bug introduced by
It seems like $parent defined by parameter $parent on line 46 can also be of type object<Daikon\Entity\Entity\EntityInterface>; however, Daikon\Entity\EntityType...Attribute::makeEntity() does only seem to accept null|object<Daikon\Entit...y\TypedEntityInterface>, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
58
    }
59
60 41
    public function getName(): string
61
    {
62 41
        return $this->name;
63
    }
64
65 3
    public function getEntityType(): EntityTypeInterface
66
    {
67 3
        return $this->entityType;
68
    }
69
70 1
    public function getParent(): ?AttributeInterface
71
    {
72 1
        return $this->getEntityType()->getParentAttribute();
73
    }
74
75 54
    protected function __construct(string $name, EntityTypeInterface $entityType, array $allowedTypeClasses)
76
    {
77 54
        $this->name = $name;
78 54
        $this->entityType = $entityType;
79 54
        $this->allowedTypes = new EntityTypeMap(array_map(function (string $typeFqcn) {
80 54
            if (!class_exists($typeFqcn)) {
81 2
                throw new MissingImplementation("Unable to load given entity-type class: '$typeFqcn'");
82
            }
83 54
            return new $typeFqcn($this);
84 54
        }, $allowedTypeClasses));
85 54
    }
86
87 19
    private function makeEntity(array $entityValues, TypedEntityInterface $parentEntity = null): NestedEntity
88
    {
89 19
        Assertion::keyExists($entityValues, TypedEntityInterface::ENTITY_TYPE);
90 17
        $typePrefix = $entityValues[TypedEntityInterface::ENTITY_TYPE];
91 17
        if (!$this->allowedTypes->has($typePrefix)) {
92 2
            throw new CorruptValues("Unknown type prefix given within nested-entity values.");
93
        }
94
        /* @var NestedEntity $entity */
95 15
        $entity = $this->allowedTypes->get($typePrefix)->makeEntity($entityValues, $parentEntity);
96 15
        return $entity;
97
    }
98
}
99