ArrayConnection::connectionFromArraySlice()   F
last analyzed

Complexity

Conditions 15
Paths 16384

Size

Total Lines 45

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 32
CRAP Score 15

Importance

Changes 0
Metric Value
dl 0
loc 45
ccs 32
cts 32
cp 1
rs 1.7499
c 0
b 0
f 0
cc 15
nc 16384
nop 4
crap 15

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
            'totalCount' => count($data),
133 1
            'edges'      => $edges,
134
            'pageInfo'   => [
135 1
                'startCursor'     => $firstEdge ? $firstEdge['cursor'] : null,
136 1
                'endCursor'       => $lastEdge ? $lastEdge['cursor'] : null,
137 1
                'hasPreviousPage' => $last ? $startOffset > $lowerBound : false,
138 1
                'hasNextPage'     => $first ? $endOffset < $upperBound : false,
139 1
            ],
140 1
        ];
141
    }
142
143 1
    public static function edgeForObjectWithIndex($object, $index)
144
    {
145
        return [
146 1
            'cursor' => ArrayConnection::keyToCursor($index),
147
            'node'   => $object
148 1
        ];
149
    }
150
151
}
152