Returns an array of DQL references ready for filtering, handling nested entities through joins

@param FilterInterface               $filter
@param DoctrineQueryHandlerInterface $queryHandler

@return array
6476
public function getFullAttributeReferences(
        FilterInterface $filter,
        DoctrineQueryHandlerInterface $queryHandler
    ): array {
        $references = [];
        foreach ($filter->getAttributes() as $attributePath) {
            $references[] = $queryHandler->resolveAttributeAlias($attributePath);
        }

        return $references;
    }
413827
private function getParamsFromFilter(FilterBuilder $filter)
    {
        $result  = [];
        $must    = [];
        $mustNot = [];

        $params = $filter->getParams();

        if ($params['entities']) {
            $result['index'] = $params['entities'];
        }

        if (isset($params['keyword'])) {
            $must[] = new MultiMatchQuery($params['keyword']['value'], $params['keyword']['fields']);
        }

        foreach ($params['params'] ?? [] as $param) {
            list($query, $operator) = $param->createFilter();

            if ($operator == FilterOperators::IN) {
                $must[] = $query;
            } else {
                $mustNot[] = $query;
            }

        }

        if ($mustNot || $must) {

            $query = new QueryBuilder();
            if ($mustNot) {
                $query->setMustNot(new MustNotQuery($mustNot));
            }
            if ($must) {
                $query->setMust(new MustQuery($must));
            }

            $result['query'] = $query->toArray();
        }

        return $result;
    }
1037419
private function applyFilters (QueryBuilder $qb, array $filters)
    {

        if (!isset($filters['groupOp']) || !in_array($filters['groupOp'], array('AND', 'OR'))){
            throw new \InvalidArgumentException('Operator does not match OR | AND');
        }

        if (!isset($filters['rules']) || !is_array($filters['rules'])){
            throw new \InvalidArgumentException('Rules are not set.');
        }
        
        $groupOp = $filters['groupOp'];
    
        $andXWithWhere = $qb->expr()->andX();
        $andXWithHaving = $qb->expr()->andX();
        
        $orXWithWhere = $qb->expr()->orX();
        $orXWithHaving = $qb->expr()->orX();

        $supportedAggregateOperators = array('eq', 'ne', 'lt', 'le', 'gt', 'ge');
    
        foreach ($filters['rules'] as $rule) {
            $rule = $this->getResolvedRule((array) $rule);
            
            $field = $this->getFieldQuery($rule['field'], $rule['op'], $rule['data'], $qb);
            $isAgrigated = $this->isAggregated($rule['field']);
            
            if ($groupOp === 'AND'){
                if (false === $isAgrigated){
                    $andXWithWhere->add($field);
                } else if ($isAgrigated && in_array($rule['op'], $supportedAggregateOperators)){
                    $andXWithHaving->add($field);
                }  
            } elseif ($groupOp === 'OR'){
                if (false === $isAgrigated){
                    $orXWithWhere->add($field);
                } else if ($isAgrigated && in_array($rule['op'], $supportedAggregateOperators)){
                    $orXWithHaving->add($field);
                }
            }
        }
    
        
          
        (count($andXWithWhere->getParts()) > 0) ? $qb->andWhere($andXWithWhere) : null;
        (count($andXWithHaving->getParts()) > 0) ? $qb->andHaving($andXWithHaving) : null; 
        
        // we use addWhere/addHaving because if we add a where/having clause beforehand then it will be ignored.
        (count($orXWithWhere->getParts()) > 0) ? $qb->andWhere($orXWithWhere) : null;
        (count($orXWithHaving->getParts()) > 0) ? $qb->andHaving($orXWithHaving) : null;     
    }
168886
public static function getCategoryFilterValues($filter, $categoryId) {
        /* @var $class ActiveRecordInterface */

        $class = $filter->type->class_name;
        $objects = $class::find()
            ->joinWith('products p')
            ->where(['p.category_id' => $categoryId])
            ->all();

        return $objects;
    }
647510
public function getFilter(QueryBuilder $qb, $dqlAlias)
    {
        $qb->select(sprintf('COUNT(%s)', $dqlAlias));

        if ($this->child instanceof Filter) {
            return $this->child->getFilter($qb, $dqlAlias);
        }

        return '';
    }
