mirror of
https://github.com/vlucas/valitron.git
synced 2025-12-31 07:01:54 +00:00
Added credit card validation for Visa, Mastercard, American Express, Dinersclub and Discover
This commit is contained in:
parent
9d51c509c4
commit
2d0790b984
@ -25,7 +25,8 @@ return array(
|
||||
'dateAfter' => "must be date after '%s'",
|
||||
'contains' => "must contain %s",
|
||||
'boolean' => "must be a boolean",
|
||||
'lengthBetween' => "must be between %d and %d characters"
|
||||
'lengthBetween' => "must be between %d and %d characters",
|
||||
'creditCard' => "must be a valid credit card number"
|
||||
);
|
||||
|
||||
|
||||
|
||||
@ -472,6 +472,107 @@ class Validator
|
||||
return (is_bool($value)) ? true : false;
|
||||
}
|
||||
|
||||
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];
|
||||
} else if (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);
|
||||
|
||||
} else if (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;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get array of fields and data
|
||||
*/
|
||||
|
||||
@ -654,6 +654,58 @@ class ValidateTest extends BaseTestCase
|
||||
$v->rule('boolean', 'test');
|
||||
$this->assertFalse($v->validate());
|
||||
}
|
||||
|
||||
public function testCreditCardValid()
|
||||
{
|
||||
$visa = [4539511619543489, 4532949059629052, 4024007171194938, 4929646403373269, 4539135861690622];
|
||||
$mastercard = [5162057048081965, 5382687859049349, 5484388880142230, 5464941521226434, 5473481232685965];
|
||||
$amex = [371442067262027, 340743030537918, 345509167493596, 343665795576848, 346087552944316];
|
||||
$dinersclub = [30363194756249, 30160097740704, 38186521192206, 38977384214552, 38563220301454];
|
||||
$discover = [6011712400392605, 6011536340491809, 6011785775263015, 6011984124619056, 6011320958064251];
|
||||
|
||||
foreach (compact('visa', 'mastercard', 'amex', 'dinersclub', 'discover') as $type => $numbers) {
|
||||
foreach($numbers as $number) {
|
||||
$v = new Validator(array('test' => $number));
|
||||
$v->rule('creditCard', 'test');
|
||||
$this->assertTrue($v->validate());
|
||||
$v->rule('creditCard', 'test', [$type, 'mastercard', 'visa']);
|
||||
$this->assertTrue($v->validate());
|
||||
$v->rule('creditCard', 'test', $type);
|
||||
$this->assertTrue($v->validate());
|
||||
$v->rule('creditCard', 'test', $type, [$type, 'mastercard', 'visa']);
|
||||
$this->assertTrue($v->validate());
|
||||
unset($d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function testcreditCardInvalid()
|
||||
{
|
||||
$visa = [3539511619543489, 3532949059629052, 3024007171194938, 3929646403373269, 3539135861690622];
|
||||
$mastercard = [4162057048081965, 4382687859049349, 4484388880142230, 4464941521226434, 4473481232685965];
|
||||
$amex = [271442067262027, 240743030537918, 245509167493596, 243665795576848, 246087552944316];
|
||||
$dinersclub = [20363194756249, 20160097740704, 28186521192206, 28977384214552, 28563220301454];
|
||||
$discover = [5011712400392605, 5011536340491809, 5011785775263015, 5011984124619056, 5011320958064251];
|
||||
|
||||
foreach (compact('visa', 'mastercard', 'amex', 'dinersclub', 'discover') as $type => $numbers) {
|
||||
foreach($numbers as $number) {
|
||||
$v = new Validator(array('test' => $number));
|
||||
$v->rule('creditCard', 'test');
|
||||
$this->assertFalse($v->validate());
|
||||
$v->rule('creditCard', 'test', [$type, 'mastercard', 'visa']);
|
||||
$this->assertFalse($v->validate());
|
||||
$v->rule('creditCard', 'test', $type);
|
||||
$this->assertFalse($v->validate());
|
||||
$v->rule('creditCard', 'test', $type, [$type, 'mastercard', 'visa']);
|
||||
$this->assertFalse($v->validate());
|
||||
$v->rule('creditCard', 'test', 'invalidCardName');
|
||||
$this->assertFalse($v->validate());
|
||||
$v->rule('creditCard', 'test', 'invalidCardName', ['invalidCardName', 'mastercard', 'visa']);
|
||||
$this->assertFalse($v->validate());
|
||||
unset($d);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function sampleFunctionCallback($field, $value, array $params) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user