Passed
Push — develop ( 02676e...d2b63d )
by Jens
08:11
created

Guzzle6Adapter::setLogger()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 6
cts 6
cp 1
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 5
nc 2
nop 3
crap 2
1
<?php
2
/**
3
 * @author @jayS-de <[email protected]>
4
 */
5
6
namespace Commercetools\Core\Client\Adapter;
7
8
use Commercetools\Core\Response\AbstractApiResponse;
9
use GuzzleHttp\Client;
10
use GuzzleHttp\Exception\RequestException;
11
use GuzzleHttp\MessageFormatter;
12
use GuzzleHttp\Middleware;
13
use GuzzleHttp\Pool;
14
use GuzzleHttp\Promise\PromiseInterface;
15
use Psr\Http\Message\RequestInterface;
16
use Psr\Http\Message\ResponseInterface;
17
use Psr\Log\LoggerInterface;
18
use Commercetools\Core\Error\Message;
19
use Commercetools\Core\Error\ApiException;
20
use Psr\Log\LogLevel;
21
22
class Guzzle6Adapter implements AdapterInterface
23
{
24
    /**
25
     * @var Client
26
     */
27
    protected $client;
28
29
    protected $logger;
30
31 108
    public function __construct(array $options = [])
32
    {
33 108
        $options = array_merge(
34
            [
35 108
                'allow_redirects' => false,
36
                'verify' => true,
37
                'timeout' => 60,
38
                'connect_timeout' => 10,
39
                'pool_size' => 25
40
            ],
41 108
            $options
42
        );
43 108
        $this->client = new Client($options);
44 108
    }
45
46 43
    public function setLogger(LoggerInterface $logger, $logLevel = LogLevel::INFO, $formatter = null)
47
    {
48 43
        if (is_null($formatter)) {
49 43
            $formatter = new MessageFormatter();
50
        }
51 43
        $this->logger = $logger;
52 43
        $this->addHandler(self::log($logger, $formatter, $logLevel));
53 43
    }
54
55
    /**
56
     * Middleware that logs requests, responses, and errors using a message
57
     * formatter.
58
     *
59
     * @param LoggerInterface  $logger Logs messages.
60
     * @param MessageFormatter $formatter Formatter used to create message strings.
61
     * @param string           $logLevel Level at which to log requests.
62
     *
63
     * @return callable Returns a function that accepts the next handler.
64
     */
65 474
    private static function log(LoggerInterface $logger, MessageFormatter $formatter, $logLevel = LogLevel::INFO)
66
    {
67
        return function (callable $handler) use ($logger, $formatter, $logLevel) {
68
            return function ($request, array $options) use ($handler, $logger, $formatter, $logLevel) {
69 474
                return $handler($request, $options)->then(
70
                    function ($response) use ($logger, $request, $formatter, $logLevel) {
71 474
                        $message = $formatter->format($request, $response);
72 474
                        $context[AbstractApiResponse::X_CORRELATION_ID] = $response->getHeader(
0 ignored issues
show
Coding Style Comprehensibility introduced by
$context was never initialized. Although not strictly required by PHP, it is generally a good practice to add $context = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
73 474
                            AbstractApiResponse::X_CORRELATION_ID
74
                        );
75 474
                        $logger->log($logLevel, $message, $context);
76 474
                        return $response;
77 474
                    },
78 474
                    function ($reason) use ($logger, $request, $formatter) {
79
                        $response = null;
80
                        $context = [];
81
                        if ($reason instanceof RequestException) {
82
                            $response = $reason->getResponse();
83
                            if (!is_null($response)) {
84
                                $context[AbstractApiResponse::X_CORRELATION_ID] = $response->getHeader(
85
                                    AbstractApiResponse::X_CORRELATION_ID
86
                                );
87
                            }
88
                        }
89
                        $message = $formatter->format($request, $response, $reason);
90
                        $logger->notice($message, $context);
91
                        return \GuzzleHttp\Promise\rejection_for($reason);
92 474
                    }
93
                );
94 38
            };
95 43
        };
96
    }
97
98 43
    public function addHandler($handler)
99
    {
100 43
        $this->client->getConfig('handler')->push($handler);
101 43
    }
102
103
    /**
104
     * @param RequestInterface $request
105
     * @return ResponseInterface
106
     */
107 517
    public function execute(RequestInterface $request)
108
    {
109
        try {
110 517
            $response = $this->client->send($request);
111 111
        } catch (RequestException $exception) {
112 111
            $response = $exception->getResponse();
113 111
            throw ApiException::create($request, $response, $exception);
114
        }
115
116 491
        return $response;
117
    }
118
119
    /**
120
     * @param RequestInterface[] $requests
121
     * @return ResponseInterface[]
122
     */
123 397
    public function executeBatch(array $requests)
124
    {
125 397
        $results = Pool::batch(
126 397
            $this->client,
127 397
            $requests
128
        );
129
130 397
        $responses = [];
131 397
        foreach ($results as $key => $result) {
132 397
            $httpResponse = $result;
133 397 View Code Duplication
            if ($result instanceof RequestException) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
134 16
                $request = $requests[$key];
135 16
                $httpResponse = $result->getResponse();
136 16
                $httpResponse = ApiException::create($request, $httpResponse, $result);
137
            }
138 397
            $responses[$key] = $httpResponse;
139
        }
140
141 397
        return $responses;
142
    }
143
144
    /**
145
     * @param $oauthUri
146
     * @param $clientId
147
     * @param $clientSecret
148
     * @param $formParams
149
     * @return ResponseInterface
150
     */
151 44
    public function authenticate($oauthUri, $clientId, $clientSecret, $formParams)
152
    {
153
        $options = [
154 44
            'form_params' => $formParams,
155 44
            'auth' => [$clientId, $clientSecret]
156
        ];
157
158
        try {
159 44
            $response = $this->client->post($oauthUri, $options);
160 3
        } catch (RequestException $exception) {
161 3
            throw ApiException::create($exception->getRequest(), $exception->getResponse(), $exception);
162
        }
163 43
        return $response;
164
    }
165
166
    /**
167
     * @param RequestInterface $request
168
     * @return AdapterPromiseInterface
169
     */
170 4
    public function executeAsync(RequestInterface $request)
171
    {
172 4
        $guzzlePromise = $this->client->sendAsync($request);
173
174 4
        return new Guzzle6Promise($guzzlePromise);
175
    }
176
177 72
    public static function getAdapterInfo()
178
    {
179 72
        return 'GuzzleHttp/' . Client::VERSION;
180
    }
181
}
182