Passed
Pull Request — master (#2506)
by Alan
03:40
created

EventDispatcher::dispatch()   B

Complexity

Conditions 7
Paths 13

Size

Total Lines 32
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 23
nc 13
nop 2
dl 0
loc 32
rs 8.6186
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of the API Platform project.
5
 *
6
 * (c) Kévin Dunglas <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace ApiPlatform\Core\Bridge\Symfony\Bundle\EventSubscriber;
15
16
use ApiPlatform\Core\Event\DeserializeEvent;
17
use ApiPlatform\Core\Event\Event as ApiPlatformEvent;
18
use ApiPlatform\Core\Event\FormatAddEvent;
19
use ApiPlatform\Core\Event\PostDeserializeEvent;
20
use ApiPlatform\Core\Event\PostReadEvent;
21
use ApiPlatform\Core\Event\PostRespondEvent;
22
use ApiPlatform\Core\Event\PostSerializeEvent;
23
use ApiPlatform\Core\Event\PostValidateEvent;
24
use ApiPlatform\Core\Event\PostWriteEvent;
25
use ApiPlatform\Core\Event\PreDeserializeEvent;
26
use ApiPlatform\Core\Event\PreReadEvent;
27
use ApiPlatform\Core\Event\PreRespondEvent;
28
use ApiPlatform\Core\Event\PreSerializeEvent;
29
use ApiPlatform\Core\Event\PreValidateEvent;
30
use ApiPlatform\Core\Event\PreWriteEvent;
31
use ApiPlatform\Core\Event\QueryParameterValidateEvent;
32
use ApiPlatform\Core\Event\ReadEvent;
33
use ApiPlatform\Core\Event\RespondEvent;
34
use ApiPlatform\Core\Event\SerializeEvent;
35
use ApiPlatform\Core\Event\ValidateEvent;
36
use ApiPlatform\Core\Event\ValidationExceptionEvent;
37
use ApiPlatform\Core\Event\WriteEvent;
38
use ApiPlatform\Core\Events;
39
use Symfony\Component\EventDispatcher\Event;
40
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
41
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
42
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
43
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
44
use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
45
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
46
use Symfony\Component\HttpKernel\KernelEvents;
47
48
/**
49
 * @internal
50
 *
51
 * @author Alan Poulain <[email protected]>
52
 */
53
final class EventDispatcher implements EventSubscriberInterface
54
{
55
    private const INTERNAL_EVENTS_CONFIGURATION = [
56
        KernelEvents::REQUEST => [
57
            QueryParameterValidateEvent::class => Events::QUERY_PARAMETER_VALIDATE,
58
            FormatAddEvent::class => Events::FORMAT_ADD,
59
60
            PreReadEvent::class => Events::PRE_READ,
61
            ReadEvent::class => Events::READ,
62
            PostReadEvent::class => Events::POST_READ,
63
64
            PreDeserializeEvent::class => Events::PRE_DESERIALIZE,
65
            DeserializeEvent::class => Events::DESERIALIZE,
66
            PostDeserializeEvent::class => Events::POST_DESERIALIZE,
67
        ],
68
        KernelEvents::VIEW => [
69
            PreValidateEvent::class => Events::PRE_VALIDATE,
70
            ValidateEvent::class => Events::VALIDATE,
71
            PostValidateEvent::class => Events::POST_VALIDATE,
72
73
            PreWriteEvent::class => Events::PRE_WRITE,
74
            WriteEvent::class => Events::WRITE,
75
            PostWriteEvent::class => Events::POST_WRITE,
76
77
            PreSerializeEvent::class => Events::PRE_SERIALIZE,
78
            SerializeEvent::class => Events::SERIALIZE,
79
            PostSerializeEvent::class => Events::POST_SERIALIZE,
80
81
            PreRespondEvent::class => Events::PRE_RESPOND,
82
            RespondEvent::class => Events::RESPOND,
83
        ],
84
        KernelEvents::RESPONSE => [
85
            PostRespondEvent::class => Events::POST_RESPOND,
86
        ],
87
        KernelEvents::EXCEPTION => [
88
            ValidationExceptionEvent::class => Events::VALIDATE_EXCEPTION,
89
        ],
90
    ];
91
92
    private $dispatcher;
93
94
    public function __construct(EventDispatcherInterface $dispatcher)
95
    {
96
        $this->dispatcher = $dispatcher;
97
    }
98
99
    public static function getSubscribedEvents(): array
100
    {
101
        return [
102
            KernelEvents::REQUEST => 'dispatch',
103
            KernelEvents::VIEW => 'dispatch',
104
            KernelEvents::RESPONSE => [['dispatch', 1]], // to be before AddLinkHeaderListener in Symfony.
105
        ];
106
    }
107
108
    public function dispatch(Event $event, string $eventName): void
109
    {
110
        $internalEventData = null;
111
112
        // case order is important because of Symfony events inheritance
113
        switch (true) {
114
            case $event instanceof GetResponseForControllerResultEvent:
115
                $internalEventData = $event->getControllerResult();
116
                $internalEventContext = ['request' => $event->getRequest()];
117
                break;
118
            case $event instanceof GetResponseForExceptionEvent:
119
                $internalEventContext = ['request' => $event->getRequest(), 'exception' => $event->getException()];
120
                break;
121
            case $event instanceof GetResponseEvent:
122
                $internalEventContext = ['request' => $event->getRequest()];
123
                break;
124
            case $event instanceof FilterResponseEvent:
125
                $internalEventContext = ['request' => $event->getRequest(), 'response' => $event->getResponse()];
126
                break;
127
            default:
128
                return;
129
        }
130
131
        foreach (self::INTERNAL_EVENTS_CONFIGURATION[$eventName] as $internalEventClass => $internalEventName) {
132
            /** @var ApiPlatformEvent $internalEvent */
133
            $internalEvent = new $internalEventClass($internalEventData, $internalEventContext);
134
135
            $this->dispatcher->dispatch($internalEventName, $internalEvent);
136
137
            $internalEventData = $internalEvent->getData();
138
            if ($response = $internalEvent->getContext()['response'] ?? null) {
139
                $event->setResponse($response);
0 ignored issues
show
Bug introduced by
The method setResponse() does not exist on Symfony\Component\EventDispatcher\Event. It seems like you code against a sub-type of Symfony\Component\EventDispatcher\Event such as FOS\UserBundle\Event\FormEvent or FOS\UserBundle\Event\GetResponseUserEvent or FOS\UserBundle\Event\FilterUserResponseEvent or Symfony\Component\HttpKe...ent\FilterResponseEvent or Symfony\Component\HttpKe...\Event\GetResponseEvent or FOS\UserBundle\Event\FilterGroupResponseEvent or FOS\UserBundle\Event\GetResponseGroupEvent. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

139
                $event->/** @scrutinizer ignore-call */ 
140
                        setResponse($response);
Loading history...
140
            }
141
        }
142
    }
143
}
144