Skip to content

Commit

Permalink
Simplify the getFixedQueryBuilder method
Browse files Browse the repository at this point in the history
  • Loading branch information
VincentLanglet committed Feb 26, 2021
1 parent 1d0dd25 commit a78062e
Showing 1 changed file with 11 additions and 53 deletions.
64 changes: 11 additions & 53 deletions src/Datagrid/ProxyQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -365,62 +365,20 @@ final public function setHint($name, $value)
*/
protected function getFixedQueryBuilder(QueryBuilder $queryBuilder)
{
$queryBuilderId = clone $queryBuilder;
$rootAlias = current($queryBuilderId->getRootAliases());

// step 1 : retrieve the targeted class
$from = $queryBuilderId->getDQLPart('from');
$class = $from[0]->getFrom();
$metadata = $queryBuilderId->getEntityManager()->getMetadataFactory()->getMetadataFor($class);

// step 2 : retrieve identifier columns
$idNames = $metadata->getIdentifierFieldNames();

// step 3 : retrieve the different subjects ids
$queryBuilderId->resetDQLPart('select');

$selects = [];
foreach ($idNames as $idName) {
$select = sprintf('%s.%s', $rootAlias, $idName);

// Put the ID select on this array to use it on results QB
$selects[$idName] = $select;
$rootAlias = current($queryBuilder->getRootAliases());

// Use IDENTITY if id is a relation too.
// See: http://doctrine-orm.readthedocs.org/en/latest/reference/dql-doctrine-query-language.html
if ($metadata->hasAssociation($idName)) {
$queryBuilderId->addSelect(sprintf('IDENTITY(%s) as %s', $select, $idName));
} else {
$queryBuilderId->addSelect($select);
}
}
// step 1 : retrieve the identifier columns
$identifierFields = $queryBuilder
->getEntityManager()
->getMetadataFactory()
->getMetadataFor(current($queryBuilder->getRootEntities()))
->getIdentifierFieldNames();

// step 2 : group by identifier columns
if ($this->isDistinct()) {
$queryBuilderId->groupBy(implode(', ', $selects));
}

$results = $queryBuilderId->getQuery()->execute([], Query::HYDRATE_ARRAY);
$platform = $queryBuilderId->getEntityManager()->getConnection()->getDatabasePlatform();
$idxMatrix = [];
foreach ($results as $id) {
foreach ($idNames as $idName) {
// Convert ids to database value in case of custom type, if provided.
$fieldType = $metadata->getTypeOfField($idName);
$idxMatrix[$idName][] = $fieldType && Type::hasType($fieldType)
? Type::getType($fieldType)->convertToDatabaseValue($id[$idName], $platform)
: $id[$idName];
}
}

// step 4 : alter the query to match the targeted ids
foreach ($idxMatrix as $idName => $idx) {
if (\count($idx) > 0) {
$idxParamName = sprintf('%s_idx', $idName);
$idxParamName = preg_replace('/[^\w]+/', '_', $idxParamName);
$queryBuilder->andWhere(sprintf('%s IN (:%s)', $selects[$idName], $idxParamName));
$queryBuilder->setParameter($idxParamName, $idx);
$queryBuilder->setMaxResults(null);
$queryBuilder->setFirstResult(null);
$queryBuilder->resetDQLPart('groupBy');
foreach ($identifierFields as $identifierField) {
$queryBuilder->addGroupBy(sprintf('%s.%s', $rootAlias, $identifierField));
}
}

Expand Down

0 comments on commit a78062e

Please sign in to comment.