Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Conveniently fetch hasAndBelongsToMany associations from within a fun…

…ction (like hasMany).

Variable names should represent their values.
Remove unnecessary references.
  • Loading branch information...
commit 7a378c3b22328a51da816e691640e99e89af2ad8 1 parent 60a8f09
@bar bar authored
Showing with 51 additions and 36 deletions.
  1. +51 −36 lib/Cake/Model/Datasource/DboSource.php
View
87 lib/Cake/Model/Datasource/DboSource.php
@@ -1229,19 +1229,19 @@ public function queryAssociation(Model $Model, Model $LinkModel, $type, $associa
}
if ($type === 'hasMany' && empty($assocData['limit']) && !empty($assocData['foreignKey'])) {
- $ins = $fetch = array();
- foreach ($resultSet as &$result) {
- if ($in = $this->insertQueryData('{$__cakeID__$}', $result, $association, $Model, $stack)) {
- $ins[] = $in;
- }
+ $assocIds = array();
+ foreach ($resultSet as $result) {
+ $assocIds[] = $this->insertQueryData('{$__cakeID__$}', $result, $association, $Model, $stack);
}
+ $assocIds = array_filter($assocIds);
- if (!empty($ins)) {
- $ins = array_unique($ins);
- $fetch = $this->fetchAssociated($Model, $query, $ins);
+ // Fetch 'hasMany' associations on every recursive level.
+ $assocResultSet = array();
+ if (!empty($assocIds)) {
+ $assocResultSet = $this->fetchHasMany($Model, $query, $assocIds);
}
- if ($recursive > 0 && !empty($fetch) && is_array($fetch)) {
+ if ($recursive > 0 && !empty($assocResultSet) && is_array($assocResultSet)) {
foreach ($LinkModel->associations() as $type1) {
foreach ($LinkModel->{$type1} as $assoc1 => $assocData1) {
$DeepModel = $LinkModel->{$assoc1};
@@ -1250,50 +1250,39 @@ public function queryAssociation(Model $Model, Model $LinkModel, $type, $associa
$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);
}
}
}
+ // Filter 'hasMany' associations on every recursive level.
if ($queryData['callbacks'] === true || $queryData['callbacks'] === 'after') {
- $this->_filterResults($fetch, $Model);
+ $this->_filterResults($assocResultSet, $Model);
}
- return $this->_mergeHasMany($resultSet, $fetch, $association, $Model);
+ return $this->_mergeHasMany($resultSet, $assocResultSet, $association, $Model);
} elseif ($type === 'hasAndBelongsToMany') {
- $ins = $fetch = array();
- foreach ($resultSet as &$result) {
- if ($in = $this->insertQueryData('{$__cakeID__$}', $result, $association, $Model, $stack)) {
- $ins[] = $in;
- }
+ $assocIds = array();
+ foreach ($resultSet as $result) {
+ $assocIds[] = $this->insertQueryData('{$__cakeID__$}', $result, $association, $Model, $stack);
}
+ $assocIds = array_filter($assocIds);
- if (!empty($ins)) {
- $ins = array_unique($ins);
- if (count($ins) > 1) {
- $query = str_replace('{$__cakeID__$}', '(' . implode(', ', $ins) . ')', $query);
- $query = str_replace('= (', 'IN (', $query);
- } else {
- $query = str_replace('{$__cakeID__$}', $ins[0], $query);
- }
- $query = str_replace(' WHERE 1 = 1', '', $query);
+ // Fetch 'hasAndBelongsToMany' associations (unaffected by recursive level).
+ $assocResultSet = array();
+ if (!empty($assocIds)) {
+ $assocResultSet = $this->fetchHasAndBelongsToMany($Model, $query, $assocIds, $association);
}
$foreignKey = $Model->hasAndBelongsToMany[$association]['foreignKey'];
$joinKeys = array($foreignKey, $Model->hasAndBelongsToMany[$association]['associationForeignKey']);
list($with, $habtmFields) = $Model->joinModel($Model->hasAndBelongsToMany[$association]['with'], $joinKeys);
$habtmFieldsCount = count($habtmFields);
- $q = $this->insertQueryData($query, null, $association, $Model, $stack);
-
- if ($q !== false) {
- $fetch = $this->fetchAll($q, $Model->cacheQueries);
- } else {
- $fetch = null;
- }
+ // Filter 'hasAndBelongsToMany' associations (unaffected by recursive level).
if ($queryData['callbacks'] === true || $queryData['callbacks'] === 'after') {
- $this->_filterResults($fetch, $Model);
+ $this->_filterResults($assocResultSet, $Model);
}
}
@@ -1370,18 +1359,44 @@ public function queryAssociation(Model $Model, Model $LinkModel, $type, $associa
}
/**
- * A more efficient way to fetch associations.
+ * Fetch 'hasMany' associations.
*
* @param Model $Model Primary model object.
* @param string $query Association query template.
* @param array $ids Array of IDs of associated records.
* @return array Association results.
*/
- public function fetchAssociated(Model $Model, $query, $ids) {
+ public function fetchHasMany(Model $Model, $query, $ids) {
+ $ids = array_unique($ids);
+
$query = str_replace('{$__cakeID__$}', implode(', ', $ids), $query);
if (count($ids) > 1) {
$query = str_replace('= (', 'IN (', $query);
}
+
+ return $this->fetchAll($query, $Model->cacheQueries);
+ }
+
+/**
+ * Fetch 'hasAndBelongsToMany' associations.
+ *
+ * @param Model $Model Primary model object.
+ * @param string $query Association query.
+ * @param array $ids Array of IDs of associated records.
+ * @param string $association Association name.
+ * @return array Association results.
+ */
+ public function fetchHasAndBelongsToMany(Model $Model, $query, $ids, $association) {
+ $ids = array_unique($ids);
+
+ if (count($ids) > 1) {
+ $query = str_replace('{$__cakeID__$}', '(' . implode(', ', $ids) . ')', $query);
+ $query = str_replace('= (', 'IN (', $query);
+ } else {
+ $query = str_replace('{$__cakeID__$}', $ids[0], $query);
+ }
+ $query = str_replace(' WHERE 1 = 1', '', $query);
+
return $this->fetchAll($query, $Model->cacheQueries);
}
Please sign in to comment.
Something went wrong with that request. Please try again.