373075
private function getIdsQuery(
        $depth = 0,
        $filter = [],
        $sortBy = [],
        CollectionInterface $collection = null,
        $select = 'collection.id'
    ) {
        $queryBuilder = $this->createQueryBuilder('collection')
            ->select($select)
            ->where('collection.depth <= :depth');

        $collectionDepth = null !== $collection ? $collection->getDepth() : 0;
        $queryBuilder->setParameter('depth', $collectionDepth + $depth);

        if (null !== $collection) {
            $queryBuilder->andWhere('collection.lft BETWEEN :lft AND :rgt AND collection.id != :id');
            $queryBuilder->setParameter('lft', $collection->getLft());
            $queryBuilder->setParameter('rgt', $collection->getRgt());
            $queryBuilder->setParameter('id', $collection->getId());
        }

        if (array_key_exists('search', $filter) && null !== $filter['search'] ||
            array_key_exists('locale', $filter) ||
            count($sortBy) > 0
        ) {
            $queryBuilder->leftJoin('collection.meta', 'collectionMeta');
            $queryBuilder->leftJoin('collection.defaultMeta', 'defaultMeta');
        }

        if (array_key_exists('search', $filter) && null !== $filter['search']) {
            $queryBuilder->andWhere('collectionMeta.title LIKE :search OR defaultMeta.locale != :locale');
            $queryBuilder->setParameter('search', '%' . $filter['search'] . '%');
        }

        if (array_key_exists('locale', $filter)) {
            $queryBuilder->andWhere('collectionMeta.locale = :locale OR defaultMeta.locale != :locale');
            $queryBuilder->setParameter('locale', $filter['locale']);
        }

        if (array_key_exists('systemCollections', $filter) && !$filter['systemCollections']) {
            $queryBuilder->leftJoin('collection.type', 'collectionType');
            $queryBuilder->andWhere('collectionType.key != :type');
            $queryBuilder->setParameter('type', SystemCollectionManagerInterface::COLLECTION_TYPE);
        }

        if (count($sortBy) > 0) {
            foreach ($sortBy as $column => $order) {
                $queryBuilder->addOrderBy(
                    'collectionMeta.' . $column,
                    ('asc' === strtolower($order) ? 'ASC' : 'DESC')
                );
            }
        }

        $queryBuilder->addOrderBy('collection.id', 'ASC');

        if (array_key_exists('limit', $filter)) {
            $queryBuilder->setMaxResults($filter['limit']);
        }
        if (array_key_exists('offset', $filter)) {
            $queryBuilder->setFirstResult($filter['offset']);
        }

        return $queryBuilder->getQuery();
    }
1058131
public function filter($filter)
    {
        preg_match_all("/(#\w+)/", $filter, $entityNames);
        preg_match_all("/(:\w+)/", $filter, $positions);

        $entityName = is_array($entityNames[0]) && isset($entityNames[0][0]) ? ltrim($entityNames[0][0], '#') : null;
        $position   = is_array($positions[0]) && isset($positions[0][0]) ? $positions[0][0] : null;

        $i = 0;

        $filtered = [];

        foreach ($this->entities as $name => $entity) {
            if ($i === 0 && ($entityName === $name || $entityName === null) && ($position === ':first' || $position === ':highest' || $position === null)) {
                $filtered[] = $entity;
            }

            if ($position === ':any' && ($entityName === $name || $entityName === null)) {
                $filtered[] = $entity;
            }

            if ($i + 1 === $this->entities->count() && ($entityName === $name || $entityName === null) && ($position === ':last' || $position === ':lowest')) {
                $filtered[] = $entity;
            }

            $i++;
        }

        $this->filtered = $filtered;

        return $this;
    }
425292
public function filter($filter): ArrayObjectInterface
    {
        return \is_callable($filter, true) ? $this->filterCallback($filter) : $this->filterConditions($filter);
    }
1275335
public function getHandlers()
    {
        $filters = &gplcart_static('filter.handlers');

        if (isset($filters)) {
            return $filters;
        }

        $filters = array();
        $this->hook->attach('filter.handlers', $filters, $this);

        foreach ($filters as $id => &$filter) {
            $filter['filter_id'] = $id;
            $filter += array(
                'role_id' => array(),
                'status' => true,
                'module' => null
            );
        }

        return $filters;
    }
716724
public function getRecords($filter = '', $order = ['.id'], $page = 1, $count = null, $dataDimensions = null)
    {
        if ($dataDimensions == null) {
            $dataDimensions = $this->getCurrentDataDimensions();
        }

        if (!is_array($order))
        {
            $order = [$order];
        }

        if ($this->readConnection instanceof FilteringConnection) {
            $records = $this->readConnection->getRecords($this->getCurrentContentTypeName(), $dataDimensions, $filter,
                $page, $count, $order);
        } else {

            $records = $this->getAllRecords($dataDimensions);

            if ($filter != '') {
                $records = RecordsFilter::filterRecords($records, $filter);
            }

            $records = RecordsSorter::orderRecords($records, $order);

            if ($count != null) {
                $records = RecordsPager::sliceRecords($records, $page, $count);
            }
        }

        foreach ($records as $record) {
            $record->setRepository($this);
        }

        return $records;
    }
