Completed
Push — master ( d52ee7...e7842c )
by Alexandr
03:54
created

ArrayConnection::cursorToOffsetWithDefault()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3
Metric Value
dl 0
loc 10
rs 9.4285
ccs 5
cts 5
cp 1
cc 3
eloc 5
nc 3
nop 2
crap 3
1
<?php
2
/**
3
 * Date: 17.05.16
4
 *
5
 * @author Portey Vasil <[email protected]>
6
 */
7
8
namespace Youshido\GraphQL\Relay\Connection;
9
10
11
class ArrayConnection
12
{
13
14
    const PREFIX = 'arrayconnection:';
15
16 1
    public static function cursorForObjectInConnection($data, $object)
17
    {
18 1
        if (!is_array($data)) return null;
19
20 1
        $index = array_search($object, $data);
21 1
        return $index === false ? null : self::offsetToCursor($index);
22
    }
23
24
    /**
25
     * @param $offset int
26
     * @return string
27
     */
28 2
    public static function offsetToCursor($offset)
29
    {
30 2
        return base64_encode(self::PREFIX . $offset);
31
    }
32
33
    /**
34
     * @param $cursor string
35
     *
36
     * @return int|null
37
     */
38 1
    public static function cursorToOffset($cursor)
39
    {
40 1
        if ($decoded = base64_decode($cursor)) {
41 1
            return (int)substr($decoded, strlen(self::PREFIX));
42
        }
43
44 1
        return null;
45
    }
46
47 2
    public static function cursorToOffsetWithDefault($cursor, $default)
48
    {
49 2
        if (!is_string($cursor)) {
50 2
            return $default;
51
        }
52
53 1
        $offset = self::cursorToOffset($cursor);
54
55 1
        return is_null($offset) ? $default : $offset;
56
    }
57
58 1
    public static function connectionFromArray(array $data, array $args = [])
59
    {
60 1
        return self::connectionFromArraySlice($data, $args, 0, count($data));
61
    }
62
63 1
    public static function connectionFromArraySlice(array $data, array $args, $sliceStart, $arrayLength)
64
    {
65 1
        $after  = isset($args['after']) ? $args['after'] : null;
66 1
        $before = isset($args['before']) ? $args['before'] : null;
67 1
        $first  = isset($args['first']) ? $args['first'] : null;
68 1
        $last   = isset($args['last']) ? $args['last'] : null;
69
70 1
        $sliceEnd = $sliceStart + count($data);
71
72 1
        $beforeOffset = ArrayConnection::cursorToOffsetWithDefault($before, $arrayLength);
73 1
        $afterOffset  = ArrayConnection::cursorToOffsetWithDefault($after, -1);
74
75 1
        $startOffset = max($sliceStart - 1, $afterOffset, -1) + 1;
76 1
        $endOffset   = min($sliceEnd, $beforeOffset, $arrayLength);
77
78 1
        if ($first) {
79 1
            $endOffset = min($endOffset, $startOffset + $first);
80 1
        }
81
82 1
        if ($last) {
83 1
            $startOffset = max($startOffset, $endOffset - $last);
84 1
        }
85
86 1
        $slice = array_slice($data, max($startOffset - $sliceStart, 0), count($data) - ($sliceEnd - $endOffset));
87 1
        $edges = array_map(['self', 'edgeForObjectWithIndex'], $slice, array_keys($slice));
88
89 1
        $firstEdge  = array_key_exists(0, $edges) ? $edges[0] : null;
90 1
        $lastEdge   = count($edges) > 0 ? $edges[count($edges) - 1] : null;
91 1
        $lowerBound = $after ? $afterOffset + 1 : 0;
92 1
        $upperBound = $before ? $beforeOffset : $arrayLength;
93
94
        return [
95 1
            'edges'    => $edges,
96
            'pageInfo' => [
97 1
                'startCursor'     => $firstEdge ? $firstEdge['cursor'] : null,
98 1
                'endCursor'       => $lastEdge ? $lastEdge['cursor'] : null,
99 1
                'hasPreviousPage' => $last ? $startOffset > $lowerBound : false,
100 1
                'hasNextPage'     => $first ? $endOffset < $upperBound : false
101 1
            ]
102 1
        ];
103
    }
104
105 1
    public static function edgeForObjectWithIndex($object, $index)
106
    {
107
        return [
108 1
            'cursor' => ArrayConnection::offsetToCursor($index),
109
            'node'   => $object
110 1
        ];
111
    }
112
113
}