SymfonyEventDispatcherDecorator::request()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 4.0092

Importance

Changes 0
Metric Value
dl 0
loc 24
ccs 11
cts 12
cp 0.9167
rs 9.536
c 0
b 0
f 0
cc 4
nc 4
nop 1
crap 4.0092
1
<?php
2
declare(strict_types = 1);
3
4
namespace Mikemirten\Component\JsonApi\HttpClient\Decorator;
5
6
use Mikemirten\Component\JsonApi\HttpClient\Decorator\SymfonyEvent\ExceptionEvent;
7
use Mikemirten\Component\JsonApi\HttpClient\Decorator\SymfonyEvent\RequestEvent;
8
use Mikemirten\Component\JsonApi\HttpClient\Decorator\SymfonyEvent\ResponseEvent;
9
use Mikemirten\Component\JsonApi\HttpClient\Exception\RequestException;
10
use Mikemirten\Component\JsonApi\HttpClient\HttpClientInterface;
11
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
12
use Psr\Http\Message\RequestInterface;
13
use Psr\Http\Message\ResponseInterface;
14
15
/**
16
 * Events handling decorator based on the Symfony EventDispatcher component.
17
 *
18
 * @package Mikemirten\Component\JsonApi\HttpClient\Decorator
19
 */
20
class SymfonyEventDispatcherDecorator implements HttpClientInterface
21
{
22
    /**
23
     * HTTP Client
24
     *
25
     * @var HttpClientInterface
26
     */
27
    protected $client;
28
29
    /**
30
     * @var EventDispatcherInterface
31
     */
32
    protected $dispatcher;
33
34
    /**
35
     * @var string
36
     */
37
    protected $requestEvent;
38
39
    /**
40
     * @var string
41
     */
42
    protected $responseEvent;
43
44
    /**
45
     * @var string
46
     */
47
    protected $exceptionEvent;
48
49
    /**
50
     * SymfonyEventDispatcherDecorator constructor.
51
     *
52
     * @param HttpClientInterface      $client
53
     * @param EventDispatcherInterface $dispatcher
54
     *
55
     * @param string $requestEvent
56
     * @param string $responseEvent
57
     * @param string $exceptionEvent
58
     */
59 4
    public function __construct(
60
        HttpClientInterface      $client,
61
        EventDispatcherInterface $dispatcher,
62
63
        string $requestEvent,
64
        string $responseEvent,
65
        string $exceptionEvent
66
    ) {
67 4
        $this->client     = $client;
68 4
        $this->dispatcher = $dispatcher;
69
70 4
        $this->requestEvent   = $requestEvent;
71 4
        $this->responseEvent  = $responseEvent;
72 4
        $this->exceptionEvent = $exceptionEvent;
73 4
    }
74
75
    /**
76
     * {@inheritdoc}
77
     */
78 4
    public function request(RequestInterface $request): ResponseInterface
79
    {
80 4
        $request = $this->dispatchOnRequest($request);
81
82
        try {
83 4
            $response = $this->client->request($request);
84
        }
85 3
        catch (\Throwable $exception) {
86 3
            $exceptionEvent = new ExceptionEvent($request, $exception);
87 3
            $this->dispatcher->dispatch($this->exceptionEvent, $exceptionEvent);
88
89 3
            if (! $exceptionEvent->hasResponse()) {
90 2
                throw $this->handleException($exception, $request);
91
            }
92
93 1
            $response = $exceptionEvent->getResponse();
94
95 1
            if (! $exceptionEvent->isResponseEventEnabled()) {
96
                return $response;
97
            }
98
        }
99
100 2
        return $this->dispatchOnResponse($response);
101
    }
102
103
    /**
104
     * Handler exception
105
     *
106
     * @param  \Throwable       $exception
107
     * @param  RequestInterface $request
108
     * @return RequestException
109
     */
110 2
    protected function handleException(\Throwable $exception, RequestInterface $request): RequestException
111
    {
112 2
        if ($exception instanceof RequestException) {
113 1
            return $exception;
114
        }
115
116 1
        return new RequestException($request, $exception);
117
    }
118
119
    /**
120
     * Dispatch on-request event
121
     *
122
     * @param  RequestInterface $request
123
     * @return RequestInterface
124
     */
125 4
    protected function dispatchOnRequest(RequestInterface $request): RequestInterface
126
    {
127 4
        $requestEvent = new RequestEvent($request);
128 4
        $this->dispatcher->dispatch($this->requestEvent, $requestEvent);
129
130 4
        return $requestEvent->getRequest();
131
    }
132
133
    /**
134
     * Dispatch on-response event
135
     *
136
     * @param  ResponseInterface $response
137
     * @return ResponseInterface
138
     */
139 2
    protected function dispatchOnResponse(ResponseInterface $response): ResponseInterface
140
    {
141 2
        $responseEvent = new ResponseEvent($response);
142 2
        $this->dispatcher->dispatch($this->responseEvent, $responseEvent);
143
144 2
        return $responseEvent->getResponse();
145
    }
146
}