This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /* |
||
4 | * The MIT License |
||
5 | * |
||
6 | * Copyright 2014-2018 James Ekow Abaka Ainooson |
||
7 | * |
||
8 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
||
9 | * of this software and associated documentation files (the "Software"), to deal |
||
10 | * in the Software without restriction, including without limitation the rights |
||
11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||
12 | * copies of the Software, and to permit persons to whom the Software is |
||
13 | * furnished to do so, subject to the following conditions: |
||
14 | * |
||
15 | * The above copyright notice and this permission notice shall be included in |
||
16 | * all copies or substantial portions of the Software. |
||
17 | * |
||
18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||
19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||
20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||
21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||
22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||
23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||
24 | * THE SOFTWARE. |
||
25 | */ |
||
26 | |||
27 | namespace ntentan\nibii; |
||
28 | |||
29 | use ntentan\nibii\exceptions\FieldNotFoundException; |
||
30 | use ntentan\nibii\exceptions\NibiiException; |
||
31 | |||
32 | /** |
||
33 | * Holds parameters used for the fields, where clauses, limits and offsets in queries. |
||
34 | * |
||
35 | * @author ekow |
||
36 | */ |
||
37 | class QueryParameters |
||
38 | { |
||
39 | /** |
||
40 | * The where clause string of the query parameters. |
||
41 | * |
||
42 | * @var string |
||
43 | */ |
||
44 | private $whereClause; |
||
45 | |||
46 | /** |
||
47 | * The string used for conjuctions. |
||
48 | * This could either be 'AND' and or an 'OR' operator. |
||
49 | * |
||
50 | * @var string |
||
51 | */ |
||
52 | private $conjunction = ''; |
||
53 | |||
54 | /** |
||
55 | * Data that will be bound when a query is executed with this object. |
||
56 | * |
||
57 | * @var array |
||
58 | */ |
||
59 | private $boundData = []; |
||
60 | |||
61 | /** |
||
62 | * This flag is set to true whenever there is bound data prepared. |
||
63 | * |
||
64 | * @var bool |
||
65 | */ |
||
66 | private $preparedBoundData = false; |
||
67 | |||
68 | /** |
||
69 | * A list of fields that have arrays bound to them. |
||
70 | * |
||
71 | * @var array |
||
72 | */ |
||
73 | private $boundArrays = []; |
||
74 | |||
75 | /** |
||
76 | * A list of fields that should be returned for the query. |
||
77 | * |
||
78 | * @var array |
||
79 | */ |
||
80 | private $fields = []; |
||
81 | |||
82 | /** |
||
83 | * The database table to be queried. |
||
84 | * |
||
85 | * @var null|string |
||
86 | */ |
||
87 | private $table; |
||
88 | |||
89 | /** |
||
90 | * When this flag is set, only the first item in the query is returned. |
||
91 | * It essentially forces a limit of 1. |
||
92 | * |
||
93 | * @var bool |
||
94 | */ |
||
95 | private $firstOnly = false; |
||
96 | |||
97 | /** |
||
98 | * The number of records to return after the query. |
||
99 | * |
||
100 | * @var int |
||
101 | */ |
||
102 | private $limit; |
||
103 | |||
104 | /** |
||
105 | * The number of items to skip in the query. |
||
106 | * |
||
107 | * @var int |
||
108 | */ |
||
109 | private $offset; |
||
110 | |||
111 | /** |
||
112 | * Holds a list of sorted fields, sort order and the order by which they should all be sorted. |
||
113 | * |
||
114 | * @var array |
||
115 | */ |
||
116 | private $sorts = []; |
||
117 | |||
118 | /** |
||
119 | * QueryParameters constructor. |
||
120 | * |
||
121 | * @param string $table The name of the table |
||
122 | */ |
||
123 | 32 | public function __construct($table = null) |
|
124 | { |
||
125 | 32 | $this->table = $table; |
|
126 | 32 | } |
|
127 | |||
128 | /** |
||
129 | * Get the comma seperated list of fields for the query. |
||
130 | * In cases where no fields have been specifid, the wildcard * is returned. |
||
131 | * |
||
132 | * @return string |
||
133 | */ |
||
134 | 24 | public function getFields() |
|
135 | { |
||
136 | 24 | $fields = '*'; |
|
137 | |||
138 | 24 | if (count($this->fields) > 0) { |
|
139 | 12 | $fields = implode(', ', $this->fields); |
|
140 | } |
||
141 | |||
142 | 24 | return $fields; |
|
143 | } |
||
144 | |||
145 | /** |
||
146 | * Set an array of fields that this query should return. |
||
147 | * |
||
148 | * @param array $fields |
||
149 | * |
||
150 | * @return $this |
||
151 | */ |
||
152 | 12 | public function setFields(array $fields) |
|
153 | { |
||
154 | 12 | $this->fields = $fields; |
|
155 | |||
156 | 12 | return $this; |
|
157 | } |
||
158 | |||
159 | /** |
||
160 | * Get the table for this query. |
||
161 | * |
||
162 | * @return null|string |
||
163 | */ |
||
164 | 32 | public function getTable() |
|
165 | { |
||
166 | 32 | return $this->table; |
|
167 | } |
||
168 | |||
169 | /** |
||
170 | * Set the table for this query. |
||
171 | * |
||
172 | * @param $table |
||
173 | * |
||
174 | * @return $this For chaining |
||
175 | */ |
||
176 | 12 | public function setTable($table) |
|
177 | { |
||
178 | 12 | $this->table = $table; |
|
179 | |||
180 | 12 | return $this; |
|
181 | } |
||
182 | |||
183 | /** |
||
184 | * Gets the limit clause of the query. |
||
185 | * |
||
186 | * @return null|string |
||
187 | */ |
||
188 | 24 | public function getLimit() |
|
189 | { |
||
190 | 24 | return $this->limit > 0 ? " LIMIT {$this->limit}" : null; |
|
191 | } |
||
192 | |||
193 | 24 | public function getOffset() |
|
0 ignored issues
–
show
|
|||
194 | { |
||
195 | 24 | return $this->offset > 0 ? " OFFSET {$this->offset}" : null; |
|
196 | } |
||
197 | |||
198 | 32 | public function getWhereClause() |
|
0 ignored issues
–
show
The return type could not be reliably inferred; please add a
@return annotation.
Our type inference engine in quite powerful, but sometimes the code does not
provide enough clues to go by. In these cases we request you to add a ![]() |
|||
199 | { |
||
200 | 32 | if ($this->whereClause) { |
|
201 | 30 | foreach ($this->boundArrays as $boundArray) { |
|
202 | 8 | $where = ''; |
|
203 | 8 | $comma = ''; |
|
204 | 8 | for ($i = 0; $i < count($this->boundData[$boundArray]); $i++) { |
|
0 ignored issues
–
show
It seems like you are calling the size function
count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.
If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration: for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}
// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
![]() |
|||
205 | 8 | $where .= "{$comma}:{$boundArray}_{$i}"; |
|
206 | 8 | $comma = ', '; |
|
207 | } |
||
208 | 8 | $this->whereClause = str_replace("%{$boundArray}%", $where, $this->whereClause); |
|
209 | } |
||
210 | } |
||
211 | |||
212 | 32 | return $this->whereClause ? " WHERE {$this->whereClause}" : ''; |
|
213 | } |
||
214 | |||
215 | 32 | public function getBoundData() |
|
216 | { |
||
217 | 32 | if ($this->preparedBoundData === false) { |
|
218 | 32 | $this->preparedBoundData = []; |
|
0 ignored issues
–
show
It seems like
array() of type array is incompatible with the declared type boolean of property $preparedBoundData .
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. ![]() |
|||
219 | 32 | foreach ($this->boundData as $key => $value) { |
|
220 | 30 | if (in_array($key, $this->boundArrays)) { |
|
221 | 8 | foreach ($value as $i => $v) { |
|
222 | 8 | $this->preparedBoundData["{$key}_{$i}"] = $v; |
|
223 | } |
||
224 | } else { |
||
225 | 28 | $this->preparedBoundData[$key] = $value; |
|
226 | } |
||
227 | } |
||
228 | } |
||
229 | |||
230 | 32 | return $this->preparedBoundData; |
|
231 | } |
||
232 | |||
233 | 4 | public function setBoundData($field, $value) |
|
234 | { |
||
235 | 4 | if (array_key_exists($field, $this->boundData)) { |
|
236 | 4 | $isArray = is_array($value); |
|
237 | 4 | $boundArray = in_array($field, $this->boundArrays); |
|
238 | 4 | if ($isArray && !$boundArray) { |
|
239 | throw new NibiiException("The field '{$field}' cannot be bound to an array"); |
||
240 | 4 | } elseif (!$isArray && $boundArray) { |
|
241 | throw new NibiiException("The field '{$field}' must be bound to an array"); |
||
242 | } |
||
243 | 4 | $this->boundData[$field] = $value; |
|
244 | 4 | $this->preparedBoundData = false; |
|
245 | |||
246 | 4 | return $this; |
|
247 | } |
||
248 | |||
249 | throw new FieldNotFoundException("The field '{$field}' has not been bound to the current query"); |
||
250 | } |
||
251 | |||
252 | 24 | public function getSorts() |
|
253 | { |
||
254 | 24 | return count($this->sorts) ? ' ORDER BY '.implode(', ', $this->sorts) : null; |
|
255 | } |
||
256 | |||
257 | 24 | public function addFilter($field, $values = null) |
|
258 | { |
||
259 | 24 | $this->whereClause .= $this->conjunction; |
|
260 | |||
261 | 24 | if (is_array($values)) { |
|
262 | 8 | $this->whereClause .= "{$field} IN (%{$field}%)"; |
|
263 | 8 | $this->boundArrays[] = $field; |
|
264 | 8 | $this->boundData[$field] = $values; |
|
265 | } else { |
||
266 | 22 | if ($values === null) { |
|
267 | $this->whereClause .= "{$field} is NULL"; |
||
268 | } else { |
||
269 | 22 | $this->whereClause .= "{$field} = :$field"; |
|
270 | 22 | $this->boundData[$field] = $values; |
|
271 | } |
||
272 | } |
||
273 | 24 | $this->conjunction = ' AND '; |
|
274 | |||
275 | 24 | return $this; |
|
276 | } |
||
277 | |||
278 | 6 | public function setFilter($filter, $values) |
|
279 | { |
||
280 | 6 | $filterCompiler = new FilterCompiler(); |
|
281 | 6 | $compiledFilter = $filterCompiler->compile($filter); |
|
282 | 6 | $compiledValues = $filterCompiler->rewriteBoundData($values); |
|
283 | 6 | $this->whereClause .= "{$this->conjunction}$compiledFilter"; |
|
284 | 6 | $this->boundData += $compiledValues; |
|
285 | 6 | } |
|
286 | |||
287 | /** |
||
288 | * @param bool $firstOnly |
||
289 | * |
||
290 | * @return $this |
||
291 | */ |
||
292 | 24 | public function setFirstOnly($firstOnly) |
|
293 | { |
||
294 | 24 | $this->firstOnly = $firstOnly; |
|
295 | |||
296 | 24 | return $this; |
|
297 | } |
||
298 | |||
299 | 24 | public function getFirstOnly() |
|
300 | { |
||
301 | 24 | return $this->firstOnly; |
|
302 | } |
||
303 | |||
304 | public function setLimit($numItems) |
||
305 | { |
||
306 | $this->limit = $numItems; |
||
307 | } |
||
308 | |||
309 | public function setOffset($offset) |
||
310 | { |
||
311 | $this->offset = $offset; |
||
312 | } |
||
313 | |||
314 | /** |
||
315 | * @param string $field |
||
316 | * @param string $direction |
||
317 | */ |
||
318 | public function addSort($field, $direction = 'ASC') |
||
319 | { |
||
320 | $this->sorts[] = "$field $direction"; |
||
321 | } |
||
322 | } |
||
323 |
Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a
@return
annotation as described here.