Completed
Push — master ( 1f0278...22c246 )
by
unknown
12s
created

MoipResource   B

Complexity

Total Complexity 36

Size/Duplication

Total Lines 296
Duplicated Lines 6.76 %

Coupling/Cohesion

Components 2
Dependencies 10

Importance

Changes 0
Metric Value
dl 20
loc 296
rs 8.8
c 0
b 0
f 0
wmc 36
lcom 2
cbo 10

16 Methods

Rating   Name   Duplication   Size   Complexity  
initialize() 0 1 ?
populate() 0 1 ?
A __construct() 0 6 1
A getIfSet() 0 10 3
A getLinks() 0 8 2
A getIfSetDate() 0 4 1
A getIfSetDateFmt() 9 9 3
A getIfSetDateTime() 11 11 2
A jsonSerialize() 0 4 1
A generatePath() 0 8 2
C generateListPath() 0 28 7
D httpRequest() 0 34 9
A getByPath() 0 10 2
A getByPathNoPopulate() 0 4 1
A createResource() 0 6 1
A deleteByPath() 0 4 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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
        if (is_array($response)) {
270
            $response = (object) $response;
271
        }
272
273
        return $this->populate($response);
274
    }
275
276
    /**
277
     * Find by path with no populate method.
278
     *
279
     * @param string $path
280
     *
281
     * @return stdClass
282
     */
283
    public function getByPathNoPopulate($path)
284
    {
285
        return $this->httpRequest($path, Requests::GET);
286
    }
287
288
    /**
289
     * Create a new item in Moip.
290
     *
291
     * @param string $path
292
     *
293
     * @return stdClass
294
     */
295
    public function createResource($path)
296
    {
297
        $response = $this->httpRequest($path, Requests::POST, $this);
298
299
        return $this->populate($response);
300
    }
301
302
    /**
303
     * Delete a new item in Moip.
304
     *
305
     * @param $path
306
     *
307
     * @return mixed
308
     */
309
    public function deleteByPath($path)
310
    {
311
        return $this->httpRequest($path, Requests::DELETE);
312
    }
313
}
314