diff --git a/Datagrid/ProxyQuery.php b/Datagrid/ProxyQuery.php index a5671823f..8b97daf65 100644 --- a/Datagrid/ProxyQuery.php +++ b/Datagrid/ProxyQuery.php @@ -51,11 +51,11 @@ public function execute(array $params = array(), $hydrationMode = null) if ($this->getSortBy()) { $sortBy = $this->getSortBy(); if (strpos($sortBy, '.') === false) { // add the current alias - $sortBy = $queryBuilder->getRootAlias() . '.' . $sortBy; + $sortBy = $queryBuilder->getRootAlias().'.'.$sortBy; } $queryBuilder->addOrderBy($sortBy, $this->getSortOrder()); } else { - $queryBuilder->resetDQLPart( 'orderBy' ); + $queryBuilder->resetDQLPart('orderBy'); } return $this->getFixedQueryBuilder($queryBuilder)->getQuery()->execute($params, $hydrationMode); @@ -83,7 +83,7 @@ private function getFixedQueryBuilder(QueryBuilder $queryBuilder) // step 3 : retrieve the different subjects id $select = sprintf('%s.%s', $queryBuilderId->getRootAlias(), $idName); $queryBuilderId->resetDQLPart('select'); - $queryBuilderId->add('select', 'DISTINCT ' . $select); + $queryBuilderId->add('select', 'DISTINCT '.$select); // for SELECT DISTINCT, ORDER BY expressions must appear in select list /* Consider @@ -95,7 +95,7 @@ private function getFixedQueryBuilder(QueryBuilder $queryBuilder) if ($this->getSortBy()) { $sortBy = $this->getSortBy(); if (strpos($sortBy, '.') === false) { // add the current alias - $sortBy = $queryBuilderId->getRootAlias() . '.' . $sortBy; + $sortBy = $queryBuilderId->getRootAlias().'.'.$sortBy; } $sortBy .= ' AS __order_by'; $queryBuilderId->addSelect($sortBy); @@ -140,7 +140,7 @@ public function __get($name) public function setSortBy($parentAssociationMappings, $fieldMapping) { $alias = $this->entityJoin($parentAssociationMappings); - $this->sortBy = $alias . '.' . $fieldMapping['fieldName']; + $this->sortBy = $alias.'.'.$fieldMapping['fieldName']; return $this; } @@ -250,8 +250,25 @@ public function entityJoin(array $associationMappings) $newAlias = 's'; + $joinedEntities = $this->queryBuilder->getDQLPart('join'); + foreach ($associationMappings as $associationMapping) { - $newAlias .= '_' . $associationMapping['fieldName']; + + // Do not add left join to already joined entities with custom query + foreach ($joinedEntities as $joinExprList) { + foreach ($joinExprList as $joinExpr) { + $newAliasTmp = $joinExpr->getAlias(); + + if (sprintf('%s.%s', $alias, $associationMapping['fieldName']) === $joinExpr->getJoin()) { + $this->entityJoinAliases[] = $newAliasTmp; + $alias = $newAliasTmp; + + continue 3; + } + } + } + + $newAlias .= '_'.$associationMapping['fieldName']; if (!in_array($newAlias, $this->entityJoinAliases)) { $this->entityJoinAliases[] = $newAlias; $this->queryBuilder->leftJoin(sprintf('%s.%s', $alias, $associationMapping['fieldName']), $newAlias); diff --git a/Tests/Filter/QueryBuilder.php b/Tests/Filter/QueryBuilder.php index 632e2fe55..64175d69a 100644 --- a/Tests/Filter/QueryBuilder.php +++ b/Tests/Filter/QueryBuilder.php @@ -11,7 +11,6 @@ namespace Sonata\DoctrineORMAdminBundle\Tests\Filter; -use Sonata\DoctrineORMAdminBundle\Filter\Filter; class QueryBuilder { @@ -60,6 +59,11 @@ public function in($name, $value) return sprintf('%s IN %s', 'in_'.$name, $value); } + public function getDQLPart($queryPart) + { + return array(); + } + /** * @return string */