Completed
Push — master ( dc1094...5b5a29 )
by Jean C.
9s
created

MoipResource::populate()

Size

Total Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

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