Completed
Push — master ( 5eb8de...a6b875 )
by Tobias
14:06
created

ProfilePlugin::handleRequest()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 39
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 20
CRAP Score 2.003

Importance

Changes 0
Metric Value
dl 0
loc 39
ccs 20
cts 22
cp 0.9091
rs 8.8571
c 0
b 0
f 0
cc 2
eloc 21
nc 2
nop 3
crap 2.003
1
<?php
2
3
namespace Http\HttplugBundle\Collector;
4
5
use Exception;
6
use Http\Client\Common\Plugin;
7
use Psr\Http\Message\RequestInterface;
8
use Psr\Http\Message\ResponseInterface;
9
10
/**
11
 * The ProfilePlugin decorates any Plugin to fill Profile to keep representation of plugin input/output. Created profile
12
 * is pushed in the current Stack.
13
 *
14
 * @author Fabien Bourigault <[email protected]>
15
 *
16
 * @internal
17
 */
18
class ProfilePlugin implements Plugin
19
{
20
    /**
21
     * @var Plugin
22
     */
23
    private $plugin;
24
25
    /**
26
     * @var Collector
27
     */
28
    private $collector;
29
30
    /**
31
     * @var Formatter
32
     */
33
    private $formatter;
34
35
    /**
36
     * @param Plugin    $plugin
37
     * @param Collector $collector
38
     * @param Formatter $formatter
39
     */
40 12
    public function __construct(Plugin $plugin, Collector $collector, Formatter $formatter)
41
    {
42 12
        $this->plugin = $plugin;
43 12
        $this->collector = $collector;
44 12
        $this->formatter = $formatter;
45 12
    }
46
47
    /**
48
     * {@inheritdoc}
49
     */
50 8
    public function handleRequest(RequestInterface $request, callable $next, callable $first)
51
    {
52 8
        $profile = new Profile(get_class($this->plugin));
53
54 8
        $stack = $this->collector->getActiveStack();
55 8
        $stack->addProfile($profile);
56
57
        // wrap the next callback to profile the plugin request changes
58 8
        $wrappedNext = function (RequestInterface $request) use ($next, $profile) {
59 7
            $this->onOutgoingRequest($request, $profile);
60
61 7
            return $next($request);
62 8
        };
63
64
        // wrap the first callback to profile the plugin request changes
65 8
        $wrappedFirst = function (RequestInterface $request) use ($first, $profile) {
66
            $this->onOutgoingRequest($request, $profile);
67
68
            return $first($request);
69 8
        };
70
71
        try {
72 8
            $promise = $this->plugin->handleRequest($request, $wrappedNext, $wrappedFirst);
73 1
        } catch (Exception $e) {
74 1
            $this->onException($request, $profile, $e, $stack);
75
76 1
            throw $e;
77
        }
78
79 6
        return $promise->then(function (ResponseInterface $response) use ($profile, $request, $stack) {
80 6
            $this->onOutgoingResponse($response, $profile, $request, $stack);
81
82 6
            return $response;
83
        }, function (Exception $exception) use ($profile, $request, $stack) {
84 1
            $this->onException($request, $profile, $exception, $stack);
85
86 1
            throw $exception;
87 7
        });
88
    }
89
90
    /**
91
     * @param RequestInterface $request
92
     * @param Profile          $profile
93
     * @param Exception        $exception
94
     * @param Stack            $stack
95
     */
96 2
    private function onException(
97
        RequestInterface $request,
98
        Profile $profile,
99
        Exception $exception,
100
        Stack $stack = null
101
    ) {
102 2
        $profile->setFailed(true);
103 2
        $profile->setResponse($this->formatter->formatException($exception));
104 2
        $this->collectRequestInformation($request, $stack);
105 2
    }
106
107
    /**
108
     * @param RequestInterface $request
109
     * @param Profile          $profile
110
     */
111 7
    private function onOutgoingRequest(RequestInterface $request, Profile $profile)
112
    {
113 7
        $profile->setRequest($this->formatter->formatRequest($request));
114 7
    }
115
116
    /**
117
     * @param ResponseInterface $response
118
     * @param Profile           $profile
119
     * @param RequestInterface  $request
120
     * @param Stack             $stack
121
     */
122 6
    private function onOutgoingResponse(ResponseInterface $response, Profile $profile, RequestInterface $request, Stack $stack = null)
123
    {
124 6
        $profile->setResponse($this->formatter->formatResponse($response));
125 6
        $this->collectRequestInformation($request, $stack);
126 6
    }
127
128
    /**
129
     * Collect request information when not already done by the HTTP client. This happens when using the CachePlugin
130
     * and the cache is hit without re-validation.
131
     *
132
     * @param RequestInterface $request
133
     * @param Stack|null       $stack
134
     */
135 8
    private function collectRequestInformation(RequestInterface $request, Stack $stack = null)
136
    {
137 8
        if (empty($stack->getRequestTarget())) {
138 7
            $stack->setRequestTarget($request->getRequestTarget());
0 ignored issues
show
Bug introduced by
It seems like $stack is not always an object, but can also be of type null. Maybe add an additional type check?

If a variable is not always an object, we recommend to add an additional type check to ensure your method call is safe:

function someFunction(A $objectMaybe = null)
{
    if ($objectMaybe instanceof A) {
        $objectMaybe->doSomething();
    }
}
Loading history...
139
        }
140 8
        if (empty($stack->getRequestMethod())) {
141 7
            $stack->setRequestMethod($request->getMethod());
142
        }
143 8
        if (empty($stack->getRequestScheme())) {
144 7
            $stack->setRequestScheme($request->getUri()->getScheme());
145
        }
146 8
        if (empty($stack->getRequestHost())) {
147 7
            $stack->setRequestHost($request->getUri()->getHost());
148
        }
149 8
        if (empty($stack->getClientRequest())) {
150 7
            $stack->setClientRequest($this->formatter->formatRequest($request));
151
        }
152 8
        if (empty($stack->getCurlCommand())) {
153 7
            $stack->setCurlCommand($this->formatter->formatAsCurlCommand($request));
154
        }
155 8
    }
156
}
157