DragonBe/vies

View on GitHub
src/Vies/Validator/ValidatorAbstract.php

Summary

Maintainability
A
35 mins
Test Coverage
<?php

declare (strict_types=1);


namespace DragonBe\Vies\Validator;

abstract class ValidatorAbstract implements ValidatorInterface
{
    const DEFAULT_WEIGHT_START = 0;
    const DEFAULT_MODULO = 11;
    const DEFAULT_VAT_POSITION = 9;

    /**
     * {@inheritdoc}
     */
    abstract public function validate(string $vatNumber): bool;

    /**
     * @param int $val
     *
     * @return int
     */
    protected function crossSum(int $val): int
    {
        $reducer = function (int $sum, string $char): int {
            return  $sum + (int) $char;
        };

        return array_reduce(str_split((string) $val), $reducer, 0);
    }

    /**
     * @param int $val
     *
     * @return bool
     */
    protected function isEven(int $val): bool
    {
        return $val % 2 === 0;
    }

    /**
     * @param array $weights
     * @param string $vatNumber
     * @param int $start
     *
     * @return int
     */
    protected function sumWeights(array $weights, string $vatNumber, int $start = self::DEFAULT_WEIGHT_START): int
    {
        $checkVal = 0;
        $count = count($weights);
        for ($i = $start; $i < $count; $i++) {
            $checkVal += (int)$vatNumber[$i] * $weights[$i];
        }

        return $checkVal;
    }

    /**
     * A method to calculate the value to check the
     * checksum of a VAT number
     *
     * @param $vatNumber
     * @param $weights
     * @param int $restModulo
     * @param int $vatNumberPosition
     * @return bool
     */
    protected function checkValue(
        $vatNumber,
        $weights,
        $restModulo = self::DEFAULT_MODULO,
        $vatNumberPosition = self::DEFAULT_VAT_POSITION,
        $weightStart = self::DEFAULT_WEIGHT_START
    ) {
        $checkVal = $this->sumWeights($weights, $vatNumber);
        if ($checkVal % 11 == 10) {
            $weights = [3, 4, 5, 6, 7, 8, 9, 10];
            $checkVal = $this->sumWeights($weights, $vatNumber, $weightStart);

            $checkVal = ($checkVal % 11) == 10 ? 0 : ($checkVal % 11);
        } else {
            $checkVal = $checkVal % $restModulo;
        }
        return $checkVal == (int) $vatNumber[$vatNumberPosition];
    }
}