Completed
Push — 1.x ( 747b4c...b6bf38 )
by Adrian
04:52 queued 11s
created

Http::execute()   D

Complexity

Conditions 12
Paths 288

Size

Total Lines 100
Code Lines 72

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 12
eloc 72
c 3
b 0
f 0
nc 288
nop 2
dl 0
loc 100
rs 4.6375

How to fix   Long Method    Complexity   

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
namespace Manticoresearch\Transport;
3
4
use Manticoresearch\Exceptions\ConnectionException;
5
use Manticoresearch\Exceptions\ResponseException;
6
use Manticoresearch\Request;
7
use Manticoresearch\Response;
8
9
/**
10
 * Class Http
11
 * @package Manticoresearch\Transport
12
 */
13
class Http extends \Manticoresearch\Transport implements TransportInterface
14
{
15
16
    /**
17
     * @var string
18
     */
19
    protected $scheme = 'http';
20
21
    /**
22
     * @var resource
23
     */
24
    protected static $curl;
25
26
    /**
27
     * @param Request $request
28
     * @param array $params
29
     * @return Response
30
     */
31
    public function execute(Request $request, $params = [])
32
    {
33
        $connection = $this->getConnection();
34
        $conn = $this->getCurlConnection($connection->getConfig('persistent'));
0 ignored issues
show
Bug introduced by
It seems like $connection->getConfig('persistent') can also be of type null; however, parameter $persistent of Manticoresearch\Transpor...tp::getCurlConnection() does only seem to accept boolean, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

34
        $conn = $this->getCurlConnection(/** @scrutinizer ignore-type */ $connection->getConfig('persistent'));
Loading history...
35
        $url = $this->scheme.'://'.$connection->getHost().':'.$connection->getPort();
36
        $endpoint = $request->getPath();
37
        $url .= $endpoint;
38
        $url = $this->setupURI($url, $request->getQuery());
0 ignored issues
show
Bug introduced by
$request->getQuery() of type string is incompatible with the type array expected by parameter $query of Manticoresearch\Transport::setupURI(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

38
        $url = $this->setupURI($url, /** @scrutinizer ignore-type */ $request->getQuery());
Loading history...
39
40
        curl_setopt($conn, CURLOPT_URL, $url);
41
        curl_setopt($conn, CURLOPT_TIMEOUT, $connection->getTimeout());
42
        curl_setopt($conn, CURLOPT_ENCODING, '');
43
        curl_setopt($conn, CURLOPT_FORBID_REUSE, 0);
44
        $data = $request->getBody();
45
        $method = $request->getMethod();
46
        $headers = $connection->getHeaders();
47
        $headers[] = sprintf('Content-Type: %s', $request->getContentType());
48
        if (!empty($data)) {
49
            if (is_array($data)) {
50
                $content = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
51
            } else {
52
                $content = $data;
53
            }
54
            curl_setopt($conn, CURLOPT_POSTFIELDS, $content);
55
        } else {
56
            curl_setopt($conn, CURLOPT_POSTFIELDS, '');
57
        }
58
        curl_setopt($conn, CURLOPT_CUSTOMREQUEST, $method);
59
        curl_setopt($conn, CURLOPT_HTTPHEADER, $headers);
60
61
        if ($connection->getConnectTimeout()>0) {
62
            curl_setopt($conn, CURLOPT_CONNECTTIMEOUT, $connection->getConnectTimeout());
63
        }
64
65
        if ($connection->getConfig('username') !== null && $connection->getConfig('password') !== null) {
66
            curl_setopt($conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
67
            curl_setopt(
68
                $conn,
69
                CURLOPT_USERPWD,
70
                $connection->getConfig('username').":".$connection->getConfig('password')
71
            );
72
        }
73
        if ($connection->getConfig('proxy') !== null) {
74
            curl_setopt($conn, CURLOPT_PROXY, $connection->getConfig('proxy'));
75
        }
76
        if (!empty($connection->getConfig('curl'))) {
77
            foreach ($connection->getConfig('curl') as $k => $v) {
78
                curl_setopt($conn, $k, $v);
79
            }
80
        }
81
        $start = microtime(true);
82
        ob_start();
83
        curl_exec($conn);
84
        $responseString = \ob_get_clean();
85
        $end = microtime(true);
86
        $errorno = curl_errno($conn);
87
        $status = curl_getinfo($conn, CURLINFO_HTTP_CODE);
88
        if (isset($params['responseClass'])) {
89
            $responseClass = $params['responseClass'];
90
            $response = new $responseClass($responseString, $status);
91
        } else {
92
            $response = new Response($responseString, $status);
93
        }
94
95
        $time = $end-$start;
96
        $response->setTime($time);
97
        $response->setTransportInfo([
98
                'url' => $url,
99
                'headers' => $headers,
100
                'body' => $request->getBody()
101
            ]);
102
        //hard error
103
        if ($errorno>0) {
104
            $error = curl_error($conn);
105
106
            /* @phpstan-ignore-next-line */
107
            self::$curl = false;
0 ignored issues
show
Documentation Bug introduced by
It seems like false of type false is incompatible with the declared type resource of property $curl.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
108
            throw new ConnectionException($error, $request);
109
        }
110
111
112
        $this->logger->debug('Request body:', [
113
                'connection' => $connection->getConfig(),
114
                'payload'=> $request->getBody()
115
            ]);
116
        $this->logger->info(
117
            'Request:',
118
            [
119
                    'url' => $url,
120
                    'status' => $status,
121
                    'time' => $time
122
                ]
123
        );
124
        $this->logger->debug('Response body:', [json_decode($responseString, true)]);
125
        //soft error
126
        if ($response->hasError()) {
127
            $this->logger->error('Response error:', [$response->getError()]);
128
            throw new ResponseException($request, $response);
129
        }
130
        return $response;
131
    }
132
133
    /**
134
     * @param bool $persistent
135
     * @return false|resource
136
     */
137
    protected function getCurlConnection(bool $persistent = true)
138
    {
139
        if (!$persistent || !self::$curl) {
140
            self::$curl = curl_init();
0 ignored issues
show
Documentation Bug introduced by
It seems like curl_init() can also be of type false. However, the property $curl is declared as type resource. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
141
        }
142
        return self::$curl;
143
    }
144
}
145