Passed
Push — master ( 5a9be5...a2cf38 )
by Michael
02:34
created

AnnotationDefinitionProvider   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 130
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 89.36%

Importance

Changes 0
Metric Value
wmc 15
lcom 1
cbo 4
dl 0
loc 130
ccs 42
cts 47
cp 0.8936
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A getDefinition() 0 21 3
A createRelationship() 0 19 3
A handleGetter() 0 12 2
A handleIdentifier() 0 14 3
A resoleType() 0 12 3
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 Relationship
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
        if ($annotation->resourceType !== null) {
76 2
            $relationship->setResourceType($annotation->resourceType);
77
        }
78
79 2
        $this->handleGetter($annotation, $relationship);
80 2
        $this->handleIdentifier($annotation, $relationship);
81
82 2
        return $relationship;
83
    }
84
85
    /**
86
     * Handler getter of related object
87
     *
88
     * @param RelationshipAnnotation $annotation
89
     * @param Relationship           $relationship
90
     */
91 2
    protected function handleGetter(RelationshipAnnotation $annotation, Relationship $relationship)
92
    {
93 2
        if ($annotation->getter === null) {
94 1
            $name   = $relationship->getName();
95 1
            $getter = 'get' . ucfirst($name);
96
97 1
            $relationship->setGetter($getter);
98 1
            return;
99
        }
100
101 1
        $relationship->setGetter($annotation->getter);
102 1
    }
103
104
    /**
105
     * Handle identifier
106
     *
107
     * @param RelationshipAnnotation $annotation
108
     * @param Relationship           $relationship
109
     */
110 2
    protected function handleIdentifier(RelationshipAnnotation $annotation, Relationship $relationship)
111
    {
112 2
        if ($annotation->idGetter !== null) {
113
            $relationship->setIdentifierGetter($annotation->idGetter);
114
            return;
115
        }
116
117 2
        if ($annotation->idProperty !== null) {
118 2
            $getter = 'get' . ucfirst($annotation->idProperty);
119
120 2
            $relationship->setIdentifierGetter($getter);
121 2
            return;
122
        }
123
    }
124
125
    /**
126
     * Resolve type of relationship
127
     *
128
     * @param  RelationshipAnnotation $annotation
129
     * @return int
130
     */
131 2
    protected function resoleType(RelationshipAnnotation $annotation): int
132
    {
133 2
        if ($annotation->type === RelationshipAnnotation::TYPE_ONE) {
134
            return Relationship::TYPE_X_TO_ONE;
135
        }
136
137 2
        if ($annotation->type === RelationshipAnnotation::TYPE_MANY) {
138 2
            return Relationship::TYPE_X_TO_MANY;
139
        }
140
141
        throw new \LogicException(sprintf('Invalid type of relation "%s" defined.', $annotation->type));
142
    }
143
}