From adb45e1d7bcb6a445c0e66dbd936092a72a52cde Mon Sep 17 00:00:00 2001 From: Johannes Kasberger <johannes.kasberger@reelworx.at> Date: Tue, 21 Feb 2017 14:27:56 +0100 Subject: [PATCH] [BUGFIX] Extbase: correct handling of mm relations This change fixes a regression after the doctrine migration and additionally fixes a wrong join condition which is also present in version 7 Resolves: #79931 Resolves: #79932 Releases: master Change-Id: I04a4ce174fb1da3baca9af8ba771a7db70d9a884 Reviewed-on: https://review.typo3.org/51782 Tested-by: TYPO3com <no-reply@typo3.com> Reviewed-by: Markus Klein <markus.klein@typo3.org> Tested-by: Markus Klein <markus.klein@typo3.org> Reviewed-by: Georg Ringer <georg.ringer@gmail.com> Tested-by: Georg Ringer <georg.ringer@gmail.com> --- .../Generic/Storage/Typo3DbQueryParser.php | 12 +++--- .../Domain/Repository/PostRepository.php | 13 +++++++ .../Persistence/Fixtures/category-mm.xml | 10 +++++ .../Functional/Persistence/RelationTest.php | 39 +++++++++++++++++++ 4 files changed, 68 insertions(+), 6 deletions(-) diff --git a/typo3/sysext/extbase/Classes/Persistence/Generic/Storage/Typo3DbQueryParser.php b/typo3/sysext/extbase/Classes/Persistence/Generic/Storage/Typo3DbQueryParser.php index 9aba64c24cd0..51810ae641ff 100644 --- a/typo3/sysext/extbase/Classes/Persistence/Generic/Storage/Typo3DbQueryParser.php +++ b/typo3/sysext/extbase/Classes/Persistence/Generic/Storage/Typo3DbQueryParser.php @@ -954,9 +954,12 @@ class Typo3DbQueryParser $relationTableName = $columnMap->getRelationTableName(); $relationTableAlias = $relationTableAlias = $this->getUniqueAlias($relationTableName, $fullPropertyPath . '_mm'); - $joinConditionExpression = $this->queryBuilder->expr()->eq( - $tableName . '.uid', - $relationTableAlias . '.' . $columnMap->getParentKeyFieldName() + $joinConditionExpression = $this->queryBuilder->expr()->andX( + $this->queryBuilder->expr()->eq( + $tableName . '.uid', + $relationTableAlias . '.' . $columnMap->getParentKeyFieldName() + ), + $this->getAdditionalMatchFieldsStatement($this->queryBuilder->expr(), $columnMap, $relationTableAlias, $realTableName) ); $this->queryBuilder->leftJoin($tableName, $relationTableName, $relationTableAlias, $joinConditionExpression); $joinConditionExpression = $this->queryBuilder->expr()->eq( @@ -964,9 +967,6 @@ class Typo3DbQueryParser $childTableAlias . '.uid' ); $this->queryBuilder->leftJoin($relationTableAlias, $childTableName, $childTableAlias, $joinConditionExpression); - $this->queryBuilder->andWhere( - $this->getAdditionalMatchFieldsStatement($this->queryBuilder->expr(), $columnMap, $relationTableAlias, $realTableName) - ); $this->unionTableAliasCache[] = $childTableAlias; $this->queryBuilder->addGroupBy($this->tableName . '.uid'); } else { diff --git a/typo3/sysext/extbase/Tests/Functional/Fixtures/Extensions/blog_example/Classes/Domain/Repository/PostRepository.php b/typo3/sysext/extbase/Tests/Functional/Fixtures/Extensions/blog_example/Classes/Domain/Repository/PostRepository.php index 6ca57c01f3b2..f51a4e538391 100644 --- a/typo3/sysext/extbase/Tests/Functional/Fixtures/Extensions/blog_example/Classes/Domain/Repository/PostRepository.php +++ b/typo3/sysext/extbase/Tests/Functional/Fixtures/Extensions/blog_example/Classes/Domain/Repository/PostRepository.php @@ -14,6 +14,8 @@ namespace ExtbaseTeam\BlogExample\Domain\Repository; * The TYPO3 project - inspiring people to share! */ +use TYPO3\CMS\Extbase\Persistence\QueryInterface; + /** * A repository for blog posts * @@ -148,4 +150,15 @@ class PostRepository extends \TYPO3\CMS\Extbase\Persistence\Repository ) ->execute(); } + + public function findAllSortedByCategory(array $uids) + { + $q = $this->createQuery(); + $q->matching($q->in('uid', $uids)); + $q->setOrderings([ + 'categories.title' => QueryInterface::ORDER_ASCENDING, + 'uid' => QueryInterface::ORDER_ASCENDING, + ]); + return $q->execute(); + } } diff --git a/typo3/sysext/extbase/Tests/Functional/Persistence/Fixtures/category-mm.xml b/typo3/sysext/extbase/Tests/Functional/Persistence/Fixtures/category-mm.xml index a92727532be0..785e287813a8 100644 --- a/typo3/sysext/extbase/Tests/Functional/Persistence/Fixtures/category-mm.xml +++ b/typo3/sysext/extbase/Tests/Functional/Persistence/Fixtures/category-mm.xml @@ -46,6 +46,16 @@ <sorting_foreign>2</sorting_foreign> </sys_category_record_mm> + <!-- some bogus records to test MM_match_fields --> + <sys_category_record_mm> + <uid_local>4</uid_local> + <uid_foreign>5</uid_foreign> + <tablenames>tx_my_extension</tablenames> + <fieldname>categories</fieldname> + <sorting>1</sorting> + <sorting_foreign>2</sorting_foreign> + </sys_category_record_mm> + <!-- blog 1 gets categories 1,2,3 --> <sys_category_record_mm> <uid_local>1</uid_local> diff --git a/typo3/sysext/extbase/Tests/Functional/Persistence/RelationTest.php b/typo3/sysext/extbase/Tests/Functional/Persistence/RelationTest.php index 6cc153d3123e..09aefcd94810 100644 --- a/typo3/sysext/extbase/Tests/Functional/Persistence/RelationTest.php +++ b/typo3/sysext/extbase/Tests/Functional/Persistence/RelationTest.php @@ -14,6 +14,7 @@ namespace TYPO3\CMS\Extbase\Tests\Functional\Persistence; * The TYPO3 project - inspiring people to share! */ +use ExtbaseTeam\BlogExample\Domain\Model\Post; use TYPO3\CMS\Core\Database\ConnectionPool; use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction; use TYPO3\CMS\Core\Utility\GeneralUtility; @@ -1009,4 +1010,42 @@ class RelationTest extends \TYPO3\TestingFramework\Core\Functional\FunctionalTes $blogRepository->update($this->blog); $this->persistentManager->persistAll(); } + + public function ensureCorrectPostOrderingByCategoryTitleDataProvider() + { + return [ + 'Post with no category and post with category' => [ + [2, 3], + [3, 2] + ], + 'Posts with category and Post with category and bogus category' => [ + [2, 1], + [1, 2] + ], + 'Posts bogus category and post with category' => [ + [5, 2], + [5, 2] + ], + ]; + } + + /** + * This test covers the case when data is ordered by criteria that is MM related with matchFields involved + * on the relation table. (post <-> sys_category_mm <-> sys_category) + * + * @test + * @dataProvider ensureCorrectPostOrderingByCategoryTitleDataProvider + */ + public function ensureCorrectPostOrderingByCategoryTitle(array $uids, array $expected) + { + /** @var \ExtbaseTeam\BlogExample\Domain\Repository\PostRepository $postRepository */ + $postRepository = $this->objectManager->get(\ExtbaseTeam\BlogExample\Domain\Repository\PostRepository::class); + $posts = $postRepository->findAllSortedByCategory($uids)->toArray(); + $result = []; + /** @var Post $post */ + foreach ($posts as $post) { + $result[] = $post->getUid(); + } + $this->assertSame($expected, $result); + } } -- GitLab