66
77use Doctrine \DBAL \Query \Expression \CompositeExpression ;
88use Doctrine \DBAL \Query \QueryBuilder ;
9+ use Doctrine \DBAL \Query \QueryException ;
910use JetBrains \PhpStorm \ArrayShape ;
1011use Symfony \Component \OptionsResolver \OptionsResolver ;
1112use Symfony \Component \Serializer \NameConverter \CamelCaseToSnakeCaseNameConverter ;
@@ -142,9 +143,13 @@ public function createFindByQueryBuilder(array $criteria, ?array $orderBy): Quer
142143
143144 $ prefixedEntityBaseFields = $ this ->getPrefixedEntityBaseFields ('p ' );
144145
146+ $ hasSelectColumns = array_filter (
147+ $ normalizedCriteria ,
148+ static fn (mixed $ value ) => $ value instanceof SelectColumns,
149+ );
150+
145151 $ queryBuilder = $ this ->entityManager ->getConnection ()
146152 ->createQueryBuilder ()
147- ->select (...$ prefixedEntityBaseFields )
148153 ->from ($ this ->entityManager ->getTablesPrefix () . static ::TABLE_NAME , 'p ' )
149154 ->addGroupBy (...$ prefixedEntityBaseFields )
150155 ;
@@ -155,7 +160,10 @@ public function createFindByQueryBuilder(array $criteria, ?array $orderBy): Quer
155160 ;
156161 }
157162
158- $ this ->addSelectForExtraFields ($ queryBuilder );
163+ if (!$ hasSelectColumns ) {
164+ $ queryBuilder ->select (...$ prefixedEntityBaseFields );
165+ $ this ->addSelectForExtraFields ($ queryBuilder );
166+ }
159167
160168 foreach ($ normalizedCriteria as $ field => $ value ) {
161169 if ($ this ->handleSpecialCriteria ($ queryBuilder , $ criteria , $ field , $ value ) === self ::IS_SPECIAL_CRITERIA ) {
@@ -167,8 +175,10 @@ public function createFindByQueryBuilder(array $criteria, ?array $orderBy): Quer
167175
168176 $ this ->addOrderByClause ($ queryBuilder , $ orderBy );
169177
170- $ queryBuilder ->addSelect (...$ this ->additionalFieldsToSelect );
171- $ this ->additionalFieldsToSelect = [];
178+ if (!empty ($ this ->additionalFieldsToSelect )) {
179+ $ queryBuilder ->addSelect (...$ this ->additionalFieldsToSelect );
180+ $ this ->additionalFieldsToSelect = [];
181+ }
172182
173183 return $ queryBuilder ;
174184 }
@@ -554,16 +564,15 @@ private function joinSelfMetaTable(QueryBuilder $queryBuilder, bool $incrementIf
554564
555565 private function hasJoin (QueryBuilder $ queryBuilder , string $ joinAlias ): bool
556566 {
557- $ joinQueryPart = $ queryBuilder ->getQueryPart ('join ' );
567+ try {
568+ if (preg_match_all ('/JOIN (\w+) (\w+) ON p\./im ' , $ queryBuilder ->getSQL (), $ matches , PREG_SET_ORDER )) {
569+ return count (array_filter ($ matches , static fn (array $ match ) => $ match [2 ] === $ joinAlias )) > 0 ;
570+ }
571+ } catch (QueryException ) {
572+ return false ;
573+ }
558574
559- return array_key_exists ('p ' , $ joinQueryPart )
560- && is_array ($ joinQueryPart ['p ' ])
561- && count (
562- array_filter (
563- $ joinQueryPart ['p ' ],
564- static fn (array $ part ) => !empty ($ part ['joinAlias ' ]) && $ part ['joinAlias ' ] === $ joinAlias ,
565- )
566- ) > 0 ;
575+ return false ;
567576 }
568577
569578 private function createRelationshipCriteria (
@@ -809,18 +818,15 @@ private function getPrefixedCriteriaForPostRelationshipCondition(
809818 private function selectColumns (QueryBuilder $ queryBuilder , array $ extraFields , SelectColumns $ value ): void
810819 {
811820 $ selects = [];
812- $ hasExtraFields = false ;
813821
814- $ queryBuilder ->resetQueryPart ( ' groupBy ' );
822+ $ queryBuilder ->resetGroupBy ( );
815823
816824 foreach ($ value ->getColumns () as $ column ) {
817825 if (in_array ($ column , $ extraFields , true )) {
818826 $ mappedMetaKey = $ this ->getMappedMetaKey ($ column );
819827 $ selects [] = select_from_eav ($ column , $ mappedMetaKey );
820- $ hasExtraFields = true ;
821828 } elseif (str_starts_with ($ column , 'MAX( ' )) {
822829 $ selects [] = $ column ;
823- $ hasExtraFields = true ;
824830 $ this ->joinSelfMetaTable ($ queryBuilder );
825831 } else {
826832 foreach ($ this ->tableAliases as $ alias => $ fields ) {
@@ -836,33 +842,5 @@ private function selectColumns(QueryBuilder $queryBuilder, array $extraFields, S
836842
837843 $ queryBuilder ->select (...$ selects , ...$ this ->additionalFieldsToSelect );
838844 $ this ->additionalFieldsToSelect = [];
839-
840- if (!$ hasExtraFields ) {
841- $ joinQueryPart = $ queryBuilder ->getQueryPart ('join ' );
842-
843- if (empty ($ joinQueryPart )) {
844- return ;
845- }
846-
847- $ queryBuilder ->resetQueryPart ('join ' );
848-
849- foreach ($ joinQueryPart ['p ' ] as $ index => $ part ) {
850- if ($ part ['joinAlias ' ] === 'pm_self ' ) {
851- unset($ joinQueryPart ['p ' ][$ index ]);
852- }
853- }
854-
855- foreach ($ joinQueryPart as $ alias => $ parts ) {
856- foreach ($ parts as $ part ) {
857- $ method = match ($ part ['joinType ' ]) {
858- 'left ' => 'leftJoin ' ,
859- 'right ' => 'rightJoin ' ,
860- default => 'join ' ,
861- };
862-
863- $ queryBuilder ->{$ method }($ alias , $ part ['joinTable ' ], $ part ['joinAlias ' ], $ part ['joinCondition ' ]);
864- }
865- }
866- }
867845 }
868846}
0 commit comments