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 : (string) self::keyToCursor($index); |
22
|
|
|
} |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* @param $offset int |
26
|
|
|
* @return string |
27
|
|
|
* @deprecated |
28
|
|
|
* Use keyToCursor instead. |
29
|
|
|
*/ |
30
|
|
|
public static function offsetToCursor($offset) |
31
|
|
|
{ |
32
|
|
|
return self::keyToCursor($offset); |
33
|
|
|
} |
34
|
|
|
|
35
|
2 |
|
public static function keyToCursor($key) |
36
|
|
|
{ |
37
|
2 |
|
return base64_encode(self::PREFIX . $key); |
38
|
|
|
} |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* @param $cursor string |
42
|
|
|
* |
43
|
|
|
* @return int|null |
44
|
|
|
* @deprecated Use cursorToKey instead. |
45
|
|
|
*/ |
46
|
|
|
public static function cursorToOffset($cursor) |
47
|
|
|
{ |
48
|
|
|
return self::cursorToKey($cursor); |
49
|
|
|
} |
50
|
|
|
|
51
|
|
|
/** |
52
|
|
|
* Converts a cursor to its array key. |
53
|
|
|
* |
54
|
|
|
* @param $cursor |
55
|
|
|
* @return null|string |
56
|
|
|
*/ |
57
|
1 |
|
public static function cursorToKey($cursor) { |
58
|
1 |
|
if ($decoded = base64_decode($cursor)) { |
59
|
1 |
|
return substr($decoded, strlen(self::PREFIX)); |
60
|
|
|
} |
61
|
1 |
|
return null; |
62
|
|
|
} |
63
|
|
|
|
64
|
|
|
/** |
65
|
|
|
* Converts a cursor to an array offset. |
66
|
|
|
* |
67
|
|
|
* @param $cursor |
68
|
|
|
* The cursor string. |
69
|
|
|
* @param $default |
70
|
|
|
* The default value, in case the cursor is not given. |
71
|
|
|
* @param array $array |
72
|
|
|
* The array to use in counting the offset. If empty, assumed to be an indexed array. |
73
|
|
|
* @return int|null |
74
|
|
|
*/ |
75
|
2 |
|
public static function cursorToOffsetWithDefault($cursor, $default, $array = []) |
76
|
|
|
{ |
77
|
2 |
|
if (!is_string($cursor)) { |
78
|
2 |
|
return $default; |
79
|
|
|
} |
80
|
|
|
|
81
|
1 |
|
$key = self::cursorToKey($cursor); |
82
|
1 |
|
if (empty($array)) { |
83
|
1 |
|
$offset = $key; |
84
|
1 |
|
} |
85
|
|
|
else { |
86
|
|
|
$offset = array_search($key, array_keys($array)); |
87
|
|
|
} |
88
|
|
|
|
89
|
1 |
|
return is_null($offset) ? $default : (int) $offset; |
90
|
|
|
} |
91
|
|
|
|
92
|
1 |
|
public static function connectionFromArray(array $data, array $args = []) |
93
|
|
|
{ |
94
|
1 |
|
return self::connectionFromArraySlice($data, $args, 0, count($data)); |
95
|
|
|
} |
96
|
|
|
|
97
|
1 |
|
public static function connectionFromArraySlice(array $data, array $args, $sliceStart, $arrayLength) |
98
|
|
|
{ |
99
|
1 |
|
$after = isset($args['after']) ? $args['after'] : null; |
100
|
1 |
|
$before = isset($args['before']) ? $args['before'] : null; |
101
|
1 |
|
$first = isset($args['first']) ? $args['first'] : null; |
102
|
1 |
|
$last = isset($args['last']) ? $args['last'] : null; |
103
|
|
|
|
104
|
1 |
|
$sliceEnd = $sliceStart + count($data); |
105
|
|
|
|
106
|
1 |
|
$beforeOffset = ArrayConnection::cursorToOffsetWithDefault($before, $arrayLength, $data); |
107
|
1 |
|
$afterOffset = ArrayConnection::cursorToOffsetWithDefault($after, -1, $data); |
108
|
|
|
|
109
|
1 |
|
$startOffset = max($sliceStart - 1, $afterOffset, -1) + 1; |
110
|
1 |
|
$endOffset = min($sliceEnd, $beforeOffset, $arrayLength); |
111
|
|
|
|
112
|
1 |
|
if ($first) { |
113
|
1 |
|
$endOffset = min($endOffset, $startOffset + $first); |
114
|
1 |
|
} |
115
|
|
|
|
116
|
1 |
|
if ($last) { |
117
|
1 |
|
$startOffset = max($startOffset, $endOffset - $last); |
118
|
1 |
|
} |
119
|
|
|
|
120
|
1 |
|
$arraySliceStart = max($startOffset - $sliceStart, 0); |
121
|
1 |
|
$arraySliceEnd = count($data) - ($sliceEnd - $endOffset) - $arraySliceStart; |
122
|
|
|
|
123
|
1 |
|
$slice = array_slice($data, $arraySliceStart, $arraySliceEnd, true); |
124
|
1 |
|
$edges = array_map(['self', 'edgeForObjectWithIndex'], $slice, array_keys($slice)); |
125
|
|
|
|
126
|
1 |
|
$firstEdge = array_key_exists(0, $edges) ? $edges[0] : null; |
127
|
1 |
|
$lastEdge = count($edges) > 0 ? $edges[count($edges) - 1] : null; |
128
|
1 |
|
$lowerBound = $after ? $afterOffset + 1 : 0; |
129
|
1 |
|
$upperBound = $before ? $beforeOffset : $arrayLength; |
130
|
|
|
|
131
|
|
|
return [ |
132
|
1 |
|
'edges' => $edges, |
133
|
|
|
'pageInfo' => [ |
134
|
1 |
|
'startCursor' => $firstEdge ? $firstEdge['cursor'] : null, |
135
|
1 |
|
'endCursor' => $lastEdge ? $lastEdge['cursor'] : null, |
136
|
1 |
|
'hasPreviousPage' => $last ? $startOffset > $lowerBound : false, |
137
|
1 |
|
'hasNextPage' => $first ? $endOffset < $upperBound : false |
138
|
1 |
|
] |
139
|
1 |
|
]; |
140
|
|
|
} |
141
|
|
|
|
142
|
1 |
|
public static function edgeForObjectWithIndex($object, $index) |
143
|
|
|
{ |
144
|
|
|
return [ |
145
|
1 |
|
'cursor' => ArrayConnection::offsetToCursor($index), |
|
|
|
|
146
|
|
|
'node' => $object |
147
|
1 |
|
]; |
148
|
|
|
} |
149
|
|
|
|
150
|
|
|
} |
This method has been deprecated. The supplier of the class has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.