2
2
3
3
namespace Victoire \Bundle \QueryBundle \Helper ;
4
4
5
+ use Doctrine \Common \Annotations \Reader ;
5
6
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 ;
6
11
use Doctrine \ORM \QueryBuilder ;
7
12
use Victoire \Bundle \BusinessEntityBundle \Helper \BusinessEntityHelper ;
8
13
use Victoire \Bundle \BusinessPageBundle \Entity \BusinessPage ;
@@ -16,17 +21,20 @@ class QueryHelper
16
21
{
17
22
protected $ businessEntityHelper = null ;
18
23
protected $ currentView ;
24
+ protected $ reader ;
19
25
20
26
/**
21
27
* Constructor.
22
28
*
23
29
* @param BusinessEntityHelper $businessEntityHelper
24
30
* @param CurrentViewHelper $currentView
31
+ * @param Reader $reader
25
32
*/
26
- public function __construct (BusinessEntityHelper $ businessEntityHelper , CurrentViewHelper $ currentView )
33
+ public function __construct (BusinessEntityHelper $ businessEntityHelper , CurrentViewHelper $ currentView, Reader $ reader )
27
34
{
28
35
$ this ->businessEntityHelper = $ businessEntityHelper ;
29
36
$ this ->currentView = $ currentView ;
37
+ $ this ->reader = $ reader ;
30
38
}
31
39
32
40
/**
@@ -125,26 +133,31 @@ public function buildWithSubQuery($containerEntity, QueryBuilder $itemsQueryBuil
125
133
if (method_exists ($ containerEntity , 'additionnalQueryPart ' )) {
126
134
$ query = $ containerEntity ->additionnalQueryPart ();
127
135
}
128
- $ orderBy = json_decode ( $ containerEntity -> getOrderBy (), true );
136
+
129
137
if ($ query !== '' && $ query !== null ) {
130
138
$ subQuery = $ em ->createQueryBuilder ()
131
139
->select ('item.id ' )
132
140
->from ($ itemsQueryBuilder ->getRootEntities ()[0 ], 'item ' );
133
141
134
142
$ itemsQueryBuilder
135
143
->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
- }
141
144
}
142
145
146
+ //Add ORDER BY if set
143
147
if (method_exists ($ containerEntity , 'getOrderBy ' )) {
144
148
$ orderBy = json_decode ($ containerEntity ->getOrderBy (), true );
145
149
if ($ orderBy ) {
146
150
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
+ }
148
161
}
149
162
}
150
163
}
@@ -174,4 +187,23 @@ public function buildWithSubQuery($containerEntity, QueryBuilder $itemsQueryBuil
174
187
175
188
return $ itemsQueryBuilder ;
176
189
}
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
+ }
177
209
}
0 commit comments