public function queryAssociation(Model $Model, Model $LinkModel, $type, $association, $assocData, &$queryData, $external, &$resultSet, $recursive, $stack)
{
if (isset($stack['_joined'])) {
$joined = $stack['_joined'];
unset($stack['_joined']);
}
$queryTemplate = $this->generateAssociationQuery($Model, $LinkModel, $type, $association, $assocData, $queryData, $external);
if (empty($queryTemplate)) {
return;
}
if (!is_array($resultSet)) {
throw new CakeException(__d('cake_dev', 'Error in Model %s', get_class($Model)));
}
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
$assocResultSet = array();
if (!empty($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) {
$DeepModel = $LinkModel->{$assoc1};
$tmpStack = $stack;
$tmpStack[] = $assoc1;
$db = $LinkModel->useDbConfig === $DeepModel->useDbConfig ? $this : $DeepModel->getDataSource();
$db->queryAssociation($LinkModel, $DeepModel, $type1, $assoc1, $assocData1, $queryData, true, $assocResultSet, $recursive - 1, $tmpStack);
}
}
}
// 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
$assocResultSet = array();
if (!empty($assocIds)) {
$assocResultSet = $this->_fetchHasAndBelongsToMany($Model, $queryTemplate, $assocIds, $association);
}
$habtmAssocData = $Model->hasAndBelongsToMany[$association];
$foreignKey = $habtmAssocData['foreignKey'];
$joinKeys = array($foreignKey, $habtmAssocData['associationForeignKey']);
list($with, $habtmFields) = $Model->joinModel($habtmAssocData['with'], $joinKeys);
$habtmFieldsCount = count($habtmFields);
// Filter
if ($queryData['callbacks'] === true || $queryData['callbacks'] === 'after') {
$this->_filterResults($assocResultSet, $Model);
}
}
$modelAlias = $Model->alias;
$primaryKey = $Model->primaryKey;
$selfJoin = $Model->name === $LinkModel->name;
foreach ($resultSet as &$row) {
if ($type === 'hasOne' || $type === 'belongsTo' || $type === 'hasMany') {
$assocResultSet = array();
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)) {
$assocResultSet[0] = array($LinkModel->alias => $row[$LinkModel->alias]);
}
} else {
$query = $this->insertQueryData($queryTemplate, $row, $association, $Model, $stack);
if ($query !== false) {
$assocResultSet = $this->fetchAll($query, $Model->cacheQueries);
}
}
}
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' || $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, $assocResultSet, $recursive - 1, $tmpStack);
}
}
}
}
if ($type === 'hasAndBelongsToMany') {
$merge = array();
foreach ($assocResultSet as $data) {
if (isset($data[$with]) && $data[$with][$foreignKey] === $row[$modelAlias][$primaryKey]) {
if ($habtmFieldsCount <= 2) {
unset($data[$with]);
}
$merge[] = $data;
}
}
if (empty($merge) && !isset($row[$association])) {
$row[$association] = $merge;
} else {
$this->_mergeAssociation($row, $merge, $association, $type);
}
} else {
$this->_mergeAssociation($row, $assocResultSet, $association, $type, $selfJoin);
}
if ($type !== 'hasAndBelongsToMany' && isset($row[$association])) {
$row[$association] = $LinkModel->afterFind($row[$association], false);
}
} else {
$tempArray[0][$association] = false;
$this->_mergeAssociation($row, $tempArray, $association, $type, $selfJoin);
}
}
}