diff --git a/README.md b/README.md index 10630b3..7dd74fc 100755 --- a/README.md +++ b/README.md @@ -65,28 +65,28 @@ If the validation fails, the package will attempt to respond with a localized er The following validation rules are currently available: -| Rule | Message Key | Description | -| --------------------- | --------------------------------- | --------------------------------------------------------------------------------------------------------------- | -| StrongPassword | validation.strong_password | Requires the presence of a "strong" password - see class for details | -| TelephoneNumber | validation.telephone_number | Requires the presence of a valid telephone number - see class for details | -| RecordOwner | validation.record_owner | Requires the authenticated user's id to match the user_id column on a given database record e.g. owner:posts,id | -| MonetaryFigure | validation.monetary_figure | Requires the presence of a monetary figure e.g $72.33 - see class for details | -| DisposableEmail | validation.disposable_email | Requires the presence of an email address which is not disposable | -| Missing | validation.missing | Requires that the given value is not present in a given database table / column - see class for details | -| Decimal | validation.decimal | Requires that the given value is a decimal with an appropriate format - see class for details | -| EncodedImage | validation.encoded_image | Requires that the given value is a base64-encoded image of a given mime type - see class for details | -| LocationCoordinates | validation.location_coordinates | Requires that the given value is a comma-separated set of latitude and longitude coordinates | -| FileExists | validation.file_exists | Requires that the given value is a path to an existing file - see class for details | -| MacAddress | validation.mac_address | Requires that the given value is a valid MAC address | -| ISBN | validation.isbn | Requires that the given value is a valid ISBN-10 or ISBN-13 number | -| EvenNumber | validation.even_number | Requires that the given value is an even number (decimals are first converted using intval) | -| OddNumber | validation.odd_number | Requires that the given value is an odd number (decimals are first converted using intval) | -| Lowercase | validation.lowercase | Requires that the given value is a lower case string | -| Uppercase | validation.uppercase | Requires that the given value is a upper case string | -| Titlecase | validation.titlecase | Requires that the given value is a title case string | -| Domain | validation.domain | Requires that the given value be a domain e.g. google.com, www.google.com | -| CitizenIdentification | validation.citizen_identification | Requires that the given value be a citizen identification number of USA, UK or France (see class for details) | -| WithoutWhitespace | validation.without_whitespace | Requires that the given value not include any whitespace characters | +| Rule | Message Key | Description | +| --------------------- | --------------------------------- | --------------------------------------------------------------------------------------------------------------------- | +| StrongPassword | validation.strong_password | Requires the presence of a "strong" password - see class for details | +| TelephoneNumber | validation.telephone_number | Requires the presence of a valid telephone number - see class for details | +| RecordOwner | validation.record_owner | Requires the authenticated user's id to match the user_id column on a given database record e.g. owner:posts,id | +| MonetaryFigure | validation.monetary_figure | Requires the presence of a monetary figure e.g $72.33 - see class for details | +| DisposableEmail | validation.disposable_email | Requires the presence of an email address which is not disposable | +| Missing | validation.missing | Requires that the given value is not present in a given database table / column - see class for details | +| Decimal | validation.decimal | Requires that the given value is a decimal with an appropriate format - see class for details | +| EncodedImage | validation.encoded_image | Requires that the given value is a base64-encoded image of a given mime type - see class for details | +| LocationCoordinates | validation.location_coordinates | Requires that the given value is a comma-separated set of latitude and longitude coordinates | +| FileExists | validation.file_exists | Requires that the given value is a path to an existing file - see class for details | +| MacAddress | validation.mac_address | Requires that the given value is a valid MAC address | +| ISBN | validation.isbn | Requires that the given value is a valid ISBN-10 or ISBN-13 number | +| EvenNumber | validation.even_number | Requires that the given value is an even number (decimals are first converted using intval) | +| OddNumber | validation.odd_number | Requires that the given value is an odd number (decimals are first converted using intval) | +| Lowercase | validation.lowercase | Requires that the given value is a lower case string | +| Uppercase | validation.uppercase | Requires that the given value is a upper case string | +| Titlecase | validation.titlecase | Requires that the given value is a title case string | +| Domain | validation.domain | Requires that the given value be a domain e.g. google.com, www.google.com | +| CitizenIdentification | validation.citizen_identification | Requires that the given value be a citizen identification number of USA, UK, France or Brazil (see class for details) | +| WithoutWhitespace | validation.without_whitespace | Requires that the given value not include any whitespace characters | ## Contributing @@ -98,4 +98,4 @@ If you'd like to support the development of Axiom, then please consider [sponsor ## License -The MIT License (MIT). Please see [License File](LICENSE.md) for more information. \ No newline at end of file +The MIT License (MIT). Please see [License File](LICENSE.md) for more information. diff --git a/src/Rules/CitizenIdentification.php b/src/Rules/CitizenIdentification.php index f7590fa..c24bf78 100644 --- a/src/Rules/CitizenIdentification.php +++ b/src/Rules/CitizenIdentification.php @@ -13,7 +13,7 @@ class CitizenIdentification extends Rule * Determine if the validation rule passes. * * The rule requires one parameter: - * 1. The identification type to use ('USA' or 'US, 'GBR' or 'GB', 'FRA' or 'FR). + * 1. The identification type to use ('USA' or 'US, 'GBR' or 'GB', 'FRA' or 'FR', 'BRA' or 'BR'). * **/ public function passes($attribute, $value) : bool @@ -34,6 +34,10 @@ public function passes($attribute, $value) : bool case 'FRA': return $this->verifyFrance($value); + case 'BR': + case 'BRA': + return $this->verifyBrazil($value); + default: return false; @@ -87,4 +91,33 @@ protected function verifyUnitedStates($value) : bool return preg_match('/^(?!000|666)[0-8][0-9]{2}-(?!00)[0-9]{2}-(?!0000)[0-9]{4}$/', $value) > 0; } -} \ No newline at end of file + + + /** + * Verify whether the given value is a valid Brazil citizen number. + * + **/ + protected function verifyBrazil($value) : bool + { + $value = preg_replace('/[^0-9]/is', '', $value); + + if (strlen($value) !== 11 || preg_match('/(\d)\1{10}/', $value)) { + return false; + } + + for ($t = 9; $t < 11; $t++) { + for ($d = 0, $c = 0; $c < $t; $c++) { + $d += $value[$c] * (($t + 1) - $c); + } + + $d = ((10 * $d) % 11) % 10; + + if ($value[$c] != $d) { + return false; + } + } + + return true; + } + +} diff --git a/tests/CitizenIdentificationTest.php b/tests/CitizenIdentificationTest.php index a5bf186..a123980 100644 --- a/tests/CitizenIdentificationTest.php +++ b/tests/CitizenIdentificationTest.php @@ -64,4 +64,24 @@ public function the_citizen_identification_rule_can_be_validated_for_fra() $this->assertTrue(validator(['id' => '1 51 02 46102 043 25'], $rule)->passes()); } -} \ No newline at end of file + + + /** @test */ + public function the_citizen_identification_rule_can_be_validated_for_bra() + { + $rule = ['id' => [new CitizenIdentification('bra')]]; + + $this->assertFalse(validator(['id' => '9876543218'], $rule)->passes()); + $this->assertFalse(validator(['id' => '03464227362'], $rule)->passes()); + $this->assertTrue(validator(['id' => '166.525.300-23'], $rule)->passes()); + $this->assertTrue(validator(['id' => '16652530023'], $rule)->passes()); + + $rule = ['id' => [new CitizenIdentification('br')]]; + + $this->assertFalse(validator(['id' => '9876543218'], $rule)->passes()); + $this->assertFalse(validator(['id' => '03464227362'], $rule)->passes()); + $this->assertTrue(validator(['id' => '166.525.300-23'], $rule)->passes()); + $this->assertTrue(validator(['id' => '16652530023'], $rule)->passes()); + } + +}