Valitron\Validator::validateCreditCard PHP Method

validateCreditCard() protected method

Validate that a field contains a valid credit card optionally filtered by an array
protected validateCreditCard ( string $field, mixed $value, array $params ) : boolean
$field string
$value mixed
$params array
return boolean
    protected function validateCreditCard($field, $value, $params)
    {
        /**
         * I there has been an array of valid cards supplied, or the name of the users card
         * or the name and an array of valid cards
         */
        if (!empty($params)) {
            /**
             * array of valid cards
             */
            if (is_array($params[0])) {
                $cards = $params[0];
            } elseif (is_string($params[0])) {
                $cardType = $params[0];
                if (isset($params[1]) && is_array($params[1])) {
                    $cards = $params[1];
                    if (!in_array($cardType, $cards)) {
                        return false;
                    }
                }
            }
        }
        /**
         * Luhn algorithm
         *
         * @return bool
         */
        $numberIsValid = function () use($value) {
            $number = preg_replace('/[^0-9]+/', '', $value);
            $sum = 0;
            $strlen = strlen($number);
            if ($strlen < 13) {
                return false;
            }
            for ($i = 0; $i < $strlen; $i++) {
                $digit = (int) substr($number, $strlen - $i - 1, 1);
                if ($i % 2 == 1) {
                    $sub_total = $digit * 2;
                    if ($sub_total > 9) {
                        $sub_total = $sub_total - 10 + 1;
                    }
                } else {
                    $sub_total = $digit;
                }
                $sum += $sub_total;
            }
            if ($sum > 0 && $sum % 10 == 0) {
                return true;
            }
            return false;
        };
        if ($numberIsValid()) {
            if (!isset($cards)) {
                return true;
            } else {
                $cardRegex = array('visa' => '#^4[0-9]{12}(?:[0-9]{3})?$#', 'mastercard' => '#^5[1-5][0-9]{14}$#', 'amex' => '#^3[47][0-9]{13}$#', 'dinersclub' => '#^3(?:0[0-5]|[68][0-9])[0-9]{11}$#', 'discover' => '#^6(?:011|5[0-9]{2})[0-9]{12}$#');
                if (isset($cardType)) {
                    // if we don't have any valid cards specified and the card we've been given isn't in our regex array
                    if (!isset($cards) && !in_array($cardType, array_keys($cardRegex))) {
                        return false;
                    }
                    // we only need to test against one card type
                    return preg_match($cardRegex[$cardType], $value) === 1;
                } elseif (isset($cards)) {
                    // if we have cards, check our users card against only the ones we have
                    foreach ($cards as $card) {
                        if (in_array($card, array_keys($cardRegex))) {
                            // if the card is valid, we want to stop looping
                            if (preg_match($cardRegex[$card], $value) === 1) {
                                return true;
                            }
                        }
                    }
                } else {
                    // loop through every card
                    foreach ($cardRegex as $regex) {
                        // until we find a valid one
                        if (preg_match($regex, $value) === 1) {
                            return true;
                        }
                    }
                }
            }
        }
        // if we've got this far, the card has passed no validation so it's invalid!
        return false;
    }