GraphEdge::validateForPagination()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 0
dl 0
loc 4
ccs 3
cts 3
cp 1
crap 2
rs 10
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\GraphNode;
24
25
use Facebook\Request;
26
use Facebook\Url\UrlManipulator;
27
use Facebook\Exception\SDKException;
28
29
/**
30
 * @package Facebook
31
 */
32
class GraphEdge implements \ArrayAccess, \Countable, \IteratorAggregate
33
{
34
    /**
35
     * @var Request the original request that generated this data
36
     */
37
    protected $request;
38
39
    /**
40
     * @var array an array of Graph meta data like pagination, etc
41
     */
42
    protected $metaData = [];
43
44
    /**
45
     * @var null|string the parent Graph edge endpoint that generated the list
46
     */
47
    protected $parentEdgeEndpoint;
48
49
    /**
50
     * @var null|string the subclass of the child GraphNode's
51
     */
52
    protected $subclassName;
53
54
    /**
55
     * The items contained in the collection.
56
     *
57
     * @var array
58
     */
59
    protected $items = [];
60
61
    /**
62
     * Init this collection of GraphNode's.
63
     *
64
     * @param Request     $request            the original request that generated this data
65
     * @param array       $data               an array of GraphNode's
66
     * @param array       $metaData           an array of Graph meta data like pagination, etc
67
     * @param null|string $parentEdgeEndpoint the parent Graph edge endpoint that generated the list
68
     * @param null|string $subclassName       the subclass of the child GraphNode's
69
     */
70 20
    public function __construct(Request $request, array $data = [], array $metaData = [], $parentEdgeEndpoint = null, $subclassName = null)
71
    {
72 20
        $this->request = $request;
73 20
        $this->metaData = $metaData;
74 20
        $this->parentEdgeEndpoint = $parentEdgeEndpoint;
75 20
        $this->subclassName = $subclassName;
76 20
        $this->items = $data;
77 20
    }
78
79
    /**
80
     * Gets the value of a field from the Graph node.
81
     *
82
     * @param string $name    the field to retrieve
83
     * @param mixed  $default the default to return if the field doesn't exist
84
     *
85
     * @return mixed
86
     */
87 4
    public function getField($name, $default = null)
88
    {
89 4
        if (isset($this->items[$name])) {
90 1
            return $this->items[$name];
91
        }
92
93 3
        return $default;
94
    }
95
96
    /**
97
     * Returns a list of all fields set on the object.
98
     *
99
     * @return array
100
     */
101 1
    public function getFieldNames()
102
    {
103 1
        return array_keys($this->items);
104
    }
105
106
    /**
107
     * Get all of the items in the collection.
108
     *
109
     * @return array
110
     */
111
    public function all()
112
    {
113
        return $this->items;
114
    }
115
116
    /**
117
     * Get the collection of items as a plain array.
118
     *
119
     * @return array
120
     */
121
    public function asArray()
122
    {
123 3
        return array_map(function ($value) {
124 3
            if ($value instanceof GraphNode || $value instanceof GraphEdge) {
125 1
                return $value->asArray();
126
            }
127
128 2
            return $value;
129 3
        }, $this->items);
130
    }
131
132
    /**
133
     * {@inheritdoc}
134
     */
135 1
    public function map(\Closure $callback)
136
    {
137 1
        return new static(
138 1
            $this->request,
139 1
            array_map($callback, $this->items, array_keys($this->items)),
140 1
            $this->metaData,
141 1
            $this->parentEdgeEndpoint,
142 1
            $this->subclassName
143
        );
144
    }
145
146
    /**
147
     * Get the collection of items as JSON.
148
     *
149
     * @param int $options
150
     *
151
     * @return string
152
     */
153 1
    public function asJson($options = 0)
154
    {
155 1
        return json_encode($this->asArray(), $options);
156
    }
157
158
    /**
159
     * Count the number of items in the collection.
160
     *
161
     * @return int
162
     */
163 2
    public function count()
164
    {
165 2
        return count($this->items);
166
    }
167
168
    /**
169
     * Get an iterator for the items.
170
     *
171
     * @return \ArrayIterator
172
     */
173 1
    public function getIterator()
174
    {
175 1
        return new \ArrayIterator($this->items);
176
    }
177
178
    /**
179
     * Determine if an item exists at an offset.
180
     *
181
     * @param mixed $key
182
     *
183
     * @return bool
184
     */
185
    public function offsetExists($key)
186
    {
187
        return array_key_exists($key, $this->items);
188
    }
189
190
    /**
191
     * Get an item at a given offset.
192
     *
193
     * @param mixed $key
194
     *
195
     * @return mixed
196
     */
197 6
    public function offsetGet($key)
198
    {
199 6
        return $this->items[$key];
200
    }
201
202
    /**
203
     * Set the item at a given offset.
204
     *
205
     * @param mixed $key
206
     * @param mixed $value
207
     *
208
     * @return void
209
     */
210
    public function offsetSet($key, $value)
211
    {
212
        if (is_null($key)) {
213
            $this->items[] = $value;
214
        } else {
215
            $this->items[$key] = $value;
216
        }
217
    }
218
219
    /**
220
     * Unset the item at a given offset.
221
     *
222
     * @param string $key
223
     *
224
     * @return void
225
     */
226
    public function offsetUnset($key)
227
    {
228
        unset($this->items[$key]);
229
    }
230
231
    /**
232
     * Convert the collection to its string representation.
233
     *
234
     * @return string
235
     */
236
    public function __toString()
237
    {
238
        return $this->asJson();
239
    }
240
241
    /**
242
     * Gets the parent Graph edge endpoint that generated the list.
243
     *
244
     * @return null|string
245
     */
246 1
    public function getParentGraphEdge()
247
    {
248 1
        return $this->parentEdgeEndpoint;
249
    }
250
251
    /**
252
     * Gets the subclass name that the child GraphNode's are cast as.
253
     *
254
     * @return null|string
255
     */
256 1
    public function getSubClassName()
257
    {
258 1
        return $this->subclassName;
259
    }
260
261
    /**
262
     * Returns the raw meta data associated with this GraphEdge.
263
     *
264
     * @return array
265
     */
266
    public function getMetaData()
267
    {
268
        return $this->metaData;
269
    }
270
271
    /**
272
     * Returns the next cursor if it exists.
273
     *
274
     * @return null|string
275
     */
276
    public function getNextCursor()
277
    {
278
        return $this->getCursor('after');
279
    }
280
281
    /**
282
     * Returns the previous cursor if it exists.
283
     *
284
     * @return null|string
285
     */
286
    public function getPreviousCursor()
287
    {
288
        return $this->getCursor('before');
289
    }
290
291
    /**
292
     * Returns the cursor for a specific direction if it exists.
293
     *
294
     * @param string $direction The direction of the page: after|before
295
     *
296
     * @return null|string
297
     */
298
    public function getCursor($direction)
299
    {
300
        if (isset($this->metaData['paging']['cursors'][$direction])) {
301
            return $this->metaData['paging']['cursors'][$direction];
302
        }
303
304
        return null;
305
    }
306
307
    /**
308
     * Generates a pagination URL based on a cursor.
309
     *
310
     * @param string $direction The direction of the page: next|previous
311
     *
312
     * @throws SDKException
313
     *
314
     * @return null|string
315
     */
316 3
    public function getPaginationUrl($direction)
317
    {
318 3
        $this->validateForPagination();
319
320
        // Do we have a paging URL?
321 3
        if (!isset($this->metaData['paging'][$direction])) {
322
            return null;
323
        }
324
325 3
        $pageUrl = $this->metaData['paging'][$direction];
326
327 3
        return UrlManipulator::baseGraphUrlEndpoint($pageUrl);
328
    }
329
330
    /**
331
     * Validates whether or not we can paginate on this request.
332
     *
333
     * @throws SDKException
334
     */
335 4
    public function validateForPagination()
336
    {
337 4
        if ($this->request->getMethod() !== 'GET') {
338 1
            throw new SDKException('You can only paginate on a GET request.', 720);
339
        }
340 3
    }
341
342
    /**
343
     * Gets the request object needed to make a next|previous page request.
344
     *
345
     * @param string $direction The direction of the page: next|previous
346
     *
347
     * @throws SDKException
348
     *
349
     * @return null|Request
350
     */
351 2
    public function getPaginationRequest($direction)
352
    {
353 2
        $pageUrl = $this->getPaginationUrl($direction);
354 2
        if (!$pageUrl) {
355
            return null;
356
        }
357
358 2
        $newRequest = clone $this->request;
359 2
        $newRequest->setEndpoint($pageUrl);
360
361 2
        return $newRequest;
362
    }
363
364
    /**
365
     * Gets the request object needed to make a "next" page request.
366
     *
367
     * @throws SDKException
368
     *
369
     * @return null|Request
370
     */
371 1
    public function getNextPageRequest()
372
    {
373 1
        return $this->getPaginationRequest('next');
374
    }
375
376
    /**
377
     * Gets the request object needed to make a "previous" page request.
378
     *
379
     * @throws SDKException
380
     *
381
     * @return null|Request
382
     */
383 1
    public function getPreviousPageRequest()
384
    {
385 1
        return $this->getPaginationRequest('previous');
386
    }
387
388
    /**
389
     * The total number of results according to Graph if it exists.
390
     *
391
     * This will be returned if the summary=true modifier is present in the request.
392
     *
393
     * @return null|int
394
     */
395
    public function getTotalCount()
396
    {
397
        if (isset($this->metaData['summary']['total_count'])) {
398
            return $this->metaData['summary']['total_count'];
399
        }
400
401
        return null;
402
    }
403
}
404