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;
}