From 915ae6debdb1e72f4d14fb6c24435d052888ecb4 Mon Sep 17 00:00:00 2001 From: Jose Lorenzo Rodriguez Date: Sat, 4 May 2013 17:39:41 +0200 Subject: [PATCH] Adding fields for contained tables when the 'fields' key is defined --- lib/Cake/ORM/Query.php | 60 ++++++++++++++++-------- lib/Cake/Test/TestCase/ORM/QueryTest.php | 33 ++++++++++++- 2 files changed, 71 insertions(+), 22 deletions(-) diff --git a/lib/Cake/ORM/Query.php b/lib/Cake/ORM/Query.php index 643be769d58..f5eb26d3fb2 100644 --- a/lib/Cake/ORM/Query.php +++ b/lib/Cake/ORM/Query.php @@ -41,17 +41,28 @@ 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() { @@ -59,8 +70,8 @@ protected function _transformQuery() { return parent::_transformQuery(); } + $this->_addDefaultFields(); $this->_addContainments(); - $this->_aliasFields(); return parent::_transformQuery(); } @@ -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); } diff --git a/lib/Cake/Test/TestCase/ORM/QueryTest.php b/lib/Cake/Test/TestCase/ORM/QueryTest.php index ac8596e8edc..78b21215bb9 100644 --- a/lib/Cake/Test/TestCase/ORM/QueryTest.php +++ b/lib/Cake/Test/TestCase/ORM/QueryTest.php @@ -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', @@ -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); + } + }