DboSource::generateAssociationQuery PHP 메소드

generateAssociationQuery() 공개 메소드

Builds a string containing an SQL statement template.
public generateAssociationQuery ( Model $Model, Model | null $LinkModel, string $type, string $association, array $assocData, &$queryData, boolean $external ) : mixed
$Model Model Primary Model object.
$LinkModel Model | null Linked model object.
$type string Association type, one of the model association types ie. hasMany.
$association string Association name.
$assocData array Association data.
$external boolean Whether or not the association query is on an external datasource.
리턴 mixed String representing a query. True, when $external is false and association $type is 'hasOne' or 'belongsTo'.
    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;
    }

Usage Example

예제 #1
0
/**
 * testGenerateAssociationQueryHasAndBelongsToManyWithPageAndLimit method
 *
 * @return void
 */
	public function testGenerateAssociationQueryHasAndBelongsToManyWithPageAndLimit() {
		$this->Model = new TestModel4();
		$this->Model->schema();
		$this->_buildRelatedModels($this->Model);

		$backup = $this->Model->hasAndBelongsToMany['TestModel7'];

		$this->Model->hasAndBelongsToMany['TestModel7']['page'] = 2;
		$this->Model->hasAndBelongsToMany['TestModel7']['limit'] = 5;

		$binding = array('type' => 'hasAndBelongsToMany', 'model' => 'TestModel7');
		$queryData = array();
		$resultSet = null;
		$null = null;

		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);

		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
		$this->assertRegExp('/^SELECT\s+`TestModel7`\.`id`, `TestModel7`\.`name`, `TestModel7`\.`created`, `TestModel7`\.`updated`, `TestModel4TestModel7`\.`test_model4_id`, `TestModel4TestModel7`\.`test_model7_id`\s+/', $result);
		$this->assertRegExp('/\s+FROM\s+\S+`test_model7`\s+AS\s+`TestModel7`\s+JOIN\s+\S+`test_model4_test_model7`\s+AS\s+`TestModel4TestModel7`/', $result);
		$this->assertRegExp('/\s+ON\s+\(`TestModel4TestModel7`\.`test_model4_id`\s+=\s+{\$__cakeID__\$}/', $result);
		$this->assertRegExp('/\s+AND\s+`TestModel4TestModel7`\.`test_model7_id`\s+=\s+`TestModel7`\.`id`\)\s+WHERE\s+/', $result);
		$this->assertRegExp('/\s+(?:\()?1\s+=\s+1(?:\))?\s*\s+LIMIT 5,\s*5\s*$/', $result);

		$result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
		$this->assertRegExp('/^SELECT\s+`TestModel4`\.`id`, `TestModel4`\.`name`, `TestModel4`\.`created`, `TestModel4`\.`updated`\s+/', $result);
		$this->assertRegExp('/\s+FROM\s+\S+`test_model4` AS `TestModel4`\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result);

		$this->Model->hasAndBelongsToMany['TestModel7'] = $backup;
	}
DboSource