Skip to content
CriteriaRequestBuilder.php 3.81 KiB
Newer Older
<?php

declare(strict_types=1);

namespace IQDEV\ElasticSearch\Converter\Request;

use IQDEV\ElasticSearch\Configuration;
use IQDEV\ElasticSearch\Converter\Request\Aggregation\Aggregation;
Nikita Chernykh's avatar
Nikita Chernykh committed
use IQDEV\ElasticSearch\Criteria\Criteria;
use IQDEV\ElasticSearch\Criteria\Filter\Collection\PostFilterCollection;
use IQDEV\ElasticSearch\Criteria\Filter\Collection\QueryFilterCollection;
use IQDEV\ElasticSearch\Criteria\Search\Search;
use IQDEV\ElasticSearch\Criteria\Search\SearchQuery;
use IQDEV\ElasticSearch\Document\Property\PropertyType;
use IQDEV\ElasticSearch\Search\Pagination;

class CriteriaRequestBuilder extends RequestBuilder
{

    public function __construct(
        private readonly Configuration $configuration,
        private readonly Criteria $criteria
    ) {
        parent::__construct();
    }

    public function build(): void
    {
        $this->setPagination();

        if (false === $this->criteria->getSorting()->isEmpty()) {
            $this->setSort();
        }

        if (false === $this->criteria->getSearch()->isEmpty()) {
            $this->setSearch();
        }

        if (false === $this->criteria->getFilters()->isEmpty()) {
            $this->setFilter();
        }

        if (false === $this->criteria->getSearch()->isEmpty() || false === $this->criteria->getFilters()->isEmpty()) {
            $this->setAggregations();
        }
    }

    public function setPagination(): void
    {
        $request = clone $this->request;

        $request->setPagination(new Pagination(
            $this->criteria->getPagination()->limit,
            $this->criteria->getPagination()->offset
        ));

        $this->request = $request;
    }

    public function setSort(): void
    {
        $request = clone $this->request;

        foreach ($this->criteria->getSorting() as $sort) {
            $request->getSort()->add($sort);
        }

        $this->request = $request;
    }

    public function setSearch(): void
    {
        $request = clone $this->request;

        foreach ($this->criteria->getSearch() as $search) {
            /** @var Search $search */
            $searchQuery = new SearchQuery($search);

            if ($search->getProperty()->getType() === PropertyType::TEXT) {
                $request->getQueryMatch()->add($searchQuery->toQueryMatch());
            } else {
                $request->getQuery()->getMust()->add($searchQuery->toMust($this->configuration));
            }
        }

        $this->request = $request;
    }

    public function setFilter(): void
    {
        $queryFilterCollection = $this->criteria->getFilters()->getQueryFilterCollection();
        if (false === $queryFilterCollection->isEmpty()) {
            $this->setQueryFilter($queryFilterCollection);
        }

        $postFilterCollection = $this->criteria->getFilters()->getPostFilterCollection();
        if (false === $postFilterCollection->isEmpty()) {
            $this->setPostFilter($postFilterCollection);
        }
    }

    private function setQueryFilter(QueryFilterCollection $filterCollection): void
    {
        $request = clone $this->request;

        $filterQuery = new FilterQuery($this->configuration, $filterCollection);
Nikita Chernykh's avatar
Nikita Chernykh committed
        $request->getQuery()->modify($filterQuery->getQuery());

        $this->request = $request;
    }

    private function setPostFilter(PostFilterCollection $filterCollection): void
    {
        $request = clone $this->request;

        $filterQuery = new FilterQuery($this->configuration, $filterCollection);
Nikita Chernykh's avatar
Nikita Chernykh committed
        $request->getPostFilter()->modify($filterQuery->getQuery());

        $this->request = $request;
    }

    public function setAggregations(): void
    {
        $request = clone $this->request;

        $aggregation = new Aggregation($this->configuration, $this->criteria);
        $request->setAggs($aggregation->getAggregation());

        $this->request = $request;
    }
}