Failed Conditions
Push — v3.x ( a479f4...cb2cf1 )
by Chad
02:16
created

src/Collection.php (3 issues)

Labels
Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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)
84
    {
85
        $this->client = $client;
86
        $this->resource = $resource;
87
        $this->filters = $filters;
88
        $this->loader = $loader;
89
        $this->rewind();
90
    }
91
92
    /**
93
     * Return the count elements in this collection, @see Countable::count().
94
     *
95
     * @return integer
96
     */
97
    final public function count()
98
    {
99
        if ($this->position === -1) {
100
            $this->next();
101
        }
102
103
        return $this->total;
104
    }
105
106
    /**
107
     * Rewind the Iterator to the first element, @see Iterator::rewind().
108
     *
109
     * @return void
110
     */
111
    final public function rewind()
112
    {
113
        $this->results = null;
114
        $this->offset = 0;
115
        $this->total = 0;
116
        $this->limit = 0;
117
        $this->position = -1;
118
    }
119
120
    /**
121
     * Return the key of the current element, @see Iterator::key().
122
     *
123
     * @return integer
124
     */
125
    final public function key()
126
    {
127
        if ($this->position === -1) {
128
            $this->next();
129
        }
130
131
        Util::ensure(false, empty($this->results), '\OutOfBoundsException', ['Collection contains no elements']);
132
        return $this->offset + $this->position;
133
    }
134
135
    /**
136
     * Checks if current position is valid, @see Iterator::valid().
137
     *
138
     * @return boolean
139
     */
140
    final public function valid()
141
    {
142
        if ($this->position === -1) {
143
            $this->next();
144
        }
145
146
        return $this->offset + $this->position < $this->total;
147
    }
148
149
    /**
150
     * Move forward to next element, @see Iterator::next().
151
     *
152
     * @return void
153
     */
154
    final public function next()
155
    {
156
        ++$this->position;
157
158
        if ($this->position < $this->limit) {
159
            return;
160
        }
161
162
        $this->offset += $this->limit;
163
        $this->filters['offset'] = $this->offset;
164
        $this->filters['limit'] = $this->limit === 0 ? 20 : $this->limit;
165
        $dataWrapper = $this->client->search($this->resource, $this->filters);
166
167
        //Limit should be the total number returned, not the specified limit in the query params
168
        $this->limit = $dataWrapper->getDataWrapper()->getData()->getCount();
0 ignored issues
show
The method getDataWrapper() does not exist on Chadicus\Marvel\Api\DataWrapper. Did you maybe mean getData()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
169
        $this->total = $dataWrapper->getDataWrapper()->getData()->getTotal();
0 ignored issues
show
The method getDataWrapper() does not exist on Chadicus\Marvel\Api\DataWrapper. Did you maybe mean getData()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
170
        $this->results = $dataWrapper->getDataWrapper()->getData()->getResults();
0 ignored issues
show
The method getDataWrapper() does not exist on Chadicus\Marvel\Api\DataWrapper. Did you maybe mean getData()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

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