Completed
Push — master ( 49d990...a59b61 )
by Jean C.
14s
created

MoipResource::generatePath()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

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