Passed
Push — master ( e7b498...658590 )
by Michael
02:23
created

dispatchOnRequest()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 7
ccs 4
cts 4
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 1
crap 1
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);
0 ignored issues
show
Compatibility introduced by
$exception of type object<Throwable> is not a sub-type of object<Exception>. It seems like you assume a concrete implementation of the interface Throwable to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
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
}