Skip to content

Commit

Permalink
Fix validation to properly identify numbers such as "00000000000" and…
Browse files Browse the repository at this point in the history
… "44444444444" as incorrect
  • Loading branch information
KKSzymanowski committed Oct 8, 2021
1 parent d6f12e6 commit 07b8f73
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 23 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
}
],
"require": {
"php": ">=7.3.0"
"php": ">=7.3.0",
"ext-calendar": "*"
},
"require-dev": {
"phpunit/phpunit": "^9.3.8",
Expand Down
7 changes: 7 additions & 0 deletions src/Exceptions/InvalidBirthDateException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

namespace Pesel\Exceptions;

class InvalidBirthDateException extends PeselValidationException
{
}
75 changes: 53 additions & 22 deletions src/Pesel.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

use DateTime;
use InvalidArgumentException;
use Pesel\Exceptions\InvalidBirthDateException;
use Pesel\Exceptions\InvalidCharactersException;
use Pesel\Exceptions\InvalidChecksumException;
use Pesel\Exceptions\InvalidGenderInputException;
Expand All @@ -37,6 +38,7 @@ class Pesel
'invalidLength' => 'Nieprawidłowa długość numeru PESEL.',
'invalidCharacters' => 'Numer PESEL może zawierać tylko cyfry.',
'invalidChecksum' => 'Numer PESEL posiada niepoprawną sumę kontrolną.',
'invalidBirthDate' => 'Numer PESEL zawiera nieprawidłową datę urodzenia.',
];

/**
Expand Down Expand Up @@ -75,6 +77,8 @@ public function __construct($number, $errorMessages = [])
$this->validateDigitsOnly();

$this->validateChecksum();

$this->validateBirthDateDigits();
}

/**
Expand Down Expand Up @@ -124,28 +128,7 @@ public function getNumber()
*/
public function getBirthDate()
{
$year = substr($this->number, 0, 2);
$month = substr($this->number, 2, 2);
$day = substr($this->number, 4, 2);

// 0 - 9
$century = substr($this->number, 2, 1);

// 2,3,4,5,6,7,8,9,10,11
$century += 2;

// 2,3,4,5,6,7,8,9,0,1
$century %= 10;

// 1,1,2,2,3,3,4,4,0,0
$century = round($century / 2, 0, PHP_ROUND_HALF_DOWN);

// 19,19,20,20,21,21,22,22,18,18
$century += 18;

$year = $century.$year;

$month = str_pad($month % 20, 2, '0', STR_PAD_LEFT);
[$year, $month, $day] = $this->getYearMonthDate();

return DateTime::createFromFormat('Y-m-d H:i:s', "$year-$month-$day 00:00:00");
}
Expand Down Expand Up @@ -234,6 +217,26 @@ protected function validateChecksum()
}
}

/**
* @throws InvalidArgumentException on invalid birth date digits
*/
protected function validateBirthDateDigits()
{
[$year, $month, $day] = $this->getYearMonthDate();

if ($year < 1800 || $year > 2299) {
throw new InvalidBirthDateException($this->errorMessages['invalidBirthDate']);
}

if ($month < 1 || $month > 12) {
throw new InvalidBirthDateException($this->errorMessages['invalidBirthDate']);
}

if ($day < 1 || $day > cal_days_in_month(CAL_GREGORIAN, $month, $year)) {
throw new InvalidBirthDateException($this->errorMessages['invalidBirthDate']);
}
}

/**
* Check if provided gender matches accepted format.
*
Expand All @@ -251,4 +254,32 @@ protected static function validateGenderInput($gender)
throw new InvalidGenderInputException('Podano płeć w niepoprawnym formacie');
}
}

protected function getYearMonthDate()
{
$year = substr($this->number, 0, 2);
$month = substr($this->number, 2, 2);
$day = substr($this->number, 4, 2);

// 0 - 9
$century = substr($this->number, 2, 1);

// 2,3,4,5,6,7,8,9,10,11
$century += 2;

// 2,3,4,5,6,7,8,9,0,1
$century %= 10;

// 1,1,2,2,3,3,4,4,0,0
$century = round($century / 2, 0, PHP_ROUND_HALF_DOWN);

// 19,19,20,20,21,21,22,22,18,18
$century += 18;

$year = $century.$year;

$month = str_pad($month % 20, 2, '0', STR_PAD_LEFT);

return [$year, $month, $day];
}
}
14 changes: 14 additions & 0 deletions tests/PeselTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,18 @@ public function testCustomInvalidChecksumMessage()
new Pesel('11111111111', $errorMessages);
}

public function testCustomInvalidBirthDateMessage()
{
$errorMessages = [
'invalidBirthDate' => 'invalidBirthDate',
];

$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage($errorMessages['invalidBirthDate']);

new Pesel('44444444444', $errorMessages);
}

public function invalidNumberDataProvider()
{
return [
Expand All @@ -190,6 +202,8 @@ public function invalidNumberDataProvider()
['96100612532'],
['61122500187'],
['78091501150'],
['00000000000'],
['44444444444'],
];
}

Expand Down

0 comments on commit 07b8f73

Please sign in to comment.