IvoryHttpAdapterDataCollector::getName()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
/*
4
 * This file is part of the Ivory Http Adapter bundle package.
5
 *
6
 * (c) Eric GELOEN <[email protected]>
7
 *
8
 * For the full copyright and license information, please read the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Ivory\HttpAdapterBundle\DataCollector;
13
14
use Ivory\HttpAdapter\Event\Events;
15
use Ivory\HttpAdapter\Event\MultiRequestCreatedEvent;
16
use Ivory\HttpAdapter\Event\MultiRequestErroredEvent;
17
use Ivory\HttpAdapter\Event\MultiRequestSentEvent;
18
use Ivory\HttpAdapter\Event\RequestCreatedEvent;
19
use Ivory\HttpAdapter\Event\RequestErroredEvent;
20
use Ivory\HttpAdapter\Event\RequestSentEvent;
21
use Ivory\HttpAdapter\Event\Subscriber\AbstractFormatterSubscriber;
22
use Ivory\HttpAdapter\HttpAdapterException;
23
use Ivory\HttpAdapter\HttpAdapterInterface;
24
use Ivory\HttpAdapter\Message\InternalRequestInterface;
25
use Ivory\HttpAdapter\Message\ResponseInterface;
26
use Symfony\Component\HttpFoundation\Request;
27
use Symfony\Component\HttpFoundation\Response;
28
use Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface;
29
30
/**
31
 * @author GeLo <[email protected]>
32
 */
