Completed
Pull Request — master (#139)
by
unknown
04:18
created

ContentClient::setLimits()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 22
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 3
Bugs 1 Features 1
Metric Value
c 3
b 1
f 1
dl 0
loc 22
ccs 0
cts 15
cp 0
rs 9.2
cc 3
eloc 13
nc 3
nop 1
crap 12
1
<?php
2
/**
3
 * Yandex PHP Library
4
 *
5
 * @copyright NIX Solutions Ltd.
6
 * @link      https://github.com/nixsolutions/yandex-php-library
7
 */
8
9
/**
10
 * @namespace
11
 */
12
namespace Yandex\Market\Content;
13
14
use GuzzleHttp\Client;
15
use GuzzleHttp\ClientInterface;
16
use Psr\Http\Message\UriInterface;
17
use Yandex\Common\AbstractServiceClient;
18
use GuzzleHttp\Psr7\Response;
19
use GuzzleHttp\Exception\ClientException;
20
use Yandex\Common\Exception\ForbiddenException;
21
use Yandex\Common\Exception\UnauthorizedException;
22
use Yandex\Market\Content\Exception\ContentRequestException;
23
use Yandex\Market\Content\Models;
24
25
/**
26
 * Class ContentClient
27
 *
28
 * @category Yandex
29
 * @package  MarketContent
30
 *
31
 * @author  Oleg Scherbakov <[email protected]>
32
 * @created 27.12.15 19:50
33
 */
34
class ContentClient extends AbstractServiceClient
35
{
36
    /**
37
     * Requested version of API
38
     *
39
     * @var string
40
     */
41
    private $version = 'v1';
42
43
    /**
44
     * API domain
45
     *
46
     * @var string
47
     */
48
    protected $serviceDomain = 'api.content.market.yandex.ru';
49
50
    /**
51
     * Store limits information during each API request
52
     *
53
     * @var array
54
     */
55
    private $limits = array();
56
57
    /**
58
     * Get url to service resource with parameters
59
     *
60
     * @param  string $resource
61
     * @see    http://api.yandex.ru/market/partner/doc/dg/concepts/method-call.xml
62
     * @return string
63
     */
64 29
    public function getServiceUrl($resource = '')
65
    {
66 29
        return $this->serviceScheme . '://' . $this->serviceDomain . '/'
67 29
        . $this->version . '/' . $resource;
68
    }
69
70
    /**
71
     * @param string $token access token
72
     */
73 29
    public function __construct($token = '')
74
    {
75 29
        $this->setAccessToken($token);
76 29
    }
77
78
    /**
79
     * @return ClientInterface
80
     */
81 View Code Duplication
    protected function getClient()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
82
    {
83
        if (is_null($this->client)) {
84
            $defaultOptions = [
85
                'base_uri' => $this->getServiceUrl(),
86
                'headers' => [
87
                    'Host' => $this->getServiceDomain(),
88
                    'Accept' => '*/*',
89
                    'Authorization' => $this->getAccessToken(),
90
                ]
91
            ];
92
            if ($this->getProxy()) {
93
                $defaultOptions['proxy'] = $this->getProxy();
94
            }
95
            if ($this->getDebug()) {
96
                $defaultOptions['debug'] = $this->getDebug();
97
            }
98
            $this->client = new Client($defaultOptions);
0 ignored issues
show
Documentation Bug introduced by
It seems like new \GuzzleHttp\Client($defaultOptions) of type object<GuzzleHttp\Client> is incompatible with the declared type null of property $client.

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...
99
        }
100
101
        return $this->client;
102
    }
103
104
    /**
105
     * Sends a request
106
     *
107
     * @param string              $method  HTTP method
108
     * @param string|UriInterface $uri     URI object or string.
109
     * @param array               $options Request options to apply.
110
     *
111
     * @return Response
112
     *
113
     * @throws ForbiddenException
114
     * @throws UnauthorizedException
115
     * @throws ContentRequestException
116
     */
117 View Code Duplication
    protected function sendRequest($method, $uri, array $options = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
118
    {
119
        try {
120
            $response = $this->getClient()->request($method, $uri, $options);
121
        } catch (ClientException $ex) {
122
            $result = $ex->getResponse();
123
            $code = $result->getStatusCode();
124
            $message = $result->getReasonPhrase();
125
126
            $body = $result->getBody();
127
            if ($body) {
128
                $jsonBody = json_decode($body);
129
                if ($jsonBody && isset($jsonBody->error) && isset($jsonBody->error->message)) {
130
                    $message = $jsonBody->error->message;
131
                }
132
            }
133
134
            if ($code === 403) {
135
                throw new ForbiddenException($message);
136
            }
137
138
            if ($code === 401) {
139
                throw new UnauthorizedException($message);
140
            }
141
142
            throw new ContentRequestException(
143
                'Service responded with error code: "' . $code . '" and message: "' . $message . '"',
144
                $code
145
            );
146
        }
147
        // @note: Finally? php >= 5.5
148
        $this->setLimits($response->getHeaders());
149
150
        return $response;
151
    }
152
153
    private function setLimits($headers)
154
    {
155
        // const as header name?
156
        $limitHeaders = [
157
            'X-RateLimit-Daily-Limit',
158
            'X-RateLimit-Daily-Remaining',
159
            'X-RateLimit-Global-Limit',
160
            'X-RateLimit-Global-Remaining',
161
            'X-RateLimit-Method-Limit',
162
            'X-RateLimit-Method-Remaining',
163
            'X-RateLimit-Until'
164
        ];
165
166
        $this->limits = array();
167
168
        foreach ($headers as $header) {
169
            if (in_array($header->getName(), $limitHeaders, true)) {
170
                $this->limits[$header->getName()] = (int) $header->__toString();
171
            }
172
173
        }
174
    }
175
176
    /**
177
     * Get information about API limits
178
     *
179
     * @return array|false
180
     */
181
    public function getLimits()
182
    {
183
        return $this->limits;
184
    }
185
186
    /**
187
     * Get information about specified API limit
188
     *
189
     * @return array|false
190
     */
191
    public function getLimit($name)
192
    {
193
        if (isset($this->limits[$name])) {
194
            return $this->limits[$name];
195
        }
196
197
        return false;
198
    }
199
200
    /**
201
     * Returns API service response.
202
     *
203
     * @param  string $resource
204
     * @return array
205
     * @throws ContentRequestException
206
     * @throws ForbiddenException
207
     * @throws UnauthorizedException
208
     */
209 29
    protected function getServiceResponse($resource)
210
    {
211 29
        $response = $this->sendRequest('GET', $this->getServiceUrl($resource));
212 29
        $decodedResponseBody = $this->getDecodedBody($response->getBody());
213
214 29
        return $decodedResponseBody;
215
    }
216
217
    /**
218
     * Returns URL-encoded query string
219
     *
220
     * @note: similar to http_build_query(),
221
     * but transform key=>value where key == value to "?key" param.
222
     *
223
     * @param array|object $queryData
224
     * @param string       $prefix
225
     * @param string       $argSeparator
226
     * @param int          $encType
227
     *
228
     * @return string $queryString
229
     */
230 25
    protected function buildQueryString($queryData, $prefix = '', $argSeparator = '&', $encType = PHP_QUERY_RFC3986)
231
    {
232 25
        foreach ($queryData as $k => &$v) {
233 22
            if (!is_scalar($v)) {
234
                $v = implode(',', $v);
235
            }
236 25
        }
237
238 25
        $queryString = http_build_query($queryData, $prefix, $argSeparator, $encType);
239
240 25
        foreach ($queryData as $k => $v) {
241 22
            if ($k==$v) {
242 1
                $queryString = str_replace("$k=$v", $v, $queryString);
243 1
            }
244 25
        }
245
246 25
        return $queryString;
247
    }
248
}
249