GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( 86b5f6...b6d48e )
by Romain
01:45
created

LinksRelation::getAssociationRouteName()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 5
nc 2
nop 1
1
<?php
2
3
namespace Halapi\Relation;
4
5
use Doctrine\Common\Collections\Collection;
6
use Doctrine\Common\Persistence\Mapping\ClassMetadata;
7
use Doctrine\Common\Persistence\ObjectManager;
8
use Doctrine\Common\Annotations\Reader;
9
use Halapi\Annotation\Embeddable;
10
use Halapi\UrlGenerator\UrlGeneratorInterface;
11
12
/**
13
 * Class LinksRelation.
14
 *
15
 * @author Romain Richard
16
 */
17
class LinksRelation extends AbstractRelation implements RelationInterface
18
{
19
    /**
20
     * @var UrlGeneratorInterface
21
     */
22
    private $urlGenerator;
23
24
    /**
25
     * @var ObjectManager
26
     */
27
    private $objectManager;
28
29
    /**
30
     * @var ClassMetadata
31
     */
32
    private $classMetadata;
33
34
    /**
35
     * @var \ReflectionClass
36
     */
37
    private $reflectionClass;
38
39
    /**
40
     * AbstractRelation constructor.
41
     *
42
     * @param Reader                $annotationReader
43
     * @param UrlGeneratorInterface $urlGenerator
44
     * @param ObjectManager         $objectManager
45
     */
46
    public function __construct(
47
        Reader $annotationReader,
48
        UrlGeneratorInterface $urlGenerator,
49
        ObjectManager $objectManager
50
    ) {
51
        $this->urlGenerator = $urlGenerator;
52
        $this->annotationReader = $annotationReader;
53
        $this->objectManager = $objectManager;
54
    }
55
56
    /**
57
     * {@inheritdoc}
58
     */
59
    public function getName()
60
    {
61
        return '_links';
62
    }
63
64
    /**
65
     * {@inheritdoc}
66
     */
67
    public function getRelation($resource)
68
    {
69
        $this->classMetadata = $this->objectManager->getClassMetadata(get_class($resource));
70
        $this->reflectionClass = new \ReflectionClass($resource);
71
        $links = $this->getSelfLink($resource);
72
73
        foreach ($this->reflectionClass->getProperties() as $property) {
74
            if ($this->isEmbeddable($property) && $property->getName()) {
75
                $propertyName = $property->getName();
76
                $relationContent = $resource->{'get'.ucfirst($propertyName)}();
77
                if ($relationContent) {
78
                    $links[$propertyName] = $this->getRelationLinks($property, $relationContent);
79
                }
80
            }
81
        }
82
83
        return $links;
84
    }
85
86
    /**
87
     * @param \ReflectionProperty $property
88
     * @param object              $relationContent
89
     *
90
     * @return string|null
91
     *
92
     * @throws \Doctrine\ORM\Mapping\MappingException
93
     */
94
    private function getRelationLink(\ReflectionProperty $property, $relationContent)
95
    {
96
        if ($this->classMetadata->hasAssociation($property->getName())) {
97
            $identifier = $this->getIdentifier($relationContent);
98
99
            return $this->urlGenerator->generate(
100
                $this->getAssociationRouteName($property),
101
                [$identifier => $this->getId($relationContent, $identifier)]
102
            );
103
        }
104
    }
105
106
    /**
107
     * Get the url of an entity based on the 'get_entity' route pattern.
108
     *
109
     * @param $resource
110
     *
111
     * @return array|null
112
     */
113
    private function getSelfLink($resource)
114
    {
115
        if ($resource instanceof \Traversable) {
116
            return;
117
        }
118
119
        $identifier = $this->getIdentifier($resource);
120
121
        return [
122
            'self' => $this->urlGenerator->generate(
123
                $this->getResourceRouteName($this->reflectionClass),
124
                [$identifier => $this->getId($resource, $identifier)]
125
            ),
126
        ];
127
    }
128
129
    /**
130
     * Get the links of a collection.
131
     *
132
     * @param \ReflectionProperty $property
133
     * @param $relationContent
134
     *
135
     * @return array|void
136
     */
137
    private function getRelationLinks(\ReflectionProperty $property, $relationContent)
138
    {
139
        if ($relationContent instanceof Collection) {
140
            $links = [];
141
            foreach ($relationContent as $relation) {
142
                $links[] = $this->getRelationLink($property, $relation);
143
            }
144
145
            return $links;
146
        }
147
148
        return $this->getRelationLink($property, $relationContent);
149
    }
150
151
    /**
152
     * Return the configured route name for an embeddable relation.
153
     *
154
     * @param \ReflectionProperty $property
155
     *
156
     * @return string
157
     */
158
    private function getAssociationRouteName(\ReflectionProperty $property)
159
    {
160
        if ($routeName = $this->annotationReader->getPropertyAnnotation($property, Embeddable::class)->getRouteName()) {
161
            return $routeName;
162
        }
163
164
        return $this->getResourceRouteName(new \ReflectionClass(
165
            $this->classMetadata->getAssociationTargetClass($property->getName())
166
        ));
167
    }
168
169
    /**
170
     * Return the configured route name for a resource, or get_*entityShortName* by default.
171
     *
172
     * @param \ReflectionClass $resource
173
     *
174
     * @return string
175
     */
176
    private function getResourceRouteName(\ReflectionClass $resource)
177
    {
178
        if ($routeName = $this->annotationReader->getClassAnnotation($resource, Embeddable::class)->getRouteName()) {
179
            return $routeName;
180
        }
181
182
        return 'get_'.strtolower($resource->getShortName());
183
    }
184
185
    /**
186
     * @param $resource
187
     *
188
     * @return mixed
189
     */
190
    private function getIdentifier($resource)
191
    {
192
        $classMetadata = $this->objectManager->getClassMetadata(get_class($resource));
193
194
        return $classMetadata->getIdentifier()[0];
195
    }
196
197
    private function getId($resource, $identifier)
198
    {
199
        $id = new \ReflectionProperty($resource, $identifier);
200
        if ($id->isPublic()) {
201
            return $id;
202
        }
203
204
        $getter = 'get'.ucfirst($identifier);
205
        $getterReflection = new \ReflectionMethod($resource, $getter);
206
        if (method_exists($resource, $getter) && $getterReflection->isPublic()) {
207
            return $resource->$getter();
208
        }
209
210
        return;
211
    }
212
}
213