Completed
Push — master ( bf8f52...4b18ce )
by Anton
11s
created

src/Yandex/Metrica/MetricaClient.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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\Metrica;
13
14
use GuzzleHttp\ClientInterface;
15
use Yandex\Common\AbstractServiceClient;
16
use GuzzleHttp\Psr7\Response;
17
use GuzzleHttp\Exception\ClientException;
18
use Yandex\Common\Exception\ForbiddenException;
19
use Yandex\Common\Exception\UnauthorizedException;
20
use Yandex\Common\Exception\TooManyRequestsException;
21
use Yandex\Metrica\Exception\BadRequestException;
22
use Yandex\Metrica\Exception\MetricaException;
23
24
/**
25
 * Class MetricaClient
26
 *
27
 * @category Yandex
28
 * @package Metrica
29
 *
30
 * @author   Alexander Khaylo <[email protected]>
31
 * @created  12.02.14 15:46
32
 */
33
class MetricaClient extends AbstractServiceClient
34
{
35
    /**
36
     * API domain
37
     *
38
     * @var string
39
     */
40
    protected $serviceDomain = 'api-metrika.yandex.ru/management/v1';
41
42
    /**
43
     * @param string $token access token
44
     * @param ClientInterface $client
45
     */
46 58
    public function __construct($token = '', ClientInterface $client = null)
47
    {
48 58
        $this->setAccessToken($token);
49 58
        if (!is_null($client)) {
50 1
            $this->setClient($client);
51
        }
52 58
    }
53
54
    /**
55
     * Get url to service resource with parameters
56
     *
57
     * @param string $resource
58
     * @param array $params
59
     * @see http://api.yandex.ru/metrika/doc/ref/concepts/method-call.xml
60
     * @return string
61
     */
62 29
    public function getServiceUrl($resource = '', $params = [])
63
    {
64 29
        $format = $resource === '' ? '' : '.json';
65 29
        $url = $this->serviceScheme . '://' . $this->serviceDomain . '/'
66 29
            . $resource . $format;
67
68 29
        if ($params) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $params of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
69 2
            $url .= '?' . http_build_query($params);
70
        }
71
72 29
        return $url;
73
    }
74
75
    /**
76
     * Sends a request
77
     *
78
     * @param string              $method  HTTP method
79
     * @param string $uri     URI object or string.
80
     * @param array               $options Request options to apply.
81
     *
82
     * @return Response
83
     *
84
     * @throws BadRequestException
85
     * @throws ForbiddenException
86
     * @throws MetricaException
87
     * @throws TooManyRequestsException
88
     * @throws UnauthorizedException
89
     */
90 27
    protected function sendRequest($method, $uri, array $options = [])
91
    {
92
        try {
93 27
            $response = $this->getClient()->request($method, $uri, $options);
94 5
        } catch (ClientException $ex) {
95 5
            $result = $ex->getResponse();
96 5
            $code = $result->getStatusCode();
97 5
            $message = $result->getReasonPhrase();
98
99 5
            $body = $result->getBody();
100 5
            if ($body) {
101 5
                $jsonBody = json_decode($body);
102 5
                if ($jsonBody && isset($jsonBody->message)) {
103 1
                    $message = $jsonBody->message;
104
                }
105
            }
106
107 5
            if ($code === 400) {
108 1
                throw new BadRequestException($message);
109
            }
110
111 4
            if ($code === 403) {
112 1
                throw new ForbiddenException($message);
113
            }
114
115 3
            if ($code === 401) {
116 1
                throw new UnauthorizedException($message);
117
            }
118
119 2
            if ($code === 429) {
120 1
                throw new TooManyRequestsException($message);
121
            }
122
123 1
            throw new MetricaException(
124 1
                'Service responded with error code: "' . $code . '" and message: "' . $message . '"',
125 1
                $code
126
            );
127
        }
128
129 22
        return $response;
130
    }
131
132
    /**
133
     * Send GET request to API resource
134
     *
135
     * @param string $resource
136
     * @param array $params
137
     * @return array
138
     */
139 6
    protected function sendGetRequest($resource, $params = [])
