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

ArrayConnection   A

Complexity

Total Complexity 29

Size/Duplication

Total Lines 140
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 0

Test Coverage

Coverage 98.18%

Importance

Changes 0
Metric Value
wmc 29
lcom 2
cbo 0
dl 0
loc 140
ccs 54
cts 55
cp 0.9818
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A cursorForObjectInConnection() 0 7 3
A offsetToCursor() 0 4 1
A keyToCursor() 0 4 1
A cursorToOffset() 0 4 1
A cursorToKey() 0 6 2
A cursorToOffsetWithDefault() 0 16 4
A connectionFromArray() 0 4 1
F connectionFromArraySlice() 0 44 15
A edgeForObjectWithIndex() 0 7 1
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
}