Completed
Push — master ( ed059a...0f6c49 )
by Karsten
02:43
created

Polymorphic   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 87
Duplicated Lines 0 %

Test Coverage

Coverage 76.92%

Importance

Changes 0
Metric Value
wmc 12
dl 0
loc 87
c 0
b 0
f 0
rs 10
ccs 20
cts 26
cp 0.7692

4 Methods

Rating   Name   Duplication   Size   Complexity  
B validate() 0 21 6
A getMapping() 0 3 1
A getCreator() 0 12 3
A getTellBy() 0 3 2
1
<?php
2
/**
3
 * File was created 14.05.2016 22:32
4
 */
5
6
namespace PeekAndPoke\Component\Slumber\Annotation\Slumber;
7
8
use Doctrine\Common\Annotations\Annotation;
9
use PeekAndPoke\Component\Creator\CreatePolymorphic;
10
use PeekAndPoke\Component\Creator\CreatorFactory;
11
use PeekAndPoke\Component\Creator\NullCreator;
12
use PeekAndPoke\Component\Slumber\Annotation\ClassCreatorMarker;
13
use PeekAndPoke\Component\Slumber\Annotation\SlumberAnnotation;
14
use PeekAndPoke\Component\Slumber\Core\Exception\SlumberException;
15
use PeekAndPoke\Component\Slumber\Core\Validation\ValidationContext;
16
17
18
/**
19
 * @Annotation
20
 * @Annotation\Target("CLASS")
21
 *
22
 * @author Karsten J. Gerber <[email protected]>
23
 */
24
class Polymorphic extends SlumberAnnotation implements ClassCreatorMarker
25
{
26
    public const DEFAULT_TELL_BY = 'type';
27
28
    /**
29
     * The data field to look at in order to tell which kind of object to instantiate
30
     *
31
     * @var string
32
     *
33
     * @Annotation\Attribute(required=false)
34
     */
35
    public $tellBy = self::DEFAULT_TELL_BY;
36
37
    /**
38
     * The default type to use, when no nothing was found in the mapping.
39
     *
40
     * Can be left empty, then "null" will be result for a type that could not be mapped.
41
     *
42
     * @var string
43
     *
44
     * @Annotation\Attribute(required=false)
45
     */
46
    public $default;
47
48
    /**
49
     * Initialize the annotation and validate the given parameters
50
     *
51
     * @param ValidationContext $context
52
     *
53
     * @throws SlumberException
54
     */
55 4
    public function validate(ValidationContext $context)
56
    {
57 4
        $mapping = $this->getMapping();
58
59 4
        if (! \is_array($mapping)) {
0 ignored issues
show
introduced by
The condition ! is_array($mapping) can never be true.
Loading history...
60
            throw $this->createValidationException($context, 'The type-mapping is missing');
61
        }
62
63 4
        foreach ($mapping as $k => $v) {
64 4
            if (! class_exists($v)) {
65
                throw $this->createValidationException(
66
                    $context,
67 4
                    'The class "' . $v . '" for "' . $k . '"does not exist'
68
                );
69
            }
70
        }
71
72 4
        if (! empty($this->default) && ! class_exists($this->default)) {
73
            throw $this->createValidationException(
74
                $context,
75
                'The class "' . $this->default . ' for the default does not exist'
76
            );
77
        }
78 4
    }
79
80
    /**
81
     * @return string
82
     */
83 4
    public function getTellBy()
84
    {
85 4
        return $this->tellBy ?: self::DEFAULT_TELL_BY;
86
    }
87
88
    /**
89
     * @return array
90
     */
91 4
    public function getMapping()
92
    {
93 4
        return (array) $this->value;
94
    }
95
96
    /**
97
     * @inheritdoc
98
     */
99 4
    public function getCreator(CreatorFactory $factory)
100
    {
101 4
        $mapping = [];
102
103 4
        foreach ($this->getMapping() as $k => $v) {
104 4
            $mapping[$k] = $factory->create(new \ReflectionClass($v));
105
        }
106
107 4
        return new CreatePolymorphic(
108 4
            $mapping,
109 4
            $this->getTellBy(),
110 4
            ! empty($this->default) ? $factory->create(new \ReflectionClass($this->default)) : new NullCreator()
111
        );
112
    }
113
}
114