From c0764c8d6f84aec1d6c1276a5e7edb351a288c39 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Mon, 15 May 2017 09:43:55 -0500 Subject: [PATCH] Added second signature for contain that matches the signature for matching --- src/ORM/EagerLoader.php | 11 ++++++++++- src/ORM/Query.php | 22 ++++++++++++++++++---- tests/TestCase/ORM/EagerLoaderTest.php | 20 ++++++++++++++++++++ tests/TestCase/ORM/QueryTest.php | 26 ++++++++++++++++++++++++++ 4 files changed, 74 insertions(+), 5 deletions(-) diff --git a/src/ORM/EagerLoader.php b/src/ORM/EagerLoader.php index c5d042faa02..ac48999884e 100644 --- a/src/ORM/EagerLoader.php +++ b/src/ORM/EagerLoader.php @@ -126,14 +126,23 @@ class EagerLoader * @param array|string $associations list of table aliases to be queried. * When this method is called multiple times it will merge previous list with * the new one. + * @param callable|null $queryBuilder The query builder callable * @return array Containments. */ - public function contain($associations = []) + public function contain($associations = [], callable $queryBuilder = null) { if (empty($associations)) { return $this->_containments; } + if ($queryBuilder) { + $associations = [ + $associations => [ + 'queryBuilder' => $queryBuilder + ] + ]; + } + $associations = (array)$associations; $associations = $this->_reformatContain($associations, $this->_containments); $this->_normalized = null; diff --git a/src/ORM/Query.php b/src/ORM/Query.php index 42e788126a3..c21b8ba763f 100644 --- a/src/ORM/Query.php +++ b/src/ORM/Query.php @@ -352,14 +352,21 @@ public function eagerLoader(EagerLoader $instance = null) * Failing to do so will trigger exceptions. * * ``` - * // Use special join conditions for getting an Articles's belongsTo 'authors' + * // Use a query builder to add conditions to the containment + * $query->contain('Authors', function ($q) { + * return $q->where(...); // add conditions + * }); + * // Use special join conditions for multiple containments in the same method call * $query->contain([ * 'Authors' => [ * 'foreignKey' => false, * 'queryBuilder' => function ($q) { * return $q->where(...); // Add full filtering conditions * } - * ] + * ], + * 'Tags' => function ($q) { + * return $q->where(...); // add conditions + * } * ]); * ``` * @@ -371,7 +378,9 @@ public function eagerLoader(EagerLoader $instance = null) * previous list will be emptied. * * @param array|string|null $associations List of table aliases to be queried. - * @param bool $override Whether override previous list with the one passed + * @param callable|bool $override The query builder for the association, or + * if associations is an array, a bool on whether to override previous list + * with the one passed * defaults to merging previous list with the new one. * @return array|$this */ @@ -386,7 +395,12 @@ public function contain($associations = null, $override = false) return $loader->contain(); } - $result = $loader->contain($associations); + $queryBuilder = null; + if (is_callable($override)) { + $queryBuilder = $override; + } + + $result = $loader->contain($associations, $queryBuilder); $this->_addAssociationsToTypeMap($this->repository(), $this->getTypeMap(), $result); return $this; diff --git a/tests/TestCase/ORM/EagerLoaderTest.php b/tests/TestCase/ORM/EagerLoaderTest.php index 2f05c2b6651..d08713d6975 100644 --- a/tests/TestCase/ORM/EagerLoaderTest.php +++ b/tests/TestCase/ORM/EagerLoaderTest.php @@ -332,6 +332,26 @@ public function testContainClosure() $this->assertEquals($expected, $loader->contain()); } + /** + * Tests using the same signature as matching with contain + * + * @return void + */ + public function testContainSecondSignature() + { + $builder = function ($query) { + }; + $loader = new EagerLoader; + $loader->contain('clients', $builder); + + $expected = [ + 'clients' => [ + 'queryBuilder' => $builder + ] + ]; + $this->assertEquals($expected, $loader->contain()); + } + /** * Tests that query builders are stacked * diff --git a/tests/TestCase/ORM/QueryTest.php b/tests/TestCase/ORM/QueryTest.php index dfbdd002ab5..0f27679a05d 100644 --- a/tests/TestCase/ORM/QueryTest.php +++ b/tests/TestCase/ORM/QueryTest.php @@ -2018,6 +2018,32 @@ public function testContainWithClosure() $this->assertEquals([1], array_unique($ids)); } + /** + * Integration test that uses the contain signature that is the same as the + * matching signature + * + * @return void + */ + public function testContainSecondSignature() + { + $table = TableRegistry::get('authors'); + $table->hasMany('articles'); + $query = new Query($this->connection, $table); + $query + ->select() + ->contain('articles', function ($q) { + return $q->where(['articles.id' => 1]); + }); + + $ids = []; + foreach ($query as $entity) { + foreach ((array)$entity->articles as $article) { + $ids[] = $article->id; + } + } + $this->assertEquals([1], array_unique($ids)); + } + /** * Integration test to ensure that filtering associations with the queryBuilder * option works.