Completed
Push — master ( 7447f5...b893a1 )
by Fabien
04:06
created

ProfilePlugin::onOutgoingRequest()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 2
crap 1
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
     * @var string
37
     */
38
    private $pluginName;
39
40
    /**
41
     * @param Plugin    $plugin
42
     * @param Collector $collector
43
     * @param Formatter $formatter
44
     * @param string    $pluginName
45
     */
46 9
    public function __construct(Plugin $plugin, Collector $collector, Formatter $formatter, $pluginName)
47
    {
48 9
        $this->plugin = $plugin;
49 9
        $this->collector = $collector;
50 9
        $this->formatter = $formatter;
51 9
        $this->pluginName = $pluginName;
52 9
    }
53
54
    /**
55
     * {@inheritdoc}
56
     */
57 8
    public function handleRequest(RequestInterface $request, callable $next, callable $first)
58
    {
59 8
        $profile = new Profile($this->pluginName);
60
61 8
        $stack = $this->collector->getCurrentStack();
62 8
        if (null !== $stack) {
63 8
            $stack->addProfile($profile);
64 8
        }
65
66
        // wrap the next callback to profile the plugin request changes
67
        $wrappedNext = function (RequestInterface $request) use ($next, $profile) {
68 7
            $this->onOutgoingRequest($request, $profile);
69
70 7
            return $next($request);
71 8
        };
72
73
        // wrap the first callback to profile the plugin request changes
74
        $wrappedFirst = function (RequestInterface $request) use ($first, $profile) {
75
            $this->onOutgoingRequest($request, $profile);
76
77
            return $first($request);
78 8
        };
79
80
        try {
81 8
            $promise = $this->plugin->handleRequest($request, $wrappedNext, $wrappedFirst);
82 8
        } catch (Exception $e) {
83 1
            $this->onException($request, $profile, $e, $stack);
84
85 1
            throw $e;
86
        }
87
88
        return $promise->then(function (ResponseInterface $response) use ($profile, $request, $stack) {
89 6
            $this->onOutgoingResponse($response, $profile, $request, $stack);
90
91 6
            return $response;
92 7
        }, function (Exception $exception) use ($profile, $request, $stack) {
93 1
            $this->onException($request, $profile, $exception, $stack);
94
95 1
            throw $exception;
96 7
        });
97
    }
98
99
    /**
100
     * @param RequestInterface $request
101
     * @param Profile          $profile
102
     * @param Exception        $exception
103
     * @param Stack            $stack
104
     */
105 2
    private function onException(
106
        RequestInterface $request,
107
        Profile $profile,
108
        Exception $exception,
109
        Stack $stack = null
110
    ) {
111 2
        $profile->setFailed(true);
112 2
        $profile->setResponse($this->formatter->formatException($exception));
113 2
        $this->collectRequestInformation($request, $stack);
114 2
    }
115
116
    /**
117
     * @param RequestInterface $request
118
     * @param Profile          $profile
119
     */
120 7
    private function onOutgoingRequest(RequestInterface $request, Profile $profile)
121
    {
122 7
        $profile->setRequest($this->formatter->formatRequest($request));
123 7
    }
124
125
    /**
126
     * @param ResponseInterface $response
127
     * @param Profile           $profile
128
     * @param RequestInterface  $request
129
     * @param Stack             $stack
130
     */
131 6
    private function onOutgoingResponse(ResponseInterface $response, Profile $profile, RequestInterface $request, Stack $stack = null)
132
    {
133 6
        $profile->setResponse($this->formatter->formatResponse($response));
134 6
        $this->collectRequestInformation($request, $stack);
135 6
    }
136
137
    /**
138
     * Collect request information when not already done by the HTTP client. This happens when using the CachePlugin
139
     * and the cache is hit without re-validation.
140
     *
141
     * @param RequestInterface $request
142
     * @param Stack|null       $stack
143
     */
144 8
    private function collectRequestInformation(RequestInterface $request, Stack $stack = null)
145
    {
146 8
        if (null === $stack) {
147
            return;
148
        }
149
150 8
        if (empty($stack->getRequestTarget())) {
151 7
            $stack->setRequestTarget($request->getRequestTarget());
152 7
        }
153 8
        if (empty($stack->getRequestMethod())) {
154 7
            $stack->setRequestMethod($request->getMethod());
155 7
        }
156 8
        if (empty($stack->getRequestScheme())) {
157 7
            $stack->setRequestScheme($request->getUri()->getScheme());
158 7
        }
159 8
        if (empty($stack->getRequestHost())) {
160 7
            $stack->setRequestHost($request->getUri()->getHost());
161 7
        }
162 8
        if (empty($stack->getClientRequest())) {
163 7
            $stack->setClientRequest($this->formatter->formatRequest($request));
164 7
        }
165 8
        if (empty($stack->getCurlCommand())) {
166 7
            $stack->setCurlCommand($this->formatter->formatAsCurlCommand($request));
167 7
        }
168 8
    }
169
}
170