protected function getNestedWhereConditions($builder, array $criteria)
    {
        $subQuery = $builder->forNestedWhere();
        foreach ($criteria as $key => $criterionData) {
            switch (true) {
                case $criterionData instanceof Criterion:
                    $criterion = $criterionData;
                    break;
                case is_string($key)
                    && ((!is_array($criterionData) && !is_object($criterionData))
                        || $criterionData instanceof Carbon):
                    $criterion = new Criterion([Criterion::ATTRIBUTE => $key, Criterion::VALUE => $criterionData]);
                    break;
                case is_int($key) && is_array($criterionData) && $this->isNestedCriteria($criterionData):
                    $boolean = 'and';
                    if (isset($criterionData[Criterion::BOOLEAN])) {
                        $boolean = $criterionData[Criterion::BOOLEAN];
                        unset($criterionData[Criterion::BOOLEAN]);
                    }
                    $subQuery->addNestedWhereQuery(
                        $this->getNestedWhereConditions($subQuery, $criterionData),
                        $boolean
                    );
                    continue 2;
                default:
                    $criterion = $this->parseCriterion($criterionData);
            }

            if (!$this->isCriterionValid($criterion)) {
                throw new BadCriteriaException($this);
            }

            switch ($criterion->operator) {
                case 'in':
                    $subQuery->whereIn($criterion->attribute, $criterion->value, $criterion->boolean);
                    break;
                case 'not in':
                    $subQuery->whereNotIn($criterion->attribute, $criterion->value, $criterion->boolean);
                    break;
                default:
                    $subQuery->where(
                        $criterion->attribute,
                        $criterion->operator,
                        $criterion->value,
                        $criterion->boolean
                    );
                    break;
            }
        }

        return $subQuery;
    }
protected function getNestedWhereConditions($builder, array $criteria)
    {
        $subQuery = $builder->forNestedWhere();
        foreach ($criteria as $key => $criterionData) {
            switch (true) {
                case $criterionData instanceof Criterion:
                    $criterion = $criterionData;
                    break;
                case is_string($key)
                    && ((!is_array($criterionData) && !is_object($criterionData))
                        || $criterionData instanceof Carbon):
                    $criterion = new Criterion([Criterion::ATTRIBUTE => $key, Criterion::VALUE => $criterionData]);
                    break;
                case is_int($key) && is_array($criterionData) && $this->isNestedCriteria($criterionData):
                    $boolean = 'and';
                    if (isset($criterionData[Criterion::BOOLEAN])) {
                        $boolean = $criterionData[Criterion::BOOLEAN];
                        unset($criterionData[Criterion::BOOLEAN]);
                    }
                    $subQuery->addNestedWhereQuery(
                        $this->getNestedWhereConditions($subQuery, $criterionData),
                        $boolean
                    );
                    continue 2;
                default:
                    $criterion = $this->parseCriterion($criterionData);
            }

            if (!$this->isCriterionValid($criterion)) {
                throw new BadCriteriaException($this);
            }

            switch ($criterion->operator) {
                case 'in':
                    $subQuery->whereIn($criterion->attribute, $criterion->value, $criterion->boolean);
                    break;
                case 'not in':
                    $subQuery->whereNotIn($criterion->attribute, $criterion->value, $criterion->boolean);
                    break;
                default:
                    $subQuery->where(
                        $criterion->attribute,
                        $criterion->operator,
                        $criterion->value,
                        $criterion->boolean
                    );
                    break;
            }
        }

        return $subQuery;
    }
protected function getNestedWhereConditions ( $ builder , array $ criteria ) { $ subQuery = $ builder -> forNestedWhere ( ) ; foreach ( $ criteria as $ key => $ criterionData ) { switch ( true ) { case $ criterionData instanceof Criterion : $ criterion = $ criterionData ; break ; case is_string ( $ key ) && ( ( ! is_array ( $ criterionData ) && ! is_object ( $ criterionData ) ) || $ criterionData instanceof Carbon ) : $ criterion = new Criterion ( [ Criterion :: ATTRIBUTE => $ key , Criterion :: VALUE => $ criterionData ] ) ; break ; case is_int ( $ key ) && is_array ( $ criterionData ) && $ this -> isNestedCriteria ( $ criterionData ) : $ boolean = 'and' ; if ( isset ( $ criterionData [ Criterion :: BOOLEAN ] ) ) { $ boolean = $ criterionData [ Criterion :: BOOLEAN ] ; unset ( $ criterionData [ Criterion :: BOOLEAN ] ) ; } $ subQuery -> addNestedWhereQuery ( $ this -> getNestedWhereConditions ( $ subQuery , $ criterionData ) , $ boolean ) ; continue 2 ; default : $ criterion = $ this -> parseCriterion ( $ criterionData ) ; } if ( ! $ this -> isCriterionValid ( $ criterion ) ) { throw new BadCriteriaException ( $ this ) ; } switch ( $ criterion -> operator ) { case 'in' : $ subQuery -> whereIn ( $ criterion -> attribute , $ criterion -> value , $ criterion -> boolean ) ; break ; case 'not in' : $ subQuery -> whereNotIn ( $ criterion -> attribute , $ criterion -> value , $ criterion -> boolean ) ; break ; default : $ subQuery -> where ( $ criterion -> attribute , $ criterion -> operator , $ criterion -> value , $ criterion -> boolean ) ; break ; } } return $ subQuery ; }
Returns query builder with applied criteria. This method work recursively and group nested criteria in one level.

@param QueryBuilder $builder Top level query builder
@param array $criteria Nested list of criteria

@return QueryBuilder

@throws BadCriteriaException when any criterion is not valid
Returns query builder with applied criteria . This method work recursively and group nested criteria in one level .