Completed
Pull Request — master (#40)
by Mr
05:34
created

Query   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 249
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 83.64%

Importance

Changes 0
Metric Value
wmc 25
lcom 1
cbo 1
dl 0
loc 249
ccs 46
cts 55
cp 0.8364
rs 10
c 0
b 0
f 0

12 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 13 3
A where() 0 4 1
A equal() 0 4 1
B world() 0 27 7
A operations() 0 5 1
A tag() 0 5 1
A add() 0 5 1
A getAttributes() 0 4 1
A setAttributes() 0 5 1
A getEndpoint() 0 4 1
A setEndpoint() 0 5 1
B getQuery() 0 22 6
1
<?php
2
3
namespace RouterOS;
4
5
use RouterOS\Exceptions\QueryException;
6
use RouterOS\Interfaces\QueryInterface;
7
use function in_array;
8
use function is_array;
9
use function is_string;
10
11
/**
12
 * Class Query for building queries
13
 *
14
 * @package RouterOS
15
 * @since   0.1
16
 */
17
class Query implements QueryInterface
18
{
19
    /**
20
     * Array of query attributes
21
     *
22
     * @var array
23
     */
24
    private $_attributes = [];
25
26
    /**
27
     * Some additional operations
28
     *
29
     * @var string
30
     */
31
    private $_operations;
32
33
    /**
34
     * Tag of query
35
     *
36
     * @var string
37
     */
38
    private $_tag;
39
40
    /**
41
     * Endpoint of query
42
     *
43
     * @var string
44
     */
45
    private $_endpoint;
46
47
    /**
48
     * List of available operators for "->where()" method
49
     */
50
    public const AVAILABLE_OPERATORS = [
51
        '-',  // Does not have
52
        '=',  // Equal
53
        '>',  // More than
54
        '<'   // Less than
55
    ];
56
57
    /**
58
     * Query constructor.
59
     *
60
     * @param array|string $endpoint   Path of endpoint
61
     * @param array        $attributes List of attributes which should be set
62
     *
63
     * @throws \RouterOS\Exceptions\QueryException
64
     */
65 19
    public function __construct($endpoint, array $attributes = [])
66
    {
67 19
        if (is_string($endpoint)) {
68 19
            $this->setEndpoint($endpoint);
69 19
            $this->setAttributes($attributes);
70 1
        } elseif (is_array($endpoint)) {
71
            $query = array_shift($endpoint);
72
            $this->setEndpoint($query);
73
            $this->setAttributes($endpoint);
74
        } else {
75 1
            throw new QueryException('Specified endpoint is incorrect');
76
        }
77 19
    }
78
79
    /**
80
     * Where logic of query
81
     *
82
     * @param string          $key      Key which need to find
83
     * @param bool|string|int $value    Value which need to check (by default true)
84
     * @param bool|string|int $operator It may be one from list [-,=,>,<]
85
     *
86
     * @return \RouterOS\Interfaces\QueryInterface
87
     * @throws \RouterOS\Exceptions\QueryException
88
     * @since 1.0.0
89
     */
90 1
    public function where(string $key, $operator = null, $value = null): QueryInterface
91
    {
92 1
        return $this->world('?' . $key, $operator, $value);
93
    }
94
95
    /**
96
     * Setter for write/update queries
97
     *
98
     * @param string          $key   Key which need to find
99
     * @param bool|string|int $value Value which need to check (by default true)
100
     *
101
     * @return \RouterOS\Interfaces\QueryInterface
102
     * @throws \RouterOS\Exceptions\QueryException
103
     * @since 1.1
104
     */
105
    public function equal(string $key, $value = null): QueryInterface
106
    {
107
        return $this->world('=' . $key, null, $value);
108
    }
109
110
    /**
111
     * Write world to RouterOS (the work is mine)
112
     *
113
     * @param string          $key      Key which need to find
114
     * @param bool|string|int $value    Value which need to check (by default true)
115
     * @param bool|string|int $operator It may be one from list [-,=,>,<]
116
     *
117
     * @return \RouterOS\Interfaces\QueryInterface
118
     * @throws \RouterOS\Exceptions\QueryException
119
     */
120 1
    private function world(string $key, $operator = null, $value = null): QueryInterface
121
    {
122 1
        if (null !== $operator && null === $value) {
123
124
            // Client may set only two parameters, that mean what $operator is $value
125 1
            $value = $operator;
126
127
            // And operator should be "="
128 1
            $operator = null;
129
        }
130
131 1
        if (null !== $operator && null !== $value) {
132
            // If operator is available in list
133 1
            if (in_array($operator, self::AVAILABLE_OPERATORS, true)) {
134 1
                $key = $operator . $key;
135
            } else {
136
                throw new QueryException('Operator "' . $operator . '" in not in allowed list [' . implode(',', self::AVAILABLE_OPERATORS) . ']');
137
            }
138
        }
139
140 1
        if (null !== $value) {
141 1
            $value = '=' . $value;
142
        }
143
144 1
        $this->add($key . $value);
145 1
        return $this;
146
    }
147
148
    /**
149
     * Append additional operations
150
     *
151
     * @param string $operations
152
     *
153
     * @return \RouterOS\Interfaces\QueryInterface
154
     * @since 1.0.0
155
     */
156 1
    public function operations(string $operations): QueryInterface
157
    {
158 1
        $this->_operations = '?#' . $operations;
159 1
        return $this;
160
    }
161
162
    /**
163
     * Append tag to query (it should be at end)
164
     *
165
     * @param string $name
166
     *
167
     * @return \RouterOS\Interfaces\QueryInterface
168
     * @since 1.0.0
169
     */
170 1
    public function tag(string $name): QueryInterface
171
    {
172 1
        $this->_tag = '.tag=' . $name;
173 1
        return $this;
174
    }
175
176
    /**
177
     * Append to array yet another attribute of query
178
     *
179
     * @param string $word
180
     *
181
     * @return \RouterOS\Interfaces\QueryInterface
182
     */
183 1
    public function add(string $word): QueryInterface
184
    {
185 1
        $this->_attributes[] = $word;
186 1
        return $this;
187
    }
188
189
    /**
190
     * Get attributes array of current query
191
     *
192
     * @return array
193
     */
194 19
    public function getAttributes(): array
195
    {
196 19
        return $this->_attributes;
197
    }
198
199
    /**
200
     * Set array of attributes
201
     *
202
     * @param array $attributes
203
     *
204
     * @return \RouterOS\Interfaces\QueryInterface
205
     * @since 0.7
206
     */
207 19
    public function setAttributes(array $attributes): QueryInterface
208
    {
209 19
        $this->_attributes = $attributes;
210 19
        return $this;
211
    }
212
213
    /**
214
     * Get endpoint of current query
215
     *
216
     * @return string|null
217
     */
218
    public function getEndpoint(): ?string
219
    {
220
        return $this->_endpoint;
221
    }
222
223
    /**
224
     * Set endpoint of query
225
     *
226
     * @param string|null $endpoint
227
     *
228
     * @return \RouterOS\Interfaces\QueryInterface
229
     * @since 0.7
230
     */
231 19
    public function setEndpoint(string $endpoint = null): QueryInterface
232
    {
233 19
        $this->_endpoint = $endpoint;
234 19
        return $this;
235
    }
236
237
    /**
238
     * Build body of query
239
     *
240
     * @return array
241
     * @throws \RouterOS\Exceptions\QueryException
242
     */
243 19
    public function getQuery(): array
244
    {
245 19
        if ($this->_endpoint === null) {
246
            throw new QueryException('Endpoint of query is not set');
247
        }
248
249
        // Get all attributes and prepend endpoint to this list
250 19
        $attributes = $this->getAttributes();
251 19
        array_unshift($attributes, $this->_endpoint);
252
253
        // If operations is set then add to query
254 19
        if (is_string($this->_operations) && !empty($this->_operations)) {
255 1
            $attributes[] = $this->_operations;
256
        }
257
258
        // If tag is set then added to query
259 19
        if (is_string($this->_tag) && !empty($this->_tag)) {
260 1
            $attributes[] = $this->_tag;
261
        }
262
263 19
        return $attributes;
264
    }
265
}
266