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 | * This file is part of vaibhavpandeyvpz/doctrine-datatables package. |
||
5 | * |
||
6 | * (c) Vaibhav Pandey <[email protected]> |
||
7 | * |
||
8 | * This source file is subject to the MIT license that is bundled |
||
9 | * with this source code in the file LICENSE.md. |
||
10 | */ |
||
11 | |||
12 | namespace Doctrine\DataTables; |
||
13 | |||
14 | use Doctrine\DBAL\Query\QueryBuilder; |
||
15 | use Doctrine\ORM\QueryBuilder as ORMQueryBuilder; |
||
16 | use Doctrine\ORM\Tools\Pagination\Paginator; |
||
17 | |||
18 | /** |
||
19 | * Class Builder |
||
20 | * @package Doctrine\DataTables |
||
21 | */ |
||
22 | class Builder |
||
23 | { |
||
24 | /** |
||
25 | * @var array |
||
26 | */ |
||
27 | protected $columnAliases = array(); |
||
28 | |||
29 | /** |
||
30 | * @var string |
||
31 | */ |
||
32 | protected $columnField = 'data'; // or 'name' |
||
33 | |||
34 | /** |
||
35 | * @var string |
||
36 | */ |
||
37 | protected $indexColumn = '*'; |
||
38 | |||
39 | /** |
||
40 | * @var bool |
||
41 | */ |
||
42 | protected $returnCollection = false; |
||
43 | |||
44 | /** |
||
45 | * @var bool |
||
46 | */ |
||
47 | protected $caseInsensitive = false; |
||
48 | |||
49 | /** |
||
50 | * @var QueryBuilder|ORMQueryBuilder |
||
51 | */ |
||
52 | protected $queryBuilder; |
||
53 | |||
54 | /** |
||
55 | * @var array |
||
56 | */ |
||
57 | protected $requestParams; |
||
58 | |||
59 | /** |
||
60 | * @return array |
||
61 | */ |
||
62 | public function getData() |
||
63 | { |
||
64 | $query = $this->getFilteredQuery(); |
||
65 | $columns = &$this->requestParams['columns']; |
||
66 | // Order |
||
67 | if (array_key_exists('order', $this->requestParams)) { |
||
68 | $order = &$this->requestParams['order']; |
||
69 | foreach ($order as $sort) { |
||
70 | $column = &$columns[intval($sort['column'])]; |
||
71 | if (array_key_exists($column[$this->columnField], $this->columnAliases)) { |
||
72 | $column[$this->columnField] = $this->columnAliases[$column[$this->columnField]]; |
||
73 | } |
||
74 | $query->addOrderBy($column[$this->columnField], $sort['dir']); |
||
75 | } |
||
76 | } |
||
77 | // Offset |
||
78 | if (array_key_exists('start', $this->requestParams)) { |
||
79 | $query->setFirstResult(intval($this->requestParams['start'])); |
||
80 | } |
||
81 | // Limit |
||
82 | if (array_key_exists('length', $this->requestParams)) { |
||
83 | $length = intval($this->requestParams['length']); |
||
84 | if ($length > 0) { |
||
85 | $query->setMaxResults($length); |
||
86 | } |
||
87 | } |
||
88 | // Fetch |
||
89 | if ($query instanceof ORMQueryBuilder) { |
||
90 | if ($this->returnCollection) |
||
91 | return $query->getQuery()->getResult(); |
||
92 | else |
||
93 | return $query->getQuery()->getScalarResult(); |
||
94 | } else { |
||
95 | return $query->execute()->fetchAll(); |
||
96 | } |
||
97 | } |
||
98 | |||
99 | /** |
||
100 | * @return QueryBuilder|ORMQueryBuilder |
||
101 | */ |
||
102 | public function getFilteredQuery() |
||
103 | { |
||
104 | $query = clone $this->queryBuilder; |
||
105 | $columns = &$this->requestParams['columns']; |
||
106 | $c = count($columns); |
||
107 | // Search |
||
108 | if (array_key_exists('search', $this->requestParams)) { |
||
109 | if ($value = trim($this->requestParams['search']['value'])) { |
||
110 | $orX = $query->expr()->orX(); |
||
111 | for ($i = 0; $i < $c; $i++) { |
||
112 | $column = &$columns[$i]; |
||
113 | if ($column['searchable'] == 'true') { |
||
114 | if (array_key_exists($column[$this->columnField], $this->columnAliases)) { |
||
115 | $column[$this->columnField] = $this->columnAliases[$column[$this->columnField]]; |
||
116 | } |
||
117 | if ($this->caseInsensitive) { |
||
118 | $searchColumn = "lower(" . $column[$this->columnField] . ")"; |
||
119 | $orX->add($query->expr()->like($searchColumn, 'lower(:search)')); |
||
120 | } else { |
||
121 | $orX->add($query->expr()->like($column[$this->columnField], ':search')); |
||
122 | } |
||
123 | } |
||
124 | } |
||
125 | if ($orX->count() >= 1) { |
||
126 | $query->andWhere($orX) |
||
127 | ->setParameter('search', "%{$value}%"); |
||
128 | } |
||
129 | } |
||
130 | } |
||
131 | // Filter |
||
132 | for ($i = 0; $i < $c; $i++) { |
||
133 | $column = &$columns[$i]; |
||
134 | $andX = $query->expr()->andX(); |
||
135 | if (($column['searchable'] == 'true') && ($value = trim($column['search']['value']))) { |
||
136 | if (array_key_exists($column[$this->columnField], $this->columnAliases)) { |
||
137 | $column[$this->columnField] = $this->columnAliases[$column[$this->columnField]]; |
||
138 | } |
||
139 | $operator = preg_match('~^\[(?<operator>[=!%<>]+)\].*$~', $value, $matches) ? $matches['operator'] : '='; |
||
140 | if ($this->caseInsensitive) { |
||
141 | $searchColumn = "lower(" . $column[$this->columnField] . ")"; |
||
142 | $filter = "lower(:filter_{$i})"; |
||
143 | } else { |
||
144 | $searchColumn = $column[$this->columnField]; |
||
145 | $filter = ":filter_{$i}"; |
||
146 | } |
||
147 | switch ($operator) { |
||
148 | case '!=': // Not equals; usage: [!=]search_term |
||
149 | $andX->add($query->expr()->neq($searchColumn, $filter)); |
||
150 | break; |
||
151 | case '%': // Like; usage: [%]search_term |
||
152 | $andX->add($query->expr()->like($searchColumn, $filter)); |
||
153 | $value = "%{$value}%"; |
||
154 | break; |
||
155 | case '<': // Less than; usage: [>]search_term |
||
156 | $andX->add($query->expr()->lt($searchColumn, $filter)); |
||
157 | break; |
||
158 | case '>': // Greater than; usage: [<]search_term |
||
159 | $andX->add($query->expr()->gt($searchColumn, $filter)); |
||
160 | break; |
||
161 | case '=': // Equals (default); usage: [=]search_term |
||
162 | default: |
||
163 | $andX->add($query->expr()->eq($searchColumn, $filter)); |
||
164 | break; |
||
165 | } |
||
166 | $query->setParameter("filter_{$i}", $value); |
||
167 | } |
||
168 | if ($andX->count() >= 1) { |
||
169 | $query->andWhere($andX); |
||
170 | } |
||
171 | } |
||
172 | // Done |
||
173 | return $query; |
||
174 | } |
||
175 | |||
176 | /** |
||
177 | * @return int |
||
178 | */ |
||
179 | public function getRecordsFiltered() |
||
180 | { |
||
181 | $query = $this->getFilteredQuery(); |
||
182 | $paginator = new Paginator($query, $fetchJoinCollection = true); |
||
0 ignored issues
–
show
|
|||
183 | return $paginator->count(); |
||
184 | } |
||
185 | |||
186 | /** |
||
187 | * @return int |
||
188 | */ |
||
189 | public function getRecordsTotal() |
||
190 | { |
||
191 | $query = clone $this->queryBuilder; |
||
192 | $paginator = new Paginator($query, $fetchJoinCollection = true); |
||
0 ignored issues
–
show
It seems like
$query defined by clone $this->queryBuilder on line 191 can also be of type object<Doctrine\DBAL\Query\QueryBuilder> ; however, Doctrine\ORM\Tools\Pagin...aginator::__construct() does only seem to accept object<Doctrine\ORM\Quer...trine\ORM\QueryBuilder> , maybe add an additional type check?
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check: /**
* @return array|string
*/
function returnsDifferentValues($x) {
if ($x) {
return 'foo';
}
return array();
}
$x = returnsDifferentValues($y);
if (is_array($x)) {
// $x is an array.
}
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue. ![]() |
|||
193 | return $paginator->count(); |
||
194 | } |
||
195 | |||
196 | /** |
||
197 | * @return array |
||
198 | */ |
||
199 | public function getResponse() |
||
200 | { |
||
201 | return array( |
||
202 | 'data' => $this->getData(), |
||
203 | 'draw' => $this->requestParams['draw'], |
||
204 | 'recordsFiltered' => $this->getRecordsFiltered(), |
||
205 | 'recordsTotal' => $this->getRecordsTotal(), |
||
206 | ); |
||
207 | } |
||
208 | |||
209 | /** |
||
210 | * @param string $indexColumn |
||
211 | * @return static |
||
212 | */ |
||
213 | public function withIndexColumn($indexColumn) |
||
214 | { |
||
215 | $this->indexColumn = $indexColumn; |
||
216 | return $this; |
||
217 | } |
||
218 | |||
219 | /** |
||
220 | * @param array $columnAliases |
||
221 | * @return static |
||
222 | */ |
||
223 | public function withColumnAliases($columnAliases) |
||
224 | { |
||
225 | $this->columnAliases = $columnAliases; |
||
226 | return $this; |
||
227 | } |
||
228 | |||
229 | /** |
||
230 | * @param bool $returnObjectCollection |
||
0 ignored issues
–
show
There is no parameter named
$returnObjectCollection . Was it maybe removed?
This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. Consider the following example. The parameter /**
* @param array $germany
* @param array $island
* @param array $italy
*/
function finale($germany, $island) {
return "2:1";
}
The most likely cause is that the parameter was removed, but the annotation was not. ![]() |
|||
231 | * @return static |
||
232 | */ |
||
233 | public function withReturnCollection($returnCollection) |
||
234 | { |
||
235 | $this->returnCollection = $returnCollection; |
||
236 | return $this; |
||
237 | } |
||
238 | |||
239 | /** |
||
240 | * @param bool $caseInsensitive |
||
241 | * @return static |
||
242 | */ |
||
243 | public function withCaseInsensitive($caseInsensitive) |
||
244 | { |
||
245 | $this->caseInsensitive = $caseInsensitive; |
||
246 | return $this; |
||
247 | } |
||
248 | |||
249 | /** |
||
250 | * @param string $columnField |
||
251 | * @return static |
||
252 | */ |
||
253 | public function withColumnField($columnField) |
||
254 | { |
||
255 | $this->columnField = $columnField; |
||
256 | return $this; |
||
257 | } |
||
258 | |||
259 | /** |
||
260 | * @param QueryBuilder|ORMQueryBuilder $queryBuilder |
||
261 | * @return static |
||
262 | */ |
||
263 | public function withQueryBuilder($queryBuilder) |
||
264 | { |
||
265 | $this->queryBuilder = $queryBuilder; |
||
266 | return $this; |
||
267 | } |
||
268 | |||
269 | /** |
||
270 | * @param array $requestParams |
||
271 | * @return static |
||
272 | */ |
||
273 | public function withRequestParams($requestParams) |
||
274 | { |
||
275 | $this->requestParams = $requestParams; |
||
276 | return $this; |
||
277 | } |
||
278 | } |
||
279 |
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.