Completed
Push — master ( 4a5840...1f0278 )
by
unknown
11s
created

MoipResource::generateListPath()   C

Complexity

Conditions 7
Paths 40

Size

Total Lines 28
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 14
nc 40
nop 3
dl 0
loc 28
rs 6.7272
c 0
b 0
f 0
1
<?php
2
3
namespace Moip\Resource;
4
5
use JsonSerializable;
6
use Moip\Exceptions;
7
use Moip\Helper\Filters;
8
use Moip\Helper\Links;
9
use Moip\Helper\Pagination;
10
use Moip\Moip;
11
use Requests;
12
use Requests_Exception;
13
use stdClass;
14
15
/**
16
 * Class MoipResource.
17
 */
18
abstract class MoipResource implements JsonSerializable
19
{
20
    /**
21
     * Version of API.
22
     *
23
     * @const string
24
     */
25
    const VERSION = 'v2';
26
27
    /**
28
     * @var \Moip\Moip
29
     */
30
    protected $moip;
31
32
    /**
33
     * @var \stdClass
34
     */
35
    protected $data;
36
37
    /**
38
     * Initialize a new instance.
39
     */
40
    abstract protected function initialize();
41
42
    /**
43
     * Mount information of a determined object.
44
     *
45
     * @param \stdClass $response
46
     *
47
     * @return mixed
48
     */
49
    abstract protected function populate(stdClass $response);
50
51
    /**
52
     * Create a new instance.
53
     *
54
     * @param \Moip\Moip $moip
55
     */
56
    public function __construct(Moip $moip)
57
    {
58
        $this->moip = $moip;
59
        $this->data = new stdClass();
60
        $this->initialize();
61
    }
62
63
    /**
64
     * Get a key of an object if it exists.
65
     *
66
     * @param string         $key
67
     * @param \stdClass|null $data
68
     *
69
     * @return mixed
70
     */
71
    protected function getIfSet($key, stdClass $data = null)
72
    {
73
        if (empty($data)) {
74
            $data = $this->data;
75
        }
76
77
        if (isset($data->$key)) {
78
            return $data->$key;
79
        }
80
    }
81
82
    /**
83
     * @return \Moip\Helper\Links
84
     */
85
    public function getLinks()
86
    {
87
        $links = $this->getIfSet('_links');
88
89
        if ($links !== null) {
90
            return new Links($links);
91
        }
92
    }
93
94
    /**
95
     * @param $key
96
     * @param $fmt
97
     * @param stdClass|null $data
98
     *
99
     * @return bool|\DateTime|null
100
     */
101 View Code Duplication
    protected function getIfSetDateFmt($key, $fmt, stdClass $data = null)
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...
102
    {
103
        $val = $this->getIfSet($key, $data);
104
        if (!empty($val)) {
105
            $dt = \DateTime::createFromFormat($fmt, $val);
106
107
            return $dt ? $dt : null;
108
        }
109
    }
110
111
    /**
112
     * Get a key, representing a date (Y-m-d), of an object if it exists.
113
     *
114
     * @param string        $key
115
     * @param stdClass|null $data
116
     *
117
     * @return \DateTime|null
118
     */
119
    protected function getIfSetDate($key, stdClass $data = null)
120
    {
121
        return $this->getIfSetDateFmt($key, 'Y-m-d', $data);
122
    }
123
124
    /**
125
     * Get a key representing a datetime (\Datetime::ATOM), of an object if it exists.
126
     *
127
     * @param string        $key
128
     * @param stdClass|null $data
129
     *
130
     * @return \DateTime|null
131
     */
132 View Code Duplication
    protected function getIfSetDateTime($key, stdClass $data = null)
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...
133
    {
134
        $rawDateTime = $this->getIfSet($key, $data);
135
136
        $dateTime = null;
137
        if (!empty($rawDateTime)) {
138
            $dateTime = new \DateTime($rawDateTime);
139
        }
140
141
        return $dateTime;
142
    }
143
144
    /**
145
     * Specify data which should be serialized to JSON.
146
     *
147
     * @return \stdClass
148
     */
149
    public function jsonSerialize()
150
    {
151
        return $this->data;
152
    }
153
154
    /**
155
     * Generate URL to request.
156
     *
157
     * @param $action
158
     * @param $id
159
     *
160
     * @return string
161
     */
162
    public function generatePath($action, $id = null)
163
    {
164
        if (!is_null($id)) {
165
            return sprintf('%s/%s/%s/%s', self::VERSION, static::PATH, $action, $id);
166
        }
167
168
        return sprintf('%s/%s/%s', self::VERSION, static::PATH, $action);
169
    }
170
171
    /**
172
     * Generate URL to request a get list.
173
     *
174
     * @param Pagination $pagination
175
     * @param Filters    $filters
176
     * @param array      $params
177
     *
178
     * @return string
179
     */
180
    public function generateListPath(Pagination $pagination = null, Filters $filters = null, $params = [])
181
    {
182
        $queryParams = [];
183
184
        if (!is_null($pagination)) {
185
            if ($pagination->getLimit() != 0) {
186
                $queryParams['limit'] = $pagination->getLimit();
187
            }
188
189
            if ($pagination->getOffset() >= 0) {
190
                $queryParams['offset'] = $pagination->getOffset();
191
            }
192
        }
193
194
        if (!is_null($filters)) {
195
            $queryParams['filters'] = $filters->__toString();
196
        }
197
198
        if (!empty($params)) {
199
            $queryParams = array_merge($queryParams, $params);
200
        }
201
202
        if (!empty($queryParams)) {
203
            return sprintf('/%s/%s?%s', self::VERSION, static::PATH, http_build_query($queryParams));
204
        }
205
206
        return sprintf('/%s/%s', self::VERSION, static::PATH);
207
    }
208
209
    /**
210
     * Execute a http request. If payload == null no body will be sent. Empty body ('{}') is supported by sending a
211
     * empty stdClass.
212
     *
213
     * @param string     $path
214
     * @param string     $method
215
     * @param mixed|null $payload
216
     *
217
     * @throws Exceptions\ValidationException  if the API returns a 4xx http status code. Usually means invalid data was sent.
218
     * @throws Exceptions\UnautorizedException if the API returns a 401 http status code. Check API token and key.
219
     * @throws Exceptions\UnexpectedException  if the API returns a 500 http status code or something unexpected happens (ie.: Network error).
220
     *
221
     * @return stdClass
222
     */
223
    protected function httpRequest($path, $method, $payload = null)
224
    {
225
        $http_sess = $this->moip->getSession();
226
        $headers = [];
227
        $body = null;
228
        if ($payload !== null) {
229
            $body = json_encode($payload, JSON_UNESCAPED_SLASHES);
230
            if ($body) {// if it's json serializable
231
                $headers['Content-Type'] = 'application/json';
232
            } else {
233
                $body = null;
234
            }
235
        }
236
237
        try {
238
            $http_response = $http_sess->request($path, $headers, $body, $method);
239
        } catch (Requests_Exception $e) {
240
            throw new Exceptions\UnexpectedException($e);
241
        }
242
243
        $code = $http_response->status_code;
244
        $response_body = $http_response->body;
245
        if ($code >= 200 && $code < 300) {
246
            return json_decode($response_body);
247
        } elseif ($code == 401) {
248
            throw new Exceptions\UnautorizedException();
249
        } elseif ($code >= 400 && $code <= 499) {
250
            $errors = Exceptions\Error::parseErrors($response_body);
251
252
            throw new Exceptions\ValidationException($code, $errors);
253
        }
254
255
        throw new Exceptions\UnexpectedException();
256
    }
257
258
    /**
259
     * Find by path.
260
     *
261
     * @param string $path
262
     *
263
     * @return stdClass
264
     */
265
    public function getByPath($path)
266
    {
267
        $response = $this->httpRequest($path, Requests::GET);
268
269
        return $this->populate($response);
270
    }
271
272
    /**
273
     * Find by path with no populate method.
274
     *
275
     * @param string $path
276
     *
277
     * @return stdClass
278
     */
279
    public function getByPathNoPopulate($path)
280
    {
281
        return $this->httpRequest($path, Requests::GET);
282
    }
283
284
    /**
285
     * Create a new item in Moip.
286
     *
287
     * @param string $path
288
     *
289
     * @return stdClass
290
     */
291
    public function createResource($path)
292
    {
293
        $response = $this->httpRequest($path, Requests::POST, $this);
294
295
        return $this->populate($response);
296
    }
297
298
    /**
299
     * Delete a new item in Moip.
300
     *
301
     * @param $path
302
     *
303
     * @return mixed
304
     */
305
    public function deleteByPath($path)
306
    {
307
        return $this->httpRequest($path, Requests::DELETE);
308
    }
309
}
310