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 |
||
0 ignored issues
–
show
|
|||
2 | App::uses('CakeText', 'Utility'); |
||
3 | |||
4 | /** |
||
5 | * EagerLoader class |
||
6 | * |
||
7 | * @internal |
||
8 | */ |
||
9 | class EagerLoader { |
||
0 ignored issues
–
show
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.
You can fix this by adding a namespace to your class: namespace YourVendor;
class YourClass { }
When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries. ![]() |
|||
10 | |||
11 | private static $handlers = array(); // @codingStandardsIgnoreLine |
||
12 | |||
13 | private $id; // @codingStandardsIgnoreLine |
||
14 | |||
15 | private $metas = array(); // @codingStandardsIgnoreLine |
||
16 | |||
17 | private $containOptions = array( // @codingStandardsIgnoreLine |
||
18 | 'conditions' => 1, |
||
19 | 'fields' => 1, |
||
20 | 'order' => 1, |
||
21 | 'limit' => 1, |
||
22 | 'offset' => 1, |
||
23 | ); |
||
24 | |||
25 | /** |
||
26 | * Constructor |
||
27 | */ |
||
28 | public function __construct() { |
||
29 | ClassRegistry::init('EagerLoader.EagerLoaderModel'); |
||
30 | |||
31 | if (class_exists('CakeText')) { |
||
32 | $this->id = CakeText::uuid(); |
||
33 | } else { |
||
34 | App::uses('String', 'Utility'); |
||
35 | $this->id = String::uuid(); |
||
36 | } |
||
37 | } |
||
38 | |||
39 | /** |
||
40 | * Handles beforeFind event |
||
41 | * |
||
42 | * @param Model $model Model |
||
43 | * @param array $query Query |
||
44 | * @return array Modified query |
||
45 | */ |
||
46 | public static function handleBeforeFind(Model $model, $query) { |
||
47 | if (is_array($query)) { |
||
48 | if (isset($query['contain'])) { |
||
49 | if ($query['contain'] === false) { |
||
50 | $query['recursive'] = -1; |
||
51 | } else { |
||
52 | $EagerLoader = new EagerLoader(); |
||
53 | $query = $EagerLoader->transformQuery($model, $query); |
||
54 | |||
55 | self::$handlers[$EagerLoader->id] = $EagerLoader; |
||
56 | if (count(self::$handlers) > 1000) { |
||
57 | $id = key(self::$handlers); |
||
58 | unset(self::$handlers[$id]); |
||
59 | } |
||
60 | } |
||
61 | } |
||
62 | } |
||
63 | return $query; |
||
64 | } |
||
65 | |||
66 | /** |
||
67 | * Handles afterFind event |
||
68 | * |
||
69 | * @param Model $model Model |
||
70 | * @param array $results Results |
||
71 | * @return array Modified results |
||
72 | * @throws UnexpectedValueException |
||
73 | */ |
||
74 | public static function handleAfterFind(Model $model, $results) { |
||
75 | if (is_array($results)) { |
||
76 | $id = Hash::get($results, '0.EagerLoaderModel.id'); |
||
77 | if ($id) { |
||
78 | if (empty(self::$handlers[$id])) { |
||
79 | throw new UnexpectedValueException(sprintf('EagerLoader "%s" is not found', $id)); |
||
80 | } |
||
81 | |||
82 | $EagerLoader = self::$handlers[$id]; |
||
83 | unset(self::$handlers[$id]); |
||
84 | |||
85 | $results = $EagerLoader->transformResults($model, $results); |
||
86 | } |
||
87 | } |
||
88 | return $results; |
||
89 | } |
||
90 | |||
91 | /** |
||
92 | * Modifies the passed query to fetch the top level attachable associations. |
||
93 | * |
||
94 | * @param Model $model Model |
||
95 | * @param array $query Query |
||
96 | * @return array Modified query |
||
97 | */ |
||
98 | private function transformQuery(Model $model, array $query) { // @codingStandardsIgnoreLine |
||
99 | ClassRegistry::init('EagerLoader.EagerLoaderModel'); |
||
100 | |||
101 | $contain = $this->reformatContain($query['contain']); |
||
102 | foreach ($contain['contain'] as $key => $val) { |
||
103 | $this->parseContain($model, $key, $val); |
||
104 | } |
||
105 | |||
106 | $query = $this->attachAssociations($model, $model->alias, $query); |
||
107 | |||
108 | $db = $model->getDataSource(); |
||
109 | $value = $db->value($this->id); |
||
110 | $name = $db->name('EagerLoaderModel' . '__' . 'id'); |
||
111 | $query['fields'][] = "($value) AS $name"; |
||
112 | $query['callbacks'] = true; |
||
113 | |||
114 | return $query; |
||
115 | } |
||
116 | |||
117 | /** |
||
118 | * Modifies the results |
||
119 | * |
||
120 | * @param Model $model Model |
||
121 | * @param array $results Results |
||
122 | * @return array Modified results |
||
123 | */ |
||
124 | private function transformResults(Model $model, array $results) { // @codingStandardsIgnoreLine |
||
0 ignored issues
–
show
|
|||
125 | foreach ($results as &$result) { |
||
126 | unset($result['EagerLoaderModel']); |
||
127 | } |
||
128 | return $this->loadExternal($model, $model->alias, $results); |
||
129 | } |
||
130 | |||
131 | /** |
||
132 | * Modifies the query to fetch attachable associations. |
||
133 | * |
||
134 | * @param Model $model Model |
||
135 | * @param string $path The target path of the model, such as 'User.Article' |
||
136 | * @param array $query Query |
||
137 | * @return array Modified query |
||
138 | */ |
||
139 | private function attachAssociations(Model $model, $path, array $query) { // @codingStandardsIgnoreLine |
||
140 | $query = $this->normalizeQuery($model, $query); |
||
141 | |||
142 | foreach ($this->metas($path) as $meta) { |
||
143 | extract($meta); |
||
144 | if ($external) { |
||
145 | $query = $this->addField($query, "$parentAlias.$parentKey"); |
||
146 | } else { |
||
147 | $query = $this->buildJoinQuery($target, $query, 'LEFT', array("$parentAlias.$parentKey" => "$alias.$targetKey"), $options); |
||
148 | } |
||
149 | } |
||
150 | |||
151 | $query['recursive'] = -1; |
||
152 | $query['contain'] = false; |
||
153 | |||
154 | return $query; |
||
155 | } |
||
156 | |||
157 | /** |
||
158 | * Fetches meta data |
||
159 | * |
||
160 | * @param string $path Path of the association |
||
161 | * @return array |
||
162 | */ |
||
163 | private function metas($path) { // @codingStandardsIgnoreLine |
||
164 | if (isset($this->metas[$path])) { |
||
165 | return $this->metas[$path]; |
||
166 | } |
||
167 | return array(); |
||
168 | } |
||
169 | |||
170 | /** |
||
171 | * Fetches external associations |
||
172 | * |
||
173 | * @param Model $model Model |
||
174 | * @param string $path The target path of the external primary model, such as 'User.Article' |
||
175 | * @param array $results The results of the parent model |
||
176 | * @return array |
||
177 | */ |
||
178 | protected function loadExternal(Model $model, $path, array $results) { // @codingStandardsIgnoreLine |
||
179 | if ($results) { |
||
180 | foreach ($this->metas($path) as $meta) { |
||
181 | extract($meta); |
||
182 | if ($external) { |
||
183 | $results = $this->mergeExternalExternal($model, $results, $meta); |
||
184 | } else { |
||
185 | $results = $this->mergeInternalExternal($model, $results, $meta); |
||
186 | } |
||
187 | } |
||
188 | } |
||
189 | return $results; |
||
190 | } |
||
191 | |||
192 | /** |
||
193 | * Merges results of external associations of an external association |
||
194 | * |
||
195 | * @param Model $model Model |
||
196 | * @param array $results Results |
||
197 | * @param array $meta Meta data to be used for eager loading |
||
198 | * @return array |
||
199 | */ |
||
200 | private function mergeExternalExternal(Model $model, array $results, array $meta) { // @codingStandardsIgnoreLine |
||
0 ignored issues
–
show
|
|||
201 | extract($meta); |
||
202 | |||
203 | $db = $target->getDataSource(); |
||
204 | |||
205 | $assocAlias = $alias; |
||
206 | $assocKey = $targetKey; |
||
207 | |||
208 | $options = $this->attachAssociations($target, $aliasPath, $options); |
||
209 | if ($has && $belong) { |
||
210 | $assocAlias = $habtmAlias; |
||
211 | $assocKey = $habtmParentKey; |
||
212 | |||
213 | $options = $this->buildJoinQuery($habtm, $options, 'INNER', array( |
||
214 | "$alias.$targetKey" => "$habtmAlias.$habtmTargetKey", |
||
215 | ), $options); |
||
216 | } |
||
217 | |||
218 | $options = $this->addField($options, "$assocAlias.$assocKey"); |
||
219 | |||
220 | $ids = Hash::extract($results, "{n}.$parentAlias.$parentKey"); |
||
221 | $ids = array_unique($ids); |
||
222 | |||
223 | if (!empty($finderQuery)) { |
||
224 | $assocResults = array(); |
||
225 | foreach ($ids as $id) { |
||
226 | $eachQuery = str_replace('{$__cakeID__$}', $db->value($id), $finderQuery); |
||
227 | $eachAssocResults = $db->fetchAll($eachQuery, $target->cacheQueries); |
||
228 | $eachAssocResults = Hash::insert($eachAssocResults, "{n}.EagerLoaderModel.assoc_id", $id); |
||
229 | $assocResults = array_merge($assocResults, $eachAssocResults); |
||
230 | } |
||
231 | } elseif ($this->hasLimitOffset($options)) { |
||
232 | $assocResults = array(); |
||
233 | foreach ($ids as $id) { |
||
234 | $eachOptions = $options; |
||
235 | $eachOptions['conditions'][] = array("$assocAlias.$assocKey" => $id); |
||
236 | $eachAssocResults = $db->read($target, $eachOptions); |
||
237 | $eachAssocResults = Hash::insert($eachAssocResults, "{n}.EagerLoaderModel.assoc_id", $id); |
||
238 | $assocResults = array_merge($assocResults, $eachAssocResults); |
||
239 | } |
||
240 | } else { |
||
241 | $options['fields'][] = '(' . $db->name($assocAlias . '.' . $assocKey) . ') AS ' . $db->name('EagerLoaderModel' . '__' . 'assoc_id'); |
||
242 | $options['conditions'][] = array("$assocAlias.$assocKey" => $ids); |
||
243 | $assocResults = $db->read($target, $options); |
||
244 | } |
||
245 | |||
246 | $assocResults = $this->filterResults($parent, $alias, $assocResults); |
||
247 | $assocResults = $this->loadExternal($target, $aliasPath, $assocResults); |
||
248 | |||
249 | if ($has && $belong) { |
||
250 | foreach ($assocResults as &$assocResult) { |
||
251 | $assocResult[$alias][$habtmAlias] = $assocResult[$habtmAlias]; |
||
252 | unset($assocResult[$habtmAlias]); |
||
253 | } |
||
254 | unset($assocResult); |
||
255 | } |
||
256 | |||
257 | foreach ($results as &$result) { |
||
258 | if (!isset($result[$parentAlias][$parentKey])) { |
||
259 | continue; |
||
260 | } |
||
261 | |||
262 | $assoc = array(); |
||
263 | foreach ($assocResults as $assocResult) { |
||
264 | if ((string)$result[$parentAlias][$parentKey] === (string)$assocResult['EagerLoaderModel']['assoc_id']) { |
||
265 | $assoc[] = $assocResult[$alias]; |
||
266 | } |
||
267 | } |
||
268 | if (!$many) { |
||
269 | $assoc = $assoc ? current($assoc) : array(); |
||
270 | } |
||
271 | $result = $this->mergeAssocResult($result, $assoc, $propertyPath); |
||
272 | } |
||
273 | |||
274 | return $results; |
||
275 | } |
||
276 | |||
277 | /** |
||
278 | * Merges results of external associations of an internal association |
||
279 | * |
||
280 | * @param Model $model Model |
||
281 | * @param array $results Results |
||
282 | * @param array $meta Meta data to be used for eager loading |
||
283 | * @return array |
||
284 | */ |
||
285 | private function mergeInternalExternal(Model $model, array $results, array $meta) { // @codingStandardsIgnoreLine |
||
286 | extract($meta); |
||
287 | |||
288 | $assocResults = array(); |
||
289 | foreach ($results as $n => &$result) { |
||
290 | if ($result[$alias][$targetKey] === null) { |
||
291 | // Remove NULL association created by LEFT JOIN |
||
292 | if (empty($eager)) { |
||
293 | $assocResults[$n] = array( $alias => array() ); |
||
294 | } |
||
295 | } else { |
||
296 | $assocResults[$n] = array( $alias => $result[$alias] ); |
||
297 | } |
||
298 | unset($result[$alias]); |
||
299 | } |
||
300 | unset($result); |
||
301 | |||
302 | if (!empty($eager) && !isset($model->$alias)) { |
||
303 | $assocResults = $this->filterResults($parent, $alias, $assocResults); |
||
304 | } |
||
305 | $assocResults = $this->loadExternal($target, $aliasPath, $assocResults); |
||
306 | |||
307 | foreach ($results as $n => &$result) { |
||
308 | if (isset($assocResults[$n][$alias])) { |
||
309 | $assoc = $assocResults[$n][$alias]; |
||
310 | $result = $this->mergeAssocResult($result, $assoc, $propertyPath); |
||
311 | } |
||
312 | } |
||
313 | unset($result); |
||
314 | |||
315 | return $results; |
||
316 | } |
||
317 | |||
318 | /** |
||
319 | * Merges associated result |
||
320 | * |
||
321 | * @param array $result Results |
||
322 | * @param array $assoc Associated results |
||
323 | * @param string $propertyPath Path of the results |
||
324 | * @return array |
||
325 | */ |
||
326 | private function mergeAssocResult(array $result, array $assoc, $propertyPath) { // @codingStandardsIgnoreLine |
||
327 | return Hash::insert($result, $propertyPath, $assoc + (array)Hash::get($result, $propertyPath)); |
||
328 | } |
||
329 | |||
330 | /** |
||
331 | * Reformat `contain` array |
||
332 | * |
||
333 | * @param array|string $contain The value of `contain` option of the query |
||
334 | * @return array |
||
335 | */ |
||
336 | private function reformatContain($contain) { // @codingStandardsIgnoreLine |
||
337 | $result = array( |
||
338 | 'options' => array(), |
||
339 | 'contain' => array(), |
||
340 | ); |
||
341 | |||
342 | $contain = (array)$contain; |
||
343 | foreach ($contain as $key => $val) { |
||
344 | if (is_int($key)) { |
||
345 | $key = $val; |
||
346 | $val = array(); |
||
347 | } |
||
348 | |||
349 | if (!isset($this->containOptions[$key])) { |
||
350 | if (strpos($key, '.') !== false) { |
||
351 | $expanded = Hash::expand(array($key => $val)); |
||
352 | list($key, $val) = each($expanded); |
||
353 | } |
||
354 | $ref =& $result['contain'][$key]; |
||
355 | $ref = Hash::merge((array)$ref, $this->reformatContain($val)); |
||
356 | } else { |
||
357 | $result['options'][$key] = $val; |
||
358 | } |
||
359 | } |
||
360 | |||
361 | return $result; |
||
362 | } |
||
363 | |||
364 | /** |
||
365 | * Normalizes the query |
||
366 | * |
||
367 | * @param Model $model Model |
||
368 | * @param array $query Query |
||
369 | * @return array Normalized query |
||
370 | */ |
||
371 | private function normalizeQuery(Model $model, array $query) { // @codingStandardsIgnoreLine |
||
372 | $db = $model->getDataSource(); |
||
373 | |||
374 | $query += array( |
||
375 | 'fields' => array(), |
||
376 | 'conditions' => array(), |
||
377 | 'order' => array() |
||
378 | ); |
||
379 | |||
380 | if (!$query['fields']) { |
||
381 | $query['fields'] = $db->fields($model, null, array(), false); |
||
382 | } |
||
383 | |||
384 | $query['fields'] = (array)$query['fields']; |
||
385 | foreach ($query['fields'] as &$field) { |
||
386 | if ($model->isVirtualField($field)) { |
||
387 | $fields = $db->fields($model, null, array($field), false); |
||
388 | $field = $fields[0]; |
||
389 | } else { |
||
390 | $field = $this->normalizeField($model, $field); |
||
391 | } |
||
392 | } |
||
393 | unset($field); |
||
394 | |||
395 | $query['conditions'] = (array)$query['conditions']; |
||
396 | foreach ($query['conditions'] as $key => $val) { |
||
397 | if ($model->hasField($key)) { |
||
398 | unset($query['conditions'][$key]); |
||
399 | $key = $this->normalizeField($model, $key); |
||
400 | $query['conditions'][] = array($key => $val); |
||
401 | } elseif ($model->isVirtualField($key)) { |
||
402 | unset($query['conditions'][$key]); |
||
403 | $conditions = $db->conditionKeysToString(array($key => $val), true, $model); |
||
404 | $query['conditions'][] = $db->expression($conditions[0]); |
||
405 | } |
||
406 | } |
||
407 | |||
408 | $order = array(); |
||
409 | foreach ((array)$query['order'] as $key => $val) { |
||
410 | if (is_int($key)) { |
||
411 | $val = $this->normalizeField($model, $val); |
||
412 | } else { |
||
413 | $key = $this->normalizeField($model, $key); |
||
414 | } |
||
415 | $order += array($key => $val); |
||
416 | } |
||
417 | $query['order'] = $order; |
||
418 | |||
419 | return $query; |
||
420 | } |
||
421 | |||
422 | /** |
||
423 | * Normalize field |
||
424 | * |
||
425 | * @param Model $model Model |
||
426 | * @param string $field Name of the field |
||
427 | * @return string |
||
428 | */ |
||
429 | private function normalizeField(Model $model, $field) { // @codingStandardsIgnoreLine |
||
430 | if ($model->hasField($field)) { |
||
431 | $field = $model->alias . '.' . $field; |
||
432 | } elseif ($model->isVirtualField($field)) { |
||
433 | $db = $model->getDataSource(); |
||
434 | $field = $model->getVirtualField($field); |
||
435 | $field = $db->dispatchMethod('_quoteFields', array($field)); |
||
436 | $field = '(' . $field . ')'; |
||
437 | } |
||
438 | return $field; |
||
439 | } |
||
440 | |||
441 | /** |
||
442 | * Modifies the query to apply joins. |
||
443 | * |
||
444 | * @param Model $target Model to be joined |
||
445 | * @param array $query Query |
||
446 | * @param string $joinType The type for join |
||
447 | * @param array $keys Key fields being used for join |
||
448 | * @param array $options Extra options for join |
||
449 | * @return array Modified query |
||
450 | */ |
||
451 | private function buildJoinQuery(Model $target, array $query, $joinType, array $keys, array $options) { // @codingStandardsIgnoreLine |
||
452 | $db = $target->getDataSource(); |
||
453 | |||
454 | $options = $this->normalizeQuery($target, $options); |
||
455 | $query['fields'] = array_merge($query['fields'], $options['fields']); |
||
456 | $query = $this->normalizeQuery($target, $query); |
||
457 | |||
458 | foreach ($keys as $lhs => $rhs) { |
||
459 | $query = $this->addField($query, $lhs); |
||
460 | $query = $this->addField($query, $rhs); |
||
461 | $options['conditions'][] = array($lhs => $db->identifier($rhs)); |
||
462 | } |
||
463 | |||
464 | $query['joins'][] = array( |
||
465 | 'type' => $joinType, |
||
466 | 'table' => $target, |
||
467 | 'alias' => $target->alias, |
||
468 | 'conditions' => $options['conditions'], |
||
469 | ); |
||
470 | return $query; |
||
471 | } |
||
472 | |||
473 | /** |
||
474 | * Adds a field into the `fields` option of the query |
||
475 | * |
||
476 | * @param array $query Query |
||
477 | * @param string $field Name of the field |
||
478 | * @return Modified query |
||
479 | */ |
||
480 | private function addField(array $query, $field) { // @codingStandardsIgnoreLine |
||
481 | if (!in_array($field, $query['fields'], true)) { |
||
482 | $query['fields'][] = $field; |
||
483 | } |
||
484 | return $query; |
||
485 | } |
||
486 | |||
487 | /** |
||
488 | * Parse the `contain` option of the query recursively |
||
489 | * |
||
490 | * @param Model $parent Parent model of the contained model |
||
491 | * @param string $alias Alias of the contained model |
||
492 | * @param array $contain Reformatted `contain` option for the deep associations |
||
493 | * @param array|null $context Context |
||
494 | * @return array |
||
495 | * @throws InvalidArgumentException |
||
496 | */ |
||
497 | private function parseContain(Model $parent, $alias, array $contain, $context = null) { // @codingStandardsIgnoreLine |
||
498 | if ($context === null) { |
||
499 | $context = array( |
||
500 | 'root' => $parent->alias, |
||
501 | 'aliasPath' => $parent->alias, |
||
502 | 'propertyPath' => '', |
||
503 | 'forceExternal' => false, |
||
504 | ); |
||
505 | } |
||
506 | |||
507 | $aliasPath = $context['aliasPath'] . '.' . $alias; |
||
508 | $propertyPath = ($context['propertyPath'] ? $context['propertyPath'] . '.' : '') . $alias; |
||
509 | |||
510 | $types = $parent->getAssociated(); |
||
511 | if (!isset($types[$alias])) { |
||
512 | throw new InvalidArgumentException(sprintf('Model "%s" is not associated with model "%s"', $parent->alias, $alias), E_USER_WARNING); |
||
513 | } |
||
514 | |||
515 | $parentAlias = $parent->alias; |
||
516 | $target = $parent->$alias; |
||
517 | $type = $types[$alias]; |
||
518 | $relation = $parent->{$type}[$alias]; |
||
519 | |||
520 | $options = $contain['options'] + array_intersect_key(Hash::filter($relation), $this->containOptions); |
||
521 | |||
522 | $has = (stripos($type, 'has') !== false); |
||
523 | $many = (stripos($type, 'many') !== false); |
||
524 | $belong = (stripos($type, 'belong') !== false); |
||
525 | |||
526 | if ($has && $belong) { |
||
527 | $parentKey = $parent->primaryKey; |
||
528 | $targetKey = $target->primaryKey; |
||
529 | $habtmAlias = $relation['with']; |
||
530 | $habtm = $parent->$habtmAlias; |
||
531 | $habtmParentKey = $relation['foreignKey']; |
||
532 | $habtmTargetKey = $relation['associationForeignKey']; |
||
533 | } elseif ($has) { |
||
534 | $parentKey = $parent->primaryKey; |
||
535 | $targetKey = $relation['foreignKey']; |
||
536 | } else { |
||
537 | $parentKey = $relation['foreignKey']; |
||
538 | $targetKey = $target->primaryKey; |
||
539 | } |
||
540 | |||
541 | if (!empty($relation['external'])) { |
||
542 | $external = true; |
||
543 | } |
||
544 | |||
545 | if (!empty($relation['finderQuery'])) { |
||
546 | $finderQuery = $relation['finderQuery']; |
||
547 | } |
||
548 | |||
549 | $meta = compact( |
||
550 | 'alias', 'parent', 'target', |
||
551 | 'parentAlias', 'parentKey', |
||
552 | 'targetKey', 'aliasPath', 'propertyPath', |
||
553 | 'options', 'has', 'many', 'belong', 'external', 'finderQuery', |
||
554 | 'habtm', 'habtmAlias', 'habtmParentKey', 'habtmTargetKey' |
||
555 | ); |
||
556 | |||
557 | if ($this->isExternal($context, $meta)) { |
||
558 | $meta['propertyPath'] = ($context['propertyPath'] ? $parentAlias . '.' : '') . $alias; |
||
559 | $meta['external'] = true; |
||
560 | |||
561 | $context['root'] = $aliasPath; |
||
562 | $context['propertyPath'] = $alias; |
||
563 | |||
564 | $path = $context['aliasPath']; |
||
565 | } else { |
||
566 | $meta['external'] = false; |
||
567 | if ($context['root'] !== $context['aliasPath']) { |
||
568 | $meta['eager'] = true; |
||
569 | } |
||
570 | |||
571 | $context['propertyPath'] = $propertyPath; |
||
572 | |||
573 | $path = $context['root']; |
||
574 | } |
||
575 | |||
576 | $this->metas[$path][] = $meta; |
||
577 | |||
578 | $context['aliasPath'] = $aliasPath; |
||
579 | $context['forceExternal'] = !empty($finderQuery); |
||
580 | |||
581 | foreach ($contain['contain'] as $key => $val) { |
||
582 | $this->parseContain($target, $key, $val, $context); |
||
583 | } |
||
584 | |||
585 | return $this->metas; |
||
586 | } |
||
587 | |||
588 | /** |
||
589 | * Returns whether the target is external or not |
||
590 | * |
||
591 | * @param array $context Context |
||
592 | * @param array $meta Meta data to be used for eager loading |
||
593 | * @return bool |
||
594 | */ |
||
595 | private function isExternal(array $context, array $meta) { // @codingStandardsIgnoreLine |
||
596 | extract($meta); |
||
597 | |||
598 | if ($parent->useDbConfig !== $target->useDbConfig) { |
||
599 | return true; |
||
600 | } |
||
601 | if (!empty($external)) { |
||
602 | return true; |
||
603 | } |
||
604 | if (!empty($many)) { |
||
605 | return true; |
||
606 | } |
||
607 | if (!empty($finderQuery)) { |
||
608 | return true; |
||
609 | } |
||
610 | if ($this->hasLimitOffset($options)) { |
||
611 | return true; |
||
612 | } |
||
613 | if ($context['forceExternal']) { |
||
614 | return true; |
||
615 | } |
||
616 | |||
617 | $metas = $this->metas($context['root']); |
||
618 | $aliases = Hash::extract($metas, '{n}.alias'); |
||
619 | if (in_array($alias, $aliases, true)) { |
||
620 | return true; |
||
621 | } |
||
622 | |||
623 | return false; |
||
624 | } |
||
625 | |||
626 | /** |
||
627 | * Returns where `limit` or `offset` option exists |
||
628 | * |
||
629 | * @param array $options Options |
||
630 | * @return bool |
||
631 | */ |
||
632 | private function hasLimitOffset($options) { // @codingStandardsIgnoreLine |
||
633 | return !empty($options['limit']) || !empty($options['offset']); |
||
634 | } |
||
635 | |||
636 | /** |
||
637 | * Triggers afterFind() method |
||
638 | * |
||
639 | * @param Model $parent Model |
||
640 | * @param string $alias Alias |
||
641 | * @param array $results Results |
||
642 | * @return array |
||
643 | */ |
||
644 | private function filterResults(Model $parent, $alias, array $results) { // @codingStandardsIgnoreLine |
||
645 | $db = $parent->getDataSource(); |
||
0 ignored issues
–
show
$db is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
646 | |||
647 | $target = $parent->$alias; |
||
648 | |||
649 | foreach ($results as $key => &$result) { |
||
650 | $data = $target->afterFind(array(array($alias => $result[$alias])), false); |
||
651 | if (isset($data[0][$alias])) { |
||
652 | $result[$alias] = $data[0][$alias]; |
||
653 | } else { |
||
654 | unset($results[$key]); |
||
655 | } |
||
656 | } |
||
657 | |||
658 | return $results; |
||
659 | } |
||
660 | } |
||
661 |
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.