1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Created by PhpStorm. |
4
|
|
|
* User: kousakananako |
5
|
|
|
* Date: 2019/05/30 |
6
|
|
|
* Time: 2:07 |
7
|
|
|
*/ |
8
|
|
|
|
9
|
|
|
namespace RouterOS\Iterators; |
10
|
|
|
|
11
|
|
|
/** |
12
|
|
|
* Class ResponseIterator |
13
|
|
|
* @package RouterOS\Iterators |
14
|
|
|
*/ |
15
|
|
|
|
16
|
|
|
class ResponseIterator implements \Iterator, \ArrayAccess, \Countable { |
17
|
|
|
|
18
|
|
|
public $parsed = []; |
19
|
|
|
public $raw = []; |
20
|
|
|
public $current; |
21
|
|
|
public $length; |
22
|
|
|
|
23
|
|
|
public function __construct($raw) { |
24
|
|
|
$this->current = 0; |
25
|
|
|
// This RAW should't be an error |
26
|
|
|
$positions = array_keys($raw, '!re'); |
27
|
|
|
$this->length = count($positions); |
28
|
|
|
$count = count($raw); |
29
|
|
|
$result = []; |
30
|
|
|
|
31
|
|
|
if (isset($positions[1])) { |
32
|
|
|
|
33
|
|
|
foreach ($positions as $key => $position) { |
34
|
|
|
// Get length of future block |
35
|
|
|
$length = isset($positions[$key + 1]) |
36
|
|
|
? $positions[$key + 1] - $position + 1 |
37
|
|
|
: $count - $position; |
38
|
|
|
|
39
|
|
|
// Convert array to simple items |
40
|
|
|
// Save as result |
41
|
|
|
$result[] = array_slice($raw, $position, $length); |
42
|
|
|
} |
43
|
|
|
|
44
|
|
|
} else { |
45
|
|
|
$result = [$raw]; |
46
|
|
|
} |
47
|
|
|
|
48
|
|
|
$this->raw = $result; |
49
|
|
|
} |
50
|
|
|
public function next() { |
51
|
|
|
++$this->current; |
52
|
|
|
} |
53
|
|
|
public function current() { |
54
|
|
|
if (isset($this->parsed[$this->current])) { |
55
|
|
|
return $this->parsed[$this->current]; |
56
|
|
|
} elseif (isset($this->raw[$this->current])) { |
57
|
|
|
return $this->parseResponse($this->raw[$this->current])[0]; |
58
|
|
|
} else { |
59
|
|
|
return FALSE; |
60
|
|
|
} |
61
|
|
|
} |
62
|
|
|
public function key() { |
63
|
|
|
return $this->current; |
64
|
|
|
} |
65
|
|
|
public function valid() { |
66
|
|
|
return isset($this->raw[$this->current]); |
67
|
|
|
} |
68
|
|
|
public function count() { |
69
|
|
|
return count($this->raw); |
70
|
|
|
} |
71
|
|
|
public function rewind() { |
72
|
|
|
$this->current = 0; |
73
|
|
|
} |
74
|
|
|
public function offsetSet($offset, $value) { |
75
|
|
|
if (is_null($offset)) { |
76
|
|
|
$this->parsed[] = $value; |
77
|
|
|
throw new \RuntimeException('don\'t append to me It will cause a Bug sometime I PROMISE'); |
78
|
|
|
} else { |
79
|
|
|
$this->parsed[$offset] = $value; |
80
|
|
|
} |
81
|
|
|
} |
82
|
|
|
public function offsetExists($offset) { |
83
|
|
|
return isset($this->raw[$offset]) && $this->raw[$offset] !== ['!re']; |
84
|
|
|
} |
85
|
|
|
public function offsetUnset($offset) { |
86
|
|
|
unset($this->parsed[$offset]); |
87
|
|
|
unset($this->raw[$offset]); |
88
|
|
|
} |
89
|
|
|
public function offsetGet($offset) { |
90
|
|
|
if (isset($this->parsed[$offset])) { |
91
|
|
|
return $this->parsed[$offset]; |
92
|
|
|
} elseif (isset($this->raw[$offset]) && $this->raw[$offset] !== NULL) { |
93
|
|
|
$f = $this->parseResponse($this->raw[$offset]); |
94
|
|
|
if ($f !== []) { |
95
|
|
|
$r = $this->parsed[$offset] = $f[0]; |
96
|
|
|
return $r; |
97
|
|
|
} |
98
|
|
|
} else { |
99
|
|
|
return FALSE; |
100
|
|
|
} |
101
|
|
|
} |
102
|
|
|
public function flush() { |
103
|
|
|
$this->raw = []; |
104
|
|
|
$this->parsed = []; |
105
|
|
|
} |
106
|
|
View Code Duplication |
private function parseResponse(array $response): array |
|
|
|
|
107
|
|
|
{ |
108
|
|
|
$result = []; |
109
|
|
|
$i = -1; |
110
|
|
|
$lines = \count($response); |
111
|
|
|
foreach ($response as $key => $value) { |
112
|
|
|
switch ($value) { |
113
|
|
|
case '!re': |
114
|
|
|
$i++; |
115
|
|
|
break; |
116
|
|
|
case '!fatal': |
117
|
|
|
$result = $response; |
118
|
|
|
break 2; |
119
|
|
|
case '!trap': |
120
|
|
|
case '!done': |
121
|
|
|
// Check for =ret=, .tag and any other following messages |
122
|
|
|
for ($j = $key + 1; $j <= $lines; $j++) { |
123
|
|
|
// If we have lines after current one |
124
|
|
|
if (isset($response[$j])) { |
125
|
|
|
$this->pregResponse($response[$j], $matches); |
126
|
|
|
if (isset($matches[1][0], $matches[2][0])) { |
127
|
|
|
$result['after'][$matches[1][0]] = $matches[2][0]; |
128
|
|
|
} |
129
|
|
|
} |
130
|
|
|
} |
131
|
|
|
break 2; |
132
|
|
|
default: |
133
|
|
|
$this->pregResponse($value, $matches); |
134
|
|
|
if (isset($matches[1][0], $matches[2][0])) { |
135
|
|
|
$result[$i][$matches[1][0]] = $matches[2][0]; |
136
|
|
|
} |
137
|
|
|
break; |
138
|
|
|
} |
139
|
|
|
} |
140
|
|
|
return $result; |
141
|
|
|
} |
142
|
|
|
private function pregResponse(string $value, &$matches) { |
143
|
|
|
preg_match_all('/^[=|\.](.*)=(.*)/', $value, $matches); |
144
|
|
|
} |
145
|
|
|
} |
146
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.