Completed
Pull Request — master (#139)
by
unknown
10:24
created

ContentClient::sendRequest()   C

Complexity

Conditions 8
Paths 10

Size

Total Lines 35
Code Lines 21

Duplication

Lines 35
Ratio 100 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
dl 35
loc 35
rs 5.3846
cc 8
eloc 21
nc 10
nop 3
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
/**
27
 * Class ContentClient
28
 *
29
 * @category Yandex
30
 * @package MarketContent
31
 *
32
 * @author   Oleg Scherbakov <[email protected]>
33
 * @created  27.12.15 19:50
34
 */
35
class ContentClient extends AbstractServiceClient
36
{
37
    /**
38
     * Requested version of API
39
     *
40
     * @var string
41
     */
42
    private $version = 'v1';
43
44
    /**
45
     * API domain
46
     *
47
     * @var string
48
     */
49
    protected $serviceDomain = 'api.content.market.yandex.ru';
50
51
    /**
52
     * Store limits information during each API request
53
     *
54
     * @var array
55
     */
56
    private $limits = array();
57
58
    /**
59
     * Get url to service resource with parameters
60
     *
61
     * @param string $resource
62
     * @see http://api.yandex.ru/market/partner/doc/dg/concepts/method-call.xml
63
     * @return string
64
     */
65
    public function getServiceUrl($resource = '')
66
    {
67
        return $this->serviceScheme . '://' . $this->serviceDomain . '/'
68
        . $this->version . '/' . $resource;
69
    }
70
71
    /**
72
     * @param string $token access token
73
     */
74
    public function __construct($token = '')
75
    {
76
        $this->setAccessToken($token);
77
    }
78
79
    /**
80
     * @return ClientInterface
81
     */
82 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...
83
    {
84
        if (is_null($this->client)) {
85
            $defaultOptions = [
86
                'base_uri' => $this->getServiceUrl(),
87
                'headers' => [
88
                    'Host' => $this->getServiceDomain(),
89
                    'Accept' => '*/*',
90
                    'Authorization' => $this->getAccessToken(),
91
                ]
92
            ];
93
            if ($this->getProxy()) {
94
                $defaultOptions['proxy'] = $this->getProxy();
95
            }
96
            if ($this->getDebug()) {
97
                $defaultOptions['debug'] = $this->getDebug();
98
            }
99
            $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...
100
        }
101
102
        return $this->client;
103
    }
104
105
    /**
106
     * Sends a request
107
     *
108
     * @param string              $method  HTTP method
109
     * @param string|UriInterface $uri     URI object or string.
110
     * @param array               $options Request options to apply.
111
     *
112
     * @return Response
113
     *
114
     * @throws ForbiddenException
115
     * @throws UnauthorizedException
116
     * @throws ContentRequestException
117
     */
118 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...
119
    {
120
        try {
121
            $response = $this->getClient()->request($method, $uri, $options);
122
        } catch (ClientException $ex) {
123
            $result = $ex->getResponse();
124
            $code = $result->getStatusCode();
125
            $message = $result->getReasonPhrase();
126
127
            $body = $result->getBody();
128
            if ($body) {
129
                $jsonBody = json_decode($body);
130
                if ($jsonBody && isset($jsonBody->error) && isset($jsonBody->error->message)) {
131
                    $message = $jsonBody->error->message;
132
                }
133
            }
134
135
            if ($code === 403) {
136
                throw new ForbiddenException($message);
137
            }
138
139
            if ($code === 401) {
140
                throw new UnauthorizedException($message);
141
            }
142
143
            throw new ContentRequestException(
144
                'Service responded with error code: "' . $code . '" and message: "' . $message . '"',
145
                $code
146
            );
147
        }
148
        // @note: Finally? php >= 5.5
149
        $this->setLimits($response->getHeaders());
150
151
        return $response;
152
    }
153
154
    private function setLimits($headers)
155
    {
156
        // const as header name?
157
        $limitHeaders = [
158
            'X-RateLimit-Daily-Limit',
159
            'X-RateLimit-Daily-Remaining',
160
            'X-RateLimit-Global-Limit',
161
            'X-RateLimit-Global-Remaining',
162
            'X-RateLimit-Method-Limit',
163
            'X-RateLimit-Method-Remaining',
164
            'X-RateLimit-Until'
165
        ];
166
167
        $this->limits = array();
168
169
        foreach($headers as $header) {
170
            if (in_array($header->getName(), $limitHeaders, true))
171
                $this->limits[$header->getName()] = (int) $header->__toString();
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
        return false;
197
    }
198
199
    /**
200
     * Returns API service response.
201
     *
202
     * @param string $resource
203
     * @return array
204
     * @throws ContentRequestException
205
     * @throws ForbiddenException
206
     * @throws UnauthorizedException
207
     */
208
    protected function getServiceResponse($resource)
209
    {
210
        $response = $this->sendRequest('GET', $this->getServiceUrl($resource));
211
        $decodedResponseBody = $this->getDecodedBody($response->getBody());
212
213
        return $decodedResponseBody;
214
    }
215
216
    /**
217
     * Returns URL-encoded query string
218
     *
219
     * @note: similar to http_build_query(),
220
     * but transform key=>value where key == value to "?key" param.
221
     *
222
     * @param array|object $queryData
223
     * @param string $numericPrefix
224
     * @param string $argSeparator
225
     * @param int $encType
226
     *
227
     * @return string $queryString
228
     */
229
    protected function buildQueryString($queryData, $numericPrefix = '', $argSeparator = '&', $encType = PHP_QUERY_RFC3986)
230
    {
231
        foreach($queryData as $k=>&$v)
232
            if (!is_scalar($v))
233
                $v = implode(',', $v);
234
235
        $queryString = http_build_query($queryData, $numericPrefix, $argSeparator, $encType);
236
237
        foreach($queryData as $k=>$v)
238
            if ($k==$v)
239
                $queryString = str_replace("$k=$v", $v, $queryString);
240
241
        return $queryString;
242
    }
243
}