Passed
Pull Request — master (#12)
by
unknown
06:31
created

Client::doRequest()   A

Complexity

Conditions 5
Paths 12

Size

Total Lines 28
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 5.7283

Importance

Changes 3
Bugs 0 Features 1
Metric Value
cc 5
eloc 14
c 3
b 0
f 1
nc 12
nop 4
dl 0
loc 28
ccs 9
cts 13
cp 0.6923
crap 5.7283
rs 9.4888
1
<?php
2
3
namespace UON;
4
5
use GuzzleHttp\Exception\GuzzleException;
6
use UON\Interfaces\ConfigInterface;
7
use UON\Interfaces\ClientInterface;
8
9
/**
10
 * @author  Paul Rock <[email protected]>
11
 * @link    http://drteam.rocks
12
 * @license MIT
13
 * @package UON
14
 */
15
class Client implements ClientInterface
16
{
17
    /**
18
     * Initial state of some variables
19
     */
20
    protected $_client;
21
    protected $_config;
22
23
    /**
24
     * Default server parameters
25
     */
26
    protected $host   = 'api.u-on.ru';
27
    protected $port   = '443';
28
    protected $path   = '/';
29
    protected $useSSL = true;
30
31
    /**
32
     * User initial values
33
     *
34
     * @var string
35
     */
36
    protected $token;
37
38
    /**
39
     * Default format of output
40
     *
41
     * @var string
42
     */
43
    protected $format = 'json';
44
45
    /**
46
     * Count of tries
47
     *
48
     * @var int
49
     */
50
    private $tries = self::TRIES;
51
52
    /**
53
     * Waiting time per each try
54
     *
55
     * @var int
56
     */
57
    private $seconds = self::SECONDS;
58
59
    /**
60
     * Client constructor.
61
     *
62
     * @param Config $config User defined configuration
63
     */
64 2
    public function __construct(Config $config)
65
    {
66
        // Extract toke from config
67 2
        $this->token = $config->get('token');
0 ignored issues
show
Documentation Bug introduced by
It seems like $config->get('token') can also be of type boolean. However, the property $token is declared as type string. 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...
68
69
        // Count of tries
70 2
        if ($config->get('tries') !== false) {
71
            $this->tries = $config->get('tries');
0 ignored issues
show
Documentation Bug introduced by
It seems like $config->get('tries') can also be of type boolean or string. However, the property $tries is declared as type integer. 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...
72
        }
73
74
        // Waiting time
75 2
        if ($config->get('seconds') !== false) {
76
            $this->tries = $config->get('seconds');
77
        }
78
79
        // Save config into local variable
80 2
        $this->_config = $config;
81
82
        // Store the client object
83 2
        $this->_client = new \GuzzleHttp\Client($config->getParameters(true));
84 2
    }
85
86
    /**
87
     * Request executor with timeout and repeat tries
88
     *
89
     * @param   string $type   Request method
90
     * @param   string $url    endpoint url
91
     * @param   array  $params List of parameters
92
     * @return  bool|\Psr\Http\Message\ResponseInterface
93
     * @throws  \GuzzleHttp\Exception\GuzzleException
94
     */
95 61
    public function repeatRequest($type, $url, $params)
96
    {
97 61
        for ($i = 1; $i < $this->tries; $i++) {
98
99
            // Execute the request to server
100 61
            $result = \in_array($type, self::ALLOWED_METHODS, false)
101 61
                ? $this->_client->request($type, $url, ['form_params' => $params])
102 61
                : null;
103
104
            // Check the code status
105 61
            $code = $result->getStatusCode();
0 ignored issues
show
Bug introduced by
The method getStatusCode() does not exist on null. ( Ignorable by Annotation )

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

105
            /** @scrutinizer ignore-call */ 
106
            $code = $result->getStatusCode();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
106
107
            // If code is not 405 (but 200 foe example) then exit from loop
108 61
            if ($code === 200 || $code === 500) {
109 60
                return $result;
110
            }
111
112
            // Waiting in seconds
113 1
            sleep($this->seconds);
114
        }
115
116
        // Return false if loop is done but no answer from server
117 1
        return false;
118
    }
119
120
    /**
121
     * Make the request and analyze the result
122
     *
123
     * @param   string $type     Request method
124
     * @param   string $endpoint Api request endpoint
125
     * @param   array  $params   List of parameters
126
     * @param   bool   $raw      Return data in raw format
127
     * @return  mixed|false Array with data or error, or False when something went fully wrong
128
     */
129 61
    public function doRequest($type, $endpoint, array $params = [], $raw = false)
130
    {
131
        // Create the base URL
132 61
        $base = $this->useSSL ? 'https' : 'http';
133
134
        // Generate the URL for request
135 61
        $url = $base . '://' . $this->host . ':' . $this->port . $this->path . $this->token . $endpoint . '.' . $this->format;
136
137
        try {
138
            // Execute the request to server
139 61
            $result = $this->repeatRequest($type, $url, $params);
140
141
            // Return result
142
            return
143 61
                ($result === false)
144 1
                    ? false
145
                    : [
146 60
                    'code'    => $result->getStatusCode(),
147 60
                    'reason'  => $result->getReasonPhrase(),
148 61
                    'message' => $raw ? (string) $result->getBody() : json_decode($result->getBody())
149
                ];
150
151
        } catch (GuzzleException $e) {
152
            echo $e->getMessage() . "\n";
153
            echo $e->getTrace();
154
        }
155
156
        return false;
157
    }
158
159
}
160