Completed
Push — master ( 578000...8d28bc )
by Dawid
07:57
created

DataCollector::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 5
cts 5
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 3
crap 1
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\ResponseSchemaCheck\CheckResult;
10
use Spiechu\SymfonyCommonsBundle\Event\ResponseSchemaCheck\Events;
11
use Spiechu\SymfonyCommonsBundle\EventListener\RequestSchemaValidatorListener;
12
use Symfony\Component\DependencyInjection\Container;
13
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
14
use Symfony\Component\HttpFoundation\Request;
15
use Symfony\Component\HttpFoundation\Response;
16
use Symfony\Component\HttpKernel\DataCollector\DataCollector as BaseDataCollector;
17
use Symfony\Component\Routing\RouterInterface;
18
19
class DataCollector extends BaseDataCollector implements EventSubscriberInterface
20
{
21
    const COLLECTOR_NAME = 'spiechu_symfony_commons.data_collector';
22
23
    /**
24
     * @var RouterInterface
25
     */
26
    protected $router;
27
28
    /**
29
     * @var Reader
30
     */
31
    protected $reader;
32
33
    /**
34
     * @var Container
35
     */
36
    protected $container;
37
38 1
    public function __construct(RouterInterface $router, Reader $reader, Container $container)
39
    {
40 1
        $this->router = $router;
41 1
        $this->reader = $reader;
42 1
        $this->container = $container;
43 1
    }
44
45
    /**
46
     * {@inheritdoc}
47
     */
48 1
    public function collect(Request $request, Response $response, \Exception $exception = null): void
49
    {
50 1
        $this->data['known_response_schemas'] = $request->attributes->has(RequestSchemaValidatorListener::ATTRIBUTE_RESPONSE_SCHEMAS)
51 1
            ? $request->attributes->get(RequestSchemaValidatorListener::ATTRIBUTE_RESPONSE_SCHEMAS)
52
            : null;
53
54 1
        $this->extractRoutesData();
55 1
    }
56
57
    /**
58
     * {@inheritdoc}
59
     */
60 1
    public function getName(): string
61
    {
62 1
        return static::COLLECTOR_NAME;
63
    }
64
65
    public function getGlobalResponseSchemas(): array
66
    {
67
        return $this->data['global_response_schemas'];
68
    }
69
70
    /**
71
     * {@inheritdoc}
72
     */
73 2
    public static function getSubscribedEvents(): array
74
    {
75
        return [
76 2
            Events::CHECK_RESULT => ['onCheckResult', 100],
77
        ];
78
    }
79
80 1
    public function onCheckResult(CheckResult $checkResult): void
81
    {
82 1
        $this->data['validation_result'] = $checkResult->getValidationResult();
83 1
    }
84
85
    public function getKnownResponseSchemas(): array
86
    {
87
        return empty($this->data['known_response_schemas']) ? [] : $this->data['known_response_schemas'];
88
    }
89
90
    public function getKnownResponseSchemaNumber(): int
91
    {
92
        $counter = 0;
93
94
        foreach ($this->getKnownResponseSchemas() as $format) {
95
            $counter += count($format);
96
        }
97
98
        return $counter;
99
    }
100
101 1
    public function responseWasChecked(): bool
102
    {
103 1
        return array_key_exists('validation_result', $this->data);
104
    }
105
106
    /**
107
     * @return ValidationViolation[]
108
     */
109
    public function getValidationErrors(): array
110
    {
111
        if (!$this->responseWasChecked()) {
112
            return [];
113
        }
114
115
        return $this->data['validation_result']->getViolations();
116
    }
117
118 1
    protected function extractRoutesData(): void
119
    {
120 1
        $this->data['global_response_schemas'] = [];
121
122 1
        foreach ($this->router->getRouteCollection() as $name => $route) {
123 1
            $defaults = $route->getDefaults();
124
125 1
            if (empty($defaults['_controller'])) {
126
                continue;
127
            }
128
129 1
            $methodAnnotation = $this->extractControllerResponseValidator($defaults['_controller']);
130
131 1
            if (!$methodAnnotation instanceof ResponseSchemaValidator) {
132
                continue;
133
            }
134
135 1
            $this->data['global_response_schemas'][] = [
136 1
                'path' => $route->getPath(),
137 1
                'name' => $name,
138 1
                'controller' => $defaults['_controller'],
139 1
                'response_schemas' => $methodAnnotation->getSchemas(),
140
            ];
141
        }
142 1
    }
143
144 1
    protected function extractControllerResponseValidator(string $controllerDefinition): ?ResponseSchemaValidator
145
    {
146 1
        [$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...
147
148 1
        $controllerClass = $this->container->has($controllerDefinition)
149
            ? $this->container->get($controllerDefinition)
150 1
            : $controllerDefinition;
151
152 1
        $reflectedMethod = new \ReflectionMethod($controllerClass, ltrim($controllerMethod, ':'));
153
154 1
        return $this->reader->getMethodAnnotation($reflectedMethod, ResponseSchemaValidator::class);
155
    }
156
}
157