Navigation Menu

Skip to content

Commit

Permalink
Adding fields for contained tables when the 'fields' key is defined
Browse files Browse the repository at this point in the history
  • Loading branch information
lorenzo committed May 4, 2013
1 parent 1f7f87d commit 915ae6d
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 22 deletions.
60 changes: 40 additions & 20 deletions lib/Cake/ORM/Query.php
Expand Up @@ -41,26 +41,37 @@ public function toArray() {
return $this->execute()->toArray();
}

public function aliasField($field) {
if (strpos($field, '.') !== false) {
public function aliasedTable() {
return $this->repository();
}

public function aliasField($field, $alias = null) {
$namespaced = strpos($field, '.') !== false;
$_field = $field;

if ($namespaced) {
list($alias, $field) = explode('.', $field);
} else {
}

if (!$alias) {
$alias = $this->repository()->alias();
}
return sprintf('%s__%s', $alias, $field);
}

public function aliasedTable($alias) {
return $this->repository();
$key = sprintf('%s__%s', $alias, $field);
if (!$namespaced) {
$_field = $alias . '.' . $field;
}

return [$key => $_field];
}

protected function _transformQuery() {
if (!$this->_dirty) {
return parent::_transformQuery();
}

$this->_addDefaultFields();
$this->_addContainments();
$this->_aliasFields();
return parent::_transformQuery();
}

Expand Down Expand Up @@ -156,26 +167,35 @@ protected function _resolveFirstLevel($associations) {

protected function _addJoin($alias, $options) {
$joinOptions = ['table' => 1, 'conditions' => 1, 'type' => 1];
$options = array_intersect_key($options, $joinOptions);
$this->join([$alias => $options]);
}

protected function _aliasFields() {
$select = $this->clause('select');
$schema = $this->repository()->schema();
$this->join([$alias => array_intersect_key($options, $joinOptions)]);

if (!count($select)) {
$this->select(array_keys($schema));
$select = $this->clause('select');
if (!empty($options['fields'])) {
$this->select($this->_aliasFields($options['fields'], $alias));
}
}

protected function _aliasFields($fields, $defaultAlias = null) {
$aliased = [];
foreach ($select as $alias => $field) {
foreach ($fields as $alias => $field) {
if (is_numeric($alias) && is_string($field)) {
$alias = $this->aliasField($field);
$aliased += $this->aliasField($field, $defaultAlias);
continue;
}
$aliased[$alias] = $field;
}

return $aliased;
}

protected function _addDefaultFields() {
$select = $this->clause('select');

if (!count($select)) {
$this->select(array_keys($this->repository()->schema()));
$select = $this->clause('select');
}

$aliased = $this->_aliasFields($select, $this->repository()->alias());
$this->select($aliased, true);
}

Expand Down
33 changes: 31 additions & 2 deletions lib/Cake/Test/TestCase/ORM/QueryTest.php
Expand Up @@ -31,12 +31,16 @@ public function setUp() {
$this->connection = new Connection(Configure::read('Datasource.test'));
}

public function tearDown() {
Table::clearRegistry();
}

/**
* Tests that fully defined belongsTo and hasOne relationships are joined correctly
*
* @return void
**/
public function testContainToJoins() {
public function testContainToJoinsOneLevel() {
$contains = ['client' => [
'associationType' => 'belongsTo',
'table' => 'clients',
Expand Down Expand Up @@ -116,10 +120,35 @@ public function testContainToJoins() {
]])
->will($this->returnValue($query));

$query
$s = $query
->select('foo.id')
->repository($table)
->contain($contains)->sql();
}

public function testContainToFieldsPredefined() {
$contains = ['client' => [
'associationType' => 'belongsTo',
'fields' => ['name', 'company_id', 'client.telephone'],
'table' => 'clients',
'order' => [
'associationType' => 'hasOne',
'fields' => ['total', 'placed']
]
]];

$table = Table::build('foo', ['schema' => ['id' => ['type' => 'integer']]]);
$query = new Query($this->connection);

$query->select('foo.id')->repository($table)->contain($contains)->sql();
$select = $query->clause('select');
$expected = [
'foo__id' => 'foo.id', 'client__name' => 'client.name',
'client__company_id' => 'client.company_id',
'client__telephone' => 'client.telephone',
'order__total' => 'order.total', 'order__placed' => 'order.placed'
];
$this->assertEquals($expected, $select);
}

}

0 comments on commit 915ae6d

Please sign in to comment.