/** * Determines whether output walkers should be used. * * @param QueryBuilder $queryBuilder * * @return bool */ private function useOutputWalkers(QueryBuilder $queryBuilder) : bool { /* * "Cannot count query that uses a HAVING clause. Use the output walkers for pagination" * * @see https://github.com/doctrine/doctrine2/blob/900b55d16afdcdeb5100d435a7166d3a425b9873/lib/Doctrine/ORM/Tools/Pagination/CountWalker.php#L50 */ if (QueryChecker::hasHavingClause($queryBuilder)) { return true; } /* * "Paginating an entity with foreign key as identifier only works when using the Output Walkers. Call Paginator#setUseOutputWalkers(true) before iterating the paginator." * * @see https://github.com/doctrine/doctrine2/blob/900b55d16afdcdeb5100d435a7166d3a425b9873/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryWalker.php#L87 */ if (QueryChecker::hasRootEntityWithForeignKeyIdentifier($queryBuilder, $this->managerRegistry)) { return true; } /* * "Cannot select distinct identifiers from query with LIMIT and ORDER BY on a column from a fetch joined to-many association. Use output walkers." * * @see https://github.com/doctrine/doctrine2/blob/900b55d16afdcdeb5100d435a7166d3a425b9873/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryWalker.php#L149 */ if (QueryChecker::hasMaxResults($queryBuilder) && QueryChecker::hasOrderByOnToManyJoin($queryBuilder, $this->managerRegistry)) { return true; } /* * When using composite identifiers pagination will need Output walkers */ if (QueryChecker::hasRootEntityWithCompositeIdentifier($queryBuilder, $this->managerRegistry)) { return true; } // Disable output walkers by default (performance) return false; }
public function testHasOrderByOnToManyJoinWithoutJoinAndWithoutOrderBy() { $queryBuilder = $this->prophesize(QueryBuilder::class); $queryBuilder->getRootEntities()->willReturn(['Dummy']); $queryBuilder->getRootAliases()->willReturn(['d']); $queryBuilder->getDQLPart('join')->willReturn([]); $queryBuilder->getDQLPart('orderBy')->willReturn([]); $classMetadata = $this->prophesize(ClassMetadata::class); $objectManager = $this->prophesize(ObjectManager::class); $objectManager->getClassMetadata('Dummy')->willReturn($classMetadata->reveal()); $managerRegistry = $this->prophesize(ManagerRegistry::class); $managerRegistry->getManagerForClass('Dummy')->willReturn($objectManager->reveal()); $this->assertFalse(QueryChecker::hasOrderByOnToManyJoin($queryBuilder->reveal(), $managerRegistry->reveal())); }