Completed
Pull Request — master (#133)
by Adrien
04:00
created

ArrayConnection::cursorToOffset()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 0
cp 0
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
crap 2
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),
0 ignored issues
show
Deprecated Code introduced by
The method Youshido\GraphQL\Relay\C...ction::offsetToCursor() has been deprecated with message: Use keyToCursor instead.

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.

Loading history...
146
            'node'   => $object
147 1
        ];
148
    }
149
150
}