ApiClient::getUrl()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of the php-shop-logistics.ru-api package.
5
 *
6
 * (c) Gennady Knyazkin <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Gennadyx\ShopLogisticsRu;
13
14
use Gennadyx\ShopLogisticsRu\Api\ApiInterface;
15
use Gennadyx\ShopLogisticsRu\Api\Delivery;
16
use Gennadyx\ShopLogisticsRu\Api\Dictionary;
17
use Gennadyx\ShopLogisticsRu\Api\Partners;
18
use Gennadyx\ShopLogisticsRu\Api\Pickup;
19
use Gennadyx\ShopLogisticsRu\Api\PostDelivery;
20
use Gennadyx\ShopLogisticsRu\Api\ProductAct;
21
use Gennadyx\ShopLogisticsRu\Api\Products;
22
use Gennadyx\ShopLogisticsRu\Api\QaReports;
23
use Gennadyx\ShopLogisticsRu\Api\ReturnAct;
24
use Gennadyx\ShopLogisticsRu\Exception\InvalidArgumentException;
25
use Gennadyx\ShopLogisticsRu\Exception\RuntimeException;
26
use Http\Client\HttpClient;
27
use Http\Message\RequestFactory;
28
use Http\Message\StreamFactory;
29
use ReflectionClass;
30
31
/**
32
 * Api client for work with shop-logistics.ru api
33
 *
34
 *
35
 * @property Delivery     $delivery      Delivery api instance
36
 * @property Dictionary   $dictionary    Dictionary api instance
37
 * @property PostDelivery $postDelivery  MailDelivery api instance
38
 * @property Partners     $partners      Partners api instance
39
 * @property Pickup       $pickup        Pickup api instance
40
 * @property Products     $products      Products api instance
41
 * @property ProductAct   $productAct    Products api instance
42
 * @property QaReports    $qaReports     QaReports api instance
43
 * @property ReturnAct    $returnAct     ReturnAct api instance
44
 *
45
 * @author Gennady Knyazkin <[email protected]>
46
 */
