Passed
Push — master ( 00c044...5a9be5 )
by Michael
02:49
created

AnnotationDefinitionProvider::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
c 0
b 0
f 0
ccs 3
cts 3
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 1
crap 1
1
<?php
2
declare(strict_types = 1);
3
4
namespace Mikemirten\Component\JsonApi\Mapper\Definition;
5
6
use Doctrine\Common\Annotations\Reader;
7
use Mikemirten\Component\JsonApi\Mapper\Definition\Annotation\Relationship as RelationshipAnnotation;
8
9
/**
10
 * Annotation Definition Provider based on the Doctrine-Annotation library
11
 *
12
 * @package Mikemirten\Component\JsonApi\Mapper\Definition
13
 */
14
class AnnotationDefinitionProvider implements DefinitionProviderInterface
15
{
16
    /**
17
     * Doctrine annotation reader
18
     *
19
     * @var Reader
20
     */
21
    protected $reader;
22
23
    /**
24
     * AnnotationDefinitionProvider constructor.
25
     *
26
     * @param Reader $reader
27
     */
28 2
    public function __construct(Reader $reader)
29
    {
30 2
        $this->reader = $reader;
31 2
    }
32
33
    /**
34
     * {@inheritdoc}
35
     */
36 2
    public function getDefinition(string $class): Definition
37
    {
38 2
        $definition = new Definition();
39 2
        $reflection = new \ReflectionClass($class);
40
41 2
        foreach ($reflection->getProperties() as $property)
42
        {
43 2
            $relationshipAnnotation = $this->reader->getPropertyAnnotation(
44
                $property,
45 2
                RelationshipAnnotation::class
46
            );
47
48 2
            if ($relationshipAnnotation !== null) {
49 2
                $relationship = $this->createRelationship($relationshipAnnotation, $property);
50
51 2
                $definition->addRelationship($relationship);
52
            }
53
        }
54
55 2
        return $definition;
56
    }
57
58
    /**
59
     * Process relationship
60
     *
61
     * @param  RelationshipAnnotation $annotation
62
     * @param  \ReflectionProperty    $property
63
     * @return Definition
64
     */
65 2
    protected function createRelationship(RelationshipAnnotation $annotation, \ReflectionProperty $property): Relationship
66
    {
67 2
        $name = ($annotation->name === null)
68 1
            ? $property->getName()
69 2
            : $annotation->name;
70
71 2
        $type = $this->resoleType($annotation);
72
73 2
        $relationship = new Relationship($name, $type);
74
75 2
        $getter = ($annotation->getter === null)
76 1
            ? ('get' . ucfirst($name))
77 2
            : $annotation->getter;
78
79 2
        $relationship->setGetter($getter);
80
81 2
        if ($annotation->resourceType !== null) {
82 2
            $relationship->setResourceType($annotation->resourceType);
83
        }
84
85 2
        $this->handleIdentifier($annotation, $relationship);
86
87 2
        return $relationship;
88
    }
89
90
    /**
91
     * Handle identifier
92
     *
93
     * @param RelationshipAnnotation $annotation
94
     * @param Relationship           $relationship
95
     */
96 2
    protected function handleIdentifier(RelationshipAnnotation $annotation, Relationship $relationship)
97
    {
98 2
        if ($annotation->idGetter !== null) {
99
            $relationship->setIdentifierGetter($annotation->idGetter);
100
            return;
101
        }
102
103 2
        if ($annotation->idProperty !== null) {
104 2
            $getter = 'get' . ucfirst($annotation->idProperty);
105
106 2
            $relationship->setIdentifierGetter($getter);
107 2
            return;
108
        }
109
    }
110
111
    /**
112
     * Resolve type of relationship
113
     *
114
     * @param  RelationshipAnnotation $annotation
115
     * @return int
116
     */
117 2
    protected function resoleType(RelationshipAnnotation $annotation): int
118
    {
119 2
        if ($annotation->type === RelationshipAnnotation::TYPE_ONE) {
120
            return Relationship::TYPE_X_TO_ONE;
121
        }
122
123 2
        if ($annotation->type === RelationshipAnnotation::TYPE_MANY) {
124 2
            return Relationship::TYPE_X_TO_MANY;
125
        }
126
127
        throw new \LogicException(sprintf('Invalid type of relation "%s" defined.', $annotation->type));
128
    }
129
}