@@ -431,24 +431,31 @@ protected function getNestedWhereConditions(QueryBuilder $builder, array $criter
431
431
$ subQuery = $ builder ->forNestedWhere ();
432
432
foreach ($ criteria as $ key => $ criterionData ) {
433
433
switch (true ) {
434
+ case $ criterionData instanceof Criterion:
435
+ $ criterion = $ criterionData ;
436
+ break ;
434
437
case is_string ($ key )
435
438
&& ((!is_array ($ criterionData ) && !is_object ($ criterionData ))
436
439
|| $ criterionData instanceof Carbon):
437
440
$ criterion = new Criterion ([Criterion::ATTRIBUTE => $ key , Criterion::VALUE => $ criterionData ]);
438
441
break ;
439
- case $ criterionData instanceof Criterion:
440
- $ criterion = $ criterionData ;
441
- break ;
442
- case is_int ($ key ) && is_array ($ criterionData ) && !empty ($ criterionData ):
443
- $ criterion = $ this ->parseCriterion ($ criterionData );
444
- break ;
442
+ case is_int ($ key ) && is_array ($ criterionData ) && $ this ->isNestedCriteria ($ criterionData ):
443
+ $ boolean = 'and ' ;
444
+ if (isset ($ criterionData [Criterion::BOOLEAN ])) {
445
+ $ boolean = $ criterionData [Criterion::BOOLEAN ];
446
+ unset($ criterionData [Criterion::BOOLEAN ]);
447
+ }
448
+ $ subQuery ->addNestedWhereQuery (
449
+ $ this ->getNestedWhereConditions ($ subQuery , $ criterionData ),
450
+ $ boolean
451
+ );
452
+ continue 2 ;
445
453
default :
446
- throw new BadCriteriaException ( $ this );
454
+ $ criterion = $ this -> parseCriterion ( $ criterionData );
447
455
}
448
456
449
457
if (!$ this ->isCriterionValid ($ criterion )) {
450
- $ subQuery ->addNestedWhereQuery ($ this ->getNestedWhereConditions ($ subQuery , $ criterionData ));
451
- continue ;
458
+ throw new BadCriteriaException ($ this );
452
459
}
453
460
454
461
switch ($ criterion ->operator ) {
@@ -472,6 +479,28 @@ protected function getNestedWhereConditions(QueryBuilder $builder, array $criter
472
479
return $ subQuery ;
473
480
}
474
481
482
+ /**
483
+ * Shows whether given criterion data is nested.
484
+ *
485
+ * @param array $criterionData Criterion data to check
486
+ *
487
+ * @return boolean
488
+ */
489
+ protected function isNestedCriteria (array $ criterionData ): bool
490
+ {
491
+ $ isValid = true ;
492
+
493
+ foreach ($ criterionData as $ key => $ possibleCriterion ) {
494
+ $ isValid = $ isValid &&
495
+ (
496
+ (is_int ($ key ) && is_array ($ possibleCriterion )) ||
497
+ ($ key === Criterion::BOOLEAN && in_array ($ possibleCriterion , ['and ' , 'or ' ]))
498
+ );
499
+ }
500
+
501
+ return $ isValid ;
502
+ }
503
+
475
504
/**
476
505
* Transforms criterion data into DTO.
477
506
*
0 commit comments