Failed Conditions
Branch v3.x (aec8e0)
by Chad
01:59
created

Collection::valid()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
c 0
b 0
f 0
rs 9.4285
cc 2
eloc 4
nc 2
nop 0
1
<?php
2
3
namespace Chadicus\Marvel\Api;
4
5
use DominionEnterprises\Util;
6
7
/**
8
 * Class for iterating index response to the Marvel API. Collections are readonly.
9
 */
10
class Collection implements \Iterator, \Countable
11
{
12
    /**
13
     * API Client.
14
     *
15
     * @var Client
16
     */
17
    private $client;
18
19
    /**
20
     * Limit to give to API.
21
     *
22
     * @var integer
23
     */
24
    private $limit;
25
26
    /**
27
     * Offset to give to API.
28
     *
29
     * @var integer
30
     */
31
    private $offset;
32
33
    /**
34
     * Resource name for collection.
35
     *
36
     * @var string
37
     */
38
    private $resource;
39
40
    /**
41
     * Array of filters to pass to API.
42
     *
43
     * @var array
44
     */
45
    private $filters;
46
47
    /**
48
     * Total number of elements in the collection.
49
     *
50
     * @var integer
51
     */
52
    private $total;
53
54
    /**
55
     * Pointer in the paginated results.
56
     *
57
     * @var integer
58
     */
59
    private $position;
60
61
    /**
62
     * A paginated set of elements from the API.
63
     *
64
     * @var null|array
65
     */
66
    private $results;
67
68
    /**
69
     * A custom callable to return a defined type when iterating over the collection.
70
     *
71
     * @var callable
72
     */
73
    private $loader;
74
75
    /**
76
     * Create a new collection.
77
     *
78
     * @param Client   $client   A client connection to the API.
79
     * @param string   $resource The name of API resource to request.
80
     * @param array    $filters  A key value pair array of search filters.
81
     * @param callable $loader   A custom callable to use when iterating over the collection.
82
     */
83
    final public function __construct(Client $client, string $resource, array $filters = [], callable $loader = null)
0 ignored issues
show
Coding Style introduced by
Unknown type hint "string" found for $resource
Loading history...
84
    {
85
        Util::throwIfNotType(['string' => [$resource]], true);
86
87
        $this->client = $client;
88
        $this->resource = $resource;
89
        $this->filters = $filters;
90
        $this->loader = $loader;
91
        $this->rewind();
92
    }
93
94
    /**
95
     * Return the count elements in this collection, @see Countable::count().
96
     *
97
     * @return integer
98
     */
99
    final public function count()
100
    {
101
        if ($this->position === -1) {
102
            $this->next();
103
        }
104
105
        return $this->total;
106
    }
107
108
    /**
109
     * Rewind the Iterator to the first element, @see Iterator::rewind().
110
     *
111
     * @return void
112
     */
113
    final public function rewind()
114
    {
115
        $this->results = null;
116
        $this->offset = 0;
117
        $this->total = 0;
118
        $this->limit = 0;
119
        $this->position = -1;
120
    }
121
122
    /**
123
     * Return the key of the current element, @see Iterator::key().
124
     *
125
     * @return integer
126
     */
127
    final public function key()
128
    {
129
        if ($this->position === -1) {
130
            $this->next();
131
        }
132
133
        Util::ensure(false, empty($this->results), '\OutOfBoundsException', ['Collection contains no elements']);
134
135
        return $this->offset + $this->position;
136
    }
137
138
    /**
139
     * Checks if current position is valid, @see Iterator::valid().
140
     *
141
     * @return boolean
142
     */
143
    final public function valid()
144
    {
145
        if ($this->position === -1) {
146
            $this->next();
147
        }
148
149
        return $this->offset + $this->position < $this->total;
150
    }
151
152
    /**
153
     * Move forward to next element, @see Iterator::next().
154
     *
155
     * @return void
156
     */
157
    final public function next()
158
    {
159
        ++$this->position;
160
161
        if ($this->position < $this->limit) {
162
            return;
163
        }
164
165
        $this->offset += $this->limit;
166
        $this->filters['offset'] = $this->offset;
167
        $this->filters['limit'] = $this->limit === 0 ? 20 : $this->limit;
168
        $dataWrapper = $this->client->search($this->resource, $this->filters);
169
170
        $this->limit = $dataWrapper->getData()->getLimit();
0 ignored issues
show
Bug introduced by
The method getData() does not seem to exist on object<Psr\Http\Message\ResponseInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
171
        $this->total = $dataWrapper->getData()->getTotal();
0 ignored issues
show
Bug introduced by
The method getData() does not seem to exist on object<Psr\Http\Message\ResponseInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
172
        $this->results = $dataWrapper->getData()->getResults();
0 ignored issues
show
Bug introduced by
The method getData() does not seem to exist on object<Psr\Http\Message\ResponseInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
173
        $this->position = 0;
174
    }
175
176
    /**
177
     * Return the current element, @see Iterator::current().
178
     *
179
     * @return mixed Returns the element in the results array or a custom type defined by $loader.
180
     */
181
    final public function current()
182
    {
183
        if ($this->position === -1) {
184
            $this->next();
185
        }
186
187
        Util::ensure(
188
            true,
189
            array_key_exists($this->position, $this->results),
190
            '\OutOfBoundsException',
191
            ['Collection contains no element at current position']
192
        );
193
194
        if ($this->loader === null) {
195
            return $this->results[$this->position];
196
        }
197
198
        return call_user_func_array($this->loader, [$this->results[$this->position]]);
199
    }
200
}
201