Test Failed
Pull Request — master (#34)
by Anatoly
02:16
created

AbstractReference::getClassAnnotation()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 8
c 0
b 0
f 0
dl 0
loc 15
rs 10
cc 2
nc 2
nop 1
1
<?php declare(strict_types=1);
2
3
/**
4
 * It's free open-source software released under the MIT License.
5
 *
6
 * @author Anatoly Fenric <[email protected]>
7
 * @copyright Copyright (c) 2018, Anatoly Fenric
8
 * @license https://github.com/sunrise-php/http-router/blob/master/LICENSE
9
 * @link https://github.com/sunrise-php/http-router
10
 */
11
12
namespace Sunrise\Http\Router\Annotation\OpenApi;
13
14
/**
15
 * Import classes
16
 */
17
use Doctrine\Common\Annotations\SimpleAnnotationReader;
18
use ReflectionClass;
19
use ReflectionMethod;
20
use ReflectionProperty;
21
use Sunrise\Http\Router\Exception\InvalidAnnotationParameterException;
22
use Sunrise\Http\Router\OpenApi\ComponentObjectInterface;
23
24
/**
25
 * Import functions
26
 */
27
use function hash;
28
use function sprintf;
29
30
/**
31
 * AbstractReference
32
 *
33
 * @link https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#reference-object
34
 */
35
abstract class AbstractReference
36
{
37
38
    /**
39
     * @var array
40
     */
41
    private static $cache = [];
42
43
    /**
44
     * @Required
45
     *
46
     * @var string
47
     */
48
    public $class;
49
50
    /**
51
     * @var string
52
     */
53
    public $method;
54
55
    /**
56
     * @var string
57
     */
58
    public $property;
59
60
    /**
61
     * @var ComponentObjectInterface
62
     */
63
    private $target;
64
65
    /**
66
     * {@inheritDoc}
67
     */
68
    public function toArray() : array
69
    {
70
        if (isset($this->target)) {
71
            return ['$ref' => sprintf(
72
                '#/components/%s/%s',
73
                $this->target->getComponentName(),
74
                $this->target->getReferenceName()
75
            )];
76
        }
77
78
        return ['$ref' => 'undefined'];
79
    }
80
81
    /**
82
     * @param SimpleAnnotationReader $annotationReader
83
     *
84
     * @return ComponentObjectInterface
85
     *
86
     * @throws InvalidAnnotationParameterException
87
     */
88
    public function getAnnotation(SimpleAnnotationReader $annotationReader) : ComponentObjectInterface
89
    {
90
        $key = hash(
91
            'md5',
92
            $this->class .
93
            $this->method .
94
            $this->property .
95
            $this->getAnnotationName()
96
        );
97
98
        $this->target =& self::$cache[$key];
99
100
        if (isset(self::$cache[$key])) {
101
            return self::$cache[$key];
102
        }
103
104
        if (isset($this->method)) {
105
            return $this->target = $this->getMethodAnnotation($annotationReader);
106
        }
107
108
        if (isset($this->property)) {
109
            return $this->target = $this->getPropertyAnnotation($annotationReader);
110
        }
111
112
        return $this->target = $this->getClassAnnotation($annotationReader);
113
    }
114
115
    /**
116
     * @param SimpleAnnotationReader $annotationReader
117
     *
118
     * @return ComponentObjectInterface
119
     *
120
     * @throws InvalidAnnotationParameterException
121
     */
122
    private function getMethodAnnotation(SimpleAnnotationReader $annotationReader) : ComponentObjectInterface
123
    {
124
        $target = $annotationReader->getMethodAnnotation(
125
            new ReflectionMethod($this->class, $this->method),
126
            $this->getAnnotationName()
127
        );
128
129
        if (null === $target) {
130
            $message = 'Method %s::%s() does not contain the annotation %s';
131
            throw new InvalidAnnotationParameterException(
132
                sprintf($message, $this->class, $this->method, $this->getAnnotationName())
133
            );
134
        }
135
136
        return $target;
137
    }
138
139
    /**
140
     * @param SimpleAnnotationReader $annotationReader
141
     *
142
     * @return ComponentObjectInterface
143
     *
144
     * @throws InvalidAnnotationParameterException
145
     */
146
    private function getPropertyAnnotation(SimpleAnnotationReader $annotationReader) : ComponentObjectInterface
147
    {
148
        $target = $annotationReader->getPropertyAnnotation(
149
            new ReflectionProperty($this->class, $this->property),
150
            $this->getAnnotationName()
151
        );
152
153
        if (null === $target) {
154
            $message = 'Property %s::$%s does not contain the annotation %s';
155
            throw new InvalidAnnotationParameterException(
156
                sprintf($message, $this->class, $this->property, $this->getAnnotationName())
157
            );
158
        }
159
160
        return $target;
161
    }
162
163
    /**
164
     * @param SimpleAnnotationReader $annotationReader
165
     *
166
     * @return ComponentObjectInterface
167
     *
168
     * @throws InvalidAnnotationParameterException
169
     */
170
    private function getClassAnnotation(SimpleAnnotationReader $annotationReader) : ComponentObjectInterface
171
    {
172
        $target = $annotationReader->getClassAnnotation(
173
            new ReflectionClass($this->class),
174
            $this->getAnnotationName()
175
        );
176
177
        if (null === $target) {
178
            $message = 'Class %s does not contain the annotation %s';
179
            throw new InvalidAnnotationParameterException(
180
                sprintf($message, $this->class, $this->getAnnotationName())
181
            );
182
        }
183
184
        return $target;
185
    }
186
187
    /**
188
     * @return string
189
     */
190
    abstract protected function getAnnotationName() : string;
191
}
192