ischenko/yii2-jsloader

View on GitHub
src/filters/Chain.php

Summary

Maintainability
A
35 mins
Test Coverage
<?php
/**
 * @copyright Copyright (c) 2016 Roman Ishchenko
 * @license https://github.com/ischenko/yii2-jsloader/blob/master/LICENSE
 * @link https://github.com/ischenko/yii2-jsloader#readme
 */

namespace ischenko\yii2\jsloader\filters;

use ischenko\yii2\jsloader\FilterInterface;
use yii\base\InvalidArgumentException;

/**
 * Chain filter
 *
 * @author Roman Ishchenko <roman@ishchenko.ck.ua>
 * @since 1.0
 */
class Chain implements FilterInterface
{
    const LOGICAL_OR = 0;
    const LOGICAL_AND = 1;

    /**
     * @var FilterInterface[]
     */
    private $filters = [];

    /**
     * @var integer
     */
    private $operator;

    /**
     * Filter constructor.
     * @param FilterInterface[] $filters
     * @param integer $operator
     */
    public function __construct(array $filters = [], $operator = self::LOGICAL_AND)
    {
        $this->setFilters($filters);
        $this->setOperator($operator);
    }

    /**
     * @return integer
     */
    public function getOperator()
    {
        return $this->operator;
    }

    /**
     * @param integer $operator
     */
    public function setOperator($operator)
    {
        if (!in_array($operator, [self::LOGICAL_OR, self::LOGICAL_AND], true)) {
            throw new InvalidArgumentException('Operator value can be only 0 or 1');
        }

        $this->operator = $operator;
    }

    /**
     * @return FilterInterface[]
     */
    public function getFilters()
    {
        return $this->filters;
    }

    /**
     * @param FilterInterface[] $filters
     */
    public function setFilters(array $filters)
    {
        foreach ($filters as $filter) {
            if (!($filter instanceof FilterInterface)) {
                throw new InvalidArgumentException(
                    'Value must be an array of objects that implement FilterInterface'
                );
            }
        }

        $this->filters = $filters;
    }

    /**
     * Performs filtering of given array
     *
     * @param array $data
     * @return array filtered data
     */
    public function filter(array $data): array
    {
        $filteredData = [];

        foreach ($data as $value) {
            if ($this->match($value)) {
                $filteredData[] = $value;
            }
        }

        return $filteredData;
    }

    /**
     * Performs checks on data
     *
     * @param mixed $data
     * @return boolean
     */
    public function match($data): bool
    {
        $match = false;
        $operator = $this->getOperator();

        foreach ($this->getFilters() as $filter) {
            $match = $filter->match($data);

            if ((!$match && $operator === self::LOGICAL_AND)
                || ($match && $operator === self::LOGICAL_OR)
            ) {
                break;
            }
        }

        return $match;
    }
}