public function generateAssociationQuery(Model $Model, $LinkModel, $type, $association, $assocData, &$queryData, $external)
{
$assocData = $this->_scrubQueryData($assocData);
$queryData = $this->_scrubQueryData($queryData);
if ($LinkModel === null) {
return $this->buildStatement(array('fields' => array_unique($queryData['fields']), 'table' => $this->fullTableName($Model), 'alias' => $Model->alias, 'limit' => $queryData['limit'], 'offset' => $queryData['offset'], 'joins' => $queryData['joins'], 'conditions' => $queryData['conditions'], 'order' => $queryData['order'], 'group' => $queryData['group']), $Model);
}
if ($external && !empty($assocData['finderQuery'])) {
return $assocData['finderQuery'];
}
if ($type === 'hasMany' || $type === 'hasAndBelongsToMany') {
if (empty($assocData['offset']) && !empty($assocData['page'])) {
$assocData['offset'] = ($assocData['page'] - 1) * $assocData['limit'];
}
}
switch ($type) {
case 'hasOne':
case 'belongsTo':
$conditions = $this->_mergeConditions($assocData['conditions'], $this->getConstraint($type, $Model, $LinkModel, $association, array_merge($assocData, compact('external'))));
if ($external) {
// Not self join
if ($Model->name !== $LinkModel->name) {
$modelAlias = $Model->alias;
foreach ($conditions as $key => $condition) {
if (is_numeric($key) && strpos($condition, $modelAlias . '.') !== false) {
unset($conditions[$key]);
}
}
}
$query = array_merge($assocData, array('conditions' => $conditions, 'table' => $this->fullTableName($LinkModel), 'fields' => $this->fields($LinkModel, $association, $assocData['fields']), 'alias' => $association, 'group' => null));
} else {
$join = array('table' => $LinkModel, 'alias' => $association, 'type' => isset($assocData['type']) ? $assocData['type'] : 'LEFT', 'conditions' => trim($this->conditions($conditions, true, false, $Model)));
$fields = array();
if ($assocData['fields'] !== false) {
$fields = $this->fields($LinkModel, $association, $assocData['fields']);
}
$queryData['fields'] = array_merge($this->prepareFields($Model, $queryData), $fields);
if (!empty($assocData['order'])) {
$queryData['order'][] = $assocData['order'];
}
if (!in_array($join, $queryData['joins'], true)) {
$queryData['joins'][] = $join;
}
return true;
}
break;
case 'hasMany':
$assocData['fields'] = $this->fields($LinkModel, $association, $assocData['fields']);
if (!empty($assocData['foreignKey'])) {
$assocData['fields'] = array_merge($assocData['fields'], $this->fields($LinkModel, $association, array("{$association}.{$assocData['foreignKey']}")));
}
$query = array('conditions' => $this->_mergeConditions($this->getConstraint('hasMany', $Model, $LinkModel, $association, $assocData), $assocData['conditions']), 'fields' => array_unique($assocData['fields']), 'table' => $this->fullTableName($LinkModel), 'alias' => $association, 'order' => $assocData['order'], 'limit' => $assocData['limit'], 'offset' => $assocData['offset'], 'group' => null);
break;
case 'hasAndBelongsToMany':
$joinFields = array();
$joinAssoc = null;
if (isset($assocData['with']) && !empty($assocData['with'])) {
$joinKeys = array($assocData['foreignKey'], $assocData['associationForeignKey']);
list($with, $joinFields) = $Model->joinModel($assocData['with'], $joinKeys);
$joinTbl = $Model->{$with};
$joinAlias = $joinTbl;
if (is_array($joinFields) && !empty($joinFields)) {
$joinAssoc = $joinAlias = $joinTbl->alias;
$joinFields = $this->fields($joinTbl, $joinAlias, $joinFields);
} else {
$joinFields = array();
}
} else {
$joinTbl = $assocData['joinTable'];
$joinAlias = $this->fullTableName($assocData['joinTable']);
}
$query = array('conditions' => $assocData['conditions'], 'limit' => $assocData['limit'], 'offset' => $assocData['offset'], 'table' => $this->fullTableName($LinkModel), 'alias' => $association, 'fields' => array_merge($this->fields($LinkModel, $association, $assocData['fields']), $joinFields), 'order' => $assocData['order'], 'group' => null, 'joins' => array(array('table' => $joinTbl, 'alias' => $joinAssoc, 'conditions' => $this->getConstraint('hasAndBelongsToMany', $Model, $LinkModel, $joinAlias, $assocData, $association))));
break;
}
if (isset($query)) {
return $this->buildStatement($query, $Model);
}
return null;
}