Completed
Pull Request — master (#21)
by Rhodri
03:41
created

GenericApi::put()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
c 0
b 0
f 0
rs 9.4285
cc 1
eloc 4
nc 1
nop 3
1
<?php
2
3
/*
4
 * This file is part of the Lakion package.
5
 *
6
 * (c) Lakion
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 Sylius\Api;
13
14
use Psr\Http\Message\ResponseInterface;
15
use Sylius\Api\Factory\AdapterFactoryInterface;
16
use Sylius\Api\Factory\ApiAdapterFactory;
17
use Sylius\Api\Factory\PaginatorFactory;
18
use Sylius\Api\Factory\PaginatorFactoryInterface;
19
use Symfony\Component\Serializer\Encoder\JsonDecode;
20
use Symfony\Component\Serializer\Encoder\XmlEncoder;
21
22
/**
23
 * @author Michał Marcinkowski <[email protected]>
24
 */
25
class GenericApi implements ApiInterface
26
{
27
28
    /**
29
     * @var array
30
     */
31
    static $formats = [
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $formats.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
32
        'json' => ['application/json', 'application/x-json'],
33
    ];
34
35
    /**
36
     * @var ClientInterface $client
37
     */
38
    private $client;
39
    /**
40
     * @var string $uri
41
     */
42
    private $uri;
43
    /**
44
     * @var PaginatorFactoryInterface $paginatorFactory
45
     */
46
    private $paginatorFactory;
47
48
    /**
49
     * @var AdapterFactoryInterface $apiAdapterFactory
50
     */
51
    private $apiAdapterFactory;
52
53
    /**
54
     * @var JsonDecode $jsonDecoder
55
     */
56
    private $jsonDecoder;
57
58
    /**
59
     * @param ClientInterface $client
60
     * @param string $uri
61
     * @param null|AdapterFactoryInterface $apiAdapterFactory
62
     * @param null|PaginatorFactoryInterface $paginatorFactory
63
     * @param null|JsonDecode $jsonDecoder
64
     */
65
    public function __construct(
66
        ClientInterface $client,
67
        $uri,
68
        AdapterFactoryInterface $apiAdapterFactory = null,
69
        PaginatorFactoryInterface $paginatorFactory = null,
70
        JsonDecode $jsonDecoder = null
71
    ) {
72
        $this->setUri($uri);
73
        $this->client = $client;
74
        $this->apiAdapterFactory = $apiAdapterFactory ?: new ApiAdapterFactory($this);
75
        $this->paginatorFactory = $paginatorFactory ?: new PaginatorFactory();
76
        $this->jsonDecoder = $jsonDecoder ?: new JsonDecode(true);
77
    }
78
79
    /**
80
     * @param  string $uri
81
     * @throws \InvalidArgumentException
82
     */
83
    private function setUri($uri)
84
    {
85
        if (empty($uri) || !is_string($uri)) {
86
            throw new \InvalidArgumentException('You must specify uri for Api');
87
        }
88
        if (($uri[strlen($uri) - 1]) !== '/') {
89
            $uri = sprintf('%s/', $uri);
90
        }
91
        $this->uri = $uri;
92
    }
93
94
    /**
95
     * @param  array $uriParameters
96
     * @return string
97
     */
98
    private function getUri(array $uriParameters = [])
99
    {
100
        $uri = $this->uri;
101
        foreach ($uriParameters as $uriParameterKey => $uriParameterValue) {
102
            $uri = str_ireplace(sprintf('{%s}', $uriParameterKey), $uriParameterValue, $uri);
103
        }
104
105
        return $uri;
106
    }
107
108
    /**
109
     * {@inheritdoc}
110
     */
111
    public function get($id, array $queryParameters = [], array $uriParameters = [])
112
    {
113
        $response = $this->client->get(sprintf('%s%s', $this->getUri($uriParameters), $id), $queryParameters);
114
115
        return $this->responseToArray($response);
116
    }
117
118
    /**
119
     * {@inheritdoc}
120
     */
121
    public function getAll(array $queryParameters = [], array $uriParameters = [])
122
    {
123
        $queryParameters['limit'] = isset($queryParameters['limit']) ? $queryParameters['limit'] : 100;
124
        $paginator = $this->createPaginator($queryParameters, $uriParameters);
125
        $results = $paginator->getCurrentPageResults();
126
        while ($paginator->hasNextPage()) {
127
            $paginator->nextPage();
128
            $results = array_merge($results, $paginator->getCurrentPageResults());
129
        }
130
131
        return $results;
132
    }
133
134
    /**
135
     * {@inheritdoc}
136
     */
137
    public function getPaginated(array $queryParameters = [], array $uriParameters = [])
138
    {
139
        $queryParameters['page'] = isset($queryParameters['page']) ? $queryParameters['page'] : 1;
140
        $queryParameters['limit'] = isset($queryParameters['limit']) ? $queryParameters['limit'] : 10;
141
142
        $response = $this->client->get($this->getUri($uriParameters), $queryParameters);
143
144
        return $this->responseToArray($response);
145
    }
146
147
    /**
148
     * {@inheritdoc}
149
     */
150
    public function createPaginator(array $queryParameters = [], array $uriParameters = [])
151
    {
152
        $queryParameters['limit'] = isset($queryParameters['limit']) ? $queryParameters['limit'] : 10;
153
154
        return $this->paginatorFactory->create($this->apiAdapterFactory->create(), $queryParameters, $uriParameters);
155
    }
156
157
    /**
158
     * {@inheritdoc}
159
     */
160
    public function create(array $body, array $uriParameters = [], array $files = [])
161
    {
162
        $response = $this->client->post($this->getUri($uriParameters), $body, $files);
163
164
        return $this->responseToArray($response);
165
    }
166
167
    /**
168
     * {@inheritdoc}
169
     */
170
    public function update($id, array $body, array $uriParameters = [], array $files = [])
171
    {
172
        $uri = sprintf('%s%s', $this->getUri($uriParameters), $id);
173
        if (empty($files)) {
174
            $response = $this->client->patch($uri, $body);
175
        } else {
176
            $response = $this->client->post($uri, $body, $files);
177
        }
178
179
        return (204 === $response->getStatusCode());
180
    }
181
182
    /**
183
     * {@inheritdoc}
184
     */
185
    public function put($id, array $body, array $uriParameters = [])
186
    {
187
        $uri = sprintf('%s%s', $this->getUri($uriParameters), $id);
188
        $response = $this->client->put($uri, $body);
189
190
        return (204 === $response->getStatusCode());
191
    }
192
193
    /**
194
     * {@inheritdoc}
195
     */
196
    public function delete($id, array $uriParameters = [])
197
    {
198
        $response = $this->client->delete(sprintf('%s%s', $this->getUri($uriParameters), $id));
199
200
        return (204 === $response->getStatusCode());
201
    }
202
203
    private function responseToArray(ResponseInterface $response)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
204
    {
205
        $responseType = $this->getResponseType($response);
206
207
        return $this->{$responseType}((string)$response->getBody());
208
    }
209
210
    private function getResponseType(ResponseInterface $response)
211
    {
212
        $responseContentType = $response->getHeaderLine('Content-Type');
213
        foreach (self::$formats as $format => $contentTypes) {
214
            foreach ($contentTypes as $contentType) {
215
                if (strpos($responseContentType, $contentType) !== false) {
216
                    return $format;
217
                }
218
            }
219
        }
220
221
        throw new InvalidResponseFormatException((string)$response->getBody(), $response->getStatusCode());
222
    }
223
224
    /**
225
     * @param $body
226
     * @return mixed
227
     */
228
    private function json($body)
229
    {
230
        return $this->jsonDecoder->decode($body, 'json');
231
    }
232
}
233