47
class ApiClient
48
{
49
    /**
50
     * Api key for testing
51
     */
52
    const TEST_KEY = '577888574a3e4df01867cd5ccc9f18a5';
53
54
    /**
55
     * Urls for request
56
     */
57
    const URL = [
58
        Environment::TEST => 'https://test.client-shop-logistics.ru/index.php?route=deliveries/api',
59
        Environment::PROD => 'http://client-shop-logistics.ru/index.php?route=deliveries/api',
60
    ];
61
62
    /**
63
     * Available api
64
     */
65
    const API = [
66
        'delivery'      => Delivery::class,
67
        'dictionary'    => Dictionary::class,
68
        'post.delivery' => PostDelivery::class,
69
        'partners'      => Partners::class,
70
        'pickup'        => Pickup::class,
71
        'products'      => Products::class,
72
        'product.act'   => ProductAct::class,
73
        'qa.reports'    => QaReports::class,
74
        'return.act'    => ReturnAct::class,
75
    ];
76
77
    /**
78
     * @var RequestFactory
79
     */
80
    private $requestFactory;
81
82
    /**
83
     * @var StreamFactory
84
     */
85
    private $streamFactory;
86
87
    /**
88
     * @var string
89
     */
90
    private $key;
91
92
    /**
93
     * @var ApiInterface[]
94
     */
95
    private $instances;
96
97
    /**
98
     * @var string
99
     */
100
    private $url;
101
102
    /**
103
     * @var callable
104
     */
105
    private $encoder;
106
107
    /**
108
     * @var callable
109
     */
110
    private $decoder;
111
112
    /**
113
     * @var HttpClient
114
     */
115
    private $httpClient;
116
117
    /**
118
     * ApiClient constructor.
119
     *
120
     * @param RequestFactory $requestFactory    Instance of RequestFactory (psr-7)
121
     * @param StreamFactory  $streamFactory     Instance of StreamFactory (psr-7)
122
     * @param HttpClient     $httpClient        Http client instance
123
     * @param callable       $encoder           Callback for encoding array to xml (without cdata).
124
     *                                          Get array argument and return xml string.
125
     * @param callable       $decoder           Callback for decoding xml to array (without cdata).
126
     *                                          Get xml string argument and return array.
127
     * @param string         $key               Api key
128
     * @param Environment    $environment       Environment (Test or production)
129
     *
130
     * @throws InvalidArgumentException
131
     */
132 17
    public function __construct(
133
        RequestFactory $requestFactory,
134
        StreamFactory $streamFactory,
135
        HttpClient $httpClient,
136
        callable $encoder,
137
        callable $decoder,
138
        $key,
139
        Environment $environment
140
    ) {
141 17
        if (!is_string($key)) {
142 1
            throw new InvalidArgumentException(
143 1
                sprintf(
144 1
                    'Api key must be string, %s given',
145 1
                    is_object($key) ? get_class($key) : gettype($key)
146
                )
147
            );
148
        }
149
150 16
        $this->key            = $key;
151 16
        $this->url            = self::URL[$environment->getValue()];
152 16
        $this->requestFactory = $requestFactory;
153 16
        $this->streamFactory  = $streamFactory;
154 16
        $this->encoder        = $encoder;
155 16
        $this->decoder        = $decoder;
156 16
        $this->httpClient     = $httpClient;
157 16
    }
158
159
    /**
160
     * Get api key
161
     *
162
     * @return string
163
     */
164 9
    public function getKey()
165
    {
166 9
        return $this->key;
167
    }
168
169
    /**
170
     * Get uri
171
     *
172
     * @return string
173
     */
174 9
    public function getUrl()
175
    {
176 9
        return $this->url;
177
    }
178
179
    /**
180
     * Get encoder
181
     *
182
     * @return callable
183
     */
184 8
    public function getEncoder()
185
    {
186 8
        return $this->encoder;
187
    }
188
189
    /**
190
     * Get decoder
191
     *
192
     * @return callable
193
     */
194 8
    public function getDecoder()
195
    {
196 8
        return $this->decoder;
197
    }
198
199
    /**
200
     * Get httpClient
201
     *
202
     * @return HttpClient
203
     */
204 8
    public function getHttpClient()
205
    {
206 8
        return $this->httpClient;
207
    }
208
209
    /**
210
     * Get requestFactory
211
     *
212
     * @return RequestFactory
213
     */
214 8
    public function getRequestFactory()
215
    {
216 8
        return $this->requestFactory;
217
    }
218
219
    /**
220
     * Get streamFactory
221
     *
222
     * @return StreamFactory
223
     */
224 2
    public function getStreamFactory()
225
    {
226 2
        return $this->streamFactory;
227
    }
228
229
    /**
230
     * @param string $name
231
     *
232
     * @return ApiInterface
233
     * @throws Exception\RuntimeException
234
     * @throws InvalidArgumentException
235
     */
236 8
    public function __get($name)
237
    {
238 8
        return $this->api(
239 8
            strtolower(preg_replace('/([a-z]+)([A-Z]+)/', '$1.$2', $name))
240
        );
241
    }
242
243
    /**
244
     * @param string $name
245
     *
246
     * @return bool
247
     */
248 1
    public function __isset($name)
249
    {
250 1
        return array_key_exists($name, self::API);
251
    }
252
253
    /**
254
     * @param string $name
255
     * @param mixed  $value
256
     *
257
     * @throws RuntimeException
258
     */
259 1
    public function __set($name, $value)
260
    {
261 1
        throw new RuntimeException('ApiClient instance is immutable.');
262
    }
263
264
    /**
265
     * Return api class instance by name
266
     *
267
     * @param string $api Api name
268
     *
269
     * @return ApiInterface
270
     * @throws \Gennadyx\ShopLogisticsRu\Exception\RuntimeException
271
     * @throws \Gennadyx\ShopLogisticsRu\Exception\InvalidArgumentException
272
     */
273 11
    public function api($api)
274
    {
275 11
        if (!array_key_exists($api, self::API)) {
276 2
            throw new InvalidArgumentException(
277 2
                sprintf('Api "%s" not found', $api)
278
            );
279
        }
280
281 9
        return $this->getApiInstance($api);
282
    }
283
284
    /**
285
     * @param string $api Api name
286
     *
287
     * @return ApiInterface
288
     * @throws InvalidArgumentException
289
     */
290 9
    private function getApiInstance($api)
291
    {
292 9
        $className = self::API[$api];
293
294 9
        if (null === $this->instances
295 9
            || !isset($this->instances[$api])
296
        ) {
297 9
            $this->instances[$api] = $this->createApiInstance($className);
298
        }
299
300 9
        return $this->instances[$api];
301
    }
302
303
    /**
304
     * @param string $className
305
     *
306
     * @return ApiInterface
307
     * @throws InvalidArgumentException
308
     */
309 9
    private function createApiInstance($className)
310
    {
311 9
        $reflectionClass = new ReflectionClass($className);
312 9
        $newInstance     = $reflectionClass->newInstance($this);
313
314 9
        if (!($newInstance instanceof ApiInterface)) {
315
            throw new InvalidArgumentException(
316
                sprintf('Api object must be a implement ApiInterface. But "%s" not implement it.', $className)
317
            );
318
        }
319
320 9
        return $newInstance;
321
    }
322
}
323