ntentan /
nibii
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 Loading history...
|
|||
| 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++) { |
|
| 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.. Loading history...
|
|||
| 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
@returnannotation as described here.