krixon/rules

View on GitHub
src/Specification/DateMatches.php

Summary

Maintainability
A
1 hr
Test Coverage
<?php

namespace Krixon\Rules\Specification;

use DateTimeInterface;
use Krixon\Rules\Operator;
use Krixon\Rules\Specification\Exception\UnsupportedOperator;

class DateMatches implements Specification
{
    private $date;
    private $operator;


    public function __construct(DateTimeInterface $date, ?Operator $operator = null)
    {
        $operator = $operator ?? Operator::equals();

        if (!$this->supportsOperator($operator)) {
            throw new UnsupportedOperator($this, $operator);
        }

        $this->date     = $date;
        $this->operator = $operator;
    }


    public function isSatisfiedBy($value) : bool
    {
        $value = $this->extract($value);

        if (!$value) {
            return false;
        }

        switch (true) {
            case $this->operator->isEquals():
                return $value == $this->date;
            case $this->operator->isLessThan():
                return $value < $this->date;
            case $this->operator->isLessThanOrEqualTo():
                return $value <= $this->date;
            case $this->operator->isGreaterThan():
                return $value > $this->date;
            case $this->operator->isGreaterThanOrEqualTo():
                return $value >= $this->date;
        }

        // @codeCoverageIgnoreStart
        // Already validated in the constructor that the operator is supported. This line cannot be reached
        // in a bug-free implementation.
        throw new UnsupportedOperator($this, $this->operator);
        // @codeCoverageIgnoreEnd
    }


    protected function supportsOperator(Operator $operator) : bool
    {
        return $operator->isEquals()
            || $operator->isLessThan()
            || $operator->isLessThanOrEqualTo()
            || $operator->isGreaterThan()
            || $operator->isGreaterThanOrEqualTo();
    }


    /**
     * Extract the value to test from the input passed to isSatisfiedBy().
     *
     * By default, this returns the input itself assuming it is of the correct type. This can be overridden to perform
     * custom extraction logic if the input is not the correct type.
     *
     * @param mixed $value
     */
    protected function extract($value) : ?DateTimeInterface
    {
        return $value instanceof DateTimeInterface ? $value : null;
    }
}