Completed
Pull Request — master (#50)
by Mr
14:25 queued 05:48
created

ResponseIterator::offsetSet()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2.032

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 4
cts 5
cp 0.8
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 2
crap 2.032
1
<?php
2
3
namespace RouterOS;
4
5
use Iterator;
6
use ArrayAccess;
7
use Countable;
8
use Serializable;
9
use function array_keys;
10
use function array_slice;
11
use function count;
12
use function serialize;
13
use function unserialize;
14
15
/**
16
 * This class was created by memory save reasons, it convert response
17
 * from RouterOS to readable array in safe way.
18
 *
19
 * @param array $raw Array RAW response from server
20
 *
21
 * @return mixed
22
 *
23
 * Based on RouterOSResponseArray solution by @arily
24
 *
25
 * @package RouterOS\Iterators
26
 * @link    https://github.com/arily/RouterOSResponseArray
27
 * @since   1.0.0
28
 */
29
class ResponseIterator implements Iterator, ArrayAccess, Countable, Serializable
30
{
31
    /**
32
     * List of parser results from array
33
     *
34
     * @var array
35
     */
36
    private $parsed = [];
37
38
    /**
39
     * List of RAW results from RouterOS
40
     *
41
     * @var array
42
     */
43
    private $raw;
44
45
    /**
46
     * Initial value of array position
47
     *
48
     * @var int
49
     */
50
    private $current = 0;
51
52
    /**
53
     * Object of main client
54
     *
55
     * @var \RouterOS\Client
56
     */
57
    private $client;
58
59
    /**
60
     * ResponseIterator constructor.
61
     *
62
     * @param \RouterOS\Client $client
63
     * @param array            $options Additional options
64
     */
65 3
    public function __construct(Client $client, array $options = [])
66
    {
67
        // Set current to default
68 3
        $this->rewind();
69
70
        // Save client as parameter of object
71 3
        $this->client = $client;
72
73
        // Read RAW data from client
74 3
        $raw = $client->read(false, $options);
75
76
        // This RAW shouldn't be an error
77 3
        $positions = array_keys($raw, '!re');
78 3
        $count     = count($raw);
79 3
        $result    = [];
80
81 3
        if (isset($positions[1])) {
82
83 2
            foreach ($positions as $key => $position) {
84
85
                // Get length of future block
86 2
                $length = isset($positions[$key + 1])
87 2
                    ? $positions[$key + 1] - $position + 1
88 2
                    : $count - $position;
89
90
                // Convert array to simple items, save as result
91 2
                $result[] = array_slice($raw, $position, $length);
92
            }
93
94
        } else {
95 2
            $result = [$raw];
96
        }
97
98 3
        $this->raw = $result;
99 3
    }
100
101
    /**
102
     * Move forward to next element
103
     */
104 1
    public function next(): void
105
    {
106 1
        ++$this->current;
107 1
    }
108
109
    /**
110
     * Previous value
111
     */
112 1
    public function prev(): void
113
    {
114 1
        --$this->current;
115 1
    }
116
117
    /**
118
     * Return the current element
119
     *
120
     * @return mixed
121
     */
122 1
    public function current()
123
    {
124 1
        if (isset($this->parsed[$this->current])) {
125 1
            return $this->parsed[$this->current];
126
        }
127
128 1
        if ($this->valid()) {
129
130 1
            if (!isset($this->parsed[$this->current])) {
131 1
                $value = $this->client->parseResponse($this->raw[$this->current])[0];
132 1
                $this->offsetSet($this->current, $value);
133
            }
134
135 1
            return $this->parsed[$this->current];
136
        }
137
138 1
        return null;
139
    }
140
141
    /**
142
     * Return the key of the current element
143
     *
144
     * @return mixed
145
     */
146 1
    public function key()
147
    {
148 1
        return $this->current;
149
    }
150
151
    /**
152
     * Checks if current position is valid
153
     *
154
     * @return bool
155
     */
156 1
    public function valid(): bool
157
    {
158 1
        return isset($this->raw[$this->current]);
159
    }
160
161
    /**
162
     * Count elements of an object
163
     *
164
     * @return int
165
     */
166 1
    public function count(): int
167
    {
168 1
        return count($this->raw);
169
    }
170
171
    /**
172
     * Rewind the Iterator to the first element
173
     */
174 3
    public function rewind(): void
175
    {
176 3
        $this->current = 0;
177 3
    }
178
179
    /**
180
     * Offset to set
181
     *
182
     * @param mixed $offset
183
     * @param mixed $value
184
     */
185 1
    public function offsetSet($offset, $value): void
186
    {
187 1
        if (null === $offset) {
188
            $this->parsed[] = $value;
189
        } else {
190 1
            $this->parsed[$offset] = $value;
191
        }
192 1
    }
193
194
    /**
195
     * Whether a offset exists
196
     *
197
     * @param mixed $offset
198
     *
199
     * @return bool
200
     */
201
    public function offsetExists($offset): bool
202
    {
203
        return isset($this->raw[$offset]) && $this->raw[$offset] !== ['!re'];
204
    }
205
206
    /**
207
     * Offset to unset
208
     *
209
     * @param mixed $offset
210
     */
211
    public function offsetUnset($offset): void
212
    {
213
        unset($this->parsed[$offset], $this->raw[$offset]);
214
    }
215
216
    /**
217
     * Offset to retrieve
218
     *
219
     * @param mixed $offset
220
     *
221
     * @return bool|mixed
222
     */
223 1
    public function offsetGet($offset)
224
    {
225 1
        if (isset($this->parsed[$offset])) {
226
            return $this->parsed[$offset];
227
        }
228
229 1
        if (isset($this->raw[$offset]) && $this->raw[$offset] !== null) {
230 1
            $f = $this->client->parseResponse($this->raw[$offset]);
231 1
            if ($f !== []) {
232 1
                return $this->parsed[$offset] = $f[0];
233
            }
234
        }
235
236
        return false;
237
    }
238
239
    /**
240
     * String representation of object
241
     *
242
     * @return string
243
     */
244 1
    public function serialize(): string
245
    {
246 1
        return serialize($this->raw);
247
    }
248
249
    /**
250
     * Constructs the object
251
     *
252
     * @param string $serialized
253
     */
254
    public function unserialize($serialized): void
255
    {
256
        $this->raw = unserialize($serialized, null);
257
    }
258
}
259