Completed
Push — master ( 48cceb...d6244f )
by Nicolas
02:39
created

Guzzle::exec()   B

Complexity

Conditions 7
Paths 36

Size

Total Lines 55

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 55
rs 8.0484
c 0
b 0
f 0
cc 7
nc 36
nop 2

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Elastica\Transport;
4
5
use Elastica\Connection;
6
use Elastica\Exception\Connection\GuzzleException;
7
use Elastica\Exception\PartialShardFailureException;
8
use Elastica\Exception\ResponseException;
9
use Elastica\JSON;
10
use Elastica\Request;
11
use Elastica\Response;
12
use Elastica\Util;
13
use GuzzleHttp\Client;
14
use GuzzleHttp\Exception\TransferException;
15
use GuzzleHttp\Psr7;
16
use GuzzleHttp\Psr7\Uri;
17
18
/**
19
 * Elastica Guzzle Transport object.
20
 *
21
 * @author Milan Magudia <[email protected]>
22
 */
23
class Guzzle extends AbstractTransport
24
{
25
    /**
26
     * Http scheme.
27
     *
28
     * @var string Http scheme
29
     */
30
    protected $_scheme = 'http';
31
32
    /**
33
     * Curl resource to reuse.
34
     *
35
     * @var Client Guzzle client to reuse
36
     */
37
    protected static $_guzzleClientConnection;
38
39
    /**
40
     * Makes calls to the elasticsearch server.
41
     *
42
     * All calls that are made to the server are done through this function
43
     *
44
     * @param array $params Host, Port, ...
45
     *
46
     * @throws \Elastica\Exception\ConnectionException
47
     * @throws \Elastica\Exception\ResponseException
48
     * @throws \Elastica\Exception\Connection\HttpException
49
     *
50
     * @return \Elastica\Response Response object
51
     */
52
    public function exec(Request $request, array $params): Response
53
    {
54
        $connection = $this->getConnection();
55
56
        $client = $this->_getGuzzleClient($connection->isPersistent());
57
58
        $options = [
59
            'base_uri' => $this->_getBaseUrl($connection),
60
            'headers' => [
61
                'Content-Type' => $request->getContentType(),
62
            ],
63
            'exceptions' => false, // 4xx and 5xx is expected and NOT an exceptions in this context
64
        ];
65
        if ($connection->getTimeout()) {
66
            $options['timeout'] = $connection->getTimeout();
67
        }
68
69
        if (null !== $proxy = $connection->getProxy()) {
70
            $options['proxy'] = $proxy;
71
        }
72
73
        $req = $this->_createPsr7Request($request, $connection);
74
75
        try {
76
            $start = \microtime(true);
77
            $res = $client->send($req, $options);
78
            $end = \microtime(true);
79
        } catch (TransferException $ex) {
80
            throw new GuzzleException($ex, $request, new Response($ex->getMessage()));
81
        }
82
83
        $responseBody = (string) $res->getBody();
84
        $response = new Response($responseBody, $res->getStatusCode());
85
        $response->setQueryTime($end - $start);
86
        if ($connection->hasConfig('bigintConversion')) {
87
            $response->setJsonBigintConversion($connection->getConfig('bigintConversion'));
0 ignored issues
show
Documentation introduced by
$connection->getConfig('bigintConversion') is of type array|string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
88
        }
89
90
        $response->setTransferInfo(
91
            [
92
                'request_header' => $request->getMethod(),
93
                'http_code' => $res->getStatusCode(),
94
            ]
95
        );
96
97
        if ($response->hasError()) {
98
            throw new ResponseException($request, $response);
99
        }
100
101
        if ($response->hasFailedShards()) {
102
            throw new PartialShardFailureException($request, $response);
103
        }
104
105
        return $response;
106
    }
107
108
    /**
109
     * @return Psr7\Request
110
     */
111
    protected function _createPsr7Request(Request $request, Connection $connection)
112
    {
113
        $req = new Psr7\Request(
114
            $request->getMethod(),
115
            $this->_getActionPath($request),
116
            $connection->hasConfig('headers') && \is_array($connection->getConfig('headers'))
117
                ? $connection->getConfig('headers')
118
                : []
119
        );
120
121
        $data = $request->getData();
122
        if (!empty($data) || '0' === $data) {
123
            if (Request::GET == $req->getMethod()) {
124
                $req = $req->withMethod(Request::POST);
125
            }
126
127
            if ($this->hasParam('postWithRequestBody') && true == $this->getParam('postWithRequestBody')) {
128
                $request->setMethod(Request::POST);
129
                $req = $req->withMethod(Request::POST);
130
            }
131
132
            $req = $req->withBody(
133
                Psr7\stream_for(
0 ignored issues
show
Deprecated Code introduced by
The function GuzzleHttp\Psr7\stream_for() has been deprecated with message: stream_for will be removed in guzzlehttp/psr7:2.0. Use Utils::streamFor instead.

This function has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.

Loading history...
134
                    \is_array($data)
135
                    ? JSON::stringify($data, JSON_UNESCAPED_UNICODE)
136
                    : $data
137
                )
138
            );
139
        }
140
141
        return $req;
142
    }
143
144
    /**
145
     * Return Guzzle resource.
146
     *
147
     * @param bool $persistent False if not persistent connection
148
     */
149
    protected function _getGuzzleClient(bool $persistent = true): Client
150
    {
151
        if (!$persistent || !self::$_guzzleClientConnection) {
152
            self::$_guzzleClientConnection = new Client();
153
        }
154
155
        return self::$_guzzleClientConnection;
156
    }
157
158
    /**
159
     * Builds the base url for the guzzle connection.
160
     */
161
    protected function _getBaseUrl(Connection $connection): string
162
    {
163
        // If url is set, url is taken. Otherwise port, host and path
164
        $url = $connection->hasConfig('url') ? $connection->getConfig('url') : '';
165
166
        if (!empty($url)) {
167
            $baseUri = $url;
168
        } else {
169
            $baseUri = (string) Uri::fromParts([
170
                'scheme' => $this->_scheme,
171
                'host' => $connection->getHost(),
172
                'port' => $connection->getPort(),
173
                'path' => \ltrim('/', $connection->getPath()),
174
            ]);
175
        }
176
177
        return \rtrim($baseUri, '/');
178
    }
179
180
    /**
181
     * Builds the action path url for each request.
182
     */
183
    protected function _getActionPath(Request $request): string
184
    {
185
        $action = $request->getPath();
186
        if ($action) {
187
            $action = '/'.\ltrim($action, '/');
188
        }
189
190
        if (!Util::isDateMathEscaped($action)) {
191
            $action = Util::escapeDateMath($action);
192
        }
193
194
        $query = $request->getQuery();
195
196
        if (!empty($query)) {
197
            $action .= '?'.\http_build_query(
198
                $this->sanityzeQueryStringBool($query)
199
            );
200
        }
201
202
        return $action;
203
    }
204
}
205