140
    {
141 6
        $response = $this->sendRequest(
142 6
            'GET',
143 6
            $this->getServiceUrl($resource, $params),
144
            [
145 6
                'headers' => [
146
                    'Accept' => 'application/x-yametrika+json',
147
                    'Content-Type' => 'application/x-yametrika+json',
148
                    'Authorization' => 'OAuth ' . $this->getAccessToken(),
149
                ]
150
            ]
151
        );
152 1
153
        $decodedResponseBody = $this->getDecodedBody($response->getBody());
154 1
155 View Code Duplication
        if (isset($decodedResponseBody['links']) && isset($decodedResponseBody['links']['next'])) {
156
            $url = $decodedResponseBody['links']['next'];
157
            unset($decodedResponseBody['rows']);
158
            unset($decodedResponseBody['links']);
159
            return $this->getNextPartOfList($url, $decodedResponseBody);
160 1
        }
161
        return $decodedResponseBody;
162
    }
163
164
    /**
165
     * Send custom GET request to API resource
166
     *
167
     * @param string $url
168
     * @param array $data
169
     * @return array
170
     */
171
    protected function getNextPartOfList($url, $data = [])
172
    {
173
        $response = $this->sendRequest(
174
            'GET',
175
            $url,
176
            [
177
                'headers' => [
178
                    'Accept' => 'application/x-yametrika+json',
179
                    'Content-Type' => 'application/x-yametrika+json',
180
                    'Authorization' => 'OAuth ' . $this->getAccessToken(),
181
                ]
182
            ]
183
        );
184
185
        $decodedResponseBody = $this->getDecodedBody($response->getBody());
186
187
        $mergedDecodedResponseBody = array_merge_recursive($data, $decodedResponseBody);
188
189 View Code Duplication
        if (isset($mergedDecodedResponseBody['links']) && isset($mergedDecodedResponseBody['links']['next'])) {
190
            $url = $mergedDecodedResponseBody['links'];
191
            unset($mergedDecodedResponseBody['rows']);
192
            unset($mergedDecodedResponseBody['links']);
193
            return $this->getNextPartOfList($url, $response);
194
        }
195
196
        return $mergedDecodedResponseBody;
197
    }
198
199
    /**
200
     * Send POST request to API resource
201
     *
202
     * @param string $resource
203
     * @param array $params
204 7
     * @return array
205
     */
206 7 View Code Duplication
    protected function sendPostRequest($resource, $params)
207 7
    {
208 7
        $response = $this->sendRequest(
209
            'POST',
210 7
            $this->getServiceUrl($resource),
211
            [
212
                'headers' => [
213
                    'Accept' => 'application/x-yametrika+json',
214 7
                    'Content-Type' => 'application/x-yametrika+json',
215
                    'Authorization' => 'OAuth ' . $this->getAccessToken(),
216
                ],
217
                'json' => $params
218 7
            ]
219
        );
220
221
        return $this->getDecodedBody($response->getBody());
222
    }
223
224
    /**
225
     * Send PUT request to API resource
226
     *
227
     * @param string $resource
228 7
     * @param array $params
229
     * @return array
230 7
     */
231 7 View Code Duplication
    protected function sendPutRequest($resource, $params)
232 7
    {
233
        $response = $this->sendRequest(
234 7
            'PUT',
235
            $this->getServiceUrl($resource),
236
            [
237
                'headers' => [
238 7
                    'Accept' => 'application/x-yametrika+json',
239
                    'Content-Type' => 'application/x-yametrika+json',
240
                    'Authorization' => 'OAuth ' . $this->getAccessToken(),
241
                ],
242 7
                'json' => $params
243
            ]
244
        );
245
246
        return $this->getDecodedBody($response->getBody());
247
    }
248
249
    /**
250
     * Send DELETE request to API resource
251 7
     *
252
     * @param string $resource
253 7
     * @return array
254 7
     */
255 7
    protected function sendDeleteRequest($resource)
256
    {
257 7
        $response = $this->sendRequest(
258
            'DELETE',
259
            $this->getServiceUrl($resource),
260
            [
261
                'headers' => [
262
                    'Accept' => 'application/x-yametrika+json',
263
                    'Content-Type' => 'application/x-yametrika+json',
264 7
                    'Authorization' => 'OAuth ' . $this->getAccessToken(),
265
                ]
266
            ]
267
        );
268
269
        return $this->getDecodedBody($response->getBody());
270
    }
271
}
272