Issues (9)

Security Analysis    no request data  

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

Model/EagerLoader.php (3 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
App::uses('CakeText', 'Utility');
3
4
/**
5
 * EagerLoader class
6
 *
7
 * @internal
8
 */
9
class EagerLoader {
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
113
		return $query;
114
	}
115
116
/**
117
 * Modifies the results
118
 *
119
 * @param Model $model Model
120
 * @param array $results Results
121
 * @return array Modified results
122
 */
123
	private  function transformResults(Model $model, array $results) { // @codingStandardsIgnoreLine
0 ignored issues
show
This method is not used, and could be removed.
Loading history...
124
		foreach ($results as &$result) {
125
			unset($result['EagerLoaderModel']);
126
		}
127
		return $this->loadExternal($model, $model->alias, $results);
128
	}
129
130
/**
131
 * Modifies the query to fetch attachable associations.
132
 *
133
 * @param Model $model Model
134
 * @param string $path The target path of the model, such as 'User.Article'
135
 * @param array $query Query
136
 * @return array Modified query
137
 */
138
	private function attachAssociations(Model $model, $path, array $query) { // @codingStandardsIgnoreLine
139
		$query = $this->normalizeQuery($model, $query);
140
141
		foreach ($this->metas($path) as $meta) {
142
			extract($meta);
143
			if ($external) {
144
				$query = $this->addField($query, "$parentAlias.$parentKey");
145
			} else {
146
				$joinType = $this->getJoinType($parent, $target, $type);
147
				$query = $this->buildJoinQuery($target, $query, $joinType, array("$parentAlias.$parentKey" => "$alias.$targetKey"), $options);
148
			}
149
		}
150
151
		$query['recursive'] = -1;
152
		$query['contain'] = false;
153
154
		return $query;
155
	}
156
157
	private function getJoinType(Model $parent, Model $child, $associationType){
158
			return $parent->{$associationType}[$child->alias]['type'] ?? 'LEFT';
159
	}
160
161
/**
162
 * Fetches meta data
163
 *
164
 * @param string $path Path of the association
165
 * @return array
166
 */
167
	private function metas($path) { // @codingStandardsIgnoreLine
168
		if (isset($this->metas[$path])) {
169
			return $this->metas[$path];
170
		}
171
		return array();
172
	}
173
174
/**
175
 * Fetches external associations
176
 *
177
 * @param Model $model Model
178
 * @param string $path The target path of the external primary model, such as 'User.Article'
179
 * @param array $results The results of the parent model
180
 * @return array
181
 */
182
	protected function loadExternal(Model $model, $path, array $results) { // @codingStandardsIgnoreLine
183
		if ($results) {
184
			foreach ($this->metas($path) as $meta) {
185
				extract($meta);
186
				if ($external) {
187
					$results = $this->mergeExternalExternal($model, $results, $meta);
188
				} else {
189
					$results = $this->mergeInternalExternal($model, $results, $meta);
190
				}
191
			}
192
		}
193
		return $results;
194
	}
195
196
/**
197
 * Merges results of external associations of an external association
198
 *
199
 * @param Model $model Model
200
 * @param array $results Results
201
 * @param array $meta Meta data to be used for eager loading
202
 * @return array
203
 */
204
	private function mergeExternalExternal(Model $model, array $results, array $meta) { // @codingStandardsIgnoreLine
0 ignored issues
show
The parameter $model is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
205
		extract($meta);
206
207
		$db = $target->getDataSource();
208
209
		$assocAlias = $alias;
210
		$assocKey = $targetKey;
211
212
		$options = $this->attachAssociations($target, $aliasPath, $options);
213
		if ($has && $belong) {
214
			$assocAlias = $habtmAlias;
215
			$assocKey = $habtmParentKey;
216
217
			$options = $this->buildJoinQuery($habtm, $options, 'INNER', array(
218
				"$alias.$targetKey" => "$habtmAlias.$habtmTargetKey",
219
			), $options);
220
		}
221
222
		$options = $this->addField($options, "$assocAlias.$assocKey");
223
224
		$ids = Hash::extract($results, "{n}.$parentAlias.$parentKey");
225
		$ids = array_unique($ids);
226
227
		if (!empty($finderQuery)) {
228
			$assocResults = array();
229
			foreach ($ids as $id) {
230
				$eachQuery = str_replace('{$__cakeID__$}', $db->value($id), $finderQuery);
231
				$eachAssocResults = $db->fetchAll($eachQuery, $target->cacheQueries);
232
				$eachAssocResults = Hash::insert($eachAssocResults, "{n}.EagerLoaderModel.assoc_id", $id);
233
				$assocResults = array_merge($assocResults, $eachAssocResults);
234
			}
235
		} elseif ($this->hasLimitOffset($options)) {
236
			$assocResults = array();
237
			foreach ($ids as $id) {
238
				$eachOptions = $options;
239
				$eachOptions['conditions'][] = array("$assocAlias.$assocKey" => $id);
240
				$eachAssocResults = $db->read($target, $eachOptions);
241
				$eachAssocResults = Hash::insert($eachAssocResults, "{n}.EagerLoaderModel.assoc_id", $id);
242
				$assocResults = array_merge($assocResults, $eachAssocResults);
243
			}
244
		} else {
245
			$options['fields'][] = '(' . $db->name($assocAlias . '.' . $assocKey) . ') AS ' . $db->name('EagerLoaderModel' . '__' . 'assoc_id');
246
			$options['conditions'][] = array("$assocAlias.$assocKey" => $ids);
247
			$assocResults = $db->read($target, $options);
248
		}
249
250
		$assocResults = $this->filterResults($parent, $alias, $assocResults);
251
		$assocResults = $this->loadExternal($target, $aliasPath, $assocResults);
252
253
		if ($has && $belong) {
254
			foreach ($assocResults as &$assocResult) {
255
				$assocResult[$alias][$habtmAlias] = $assocResult[$habtmAlias];
256
				unset($assocResult[$habtmAlias]);
257
			}
258
			unset($assocResult);
259
		}
260
261
		foreach ($results as &$result) {
262
			if (!isset($result[$parentAlias][$parentKey])) {
263
				continue;
264
			}
265
266
			$assoc = array();
267
			foreach ($assocResults as $assocResult) {
268
				if ((string)$result[$parentAlias][$parentKey] === (string)$assocResult['EagerLoaderModel']['assoc_id']) {
269
					$assoc[] = $assocResult[$alias];
270
				}
271
			}
272
			if (!$many) {
273
				$assoc = $assoc ? current($assoc) : array();
274
			}
275
			$result = $this->mergeAssocResult($result, $assoc, $propertyPath);
276
		}
277
278
		return $results;
279
	}
280
281
/**
282
 * Merges results of external associations of an internal association
283
 *
284
 * @param Model $model Model
285
 * @param array $results Results
286
 * @param array $meta Meta data to be used for eager loading
287
 * @return array
288
 */
289
	private function mergeInternalExternal(Model $model, array $results, array $meta) { // @codingStandardsIgnoreLine
290
		extract($meta);
291
292
		$assocResults = array();
293
		foreach ($results as $n => &$result) {
294
			if ($result[$alias][$targetKey] === null) {
295
				// Remove NULL association created by LEFT JOIN
296
				if (empty($eager)) {
297
					$assocResults[$n] = array( $alias => array() );
298
				}
299
			} else {
300
				$assocResults[$n] = array( $alias => $result[$alias] );
301
			}
302
			unset($result[$alias]);
303
		}
304
		unset($result);
305
306
		if (!empty($eager) && !isset($model->$alias)) {
307
			$assocResults = $this->filterResults($parent, $alias, $assocResults);
308
		}
309
		$assocResults = $this->loadExternal($target, $aliasPath, $assocResults);
310
311
		foreach ($results as $n => &$result) {
312
			if (isset($assocResults[$n][$alias])) {
313
				$assoc = $assocResults[$n][$alias];
314
				$result = $this->mergeAssocResult($result, $assoc, $propertyPath);
315
			}
316
		}
317
		unset($result);
318
319
		return $results;
320
	}
321
322
/**
323
 * Merges associated result
324
 *
325
 * @param array $result Results
326
 * @param array $assoc Associated results
327
 * @param string $propertyPath Path of the results
328
 * @return array
329
 */
330
	private function mergeAssocResult(array $result, array $assoc, $propertyPath) { // @codingStandardsIgnoreLine
331
		return Hash::insert($result, $propertyPath, $assoc + (array)Hash::get($result, $propertyPath));
332
	}
333
334
/**
335
 * Reformat `contain` array
336
 *
337
 * @param array|string $contain The value of `contain` option of the query
338
 * @return array
339
 */
340
	private function reformatContain($contain) { // @codingStandardsIgnoreLine
341
		$result = array(
342
			'options' => array(),
343
			'contain' => array(),
344
		);
345
346
		$contain = (array)$contain;
347
		foreach ($contain as $key => $val) {
348
			if (is_int($key)) {
349
				$key = $val;
350
				$val = array();
351
			}
352
353
			if (!isset($this->containOptions[$key])) {
354
				if (strpos($key, '.') !== false) {
355
					$expanded = Hash::expand(array($key => $val));
356
					list($key, $val) = each($expanded);
357
				}
358
				$ref =& $result['contain'][$key];
359
				$ref = Hash::merge((array)$ref, $this->reformatContain($val));
360
			} else {
361
				$result['options'][$key] = $val;
362
			}
363
		}
364
365
		return $result;
366
	}
367
368
/**
369
 * Normalizes the query
370
 *
371
 * @param Model $model Model
372
 * @param array $query Query
373
 * @return array Normalized query
374
 */
375
	private function normalizeQuery(Model $model, array $query) { // @codingStandardsIgnoreLine
376
		$db = $model->getDataSource();
377
378
		$query += array(
379
			'fields' => array(),
380
			'conditions' => array(),
381
			'order' => array()
382
		);
383
384
		if (!$query['fields']) {
385
			$query['fields'] = $db->fields($model, null, array(), false);
386
		}
387
388
		$query['fields'] = (array)$query['fields'];
389
		foreach ($query['fields'] as &$field) {
390
			if ($model->isVirtualField($field)) {
391
				$fields = $db->fields($model, null, array($field), false);
392
				$field = $fields[0];
393
			} else {
394
				$field = $this->normalizeField($model, $field);
395
			}
396
		}
397
		unset($field);
398
399
		$query['conditions'] = (array)$query['conditions'];
400
		foreach ($query['conditions'] as $key => $val) {
401
			if ($model->hasField($key)) {
402
				unset($query['conditions'][$key]);
403
				$key = $this->normalizeField($model, $key);
404
				$query['conditions'][] = array($key => $val);
405
			} elseif ($model->isVirtualField($key)) {
406
				unset($query['conditions'][$key]);
407
				$conditions = $db->conditionKeysToString(array($key => $val), true, $model);
408
				$query['conditions'][] = $db->expression($conditions[0]);
409
			}
410
		}
411
412
		$order = array();
413
		foreach ((array)$query['order'] as $key => $val) {
414
			if (is_int($key)) {
415
				$val = $this->normalizeField($model, $val);
416
			} else {
417
				$key = $this->normalizeField($model, $key);
418
			}
419
			$order += array($key => $val);
420
		}
421
		$query['order'] = $order;
422
423
		return $query;
424
	}
425
426
/**
427
 * Normalize field
428
 *
429
 * @param Model $model Model
430
 * @param string $field Name of the field
431
 * @return string
432
 */
433
	private function normalizeField(Model $model, $field) { // @codingStandardsIgnoreLine
434
		if ($model->hasField($field)) {
435
			$field = $model->alias . '.' . $field;
436
		} elseif ($model->isVirtualField($field)) {
437
			$db = $model->getDataSource();
438
			$field = $model->getVirtualField($field);
439
			$field = $db->dispatchMethod('_quoteFields', array($field));
440
			$field = '(' . $field . ')';
441
		}
442
		return $field;
443
	}
444
445
/**
446
 * Modifies the query to apply joins.
447
 *
448
 * @param Model $target Model to be joined
449
 * @param array $query Query
450
 * @param string $joinType The type for join
451
 * @param array $keys Key fields being used for join
452
 * @param array $options Extra options for join
453
 * @return array Modified query
454
 */
455
	private function buildJoinQuery(Model $target, array $query, $joinType, array $keys, array $options) { // @codingStandardsIgnoreLine
456
		$db = $target->getDataSource();
457
458
		$options = $this->normalizeQuery($target, $options);
459
		$query['fields'] = array_merge($query['fields'], $options['fields']);
460
		$query = $this->normalizeQuery($target, $query);
461
462
		foreach ($keys as $lhs => $rhs) {
463
			$query = $this->addField($query, $lhs);
464
			$query = $this->addField($query, $rhs);
465
			$options['conditions'][] = array($lhs => $db->identifier($rhs));
466
		}
467
468
		$query['joins'][] = array(
469
			'type' => $joinType,
470
			'table' => $target,
471
			'alias' => $target->alias,
472
			'conditions' => $options['conditions'],
473
		);
474
		return $query;
475
	}
476
477
/**
478
 * Adds a field into the `fields` option of the query
479
 *
480
 * @param array $query Query
481
 * @param string $field Name of the field
482
 * @return Modified query
483
 */
484
	private function addField(array $query, $field) { // @codingStandardsIgnoreLine
485
		if (!in_array($field, $query['fields'], true)) {
486
			$query['fields'][] = $field;
487
		}
488
		return $query;
489
	}
490
491
/**
492
 * Parse the `contain` option of the query recursively
493
 *
494
 * @param Model $parent Parent model of the contained model
495
 * @param string $alias Alias of the contained model
496
 * @param array $contain Reformatted `contain` option for the deep associations
497
 * @param array|null $context Context
498
 * @return array
499
 * @throws InvalidArgumentException
500
 */
501
	private function parseContain(Model $parent, $alias, array $contain, $context = null) { // @codingStandardsIgnoreLine
502
		if ($context === null) {
503
			$context = array(
504
				'root' => $parent->alias,
505
				'aliasPath' => $parent->alias,
506
				'propertyPath' => '',
507
				'forceExternal' => false,
508
			);
509
		}
510
511
		$aliasPath = $context['aliasPath'] . '.' . $alias;
512
		$propertyPath = ($context['propertyPath'] ? $context['propertyPath'] . '.' : '') . $alias;
513
514
		$types = $parent->getAssociated();
515
		if (!isset($types[$alias])) {
516
			throw new InvalidArgumentException(sprintf('Model "%s" is not associated with model "%s"', $parent->alias, $alias), E_USER_WARNING);
517
		}
518
519
		$parentAlias = $parent->alias;
520
		$target = $parent->$alias;
521
		$type = $types[$alias];
522
		$relation = $parent->{$type}[$alias];
523
524
		$options = $contain['options'] + array_intersect_key(Hash::filter($relation), $this->containOptions);
525
526
		$has = (stripos($type, 'has') !== false);
527
		$many = (stripos($type, 'many') !== false);
528
		$belong = (stripos($type, 'belong') !== false);
529
530
		if ($has && $belong) {
531
			$parentKey = $parent->primaryKey;
532
			$targetKey = $target->primaryKey;
533
			$habtmAlias = $relation['with'];
534
			$habtm = $parent->$habtmAlias;
535
			$habtmParentKey = $relation['foreignKey'];
536
			$habtmTargetKey = $relation['associationForeignKey'];
537
		} elseif ($has) {
538
			$parentKey = $parent->primaryKey;
539
			$targetKey = $relation['foreignKey'];
540
		} else {
541
			$parentKey = $relation['foreignKey'];
542
			$targetKey = $target->primaryKey;
543
		}
544
545
		if (!empty($relation['external'])) {
546
			$external = true;
547
		}
548
549
		if (!empty($relation['finderQuery'])) {
550
			$finderQuery = $relation['finderQuery'];
551
		}
552
553
		$meta = compact(
554
			'alias', 'parent', 'target',
555
			'parentAlias', 'parentKey',
556
			'targetKey', 'aliasPath', 'propertyPath',
557
			'options', 'has', 'many', 'belong', 'external', 'finderQuery',
558
			'habtm', 'habtmAlias', 'habtmParentKey', 'habtmTargetKey', 'type'
559
		);
560
561
		if ($this->isExternal($context, $meta)) {
562
			$meta['propertyPath'] = ($context['propertyPath'] ? $parentAlias . '.' : '') . $alias;
563
			$meta['external'] = true;
564
565
			$context['root'] = $aliasPath;
566
			$context['propertyPath'] = $alias;
567
568
			$path = $context['aliasPath'];
569
		} else {
570
			$meta['external'] = false;
571
			if ($context['root'] !== $context['aliasPath']) {
572
				$meta['eager'] = true;
573
			}
574
575
			$context['propertyPath'] = $propertyPath;
576
577
			$path = $context['root'];
578
		}
579
580
		$this->metas[$path][] = $meta;
581
582
		$context['aliasPath'] = $aliasPath;
583
		$context['forceExternal'] = !empty($finderQuery);
584
585
		foreach ($contain['contain'] as $key => $val) {
586
			$this->parseContain($target, $key, $val, $context);
587
		}
588
589
		return $this->metas;
590
	}
591
592
/**
593
 * Returns whether the target is external or not
594
 *
595
 * @param array $context Context
596
 * @param array $meta Meta data to be used for eager loading
597
 * @return bool
598
 */
599
	private function isExternal(array $context, array $meta) { // @codingStandardsIgnoreLine
600
		extract($meta);
601
602
		if ($parent->useDbConfig !== $target->useDbConfig) {
603
			return true;
604
		}
605
		if (!empty($external)) {
606
			return true;
607
		}
608
		if (!empty($many)) {
609
			return true;
610
		}
611
		if (!empty($finderQuery)) {
612
			return true;
613
		}
614
		if ($this->hasLimitOffset($options)) {
615
			return true;
616
		}
617
		if ($context['forceExternal']) {
618
			return true;
619
		}
620
621
		$metas = $this->metas($context['root']);
622
		$aliases = Hash::extract($metas, '{n}.alias');
623
		if (in_array($alias, $aliases, true)) {
624
			return true;
625
		}
626
627
		return false;
628
	}
629
630
/**
631
 * Returns where `limit` or `offset` option exists
632
 *
633
 * @param array $options Options
634
 * @return bool
635
 */
636
	private function hasLimitOffset($options) { // @codingStandardsIgnoreLine
637
		return !empty($options['limit']) || !empty($options['offset']);
638
	}
639
640
/**
641
 * Triggers afterFind() method
642
 *
643
 * @param Model $parent Model
644
 * @param string $alias Alias
645
 * @param array $results Results
646
 * @return array
647
 */
648
	private function filterResults(Model $parent, $alias, array $results) { // @codingStandardsIgnoreLine
649
		$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 $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
650
651
		$target = $parent->$alias;
652
653
		foreach ($results as $key => &$result) {
654
			$data = $target->afterFind(array(array($alias => $result[$alias])), false);
655
			if (isset($data[0][$alias])) {
656
				$result[$alias] = $data[0][$alias];
657
			} else {
658
				unset($results[$key]);
659
			}
660
		}
661
662
		return $results;
663
	}
664
}
665