Completed
Pull Request — master (#40)
by Mr
06:35
created

ResponseIterator::offsetGet()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
dl 0
loc 15
ccs 0
cts 8
cp 0
rs 9.4555
c 0
b 0
f 0
cc 5
nc 4
nop 1
crap 30
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 Client $client
63
     */
64
    public function __construct(Client $client)
65
    {
66
        // Set current to default
67
        $this->rewind();
68
69
        // Save client as parameter of object
70
        $this->client = $client;
71
72
        // Read RAW data from client
73
        $raw = $client->read(false);
74
75
        // This RAW should't be an error
76
        $positions = array_keys($raw, '!re');
77
        $count     = count($raw);
78
        $result    = [];
79
80
        if (isset($positions[1])) {
81
82
            foreach ($positions as $key => $position) {
83
84
                // Get length of future block
85
                $length = isset($positions[$key + 1])
86
                    ? $positions[$key + 1] - $position + 1
87
                    : $count - $position;
88
89
                // Convert array to simple items, save as result
90
                $result[] = array_slice($raw, $position, $length);
91
            }
92
93
        } else {
94
            $result = [$raw];
95
        }
96
97
        $this->raw = $result;
98
    }
99
100
    /**
101
     * Move forward to next element
102
     */
103
    public function next(): void
104
    {
105
        ++$this->current;
106
    }
107
108
    /**
109
     * Previous value
110
     */
111
    public function prev(): void
112
    {
113
        --$this->current;
114
    }
115
116
    /**
117
     * Return the current element
118
     *
119
     * @return mixed
120
     */
121
    public function current()
122
    {
123
        if (isset($this->parsed[$this->current])) {
124
            return $this->parsed[$this->current];
125
        }
126
127
        if ($this->valid()) {
128
129
            if (!isset($this->parsed[$this->current])) {
130
                $value = $this->client->parseResponse($this->raw[$this->current])[0];
131
                $this->offsetSet($this->current, $value);
132
            }
133
134
            return $this->parsed[$this->current];
135
        }
136
137
        return null;
138
    }
139
140
    /**
141
     * Return the key of the current element
142
     *
143
     * @return mixed
144
     */
145
    public function key()
146
    {
147
        return $this->current;
148
    }
149
150
    /**
151
     * Checks if current position is valid
152
     *
153
     * @return bool
154
     */
155
    public function valid(): bool
156
    {
157
        return isset($this->raw[$this->current]);
158
    }
159
160
    /**
161
     * Count elements of an object
162
     *
163
     * @return int
164
     */
165
    public function count(): int
166
    {
167
        return count($this->raw);
168
    }
169
170
    /**
171
     * Rewind the Iterator to the first element
172
     */
173
    public function rewind(): void
174
    {
175
        $this->current = 0;
176
    }
177
178
    /**
179
     * Offset to set
180
     *
181
     * @param mixed $offset
182
     * @param mixed $value
183
     */
184
    public function offsetSet($offset, $value): void
185
    {
186
        if (null === $offset) {
187
            $this->parsed[] = $value;
188
        } else {
189
            $this->parsed[$offset] = $value;
190
        }
191
    }
192
193
    /**
194
     * Whether a offset exists
195
     *
196
     * @param mixed $offset
197
     *
198
     * @return bool
199
     */
200
    public function offsetExists($offset): bool
201
    {
202
        return isset($this->raw[$offset]) && $this->raw[$offset] !== ['!re'];
203
    }
204
205
    /**
206
     * Offset to unset
207
     *
208
     * @param mixed $offset
209
     */
210
    public function offsetUnset($offset): void
211
    {
212
        unset($this->parsed[$offset], $this->raw[$offset]);
213
    }
214
215
    /**
216
     * Offset to retrieve
217
     *
218
     * @param mixed $offset
219
     *
220
     * @return bool|mixed
221
     */
222
    public function offsetGet($offset)
223
    {
224
        if (isset($this->parsed[$offset])) {
225
            return $this->parsed[$offset];
226
        }
227
228
        if (isset($this->raw[$offset]) && $this->raw[$offset] !== null) {
229
            $f = $this->client->parseResponse($this->raw[$offset]);
230
            if ($f !== []) {
231
                return $this->parsed[$offset] = $f[0];
232
            }
233
        }
234
235
        return false;
236
    }
237
238
    /**
239
     * String representation of object
240
     *
241
     * @return string
242
     */
243
    public function serialize(): string
244
    {
245
        return serialize($this->raw);
246
    }
247
248
    /**
249
     * Constructs the object
250
     *
251
     * @param string $serialized
252
     */
253
    public function unserialize($serialized): void
254
    {
255
        $this->raw = unserialize($serialized, null);
256
    }
257
}
258