Completed
Push — master ( 7113c4...8875d3 )
by Yassine
14s
created

Response::decodeBody()   B

Complexity

Conditions 6
Paths 16

Size

Total Lines 22
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 6.1308

Importance

Changes 0
Metric Value
cc 6
eloc 12
nc 16
nop 0
dl 0
loc 22
ccs 11
cts 13
cp 0.8462
crap 6.1308
rs 8.6737
c 0
b 0
f 0
1
<?php
2
/**
3
 * Copyright 2017 Facebook, Inc.
4
 *
5
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
6
 * use, copy, modify, and distribute this software in source code or binary
7
 * form for use in connection with the web services and APIs provided by
8
 * Facebook.
9
 *
10
 * As with any software that integrates with the Facebook platform, your use
11
 * of this software is subject to the Facebook Developer Principles and
12
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
13
 * shall be included in all copies or substantial portions of the software.
14
 *
15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21
 * DEALINGS IN THE SOFTWARE.
22
 */
23
namespace Facebook;
24
25
use Facebook\GraphNode\GraphNodeFactory;
26
use Facebook\Exception\ResponseException;
27
use Facebook\Exception\SDKException;
28
29
/**
30
 * @package Facebook
31
 */
32
class Response
33
{
34
    /**
35
     * @var int the HTTP status code response from Graph
36
     */
37
    protected $httpStatusCode;
38
39
    /**
40
     * @var array the headers returned from Graph
41
     */
42
    protected $headers;
43
44
    /**
45
     * @var string the raw body of the response from Graph
46
     */
47
    protected $body;
48
49
    /**
50
     * @var array the decoded body of the Graph response
51
     */
52
    protected $decodedBody = [];
53
54
    /**
55
     * @var Request the original request that returned this response
56
     */
57
    protected $request;
58
59
    /**
60
     * @var SDKException the exception thrown by this request
61
     */
62
    protected $thrownException;
63
64
    /**
65
     * Creates a new Response entity.
66
     *
67
     * @param Request     $request
68
     * @param null|string $body
69
     * @param null|int    $httpStatusCode
70
     * @param null|array  $headers
71
     */
72 46
    public function __construct(Request $request, $body = null, $httpStatusCode = null, array $headers = [])
73
    {
74 46
        $this->request = $request;
75 46
        $this->body = $body;
76 46
        $this->httpStatusCode = $httpStatusCode;
77 46
        $this->headers = $headers;
78
79 46
        $this->decodeBody();
80 46
    }
81
82
    /**
83
     * Return the original request that returned this response.
84
     *
85
     * @return Request
86
     */
87 13
    public function getRequest()
88
    {
89 13
        return $this->request;
90
    }
91
92
    /**
93
     * Return the Application entity used for this response.
94
     *
95
     * @return Application
96
     */
97
    public function getApplication()
98
    {
99
        return $this->request->getApplication();
100
    }
101
102
    /**
103
     * Return the access token that was used for this response.
104
     *
105
     * @return null|string
106
     */
107 1
    public function getAccessToken()
108
    {
109 1
        return $this->request->getAccessToken();
110
    }
111
112
    /**
113
     * Return the HTTP status code for this response.
114
     *
115
     * @return int
116
     */
117 14
    public function getHttpStatusCode()
118
    {
119 14
        return $this->httpStatusCode;
120
    }
121
122
    /**
123
     * Return the HTTP headers for this response.
124
     *
125
     * @return array
126
     */
127 5
    public function getHeaders()
128
    {
129 5
        return $this->headers;
130
    }
131
132
    /**
133
     * Return the raw body response.
134
     *
135
     * @return string
136
     */
137 13
    public function getBody()
138
    {
139 13
        return $this->body;
140
    }
141
142
    /**
143
     * Return the decoded body response.
144
     *
145
     * @return array
146
     */
147 41
    public function getDecodedBody()
148
    {
149 41
        return $this->decodedBody;
150
    }
151
152
    /**
153
     * Get the app secret proof that was used for this response.
154
     *
155
     * @return null|string
156
     */
157 1
    public function getAppSecretProof()
158
    {
159 1
        return $this->request->getAppSecretProof();
160
    }
161
162
    /**
163
     * Get the ETag associated with the response.
164
     *
165
     * @return null|string
166
     */
167 2
    public function getETag()
168
    {
169 2
        return isset($this->headers['ETag']) ? $this->headers['ETag'] : null;
170
    }
171
172
    /**
173
     * Get the version of Graph that returned this response.
174
     *
175
     * @return null|string
176
     */
177 1
    public function getGraphVersion()
178
    {
179 1
        return isset($this->headers['Facebook-API-Version']) ? $this->headers['Facebook-API-Version'] : null;
180
    }
181
182
    /**
183
     * Returns true if Graph returned an error message.
184
     *
185
     * @return bool
186
     */
187 46
    public function isError()
188
    {
189 46
        return isset($this->decodedBody['error']);
190
    }
191
192
    /**
193
     * Throws the exception.
194
     *
195
     * @throws SDKException
196
     */
197
    public function throwException()
198
    {
199
        throw $this->thrownException;
200
    }
201
202
    /**
203
     * Instantiates an exception to be thrown later.
204
     */
205 11
    public function makeException()
206
    {
207 11
        $this->thrownException = ResponseException::create($this);
208 11
    }
209
210
    /**
211
     * Returns the exception that was thrown for this request.
212
     *
213
     * @return null|ResponseException
214
     */
215 4
    public function getThrownException()
216
    {
217 4
        return $this->thrownException;
218
    }
219
220
    /**
221
     * Convert the raw response into an array if possible.
222
     *
223
     * Graph will return 2 types of responses:
224
     * - JSON(P)
225
     *    Most responses from Graph are JSON(P)
226
     * - application/x-www-form-urlencoded key/value pairs
227
     *    Happens on the `/oauth/access_token` endpoint when exchanging
228
     *    a short-lived access token for a long-lived access token
229
     * - And sometimes nothing :/ but that'd be a bug.
230
     */
231 46
    public function decodeBody()
232
    {
233 46
        $this->decodedBody = json_decode($this->body, true);
234
235 46
        if ($this->decodedBody === null) {
236 4
            $this->decodedBody = [];
237 4
            parse_str($this->body, $this->decodedBody);
238 43
        } elseif (is_bool($this->decodedBody)) {
239
            // Backwards compatibility for Graph < 2.1.
240
            // Mimics 2.1 responses.
241
            // @TODO Remove this after Graph 2.0 is no longer supported
242 1
            $this->decodedBody = ['success' => $this->decodedBody];
243 43
        } elseif (is_numeric($this->decodedBody)) {
244
            $this->decodedBody = ['id' => $this->decodedBody];
245
        }
246
247 46
        if (!is_array($this->decodedBody)) {
248
            $this->decodedBody = [];
249
        }
250
251 46
        if ($this->isError()) {
252 11
            $this->makeException();
253
        }
254 46
    }
255
256
    /**
257
     * Instantiate a new GraphObject from response.
258
     *
259
     * @param null|string $subclassName the GraphNode subclass to cast to
260
     *
261
     * @throws SDKException
262
     *
263
     * @return \Facebook\GraphNode\GraphObject
264
     *
265
     * @deprecated 5.0.0 getGraphObject() has been renamed to getGraphNode()
266
     *
267
     * @todo v6: Remove this method
268
     */
269
    public function getGraphObject($subclassName = null)
270
    {
271
        return $this->getGraphNode($subclassName);
272
    }
273
274
    /**
275
     * Instantiate a new GraphNode from response.
276
     *
277
     * @param null|string $subclassName the GraphNode subclass to cast to
278
     *
279
     * @throws SDKException
280
     *
281
     * @return \Facebook\GraphNode\GraphNode
282
     */
283 2
    public function getGraphNode($subclassName = null)
284
    {
285 2
        $factory = new GraphNodeFactory($this);
286
287 2
        return $factory->makeGraphNode($subclassName);
288
    }
289
290
    /**
291
     * Convenience method for creating a GraphAlbum collection.
292
     *
293
     * @throws SDKException
294
     *
295
     * @return \Facebook\GraphNode\GraphAlbum
296
     */
297
    public function getGraphAlbum()
298
    {
299
        $factory = new GraphNodeFactory($this);
300
301
        return $factory->makeGraphAlbum();
302
    }
303
304
    /**
305
     * Convenience method for creating a GraphPage collection.
306
     *
307
     * @throws SDKException
308
     *
309
     * @return \Facebook\GraphNode\GraphPage
310
     */
311
    public function getGraphPage()
312
    {
313
        $factory = new GraphNodeFactory($this);
314
315
        return $factory->makeGraphPage();
316
    }
317
318
    /**
319
     * Convenience method for creating a GraphSessionInfo collection.
320
     *
321
     * @throws SDKException
322
     *
323
     * @return \Facebook\GraphNode\GraphSessionInfo
324
     */
325
    public function getGraphSessionInfo()
326
    {
327
        $factory = new GraphNodeFactory($this);
328
329
        return $factory->makeGraphSessionInfo();
330
    }
331
332
    /**
333
     * Convenience method for creating a GraphUser collection.
334
     *
335
     * @throws SDKException
336
     *
337
     * @return \Facebook\GraphNode\GraphUser
338
     */
339
    public function getGraphUser()
340
    {
341
        $factory = new GraphNodeFactory($this);
342
343
        return $factory->makeGraphUser();
344
    }
345
346
    /**
347
     * Convenience method for creating a GraphEvent collection.
348
     *
349
     * @throws SDKException
350
     *
351
     * @return \Facebook\GraphNode\GraphEvent
352
     */
353
    public function getGraphEvent()
354
    {
355
        $factory = new GraphNodeFactory($this);
356
357
        return $factory->makeGraphEvent();
358
    }
359
360
    /**
361
     * Convenience method for creating a GraphGroup collection.
362
     *
363
     * @throws SDKException
364
     *
365
     * @return \Facebook\GraphNode\GraphGroup
366
     */
367
    public function getGraphGroup()
368
    {
369
        $factory = new GraphNodeFactory($this);
370
371
        return $factory->makeGraphGroup();
372
    }
373
374
    /**
375
     * Instantiate a new GraphList from response.
376
     *
377
     * @param null|string $subclassName the GraphNode subclass to cast list items to
378
     * @param bool        $auto_prefix  toggle to auto-prefix the subclass name
379
     *
380
     * @throws SDKException
381
     *
382
     * @return \Facebook\GraphNode\GraphList
383
     *
384
     * @deprecated 5.0.0 getGraphList() has been renamed to getGraphEdge()
385
     *
386
     * @todo v6: Remove this method
387
     */
388
    public function getGraphList($subclassName = null, $auto_prefix = true)
389
    {
390
        return $this->getGraphEdge($subclassName, $auto_prefix);
391
    }
392
393
    /**
394
     * Instantiate a new GraphEdge from response.
395
     *
396
     * @param null|string $subclassName the GraphNode subclass to cast list items to
397
     * @param bool        $auto_prefix  toggle to auto-prefix the subclass name
398
     *
399
     * @throws SDKException
400
     *
401
     * @return \Facebook\GraphNode\GraphEdge
402
     */
403 3
    public function getGraphEdge($subclassName = null, $auto_prefix = true)
404
    {
405 3
        $factory = new GraphNodeFactory($this);
406
407 3
        return $factory->makeGraphEdge($subclassName, $auto_prefix);
408
    }
409
}
410