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

DataCollector   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 134
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Test Coverage

Coverage 0%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 19
lcom 1
cbo 8
dl 0
loc 134
ccs 0
cts 80
cp 0
rs 10
c 2
b 0
f 0

12 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A collect() 0 8 2
A getName() 0 4 1
A getGlobalResponseSchemas() 0 4 1
A getSubscribedEvents() 0 6 1
A onCheckResult() 0 4 1
A getKnownResponseSchemas() 0 4 2
A getKnownResponseSchemaNumber() 0 10 2
A responseWasChecked() 0 4 1
A getValidationErrors() 0 8 2
B extractRoutesData() 0 25 4
A extractControllerResponseValidator() 0 8 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
    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