Completed
Pull Request — master (#42)
by
unknown
02:42
created

MoipResource::httpRequest()   D

Complexity

Conditions 9
Paths 15

Size

Total Lines 32
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 7
Bugs 1 Features 1
Metric Value
c 7
b 1
f 1
dl 0
loc 32
rs 4.909
cc 9
eloc 24
nc 15
nop 3
1
<?php
2
3
namespace Moip\Resource;
4
5
use JsonSerializable;
6
use Moip\Exceptions;
7
use Moip\Moip;
8
use Requests;
9
use Requests_Exception;
10
use stdClass;
11
12
abstract class MoipResource implements JsonSerializable
13
{
14
    /**
15
     * Version of API.
16
     *
17
     * @const string
18
     */
19
    const VERSION = 'v2';
20
21
    /**
22
     * @var \Moip\Moip
23
     */
24
    protected $moip;
25
26
    /**
27
     * @var \stdClass
28
     */
29
    protected $data;
30
31
    /**
32
     * Initialize a new instance.
33
     */
34
    abstract protected function initialize();
35
36
    /**
37
     * Mount information of a determined object.
38
     *
39
     * @param \stdClass $response
40
     *
41
     * @return mixed
42
     */
43
    abstract protected function populate(stdClass $response);
44
45
    /**
46
     * Create a new instance.
47
     *
48
     * @param \Moip\Moip $moip
49
     */
50
    public function __construct(Moip $moip)
51
    {
52
        $this->moip = $moip;
53
        $this->data = new stdClass();
54
        $this->initialize();
55
    }
56
57
    /**
58
     * Get a key of an object if it exists.
59
     *
60
     * @param string         $key
61
     * @param \stdClass|null $data
62
     *
63
     * @return mixed
64
     */
65
    protected function getIfSet($key, stdClass $data = null)
66
    {
67
        if (empty($data)) {
68
            $data = $this->data;
69
        }
70
71
        if (isset($data->$key)) {
72
            return $data->$key;
73
        }
74
    }
75
76
    protected function getIfSetDateFmt($key, $fmt, stdClass $data = null)
77
    {
78
        $val = $this->getIfSet($key, $data);
79
        if (!empty($val)) {
80
            $dt = \DateTime::createFromFormat($fmt, $val);
81
82
            return $dt ? $dt : null;
83
        }
84
    }
85
86
    /**
87
     * Get a key, representing a date (Y-m-d), of an object if it exists.
88
     *
89
     * @param string        $key
90
     * @param stdClass|null $data
91
     *
92
     * @return \DateTime|null
93
     */
94
    protected function getIfSetDate($key, stdClass $data = null)
95
    {
96
        return $this->getIfSetDateFmt($key, 'Y-m-d', $data);
97
    }
98
99
    /**
100
     * Get a key representing a datetime (\Datetime::ATOM), of an object if it exists.
101
     *
102
     * @param string        $key
103
     * @param stdClass|null $data
104
     *
105
     * @return \DateTime|null
106
     */
107
    protected function getIfSetDateTime($key, stdClass $data = null)
108
    {
109
        return $this->getIfSetDateFmt($key, \DateTime::ATOM, $data);
110
    }
111
112
    /**
113
     * Specify data which should be serialized to JSON.
114
     *
115
     * @return \stdClass
116
     */
117
    public function jsonSerialize()
118
    {
119
        return $this->data;
120
    }
121
122
    /**
123
     * Execute a http request. If payload == null no body will be sent. Empty body ('{}') is supported by sending a
124
     * empty stdClass.
125
     *
126
     * @param string     $path
127
     * @param string     $method
128
     * @param mixed|null $payload
129
     *
130
     * @throws Exceptions\ValidationException  if the API returns a 4xx http status code. Usually means invalid data was sent.
131
     * @throws Exceptions\UnautorizedException if the API returns a 401 http status code. Check API token and key.
132
     * @throws Exceptions\UnexpectedException  if the API returns a 500 http status code or something unexpected happens (ie.: Network error).
133
     *
134
     * @return stdClass
135
     */
136
    protected function httpRequest($path, $method, $payload = null)
137
    {
138
        $http_sess = $this->moip->getSession();
139
        $headers = [];
140
        $body = null;
141
        if ($payload !== null) {
142
            $body = json_encode($payload, JSON_UNESCAPED_SLASHES);
143
            if ($body) {// if it's json serializable
144
                $headers['Content-Type'] = 'application/json';
145
            } else {
146
                $body = null;
147
            }
148
        }
149
150
        try {
151
            $http_response = $http_sess->request($path, $headers, $body, $method);
1 ignored issue
show
Bug introduced by
It seems like $body defined by json_encode($payload, JSON_UNESCAPED_SLASHES) on line 142 can also be of type string; however, Requests_Session::request() does only seem to accept array|null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
152
        } catch (Requests_Exception $e) {
153
            throw new Exceptions\UnexpectedException($e);
154
        }
155
156
        $code = $http_response->status_code;
157
        $response_body = $http_response->body;
158
        if ($code >= 200 && $code < 300) {
159
            return json_decode($response_body);
160
        } elseif ($code == 401) {
161
            throw new Exceptions\UnautorizedException();
162
        } elseif ($code >= 400 && $code <= 499) {
163
            $errors = Exceptions\Error::parseErrors($response_body);
164
            throw new Exceptions\ValidationException($code, $errors);
165
        }
166
        throw new Exceptions\UnexpectedException();
167
    }
168
169
    /**
170
     * Find by path.
171
     *
172
     * @param string $path
173
     *
174
     * @return stdClass
175
     */
176
    public function getByPath($path)
177
    {
178
        $response = $this->httpRequest($path, Requests::GET);
179
180
        return $this->populate($response);
181
    }
182
183
    /**
184
     * Create a new item in Moip.
185
     *
186
     * @param string $path
187
     *
188
     * @return stdClass
189
     */
190
    public function createResource($path)
191
    {
192
        $response = $this->httpRequest($path, Requests::POST, $this);
193
194
        return $this->populate($response);
195
    }
196
}
197