From 5dd1ba2a1f123c7ecccc5700fa56795f34dbfd80 Mon Sep 17 00:00:00 2001 From: Jose Lorenzo Rodriguez Date: Sun, 15 Jun 2014 12:10:43 +0200 Subject: [PATCH] Implemented dot notation for specifying associations in the marshaller --- src/ORM/Marshaller.php | 35 ++++++++++++++++++++++ tests/TestCase/ORM/MarshallerTest.php | 18 ++--------- tests/TestCase/ORM/QueryRegressionTest.php | 4 +-- 3 files changed, 40 insertions(+), 17 deletions(-) diff --git a/src/ORM/Marshaller.php b/src/ORM/Marshaller.php index d0a5932cfee..d5879780174 100644 --- a/src/ORM/Marshaller.php +++ b/src/ORM/Marshaller.php @@ -66,6 +66,7 @@ public function __construct(Table $table, $safe = false) { */ protected function _buildPropertyMap($include) { $map = []; + $include = $this->_normalizeAssociations($include); foreach ($include as $key => $nested) { if (is_int($key) && is_scalar($nested)) { $key = $nested; @@ -83,6 +84,40 @@ protected function _buildPropertyMap($include) { return $map; } +/** + * Returns an array out of the original passed associations list where dot notation + * is transformed into nested arrays so that they can be parsed by other association + * marshallers. + * + * @param array $associations The array of included associations. + * @return array An array having dot notation trnasformed into nested arrays + */ + protected function _normalizeAssociations($associations) { + $result = []; + foreach ($associations as $table => $options) { + $pointer =& $result; + + if (is_int($table)) { + $table = $options; + $options = []; + } + + if (strpos($table, '.')) { + $path = explode('.', $table); + $table = array_pop($path); + foreach ($path as $t) { + $pointer += [$t => ['associated' => []]]; + $pointer =& $pointer[$t]['associated']; + } + } + + $pointer += [$table => []]; + $pointer[$table] = $options + $pointer[$table]; + } + + return $result; + } + /** * Hydrate one entity and its associated data. * diff --git a/tests/TestCase/ORM/MarshallerTest.php b/tests/TestCase/ORM/MarshallerTest.php index 83dfbfa5b3e..371f843883f 100644 --- a/tests/TestCase/ORM/MarshallerTest.php +++ b/tests/TestCase/ORM/MarshallerTest.php @@ -352,13 +352,7 @@ public function testOneBelongsToManyJoinDataAssociated() { $articlesTags->belongsTo('Users'); $marshall = new Marshaller($this->articles); - $result = $marshall->one($data, [ - 'Tags' => [ - 'associated' => [ - '_joinData' => ['associated' => ['Users']] - ] - ] - ]); + $result = $marshall->one($data, ['Tags._joinData.Users']); $this->assertInstanceOf( 'Cake\ORM\Entity', $result->tags[0]->_joinData->user, @@ -392,7 +386,7 @@ public function testOneDeepAssociations() { ] ]; $marshall = new Marshaller($this->comments); - $result = $marshall->one($data, ['Articles' => ['associated' => ['Users']]]); + $result = $marshall->one($data, ['Articles.Users']); $this->assertEquals( $data['article']['title'], @@ -870,13 +864,7 @@ public function testMergeJoinDataAssociations() { $articlesTags = TableRegistry::get('ArticlesTags'); $articlesTags->belongsTo('Users'); - $options = [ - 'Tags' => [ - 'associated' => [ - '_joinData' => ['associated' => ['Users']] - ] - ] - ]; + $options = ['Tags._joinData.Users']; $marshall = new Marshaller($this->articles); $entity = $marshall->one($data, $options); $entity->accessible('*', true); diff --git a/tests/TestCase/ORM/QueryRegressionTest.php b/tests/TestCase/ORM/QueryRegressionTest.php index 33366a69a33..e081498abe6 100644 --- a/tests/TestCase/ORM/QueryRegressionTest.php +++ b/tests/TestCase/ORM/QueryRegressionTest.php @@ -151,7 +151,7 @@ public function testCreateJointData() { ] ] ]; - $entity = $articles->patchEntity($entity, $data, ['Highlights' => ['associated' => ['_joinData']]]); + $entity = $articles->patchEntity($entity, $data, ['Highlights._joinData']); $articles->save($entity); $entity = $articles->get(2, ['contain' => ['Highlights']]); $this->assertEquals(4, $entity->highlights[0]->_joinData->tag_id); @@ -214,7 +214,7 @@ public function testBelongsToManyDeepSave() { ] ]; $entity = $articles->patchEntity($entity, $data, [ - 'Highlights' => ['associated' => ['_joinData' => ['associated' => ['Authors']], 'Authors']] + 'Highlights._joinData.Authors', 'Highlights.Authors' ]); $articles->save($entity, [ 'associated' => [