Completed
Push — master ( 1e51ab...79451c )
by Dawid
02:06
created

DataCollector::reset()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
ccs 0
cts 3
cp 0
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Spiechu\SymfonyCommonsBundle\Service;
6
7
use Doctrine\Common\Annotations\Reader;
8
use Spiechu\SymfonyCommonsBundle\Annotation\Controller\ResponseSchemaValidator;
9
use Spiechu\SymfonyCommonsBundle\Event\ApiVersion\ApiVersionSetEvent;
10
use Spiechu\SymfonyCommonsBundle\Event\ApiVersion\Events as ApiVersionEvents;
11
use Spiechu\SymfonyCommonsBundle\Event\ResponseSchemaCheck\CheckResult;
12
use Spiechu\SymfonyCommonsBundle\Event\ResponseSchemaCheck\Events as ResponseSchemaCheckEvents;
13
use Spiechu\SymfonyCommonsBundle\EventListener\RequestSchemaValidatorListener;
14
use Symfony\Component\DependencyInjection\Container;
15
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
16
use Symfony\Component\HttpFoundation\Request;
17
use Symfony\Component\HttpFoundation\Response;
18
use Symfony\Component\HttpKernel\DataCollector\DataCollector as BaseDataCollector;
19
use Symfony\Component\Routing\RouterInterface;
20
21
class DataCollector extends BaseDataCollector implements EventSubscriberInterface
22
{
23
    const COLLECTOR_NAME = 'spiechu_symfony_commons.data_collector';
24
25
    /**
26
     * @var RouterInterface
27
     */
28
    protected $router;
29
30
    /**
31
     * @var Reader
32
     */
33
    protected $reader;
34
35
    /**
36
     * @var Container
37
     */
38
    protected $container;
39
40
    /**
41
     * @param RouterInterface $router
42
     * @param Reader $reader
43
     * @param Container $container
44
     */
45 6
    public function __construct(RouterInterface $router, Reader $reader, Container $container)
46
    {
47 6
        $this->router = $router;
48 6
        $this->reader = $reader;
49 6
        $this->container = $container;
50 6
    }
51
52
    /**
53
     * {@inheritdoc}
54
     */
55 6
    public function collect(Request $request, Response $response, \Exception $exception = null): void
56
    {
57 6
        $this->data['known_response_schemas'] = $request->attributes->has(RequestSchemaValidatorListener::ATTRIBUTE_RESPONSE_SCHEMAS)
58 1
            ? $request->attributes->get(RequestSchemaValidatorListener::ATTRIBUTE_RESPONSE_SCHEMAS)
59 5
            : null;
60
61 6
        $this->extractRoutesData();
62 6
    }
63
64
    /**
65
     * {@inheritdoc}
66
     */
67 6
    public function getName(): string
68
    {
69 6
        return static::COLLECTOR_NAME;
70
    }
71
72
    /**
73
     * Forward compatibility with Symfony 3.4
74
     */
75
    public function reset(): void
76
    {
77
        $this->data = [];
78
    }
79
80
    /**
81
     * @return array
82
     */
83
    public function getGlobalResponseSchemas(): array
84
    {
85
        return $this->data['global_response_schemas'];
86
    }
87
88
    /**
89
     * {@inheritdoc}
90
     */
91 3
    public static function getSubscribedEvents(): array
92
    {
93
        return [
94 3
            ResponseSchemaCheckEvents::CHECK_RESULT => ['onCheckResult', 100],
95 3
            ApiVersionEvents::API_VERSION_SET => ['onApiVersionSet', 100],
96
        ];
97
    }
98
99
    /**
100
     * @param CheckResult $checkResult
101
     */
102 1
    public function onCheckResult(CheckResult $checkResult): void
103
    {
104 1
        $this->data['validation_result'] = $checkResult->getValidationResult();
105 1
    }
106
107
    /**
108
     * @param ApiVersionSetEvent $apiVersionSetEvent
109
     */
110 5
    public function onApiVersionSet(ApiVersionSetEvent $apiVersionSetEvent): void
111
    {
112 5
        $this->data['api_version_set'] = $apiVersionSetEvent->getApiVersion();
113 5
    }
114
115
    /**
116
     * @return array
117
     */
118
    public function getKnownResponseSchemas(): array
119
    {
120
        return empty($this->data['known_response_schemas']) ? [] : $this->data['known_response_schemas'];
121
    }
122
123
    /**
124
     * @return int
125
     */
126
    public function getKnownResponseSchemaNumber(): int
127
    {
128
        $counter = 0;
129
130
        foreach ($this->getKnownResponseSchemas() as $format) {
131
            $counter += count($format);
132
        }
133
134
        return $counter;
135
    }
136
137
    /**
138
     * @return bool
139
     */
140 1
    public function responseWasChecked(): bool
141
    {
142 1
        return array_key_exists('validation_result', $this->data);
143
    }
144
145
    /**
146
     * @return bool
147
     */
148 5
    public function apiVersionWasSet(): bool
149
    {
150 5
        return array_key_exists('api_version_set', $this->data);
151
    }
152
153
    /**
154
     * @return null|string
155
     */
156 5
    public function getApiVersion(): ?string
157
    {
158 5
        return $this->apiVersionWasSet() ? $this->data['api_version_set'] : null;
159
    }
160
161
    /**
162
     * @return ValidationViolation[]
163
     */
164
    public function getValidationErrors(): array
165
    {
166
        if (!$this->responseWasChecked()) {
167
            return [];
168
        }
169
170
        return $this->data['validation_result']->getViolations();
171
    }
172
173 6
    protected function extractRoutesData(): void
174
    {
175 6
        $this->data['global_response_schemas'] = [];
176
177 6
        foreach ($this->router->getRouteCollection() as $name => $route) {
178 6
            $defaults = $route->getDefaults();
179
180 6
            if (empty($defaults['_controller'])) {
181
                continue;
182
            }
183
184 6
            $methodAnnotation = $this->extractControllerResponseValidator($defaults['_controller']);
185
186 6
            if (!$methodAnnotation instanceof ResponseSchemaValidator) {
187 6
                continue;
188
            }
189
190 6
            $this->data['global_response_schemas'][] = [
191 6
                'path' => $route->getPath(),
192 6
                'name' => $name,
193 6
                'controller' => $defaults['_controller'],
194 6
                'response_schemas' => $methodAnnotation->getSchemas(),
195
            ];
196
        }
197 6
    }
198
199
    /**
200
     * @param string $controllerDefinition
201
     *
202
     * @throws \Exception
203
     *
204
     * @return null|ResponseSchemaValidator
205
     */
206 6
    protected function extractControllerResponseValidator(string $controllerDefinition): ?ResponseSchemaValidator
207
    {
208 6
        [$controllerDefinition, $controllerMethod] = explode(':', $controllerDefinition, 2);
0 ignored issues
show
Bug introduced by
The variable $controllerMethod does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
209
210 6
        $controllerClass = $this->container->has($controllerDefinition)
211
            ? $this->container->get($controllerDefinition)
212 6
            : $controllerDefinition;
213
214 6
        $reflectedMethod = new \ReflectionMethod($controllerClass, ltrim($controllerMethod, ':'));
215
216 6
        return $this->reader->getMethodAnnotation($reflectedMethod, ResponseSchemaValidator::class);
217
    }
218
}
219