Browse Source

Be more semantic with variable names.
Isue less loockups for deep arrays.
A bit of documentation added.

Ber Clausen 12 years ago
parent
commit
86b69964ef
1 changed files with 49 additions and 27 deletions
  1. 49 27
      lib/Cake/Model/Datasource/DboSource.php

+ 49 - 27
lib/Cake/Model/Datasource/DboSource.php

@@ -1198,7 +1198,15 @@ class DboSource extends DataSource {
 	}
 
 /**
- * Queries associations. Used to fetch results on recursive models.
+ * Queries associations.
+ *
+ * Used to fetch results on recursive models.
+ *
+ * - 'hasMany' associations with no limit set:
+ *    Fetch, filter and merge is done recursively for every level.
+ *
+ * - 'hasAndBelongsToMany' associations:
+ *    Fetch and filter is done unaffected by the (recursive) level set.
  *
  * @param Model $Model Primary Model object.
  * @param Model $LinkModel Linked model object.
@@ -1219,8 +1227,8 @@ class DboSource extends DataSource {
 			unset($stack['_joined']);
 		}
 
-		$query = $this->generateAssociationQuery($Model, $LinkModel, $type, $association, $assocData, $queryData, $external);
-		if (empty($query)) {
+		$queryTemplate = $this->generateAssociationQuery($Model, $LinkModel, $type, $association, $assocData, $queryData, $external);
+		if (empty($queryTemplate)) {
 			return;
 		}
 
@@ -1229,18 +1237,21 @@ class DboSource extends DataSource {
 		}
 
 		if ($type === 'hasMany' && empty($assocData['limit']) && !empty($assocData['foreignKey'])) {
+			// 'hasMany' associations with no limit set.
+
 			$assocIds = array();
 			foreach ($resultSet as $result) {
 				$assocIds[] = $this->insertQueryData('{$__cakeID__$}', $result, $association, $Model, $stack);
 			}
 			$assocIds = array_filter($assocIds);
 
-			// Fetch 'hasMany' associations on every recursive level.
+			// Fetch
 			$assocResultSet = array();
 			if (!empty($assocIds)) {
-				$assocResultSet = $this->fetchHasMany($Model, $query, $assocIds);
+				$assocResultSet = $this->fetchHasMany($Model, $queryTemplate, $assocIds);
 			}
 
+			// Recursively query associations
 			if ($recursive > 0 && !empty($assocResultSet) && is_array($assocResultSet)) {
 				foreach ($LinkModel->associations() as $type1) {
 					foreach ($LinkModel->{$type1} as $assoc1 => $assocData1) {
@@ -1255,32 +1266,36 @@ class DboSource extends DataSource {
 				}
 			}
 
-			// Filter 'hasMany' associations on every recursive level.
+			// Filter
 			if ($queryData['callbacks'] === true || $queryData['callbacks'] === 'after') {
 				$this->_filterResults($assocResultSet, $Model);
 			}
 
+			// Merge
 			return $this->_mergeHasMany($resultSet, $assocResultSet, $association, $Model);
 
 		} elseif ($type === 'hasAndBelongsToMany') {
+			// 'hasAndBelongsToMany' associations.
+
 			$assocIds = array();
 			foreach ($resultSet as $result) {
 				$assocIds[] = $this->insertQueryData('{$__cakeID__$}', $result, $association, $Model, $stack);
 			}
 			$assocIds = array_filter($assocIds);
 
-			// Fetch 'hasAndBelongsToMany' associations (unaffected by recursive level).
+			// Fetch
 			$assocResultSet = array();
 			if (!empty($assocIds)) {
-				$assocResultSet = $this->fetchHasAndBelongsToMany($Model, $query, $assocIds, $association);
+				$assocResultSet = $this->fetchHasAndBelongsToMany($Model, $queryTemplate, $assocIds, $association);
 			}
 
-			$foreignKey = $Model->hasAndBelongsToMany[$association]['foreignKey'];
-			$joinKeys = array($foreignKey, $Model->hasAndBelongsToMany[$association]['associationForeignKey']);
-			list($with, $habtmFields) = $Model->joinModel($Model->hasAndBelongsToMany[$association]['with'], $joinKeys);
+			$habtmAssocData = $Model->hasAndBelongsToMany[$association];
+			$foreignKey = $habtmAssocData['foreignKey'];
+			$joinKeys = array($foreignKey, $habtmAssocData['associationForeignKey']);
+			list($with, $habtmFields) = $Model->joinModel($habtmAssocData['with'], $joinKeys);
 			$habtmFieldsCount = count($habtmFields);
 
-			// Filter 'hasAndBelongsToMany' associations (unaffected by recursive level).
+			// Filter
 			if ($queryData['callbacks'] === true || $queryData['callbacks'] === 'after') {
 				$this->_filterResults($assocResultSet, $Model);
 			}
@@ -1290,38 +1305,45 @@ class DboSource extends DataSource {
 		$primaryKey = $Model->primaryKey;
 
 		foreach ($resultSet as &$row) {
-			if ($type !== 'hasAndBelongsToMany') {
-				$q = $this->insertQueryData($query, $row, $association, $Model, $stack);
-
-				$fetch = null;
-				if ($q !== false) {
-					$joinedData = array();
-					if (($type === 'belongsTo' || $type === 'hasOne') && isset($row[$LinkModel->alias], $joined[$Model->alias]) && in_array($LinkModel->alias, $joined[$Model->alias])) {
+			if ($type === 'hasOne' || $type === 'belongsTo' || $type === 'hasMany') {
+				$query = $this->insertQueryData($queryTemplate, $row, $association, $Model, $stack);
+
+				$assocResultSet = array();
+				if ($query !== false) {
+					if (
+						($type === 'hasOne' || $type === 'belongsTo') &&
+						isset($row[$LinkModel->alias], $joined[$Model->alias]) &&
+						in_array($LinkModel->alias, $joined[$Model->alias])
+					) {
 						$joinedData = Hash::filter($row[$LinkModel->alias]);
 						if (!empty($joinedData)) {
-							$fetch[0] = array($LinkModel->alias => $row[$LinkModel->alias]);
+							$assocResultSet[0] = array($LinkModel->alias => $row[$LinkModel->alias]);
 						}
 					} else {
-						$fetch = $this->fetchAll($q, $Model->cacheQueries);
+						$assocResultSet = $this->fetchAll($query, $Model->cacheQueries);
 					}
 				}
 			}
 
 			$selfJoin = ($Model->name === $LinkModel->name);
 
-			if (!empty($fetch) && is_array($fetch)) {
+			if (!empty($assocResultSet) && is_array($assocResultSet)) {
 				if ($recursive > 0) {
 					foreach ($LinkModel->associations() as $type1) {
 						foreach ($LinkModel->{$type1} as $assoc1 => $assocData1) {
 							$DeepModel = $LinkModel->{$assoc1};
 
-							if ($type1 === 'belongsTo' || ($DeepModel->alias === $modelAlias && $type === 'belongsTo') || ($DeepModel->alias !== $modelAlias)) {
+							if (
+								$type1 === 'belongsTo' ||
+								($type === 'belongsTo' && $DeepModel->alias === $modelAlias) ||
+								($DeepModel->alias !== $modelAlias)
+							) {
 								$tmpStack = $stack;
 								$tmpStack[] = $assoc1;
 
 								$db = $LinkModel->useDbConfig === $DeepModel->useDbConfig ? $this : $DeepModel->getDataSource();
 
-								$db->queryAssociation($LinkModel, $DeepModel, $type1, $assoc1, $assocData1, $queryData, true, $fetch, $recursive - 1, $tmpStack);
+								$db->queryAssociation($LinkModel, $DeepModel, $type1, $assoc1, $assocData1, $queryData, true, $assocResultSet, $recursive - 1, $tmpStack);
 							}
 						}
 					}
@@ -1329,8 +1351,7 @@ class DboSource extends DataSource {
 
 				if ($type === 'hasAndBelongsToMany') {
 					$merge = array();
-
-					foreach ($fetch as $data) {
+					foreach ($assocResultSet as $data) {
 						if (isset($data[$with]) && $data[$with][$foreignKey] === $row[$modelAlias][$primaryKey]) {
 							if ($habtmFieldsCount <= 2) {
 								unset($data[$with]);
@@ -1338,13 +1359,14 @@ class DboSource extends DataSource {
 							$merge[] = $data;
 						}
 					}
+
 					if (empty($merge) && !isset($row[$association])) {
 						$row[$association] = $merge;
 					} else {
 						$this->_mergeAssociation($row, $merge, $association, $type);
 					}
 				} else {
-					$this->_mergeAssociation($row, $fetch, $association, $type, $selfJoin);
+					$this->_mergeAssociation($row, $assocResultSet, $association, $type, $selfJoin);
 				}
 
 				if ($type !== 'hasAndBelongsToMany' && isset($row[$association])) {