Completed
Push — master ( 3f21c4...d0cb1d )
by Dawid
09:14
created

DataCollector::getKnownResponseSchemaNumber()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 10
ccs 0
cts 8
cp 0
rs 9.4285
c 0
b 0
f 0
nc 2
cc 2
eloc 5
nop 0
crap 6
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
    protected const DATA_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
    public function __construct(RouterInterface $router, Reader $reader, Container $container)
39
    {
40
        $this->router = $router;
41
        $this->reader = $reader;
42
        $this->container = $container;
43
    }
44
45
    /**
46
     * {@inheritdoc}
47
     */
48
    public function collect(Request $request, Response $response, \Exception $exception = null): void
49
    {
50
        $this->data['known_response_schemas'] = $request->attributes->has(RequestSchemaValidatorListener::ATTRIBUTE_RESPONSE_SCHEMAS)
51
            ? $request->attributes->get(RequestSchemaValidatorListener::ATTRIBUTE_RESPONSE_SCHEMAS)
52
            : null;
53
54
        $this->extractRoutesData();
55
    }
56
57
    /**
58
     * {@inheritdoc}
59
     */
60
    public function getName(): string
61
    {
62
        return static::DATA_COLLECTOR_NAME;
63
    }
64
65
    public function getGlobalResponseSchemas(): array
66
    {
67
        return $this->data['global_response_schemas'];
68
    }
69
70
    /**
71
     * {@inheritdoc}
72
     */
73
    public static function getSubscribedEvents(): array
74
    {
75
        return [
76
            Events::CHECK_RESULT => ['onCheckResult', 100],
77
        ];
78
    }
79
80
    public function onCheckResult(CheckResult $checkResult): void
81
    {
82
        $this->data['validation_result'] = $checkResult->getValidationResult();
83
    }
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
    public function responseWasChecked(): bool
102
    {
103
        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
    protected function extractRoutesData(): void
119
    {
120
        $this->data['global_response_schemas'] = [];
121
122
        foreach ($this->router->getRouteCollection() as $name => $route) {
123
            $defaults = $route->getDefaults();
124
125
            if (empty($defaults['_controller'])) {
126
                continue;
127
            }
128
129
            $methodAnnotation = $this->extractControllerResponseValidator($defaults['_controller']);
130
131
            if (!$methodAnnotation instanceof ResponseSchemaValidator) {
132
                continue;
133
            }
134
135
            $this->data['global_response_schemas'][] = [
136
                'path' => $route->getPath(),
137
                'name' => $name,
138
                'controller' => $defaults['_controller'],
139
                'response_schemas' => $methodAnnotation->getSchemas(),
140
            ];
141
        }
142
    }
143
144
    protected function extractControllerResponseValidator(string $controllerDefinition): ?ResponseSchemaValidator
145
    {
146
        [$controllerService, $controllerMethod] = explode(':', $controllerDefinition, 2);
0 ignored issues
show
Bug introduced by
The variable $controllerService 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...
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
        $reflectedMethod = new \ReflectionMethod($this->container->get($controllerService), ltrim($controllerMethod, ':'));
149
150
        return $this->reader->getMethodAnnotation($reflectedMethod, ResponseSchemaValidator::class);
151
    }
152
}
153