Skip to content
FilterCollection.php 4.83 KiB
Newer Older
Nikita Chernykh's avatar
Nikita Chernykh committed
namespace IQDEV\ElasticSearch\Criteria\Filter\Collection;
Nikita Chernykh's avatar
Nikita Chernykh committed
use IQDEV\ElasticSearch\Criteria\Filter\Filter;
use IQDEV\ElasticSearch\Criteria\Filter\FilterOperator;
use IQDEV\ElasticSearch\Criteria\Filter\FilterType;
use IQDEV\ElasticSearch\Criteria\Filter\LogicOperator;
use Ramsey\Collection\AbstractCollection;

/**
 * @method self add(FilterGroupCollection $item)
 */
class FilterCollection extends AbstractCollection
{
    /** @var LogicOperator Тип логической операции для коллекции */
    protected LogicOperator $type;

    /**
     * @param FilterGroupCollection[] $data
     */
    public function __construct(array $data = [])
    {
        parent::__construct($data);
        $this->type = LogicOperator::AND;
    }

    /**
     * @inheritDoc
     */
    public function getType(): string
    {
        return FilterGroupCollection::class;
    }

    /**
     * Установка типа логической операции
     *
     * @param LogicOperator $type
     *
     * @return $this
     */
    public function setLogicalType(LogicOperator $type): self
    {
        $this->type = $type;

        return $this;
    }

    /**
     * Получение типа логической операции
     *
     * @return LogicOperator
     */
    public function getLogicalType(): LogicOperator
    {
        return $this->type;
    }

    public function getFilterCollectionByType(FilterType $type): PostFilterCollection|QueryFilterCollection
    {
        $collection =  match ($type) {
            FilterType::POST => new PostFilterCollection(),
            FilterType::QUERY => new QueryFilterCollection(),
        };

        $collection->data = array_filter(
            $this->toArray(),
            static fn (FilterGroupCollection $group) => $group->getFilterType() === $type
        );

        return $collection;
    }

    public function getQueryFilterCollection(): QueryFilterCollection
    {
        $collection = new QueryFilterCollection();

        $collection->data = array_filter(
            $this->toArray(),
            static fn (FilterGroupCollection $group) => $group->getFilterType() === FilterType::QUERY
        );

        return $collection;
    }

    public function getPostFilterCollection(): PostFilterCollection
    {
        $collection = new PostFilterCollection();

        $collection->data = array_filter(
            $this->toArray(),
            static fn (FilterGroupCollection $group) => $group->getFilterType() === FilterType::POST
        );

        return $collection;
    }

    public function getKeywordFilters(array $excludeFilter = []): FilterCollection
    {
        $filterCollection = new FilterCollection();

        foreach ($this->data as $filterGroup) {
            /** @var FilterGroupCollection $filterGroup */

            $keywordFilterGroup = new FilterGroupCollection();

            foreach ($filterGroup->data as $filter) {
                /** @var Filter $filter */

                $field = $filter->field()->value();

                if (in_array($field, $excludeFilter, true)
                    || in_array($filter->operator(), [
                        FilterOperator::LT,
                        FilterOperator::LTE,
                        FilterOperator::GT,
                        FilterOperator::GTE
                    ], true)
                ) {
                    continue;
                }

                $keywordFilterGroup->add($filter);
            }

            if (false === $keywordFilterGroup->isEmpty()) {
                $keywordFilterGroup->setLogicOperator($filterGroup->getLogicOperator());
                $filterCollection->add($keywordFilterGroup);
            }
        }

        return $filterCollection;
    }

    public function getNumberFilters(array $excludeFilter = []): FilterCollection
    {
        $filterCollection = new FilterCollection();

        foreach ($this as $filterGroup) {
            /** @var FilterGroupCollection $filterGroup */

            $numberFilterGroup = new FilterGroupCollection();

            foreach ($filterGroup as $filter) {
                /** @var Filter $filter */

                $field = $filter->field()->value();

                if (in_array($field, $excludeFilter, true)) {
                    continue;
                }

                if (in_array($filter->operator(), [
                    FilterOperator::LT,
                    FilterOperator::LTE,
                    FilterOperator::GT,
                    FilterOperator::GTE
                ], true)) {
                    $numberFilterGroup->add($filter);
                }
            }

            if (false === $numberFilterGroup->isEmpty()) {
                $numberFilterGroup->setLogicOperator($filterGroup->getLogicOperator());
                $filterCollection->add($numberFilterGroup);
            }
        }

        return $filterCollection;
    }
}