Skip to content

Commit 337290d

Browse files
committed
Merge pull request #277 from gregumo/master
Remove orderBy duplicata and manage orderBy for association fields in QueryHelper
2 parents 4fb9f83 + 30fe80d commit 337290d

File tree

2 files changed

+41
-8
lines changed

2 files changed

+41
-8
lines changed

Bundle/QueryBundle/Helper/QueryHelper.php

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@
22

33
namespace Victoire\Bundle\QueryBundle\Helper;
44

5+
use Doctrine\Common\Annotations\Reader;
56
use Doctrine\ORM\EntityManager;
7+
use Doctrine\ORM\Mapping\ManyToMany;
8+
use Doctrine\ORM\Mapping\ManyToOne;
9+
use Doctrine\ORM\Mapping\OneToMany;
10+
use Doctrine\ORM\Mapping\OneToOne;
611
use Doctrine\ORM\QueryBuilder;
712
use Victoire\Bundle\BusinessEntityBundle\Helper\BusinessEntityHelper;
813
use Victoire\Bundle\BusinessPageBundle\Entity\BusinessPage;
@@ -16,17 +21,20 @@ class QueryHelper
1621
{
1722
protected $businessEntityHelper = null;
1823
protected $currentView;
24+
protected $reader;
1925

2026
/**
2127
* Constructor.
2228
*
2329
* @param BusinessEntityHelper $businessEntityHelper
2430
* @param CurrentViewHelper $currentView
31+
* @param Reader $reader
2532
*/
26-
public function __construct(BusinessEntityHelper $businessEntityHelper, CurrentViewHelper $currentView)
33+
public function __construct(BusinessEntityHelper $businessEntityHelper, CurrentViewHelper $currentView, Reader $reader)
2734
{
2835
$this->businessEntityHelper = $businessEntityHelper;
2936
$this->currentView = $currentView;
37+
$this->reader = $reader;
3038
}
3139

3240
/**
@@ -125,26 +133,31 @@ public function buildWithSubQuery($containerEntity, QueryBuilder $itemsQueryBuil
125133
if (method_exists($containerEntity, 'additionnalQueryPart')) {
126134
$query = $containerEntity->additionnalQueryPart();
127135
}
128-
$orderBy = json_decode($containerEntity->getOrderBy(), true);
136+
129137
if ($query !== '' && $query !== null) {
130138
$subQuery = $em->createQueryBuilder()
131139
->select('item.id')
132140
->from($itemsQueryBuilder->getRootEntities()[0], 'item');
133141

134142
$itemsQueryBuilder
135143
->andWhere('main_item.id IN ('.$subQuery->getQuery()->getDql().' '.$query.')');
136-
if ($orderBy) {
137-
foreach ($orderBy as $addOrderBy) {
138-
$itemsQueryBuilder->addOrderBy('main_item.'.$addOrderBy['by'], $addOrderBy['order']);
139-
}
140-
}
141144
}
142145

146+
//Add ORDER BY if set
143147
if (method_exists($containerEntity, 'getOrderBy')) {
144148
$orderBy = json_decode($containerEntity->getOrderBy(), true);
145149
if ($orderBy) {
146150
foreach ($orderBy as $addOrderBy) {
147-
$itemsQueryBuilder->addOrderBy('main_item.'.$addOrderBy['by'], $addOrderBy['order']);
151+
$reflectionClass = new \ReflectionClass($itemsQueryBuilder->getRootEntities()[0]);
152+
$reflectionProperty = $reflectionClass->getProperty($addOrderBy['by']);
153+
154+
//If ordering field is an association, treat it as a boolean
155+
if ($this->isAssociationField($reflectionProperty)) {
156+
$itemsQueryBuilder->addSelect('CASE WHEN main_item.'.$addOrderBy['by'].' IS NULL THEN 0 ELSE 1 END AS HIDDEN caseOrder');
157+
$itemsQueryBuilder->addOrderBy('caseOrder', $addOrderBy['order']);
158+
} else {
159+
$itemsQueryBuilder->addOrderBy('main_item.'.$addOrderBy['by'], $addOrderBy['order']);
160+
}
148161
}
149162
}
150163
}
@@ -174,4 +187,23 @@ public function buildWithSubQuery($containerEntity, QueryBuilder $itemsQueryBuil
174187

175188
return $itemsQueryBuilder;
176189
}
190+
191+
/**
192+
* Check if field is a OneToOne, OneToMany, ManyToOne or ManyToMany association.
193+
*
194+
* @param \ReflectionProperty $field
195+
*
196+
* @return bool
197+
*/
198+
private function isAssociationField(\ReflectionProperty $field)
199+
{
200+
$annotations = $this->reader->getPropertyAnnotations($field);
201+
foreach ($annotations as $key => $annotationObj) {
202+
if ($annotationObj instanceof OneToOne || $annotationObj instanceof OneToMany || $annotationObj instanceof ManyToOne || $annotationObj instanceof ManyToMany) {
203+
return true;
204+
}
205+
}
206+
207+
return false;
208+
}
177209
}

Bundle/QueryBundle/Resources/config/services.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ services:
44
arguments:
55
- "@victoire_core.helper.business_entity_helper"
66
- "@victoire_core.current_view"
7+
- "@annotation_reader"

0 commit comments

Comments
 (0)