Completed
Push — master ( deea37...cc8ae8 )
by Zbigniew
04:07
created

ResourceAbstract::getConfig()   A

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
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
/**
3
 * This file is part of the WrikePhpSdk package.
4
 *
5
 * (c) Zbigniew Ślązak
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Zibios\WrikePhpSdk\Api;
12
13
use Zibios\WrikePhpSdk\Documents\ResponseDocumentInterface;
14
use Zibios\WrikePhpSdk\Enums\RequestMethodEnum;
15
use Zibios\WrikePhpSdk\Enums\ResourceMethodEnum;
16
use Zibios\WrikePhpSdk\Enums\ResponseModeEnum;
17
use Zibios\WrikePhpSdk\Exceptions\Api\ApiException;
18
19
/**
20
 * Resource Abstract
21
 */
22
abstract class ResourceAbstract implements ResourceInterface
0 ignored issues
show
Coding Style introduced by
ResourceAbstract does not seem to conform to the naming convention (^Abstract|Factory$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
23
{
24
    const ASSERT_TYPE_NULL = 'null';
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 3 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
25
    const ASSERT_TYPE_STRING = 'string';
26
    const ASSERT_TYPE_ARRAY = 'array';
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 2 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
27
28
    /**
29
     * @var ConfigInterface
30
     */
31
    protected $config;
32
33
    /**
34
     * @param ConfigInterface $config
35
     */
36 65
    public function __construct(ConfigInterface $config)
37
    {
38 65
        $this->config = $config;
39 65
    }
40
41
    /**
42
     * @return string
43
     */
44
    abstract protected function getResponseClass();
45
46
    /**
47
     * @return array
48
     */
49
    abstract protected function getResourceMethodConfiguration();
50
51
    /**
52
     * @return ConfigInterface
53
     */
54 54
    protected function getConfig()
55
    {
56 54
        return $this->config;
57
    }
58
59
    /**
60
     * @param ConfigInterface $config
61
     *
62
     * @return $this
63
     */
64
    protected function setConfig(ConfigInterface $config)
65
    {
66
        $this->config = $config;
67
68
        return $this;
69
    }
70
71
    /**
72
     * @param string $requestMethod
73
     * @param string $resourceMethod
74
     * @param array $params
75
     * @param string|array|null $id
76
     *
77
     * @return mixed
78
     * @throws \LogicException
79
     * @throws \GuzzleHttp\Exception\GuzzleException
80
     * @throws \Exception
81
     * @throws \InvalidArgumentException
82
     * @throws \Zibios\WrikePhpSdk\Exceptions\Api\ApiException
83
     * @throws \Zibios\WrikePhpSdk\Exceptions\Api\AccessForbiddenException
84
     * @throws \Zibios\WrikePhpSdk\Exceptions\Api\InvalidParameterException
85
     * @throws \Zibios\WrikePhpSdk\Exceptions\Api\InvalidRequestException
86
     * @throws \Zibios\WrikePhpSdk\Exceptions\Api\NotAllowedException
87
     * @throws \Zibios\WrikePhpSdk\Exceptions\Api\NotAuthorizedException
88
     * @throws \Zibios\WrikePhpSdk\Exceptions\Api\ParameterRequiredException
89
     * @throws \Zibios\WrikePhpSdk\Exceptions\Api\ResourceNotFoundException
90
     * @throws \Zibios\WrikePhpSdk\Exceptions\Api\ServerErrorException
91
     */
92 54
    protected function request($requestMethod, $resourceMethod, array $params, $id)
93
    {
94 54
        RequestMethodEnum::assertIsValidValue($requestMethod);
95 54
        ResourceMethodEnum::assertIsValidValue($resourceMethod);
96 54
        return $this->executeRequest(
97
            $requestMethod,
98 54
            $this->prepareRequestPathForResourceMethod($resourceMethod, $id),
99 54
            $this->prepareRequestOptionsForRequestMethod($requestMethod, $params),
100 54
            $this->getResponseClass()
101
        );
102
    }
103
104
    /**
105
     * @param string $requestMethod
106
     * @param string $path
107
     * @param array $options
108
     * @param string $responseDocumentClass
109
     *
110
     * @return mixed
111
     * @throws \LogicException
112
     * @throws \GuzzleHttp\Exception\GuzzleException
113
     * @throws \Exception
114
     * @throws \InvalidArgumentException
115
     * @throws \Zibios\WrikePhpSdk\Exceptions\Api\ApiException
116
     * @throws \Zibios\WrikePhpSdk\Exceptions\Api\AccessForbiddenException
117
     * @throws \Zibios\WrikePhpSdk\Exceptions\Api\InvalidParameterException
118
     * @throws \Zibios\WrikePhpSdk\Exceptions\Api\InvalidRequestException
119
     * @throws \Zibios\WrikePhpSdk\Exceptions\Api\NotAllowedException
120
     * @throws \Zibios\WrikePhpSdk\Exceptions\Api\NotAuthorizedException
121
     * @throws \Zibios\WrikePhpSdk\Exceptions\Api\ParameterRequiredException
122
     * @throws \Zibios\WrikePhpSdk\Exceptions\Api\ResourceNotFoundException
123
     * @throws \Zibios\WrikePhpSdk\Exceptions\Api\ServerErrorException
124
     */
125 54
    private function executeRequest($requestMethod, $path, array $options, $responseDocumentClass)
126
    {
127 54
        $client = $this->getConfig()->getClient();
128
129 54
        $response = null;
130
        try {
131 54
            $response = $client->request($requestMethod, $path, $options);
132 34
        } catch (\Exception $e) {
133 34
            if ($this->getConfig()->isWrikeExceptionsMode()) {
134 17
                throw ApiException::create($e);
135
            }
136 17
            throw $e;
137
        }
138
139 20
        $responseMode = $this->getConfig()->getResponseMode();
140 20
        ResponseModeEnum::assertIsValidValue($responseMode);
141
142 20
        if ($responseMode === ResponseModeEnum::RESPONSE_RAW) {
143 16
            return $response;
144
        }
145
146 20
        $bodyString = (string) $response->getBody();
147 20
        if ($responseMode === ResponseModeEnum::BODY_STRING) {
148 16
            return $bodyString;
149
        }
150
151 20
        if ($responseMode === ResponseModeEnum::BODY_OBJECT) {
152 16
            return json_decode($bodyString, true);
153
        }
154
155
        /** @var ResponseDocumentInterface $responseDocument */
156 20
        $responseDocument = $this->getConfig()->getSerializer()->deserialize(
157 20
            (string) $response->getBody(),
158
            $responseDocumentClass,
159 20
            'json'
160
        );
161 20
        if ($responseMode === ResponseModeEnum::BODY_DOCUMENT) {
162 16
            return $responseDocument;
163
        }
164
165 20
        if ($responseMode === ResponseModeEnum::DOCUMENT) {
166 20
            return $responseDocument->getData();
167
        }
168
169
        throw new \LogicException();
170
    }
171
172
    /**
173
     * @param mixed $value
174
     * @param string $type
175
     *
176
     * @throws \InvalidArgumentException
177
     */
178 54
    private function assertIsValidId($value, $type)
179
    {
180
        switch ($type) {
181 54
            case self::ASSERT_TYPE_NULL:
182 39
                if ($value !== null) {
183
                    throw new \InvalidArgumentException();
184
                }
185 39
                break;
186 15
            case self::ASSERT_TYPE_STRING:
187 15
                if (is_string($value) === false || trim($value) === '' || strlen($value) > 128) {
188
                    throw new \InvalidArgumentException(sprintf('Invalid Id, should be not empty string!'));
189
                }
190 15
                break;
191 1
            case self::ASSERT_TYPE_ARRAY:
192 1
                if (is_array($value) === false) {
193
                    throw new \InvalidArgumentException();
194
                }
195
                /** @var array $value */
196 1
                foreach ($value as $id) {
197 1
                    $this->assertIsValidId($id, self::ASSERT_TYPE_STRING);
198
                }
199 1
                break;
200
            default:
201
                throw new \InvalidArgumentException();
202
        }
203 54
    }
204
205
    /**
206
     * @param string $resourceMethod
207
     * @param string|array|null $id
208
     *
209
     * @return string
210
     * @throws \InvalidArgumentException
211
     */
212 54
    private function prepareRequestPathForResourceMethod($resourceMethod, $id)
213
    {
214 54
        $resourceMethodConfiguration = $this->getResourceMethodConfiguration();
215 54
        if (array_key_exists($resourceMethod, $resourceMethodConfiguration) === false) {
216
            throw new \InvalidArgumentException();
217
        }
218 54
        $requestPathFormat = $resourceMethodConfiguration[$resourceMethod];
219
220
        switch ($resourceMethod) {
221 54
            case ResourceMethodEnum::GET_ALL:
222 39
                $this->assertIsValidId($id, self::ASSERT_TYPE_NULL);
223 39
                return sprintf($requestPathFormat, $id);
224 15
            case ResourceMethodEnum::GET_BY_IDS:
225 1
                $this->assertIsValidId($id, self::ASSERT_TYPE_ARRAY);
226 1
                return sprintf($requestPathFormat, implode(',', $id));
227 14
            case ResourceMethodEnum::GET_ALL_IN_ACCOUNT:
228 11
            case ResourceMethodEnum::CREATE_IN_ACCOUNT:
229 9
            case ResourceMethodEnum::GET_BY_ID:
230 6
            case ResourceMethodEnum::UPDATE:
231 2
            case ResourceMethodEnum::DELETE:
232 14
                $this->assertIsValidId($id, self::ASSERT_TYPE_STRING);
233 14
                return sprintf($requestPathFormat, $id);
234
            default:
235
                throw new \InvalidArgumentException(sprintf('"%s" resource method not yet supported', $resourceMethod));
236
        }
237
    }
238
239
    /**
240
     * @param string $requestMethod
241
     * @param array $params
242
     *
243
     * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array<string,array>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
244
     * @throws \InvalidArgumentException
245
     */
246 54
    protected function prepareRequestOptionsForRequestMethod($requestMethod, array $params)
247
    {
248
        $options = [
249 54
            'headers' => ['Content-Type' => 'application/json'],
250
        ];
251
252
        switch ($requestMethod) {
253 54
            case RequestMethodEnum::GET:
254 46
                if (count($params) > 0) {
255
                    $options['query'] = $params;
256
                }
257 46
                break;
258 8
            case RequestMethodEnum::PUT:
259 4
            case RequestMethodEnum::POST:
260 6
                if (count($params) > 0) {
261
                    $options['body'] = $this->getConfig()->getSerializer()->serialize($params, 'json');
262
                }
263 6
                break;
264 2
            case RequestMethodEnum::DELETE:
265 2
                break;
266
            default:
267
                throw new \InvalidArgumentException();
268
        }
269
270 54
        return $options;
271
    }
272
}
273