1355326
private function parseFilters(TableInterface $table, Request $request)
    {
        $filters = [];

        $queryParams = $request->get($table->getFormId());

        foreach ($table->getAllFilters() as $filter) {
            if (isset($queryParams[$filter->getName()])) {
                $searchParamRaw = trim($queryParams[$filter->getName()]);
                if ($searchParamRaw != '') {
                    $filters[$filter->getName()] = $searchParamRaw;
                }
            }
        }

        return $filters;
    }
1090479
private function _getObjectsByFilter(Filter $filterQuery)
    {
        $records = [];
        $props = [];
        $filters = [];
        foreach ($filterQuery->getComparisons() as $comparison) {
            $props[] = $comparison->prop;
            if ($comparison->expression && $comparison->comparison && $comparison->prop) {
                $expression = ($comparison->expression !== 'WHERE') ? $comparison->expression . ' ' : '';
                $prop = is_int($comparison->val) ? 'CAST(' . $comparison->prop . ' AS INT)' : $comparison->prop;
                $compare = $comparison->comparison;
                $value = (!isset($comparison->val) || is_null($comparison->val)) ? 'NULL' : $comparison->val;
                $filters[] = $expression . $prop . ' ' . $compare . ' \'' . $value . '\'';
            }
        }

        $props = array_unique($props);
        $joins = [];
        foreach ($props as $prop)
        {
            $standardFields = [
                '__id',
                '__type',
                '__collection',
                '__origin'
            ];
            if (!in_array($prop, $standardFields)) {
                $asTbl = $this->_generateAlphaToken();
                $joins[] =
                    'JOIN(' .
                        'SELECT id, val AS ' . $prop . ' ' .
                        'FROM ' . $this->_name . '__index ' .
                        'WHERE prop = \'' . $prop . '\'' .
                    ') AS ' . $asTbl . ' ' .
                    'ON A.id = ' . $asTbl . '.id';
            }
        }

        $select = Statement::get(
            'GET_OBJECTS_BY_FILTER',
            [
                '@collection' => $this->_name,
                '@columns' => (count($props) > 0) ? ', ' . implode($props, ', ') : '',
                '@joinColumns' => (count($joins) > 0) ? implode($joins, ' ') . ' ' : '',
                '@type' => $this->_connector->quote($filterQuery->getIndexType()),
                '@filters' => ($filters) ? 'AND (' . implode($filters, ' ') . ') ' : '',
                '@order' => $filterQuery->getOrderBy(),
                '@reverse' => ($filterQuery->getReverse()) ? 'DESC' : 'ASC',
                '@limit' => $filterQuery->getLength(),
                '@offset' => $filterQuery->getOffset()
            ]
        );

        $result = $this->_connector->query($select);
        if ($result) {
            $records = $result->fetchAll();
        }
        return ($records) ? array_map([$this, '_mapObjectIds'], $records) : [];
    }
521339
public function getFilter(QueryBuilder $qb, $dqlAlias)
    {
        if (null !== $this->dqlAlias) {
            $dqlAlias = $this->dqlAlias;
        }

        $field = ArgumentToOperandConverter::toField($this->field);
        $value = ArgumentToOperandConverter::toValue($this->value);

        return (string) $qb->expr()->in(
            $field->transform($qb, $dqlAlias),
            $value->transform($qb, $dqlAlias)
        );
    }
91195
public function getSmartyFilter(ConnectionInterface $con = null)
    {
        if ($this->aSmartyFilter === null && ($this->id !== null)) {
            $this->aSmartyFilter = ChildSmartyFilterQuery::create()->findPk($this->id, $con);
            /* The following can be used additionally to
                guarantee the related object contains a reference
                to this object.  This level of coupling may, however, be
                undesirable since it could result in an only partially populated collection
                in the referenced object.
                $this->aSmartyFilter->addSmartyFilterI18ns($this);
             */
        }

        return $this->aSmartyFilter;
    }
979438
public function getIterator(IteratorFilter $filter = null)
    {
        if (is_null($filter)) {
            $filter = new IteratorFilter();
        }

        $param = [];
        $formatter = new IteratorFilterSqlFormatter();
        $sql = $formatter->getFilter($filter->getRawFilters(), $param);

        $query = Query::getInstance()
            ->table($this->getUserDefinition()->table())
            ->where($sql, $param);

        return $this->userRepository->getByQuery($query);
    }
1195368
private static function determineFilterIsNullOrIsNotNull(array $filter, QueryBuilder $queryBuilder)
    {
        if (!\in_array($filter['operation'], ['IS NULL', 'IS NOT NULL'])) {
            return null;
        }

        return static::filterIsNullOrIsNotNull($filter, $queryBuilder);
    }
384662
public function createQueryHandler(
        QueryHandlerConfigurationInterface $queryHandlerConfiguration
    ): QueryHandlerInterface {
        return new DoctrineQueryHandler($this->filterTypeRegistry, $queryHandlerConfiguration, $this->doctrine);
    }