Exemplo n.º 1
0
    /**
     * Returns true if and only if $value follows the Luhn algorithm (mod-10 checksum)
     *
     * @param  string $value
     * @return boolean
     */
    public function isValid($value)
    {
        $this->_setValue($value);

        if (!is_string($value)) {
            $this->_error(self::INVALID, $value);
            return false;
        }

        if (!ctype_digit($value)) {
            $this->_error(self::CONTENT, $value);
            return false;
        }

        $length = strlen($value);
        $types  = $this->getType();
        $foundp = false;
        $foundl = false;
        foreach ($types as $type) {
            foreach ($this->_cardType[$type] as $prefix) {
                if (substr($value, 0, strlen($prefix)) == $prefix) {
                    $foundp = true;
                    if (in_array($length, $this->_cardLength[$type])) {
                        $foundl = true;
                        break 2;
                    }
                }
            }
        }

        if ($foundp == false){
            $this->_error(self::PREFIX, $value);
            return false;
        }

        if ($foundl == false) {
            $this->_error(self::LENGTH, $value);
            return false;
        }

        $sum    = 0;
        $weight = 2;

        for ($i = $length - 2; $i >= 0; $i--) {
            $digit = $weight * $value[$i];
            $sum += floor($digit / 10) + $digit % 10;
            $weight = $weight % 2 + 1;
        }

        if ((10 - $sum % 10) % 10 != $value[$length - 1]) {
            $this->_error(self::CHECKSUM, $value);
            return false;
        }

        if (!empty($this->_service)) {
            try {
                $callback = new Callback($this->_service);
                $callback->setOptions($this->_type);
                if (!$callback->isValid($value)) {
                    $this->_error(self::SERVICE, $value);
                    return false;
                }
            } catch (\Exception $e) {
                $this->_error(self::SERVICEFAILURE, $value);
                return false;
            }
        }

        return true;
    }