33
class IvoryHttpAdapterDataCollector extends AbstractFormatterSubscriber implements DataCollectorInterface, \Countable, \Serializable
34
{
35
    /**
36
     * @var array
37
     */
38
    private $datas = [
39
        'responses'  => [],
40
        'exceptions' => [],
41
    ];
42
43
    /**
44
     * {@inheritdoc}
45
     */
46
    public function collect(Request $request, Response $response, \Exception $exception = null)
47
    {
48
        // Nothing to do
49
    }
50
51
    /**
52
     * @return array
53
     */
54
    public function getResponses()
55
    {
56
        return $this->datas['responses'];
57
    }
58
59
    /**
60
     * @return array
61
     */
62
    public function getExceptions()
63
    {
64
        return $this->datas['exceptions'];
65
    }
66
67
    /**
68
     * @return float
69
     */
70
    public function getTime()
71
    {
72
        $time = 0;
73
74
        foreach (array_merge($this->datas['responses'], $this->datas['exceptions']) as $datas) {
75
            $time += $datas['request']['parameters']['time'];
76
        }
77
78
        return $time;
79
    }
80
81
    /**
82
     * @param RequestCreatedEvent $event
83
     */
84
    public function onRequestCreated(RequestCreatedEvent $event)
85
    {
86
        $event->setRequest($this->getTimer()->start($event->getRequest()));
87
    }
88
89
    /**
90
     * @param RequestSentEvent $event
91
     */
92
    public function onRequestSent(RequestSentEvent $event)
93
    {
94
        $event->setRequest($this->collectResponse(
95
            $event->getHttpAdapter(),
96
            $event->getRequest(),
97
            $event->getResponse()
0 ignored issues
show
Bug introduced by
It seems like $event->getResponse() can be null; however, collectResponse() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
98
        ));
99
    }
100
101
    /**
102
     * @param RequestErroredEvent $event
103
     */
104
    public function onRequestErrored(RequestErroredEvent $event)
105
    {
106
        $event->getException()->setRequest($this->collectException($event->getHttpAdapter(), $event->getException()));
107
    }
108
109
    /**
110
     * @param MultiRequestCreatedEvent $event
111
     */
112
    public function onMultiRequestCreated(MultiRequestCreatedEvent $event)
113
    {
114
        $requests = [];
115
116
        foreach ($event->getRequests() as $request) {
117
            $requests[] = $this->getTimer()->start($request);
118
        }
119
120
        $event->setRequests($requests);
121
    }
122
123
    /**
124
     * @param MultiRequestSentEvent $event
125
     */
126
    public function onMultiRequestSent(MultiRequestSentEvent $event)
127
    {
128
        $responses = [];
129
130
        foreach ($event->getResponses() as $response) {
131
            $responses[] = $response->withParameter(
132
                'request',
133
                $this->collectResponse($event->getHttpAdapter(), $response->getParameter('request'), $response)
134
            );
135
        }
136
137
        $event->setResponses($responses);
138
    }
139
140
    /**
141
     * @param MultiRequestErroredEvent $event
142
     */
143
    public function onMultiRequestErrored(MultiRequestErroredEvent $event)
144
    {
145
        foreach ($event->getExceptions() as $exception) {
146
            $exception->setRequest($this->collectException($event->getHttpAdapter(), $exception));
147
        }
148
    }
149
150
    /**
151
     * {@inheritdoc}
152
     */
153
    public function getName()
154
    {
155
        return 'ivory.http_adapter';
156
    }
157
158
    /**
159
     * {@inheritdoc}
160
     */
161
    public function count()
162
    {
163
        return count($this->datas['responses']) + count($this->datas['exceptions']);
164
    }
165
166
    /**
167
     * {@inheritdoc}
168
     */
169
    public function serialize()
170
    {
171
        return serialize($this->datas);
172
    }
173
174
    /**
175
     * {@inheritdoc}
176
     */
177
    public function unserialize($serialized)
178
    {
179
        $this->datas = unserialize($serialized);
180
    }
181
182
    /**
183
     * {@inheritdoc}
184
     */
185
    public static function getSubscribedEvents()
186
    {
187
        return [
188
            Events::REQUEST_CREATED       => ['onRequestCreated', 100],
189
            Events::REQUEST_SENT          => ['onRequestSent', 100],
190
            Events::REQUEST_ERRORED       => ['onRequestErrored', 100],
191
            Events::MULTI_REQUEST_CREATED => ['onMultiRequestCreated', 100],
192
            Events::MULTI_REQUEST_SENT    => ['onMultiRequestSent', 100],
193
            Events::MULTI_REQUEST_ERRORED => ['onMultiRequestErrored', 100],
194
        ];
195
    }
196
197
    /**
198
     * @param HttpAdapterInterface     $httpAdapter
199
     * @param InternalRequestInterface $request
200
     * @param ResponseInterface        $response
201
     *
202
     * @return InternalRequestInterface
203
     */
204
    private function collectResponse(
205
        HttpAdapterInterface $httpAdapter,
206
        InternalRequestInterface $request,
207
        ResponseInterface $response
208
    ) {
209
        $request = $this->getTimer()->stop($request);
210
211
        $this->datas['responses'][] = [
212
            'adapter'  => $httpAdapter->getName(),
213
            'request'  => $this->getFormatter()->formatRequest($request),
214
            'response' => $this->getFormatter()->formatResponse($response),
215
        ];
216
217
        return $request;
218
    }
219
220
    /**
221
     * @param HttpAdapterInterface $httpAdapter
222
     * @param HttpAdapterException $exception
223
     *
224
     * @return InternalRequestInterface
225
     */
226
    private function collectException(HttpAdapterInterface $httpAdapter, HttpAdapterException $exception)
227
    {
228
        $request = $this->getTimer()->stop($exception->getRequest());
0 ignored issues
show
Bug introduced by
It seems like $exception->getRequest() can be null; however, stop() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
229
230
        $this->datas['exceptions'][] = [
231
            'adapter'   => $httpAdapter->getName(),
232
            'exception' => $this->getFormatter()->formatException($exception),
233
            'request'   => $this->getFormatter()->formatRequest($request),
234
            'response'  => $exception->hasResponse()
235
                ? $this->getFormatter()->formatResponse($exception->getResponse())
0 ignored issues
show
Bug introduced by
It seems like $exception->getResponse() can be null; however, formatResponse() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
236
                : null,
237
        ];
238
239
        return $request;
240
    }
241
}
242