From c2eece6785121a239488badf8f95d137e48b0d5b Mon Sep 17 00:00:00 2001 From: Henrique Moody Date: Wed, 13 Jan 2016 22:57:04 -0200 Subject: [PATCH] Create "IdentityCard" rule Original-Author: Tomasz Regdos . --- docs/IdentityCard.md | 21 +++++++++ docs/VALIDATORS.md | 2 + library/Exceptions/IdentityCardException.php | 27 +++++++++++ .../Locale/PlIdentityCardException.php | 29 ++++++++++++ library/Rules/IdentityCard.php | 31 ++++++++++++ library/Rules/Locale/PlIdentityCard.php | 47 +++++++++++++++++++ library/Validator.php | 1 + tests/integration/rules/identityCard_1.phpt | 11 +++++ tests/integration/rules/identityCard_2.phpt | 16 +++++++ tests/integration/rules/identityCard_3.phpt | 15 ++++++ tests/integration/rules/identityCard_4.phpt | 16 +++++++ tests/integration/rules/identityCard_5.phpt | 16 +++++++ .../unit/Rules/Locale/PlIdentityCardTest.php | 44 +++++++++++++++++ 13 files changed, 276 insertions(+) create mode 100644 docs/IdentityCard.md create mode 100644 library/Exceptions/IdentityCardException.php create mode 100644 library/Exceptions/Locale/PlIdentityCardException.php create mode 100644 library/Rules/IdentityCard.php create mode 100644 library/Rules/Locale/PlIdentityCard.php create mode 100644 tests/integration/rules/identityCard_1.phpt create mode 100644 tests/integration/rules/identityCard_2.phpt create mode 100644 tests/integration/rules/identityCard_3.phpt create mode 100644 tests/integration/rules/identityCard_4.phpt create mode 100644 tests/integration/rules/identityCard_5.phpt create mode 100644 tests/unit/Rules/Locale/PlIdentityCardTest.php diff --git a/docs/IdentityCard.md b/docs/IdentityCard.md new file mode 100644 index 000000000..052eca1a2 --- /dev/null +++ b/docs/IdentityCard.md @@ -0,0 +1,21 @@ +# IdentityCard + +- `v::identityCard(string $countryCode)` + +Validates Identity Card numbers according to the defined country. + +```php +v::identityCard('PL')->validate('AYW036733'); // true +v::identityCard('PL')->validate('APH505567'); // true +v::identityCard('PL')->validate('APH 505567'); // false +v::identityCard('PL')->validate('AYW036731'); // false +``` + +For now this rule only accepts Polish Identity Card numbers (Dowód Osobisty). + +*** +See also: + + * [Bank](Bank.md) + * [Pesel](Pesel.md) + * [SubdivisionCode](SubdivisionCode.md) diff --git a/docs/VALIDATORS.md b/docs/VALIDATORS.md index 9adf5d35d..1628f1cef 100644 --- a/docs/VALIDATORS.md +++ b/docs/VALIDATORS.md @@ -139,6 +139,7 @@ * [CountryCode](CountryCode.md) * [CurrencyCode](CurrencyCode.md) + * [IdentityCard](IdentityCard.md) * [LanguageCode](LanguageCode.md) * [PostalCode](PostalCode.md) * [SubdivisionCode](SubdivisionCode.md) @@ -244,6 +245,7 @@ * [FloatType](FloatType.md) * [Graph](Graph.md) * [HexRgbColor](HexRgbColor.md) + * [IdentityCard](IdentityCard.md) * [Image](Image.md) * [Imei](Imei.md) * [In](In.md) diff --git a/library/Exceptions/IdentityCardException.php b/library/Exceptions/IdentityCardException.php new file mode 100644 index 000000000..94d6d0af6 --- /dev/null +++ b/library/Exceptions/IdentityCardException.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the "LICENSE.md" + * file that was distributed with this source code. + */ + +namespace Respect\Validation\Exceptions; + +class IdentityCardException extends ValidationException +{ + /** + * @var array + */ + public static $defaultTemplates = [ + self::MODE_DEFAULT => [ + self::STANDARD => '{{name}} must be a valid Identity Card number for {{countryCode}}', + ], + self::MODE_NEGATIVE => [ + self::STANDARD => '{{name}} must not be a valid Identity Card number for {{countryCode}}', + ], + ]; +} diff --git a/library/Exceptions/Locale/PlIdentityCardException.php b/library/Exceptions/Locale/PlIdentityCardException.php new file mode 100644 index 000000000..b2b075558 --- /dev/null +++ b/library/Exceptions/Locale/PlIdentityCardException.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the "LICENSE.md" + * file that was distributed with this source code. + */ + +namespace Respect\Validation\Exceptions\Locale; + +use Respect\Validation\Exceptions\ValidationException; + +class PlIdentityCardException extends ValidationException +{ + /** + * @var array + */ + public static $defaultTemplates = [ + self::MODE_DEFAULT => [ + self::STANDARD => '{{name}} must be a valid Polish Identity Card number', + ], + self::MODE_NEGATIVE => [ + self::STANDARD => '{{name}} must not be a valid Polish Identity Card number', + ], + ]; +} diff --git a/library/Rules/IdentityCard.php b/library/Rules/IdentityCard.php new file mode 100644 index 000000000..ed8be2421 --- /dev/null +++ b/library/Rules/IdentityCard.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the "LICENSE.md" + * file that was distributed with this source code. + */ + +namespace Respect\Validation\Rules; + +use Respect\Validation\Exceptions\ComponentException; + +class IdentityCard extends AbstractWrapper +{ + public $countryCode; + + public function __construct($countryCode) + { + $shortName = ucfirst(strtolower($countryCode)).'IdentityCard'; + $className = __NAMESPACE__.'\\Locale\\'.$shortName; + if (!class_exists($className)) { + throw new ComponentException(sprintf('There is no support for identity cards from "%s"', $countryCode)); + } + + $this->countryCode = $countryCode; + $this->validatable = new $className(); + } +} diff --git a/library/Rules/Locale/PlIdentityCard.php b/library/Rules/Locale/PlIdentityCard.php new file mode 100644 index 000000000..83d5a0d13 --- /dev/null +++ b/library/Rules/Locale/PlIdentityCard.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the "LICENSE.md" + * file that was distributed with this source code. + */ + +namespace Respect\Validation\Rules\Locale; + +use Respect\Validation\Rules\AbstractRule; + +/** + * Validator for Polish identity card. + * + * @link https://en.wikipedia.org/wiki/Polish_identity_card + */ +class PlIdentityCard extends AbstractRule +{ + public function validate($input) + { + if (!preg_match('/^[A-Z0-9]{9}$/', $input)) { + return false; + } + + $weights = [7, 3, 1, 0, 7, 3, 1, 7, 3]; + $weightedSum = 0; + for ($i = 0; $i < 9; ++$i) { + $code = ord($input[$i]); + if ($i < 3 && $code <= 57) { // 57 is "9" + return false; + } + + if ($i > 2 && $code >= 65) { // 65 is "A" + return false; + } + + $difference = $code <= 57 ? 48 : 55; // 48 is "0" + $weightedSum += ($code - $difference) * $weights[$i]; + } + + return $weightedSum % 10 == $input[3]; + } +} diff --git a/library/Validator.php b/library/Validator.php index ab2b8c335..1d4305c94 100644 --- a/library/Validator.php +++ b/library/Validator.php @@ -70,6 +70,7 @@ * @method static Validator floatType() * @method static Validator graph(string $additionalChars = null) * @method static Validator hexRgbColor() + * @method static Validator identityCard(string $countryCode) * @method static Validator image(finfo $fileInfo = null) * @method static Validator imei() * @method static Validator in(mixed $haystack, bool $compareIdentical = false) diff --git a/tests/integration/rules/identityCard_1.phpt b/tests/integration/rules/identityCard_1.phpt new file mode 100644 index 000000000..5a36ffb33 --- /dev/null +++ b/tests/integration/rules/identityCard_1.phpt @@ -0,0 +1,11 @@ +--FILE-- +check('AYE205410'); +v::identityCard('PL')->assert('AYE205410'); +?> +--EXPECTF-- diff --git a/tests/integration/rules/identityCard_2.phpt b/tests/integration/rules/identityCard_2.phpt new file mode 100644 index 000000000..3cf6c2308 --- /dev/null +++ b/tests/integration/rules/identityCard_2.phpt @@ -0,0 +1,16 @@ +--FILE-- +check('AYE205411'); +} catch (PlIdentityCardException $e) { + echo $e->getMainMessage(); +} +?> +--EXPECTF-- +"AYE205411" must be a valid Polish Identity Card number diff --git a/tests/integration/rules/identityCard_3.phpt b/tests/integration/rules/identityCard_3.phpt new file mode 100644 index 000000000..4d5cbd586 --- /dev/null +++ b/tests/integration/rules/identityCard_3.phpt @@ -0,0 +1,15 @@ +--FILE-- +assert('AYE205411'); +} catch (AllOfException $e) { + echo $e->getFullMessage(); +} +--EXPECTF-- +- "AYE205411" must be a valid Polish Identity Card number diff --git a/tests/integration/rules/identityCard_4.phpt b/tests/integration/rules/identityCard_4.phpt new file mode 100644 index 000000000..8fa3bd1d0 --- /dev/null +++ b/tests/integration/rules/identityCard_4.phpt @@ -0,0 +1,16 @@ +--FILE-- +check('AYE205410'); +} catch (IdentityCardException $e) { + echo $e->getMainMessage(); +} +?> +--EXPECTF-- +"AYE205410" must not be a valid Identity Card number for "PL" diff --git a/tests/integration/rules/identityCard_5.phpt b/tests/integration/rules/identityCard_5.phpt new file mode 100644 index 000000000..89d882327 --- /dev/null +++ b/tests/integration/rules/identityCard_5.phpt @@ -0,0 +1,16 @@ +--FILE-- +assert('AYE205410'); +} catch (AllOfException $e) { + echo $e->getFullMessage(); +} +?> +--EXPECTF-- +- "AYE205410" must not be a valid Identity Card number for "PL" diff --git a/tests/unit/Rules/Locale/PlIdentityCardTest.php b/tests/unit/Rules/Locale/PlIdentityCardTest.php new file mode 100644 index 000000000..4fbfe78e0 --- /dev/null +++ b/tests/unit/Rules/Locale/PlIdentityCardTest.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the "LICENSE.md" + * file that was distributed with this source code. + */ + +namespace Respect\Validation\Rules\Locale; + +use Respect\Validation\Rules\RuleTestCase; + +/** + * @group rule + * @covers Respect\Validation\Rules\Locale\PlIdentityCard + */ +class PlIdentityCardTest extends RuleTestCase +{ + public function providerForValidInput() + { + $rule = new PlIdentityCard(); + + return [ + [$rule, 'APH505567'], + [$rule, 'AYE205410'], + [$rule, 'AYW036733'], + ]; + } + + public function providerForInvalidInput() + { + $rule = new PlIdentityCard(); + + return [ + [$rule, 'AAAAAAAAA'], + [$rule, 'APH 505567'], + [$rule, 'AYE205411'], + [$rule, 'AYW036731'], + ]; + } +}