Skip to content

Commit

Permalink
Update post_code and PESEL rules (#3)
Browse files Browse the repository at this point in the history
- add changes from newest version
  • Loading branch information
WiktorPacer authored Feb 15, 2022
1 parent 5edb1a7 commit fa09b45
Show file tree
Hide file tree
Showing 8 changed files with 248 additions and 35 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
# Changelog
## v.4.1.0
- update post_code rule - add support for options (see README.md)
- update PESEL rule - add suport for options (see README.md)
## v.4.0.5
- add passport_numer role
## v.4.0.4
Expand Down
44 changes: 38 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,27 +22,59 @@ For customize validaiton messages run:
Framework | Package | Note
:---------|:--------|:------
5.8.x | ^1.x.x | No longer maintained.
6.0.x | ^2.x.x |
7.x.x | ^3.x.x |
6.0.x | ^2.x.x | Bug fixes only.
7.x.x | ^3.x.x | Bug fixes only.
8.x.x | ^4.x.x | PHP ^8.0 Supported from 4.0.3
9.x.x | ^5.x.x |
#### Lumen
Framework | Package | Note
:---------|:--------|:------
5.8.x | ^1.x.x | No longer maintained.
6.0.x | ^2.x.x |
7.x.x | ^3.x.x |
6.0.x | ^2.x.x | Bug fixes only.
7.x.x | ^3.x.x | Bug fixes only.
8.x.x | ^4.x.x | PHP ^8.0 Supported from 4.0.3
9.x.x | ^5.x.x |

## Rules

1. 'PESEL' - validate [PESEL](https://pl.wikipedia.org/wiki/PESEL) number
1. 'PESEL' - validate [PESEL](https://pl.wikipedia.org/wiki/PESEL) number. We can validate additional parameters:
* Gender - check if gender value in PESEL
* gender_male
* gender_female
2. 'REGON' - validate [REGON](https://pl.wikipedia.org/wiki/REGON) number
3. 'NIP' - validate [NIP](https://pl.wikipedia.org/wiki/NIP) number
4. 'id_card_number' - validate Polish ID Card number
5. 'post_code' - validate Polish post codes (accept codes in format 00-000 and 00000),
5. 'post_code' - validate Polish post codes. By default accept codes in format 00-000 and 00000. You can change this with options:
* with_dash - only post codes with format 00-000 are valid
* without_dash - only post codew with format 00000 are valid
6. 'PWZ' - validate PWZ (Prawo wykonywania zawodu lekarza/farmaceuty) numer (more information [HERE](https://nil.org.pl/rejestry/centralny-rejestr-lekarzy/zasady-weryfikowania-nr-prawa-wykonywania-zawodu))
7. 'passport_number' - validate Polish passport number

## Usage example

Without optional parameters
```php
$validator = Validator::make(
$request->all(),
[
'post_code' => 'post_code',
'pesel' => 'PESEL',
'nip_number' => 'NIP',
]
);
```

With optional parameters
```php
$validator = Validator::make(
$request->all(),
[
'post_code' => 'post_code:without_dash',
'pesel' => 'PESEL:gender_female',
]
);
```

## Code Authors

The algorithms used in the functions are based on existing solutions. Below are links to the sources:
Expand Down
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
"illuminate/support": "^8.0"
},
"require-dev": {
"phpunit/phpunit": "^9.0"
"phpunit/phpunit": "^9.0",
"orchestra/testbench": "^6.24"
},
"license": "MIT",
"authors": [
Expand Down
62 changes: 57 additions & 5 deletions src/Rules/PESELRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,56 @@
namespace PacerIT\LaravelPolishValidationRules\Rules;

use Illuminate\Contracts\Validation\Rule;
use Illuminate\Support\Arr;

/**
* Class PESELRule.
*
* @author Wiktor Pacer <[email protected]>
*
* @since 2019-08-12
*/
class PESELRule implements Rule
{
// Gender digit position in PESEL number.
const GENDER_POSITION = 9;
const GENDER_MALE = 0;
const GENDER_FEMALE = 1;

/**
* Determine if the validation rule passes.
*
* @param string $attribute
* @param mixed $value
* @param array $parameters
*
* @return bool
*/
public function passes($attribute, $value)
public function passes($attribute, $value, $parameters = [])
{
return $this->checkPESEL($value);
// First we check if PESEL is valid. If not, there is no need to check other attributes.
if (!$this->checkPESEL($value)) {
return false;
}

// Get parameters.
$parameters = explode(':', (string) Arr::first($parameters));

$result = true;
foreach ($parameters as $mode) {
switch ($mode) {
case 'gender_male':
$result = $this->validateGender($value);
break;

case 'gender_female':
$result = $this->validateGender($value, self::GENDER_FEMALE);
break;

default:
return true;
}
}

return $result;
}

/**
Expand All @@ -34,7 +63,6 @@ public function passes($attribute, $value)
* @return bool
*
* @see http://phpedia.pl/wiki/PESEL Souce of this algorithm
* @since 2019-08-12
*/
private function checkPESEL(?string $string): bool
{
Expand Down Expand Up @@ -62,6 +90,30 @@ private function checkPESEL(?string $string): bool
return false;
}

/**
* Validate gender in PESEL number.
*
* @param string $pesel
* @param int $gender
*
* @return bool
*/
private function validateGender(string $pesel, int $gender = self::GENDER_MALE): bool
{
$genderFromPesel = $pesel[self::GENDER_POSITION];
$result = (bool) ($genderFromPesel % 2);

if ($gender === self::GENDER_MALE && $result) {
return true;
}

if ($gender === self::GENDER_FEMALE && !$result) {
return true;
}

return false;
}

/**
* Get the validation error message.
*
Expand Down
44 changes: 34 additions & 10 deletions src/Rules/PostCodeRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,43 @@
namespace PacerIT\LaravelPolishValidationRules\Rules;

use Illuminate\Contracts\Validation\Rule;
use Illuminate\Support\Arr;

/**
* Class PostCodeRule.
*
* @author Wiktor Pacer <[email protected]>
*
* @since 09/09/2020
*/
class PostCodeRule implements Rule
{
const REGEX_DASH_REQUIRED = '/^[0-9]{2}-[0-9]{3}$/Du';
const REGEX_DASH_NOT_ALLOWED = '/^[0-9]{5}$/Du';
const REGEX_DASH_OPTIONAL = '/^[0-9]{2}-?[0-9]{3}$/Du';

/**
* Determine if the validation rule passes.
*
* @param string $attribute
* @param mixed $value
* @param array $parameters
*
* @return bool
*/
public function passes($attribute, $value)
public function passes($attribute, $value, $parameters = [])
{
return $this->checkPostCode($value);
// Get first parameter.
$mode = (string) Arr::first($parameters);

switch ($mode) {
case 'with_dash':
return $this->checkPostCode($value, 1);

case 'without_dash':
return $this->checkPostCode($value, 2);

default:
return $this->checkPostCode($value);
}
}

/**
Expand All @@ -34,20 +50,28 @@ public function passes($attribute, $value)
* @return bool
*
* @author Wiktor Pacer <[email protected]>
*
* @since 09/09/2020
*/
private function checkPostCode(?string $string): bool
private function checkPostCode(?string $string, int $mode = 0): bool
{
if ($string === null) {
return false;
}

if (!preg_match('/^[0-9]{2}-?[0-9]{3}$/Du', $string)) {
return false;
switch ($mode) {
case 1:
$regex = self::REGEX_DASH_REQUIRED;
break;

case 2:
$regex = self::REGEX_DASH_NOT_ALLOWED;
break;

default:
$regex = self::REGEX_DASH_OPTIONAL;
break;
}

return true;
return preg_match($regex, $string);
}

/**
Expand Down
13 changes: 10 additions & 3 deletions tests/Unit/AbstractRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,26 @@
namespace Tests\Unit;

use Illuminate\Contracts\Validation\Rule;
use PHPUnit\Framework\TestCase;
use Orchestra\Testbench\TestCase;
use PacerIT\LaravelPolishValidationRules\Providers\LaravelPolishValidationRulesServiceProvider;

/**
* Class AbstractRuleTest.
*
* @author Wiktor Pacer <[email protected]>
*
* @since 2019-08-12
*/
abstract class AbstractRuleTest extends TestCase
{
/**
* @var Rule
*/
protected $rule;

/**
* @inheritDoc
*/
protected function getPackageProviders($app)
{
return [LaravelPolishValidationRulesServiceProvider::class];
}
}
63 changes: 63 additions & 0 deletions tests/Unit/PESELRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Tests\Unit;

use Illuminate\Support\Facades\Validator;
use PacerIT\LaravelPolishValidationRules\Rules\PESELRule;

/**
Expand Down Expand Up @@ -65,4 +66,66 @@ public function testNullPESEL()
{
$this->assertFalse($this->rule->passes('pessel', null));
}

/**
* Test PESEL "gender_male" option.
*
* @author Wiktor Pacer <[email protected]>
*/
public function testGenderMaleOption()
{
$rules = ['pesel' => 'PESEL:gender_male'];

$validMalePesel = [
'07262444973',
'18011233773',
'26121492032',
];

// Test for male gender.
foreach ($validMalePesel as $validPesel) {
$data = ['pesel' => $validPesel];
$validator = Validator::make($data, $rules);
$this->assertFalse($validator->fails());
}

$rules = ['pesel' => 'PESEL:gender_female'];

foreach ($validMalePesel as $validPesel) {
$data = ['pesel' => $validPesel];
$validator = Validator::make($data, $rules);
$this->assertTrue($validator->fails());
}
}

/**
* Test PESEL "gender_female" option.
*
* @author Wiktor Pacer <[email protected]>
*/
public function testGenderFemaleOption()
{
$rules = ['pesel' => 'PESEL:gender_female'];

$validFemalePesel = [
'08260713768',
'59092028627',
'20083149926',
];

// Test for female gender.
foreach ($validFemalePesel as $validPesel) {
$data = ['pesel' => $validPesel];
$validator = Validator::make($data, $rules);
$this->assertFalse($validator->fails());
}

$rules = ['pesel' => 'PESEL:gender_male'];

foreach ($validFemalePesel as $validPesel) {
$data = ['pesel' => $validPesel];
$validator = Validator::make($data, $rules);
$this->assertTrue($validator->fails());
}
}
}
Loading

0 comments on commit fa09b45

Please sign in to comment.