Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/php.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ jobs:
strategy:
fail-fast: false
matrix:
php: ['8.1']
php: ['8.5']
dependency-version: [prefer-lowest, prefer-stable]

name: PHP ${{ matrix.php }} - ${{ matrix.dependency-version }}

steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v6

- name: Setup PHP
uses: shivammathur/setup-php@v2
Expand All @@ -39,7 +39,7 @@ jobs:

- name: Cache Composer packages
id: composer-cache
uses: actions/cache@v2
uses: actions/cache@v5
with:
path: vendor
key: ${{ runner.os }}-node-${{ hashFiles('**/composer.lock') }}
Expand Down
6 changes: 3 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ public function extract(string $id): Citizen
{
$id = $this->sanitize($id);

if (! (new SocratiaIdValidator())->validate($id)) {
if (! new SocratiaIdValidator()->validate($id)) {
// Throw one of our internal exceptions
throw new InvalidIdException();
}
Expand Down Expand Up @@ -373,9 +373,9 @@ abstract class:

namespace Reducktion\Socrates\Tests\Feature\Europe;

use Reducktion\Socrates\Tests\Feature\FeatureTest;
use Reducktion\Socrates\Tests\Feature\FeatureTestCase;

class SocratiaTest extends FeatureTest
class SocratiaTest extends FeatureTestCase
{
public function test_extract_behaviour(): void
{
Expand Down
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@
}
],
"require": {
"php": "^8.1"
"php": "^8.5"
},
"require-dev": {
"roave/security-advisories": "dev-master",
"phpunit/phpunit": "^9.0"
"phpunit/phpunit": "^12.0"
},
"autoload": {
"psr-4": {
Expand Down
7 changes: 2 additions & 5 deletions phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,9 @@
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
bootstrap="vendor/autoload.php"
colors="true"
verbose="true"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd">
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd"
>
<coverage>
<include>
<directory suffix=".php">src/</directory>
</include>
</coverage>
<testsuites>
<testsuite name="Socrates Test Suite">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class AlbaniaCitizenInformationExtractor implements CitizenInformationExtractor
{
public function extract(string $id): Citizen
{
if (! (new AlbaniaIdValidator())->validate($id)) {
if (! new AlbaniaIdValidator()->validate($id)) {
throw new InvalidIdException();
}

Expand All @@ -34,11 +34,8 @@ private function getGender(string $id): Gender
return Gender::Male;
}

if ($identifier === 5 || $identifier === 6) {
return Gender::Female;
}

return Gender::Female;

}

private function getDateOfBirth(string $id): DateTime
Expand Down
52 changes: 45 additions & 7 deletions src/Core/Europe/Belgium/BelgiumCitizenInformationExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
* Class BelgiumCitizenInformationExtractor
*
* Algorithm adapted from: http://www.ibz.rrn.fgov.be/fileadmin/user_upload/nl/rr/instructies/IT-lijst/IT000_Rijksregisternummer.pdf.
* Foreign workers have a BIS number. More information about these types of numbers can be found here: https://testdatagenerator.bignited.be/.
*
* @package Reducktion\Socrates\Core\Belgium
*/
Expand All @@ -21,16 +22,22 @@ public function extract(string $id): Citizen
{
$id = $this->sanitize($id);

if (! (new BelgiumIdValidator())->validate($id)) {
if (! new BelgiumIdValidator()->validate($id)) {
throw new InvalidIdException();
}

$gender = $this->getGender($id);
$dateOfBirth = $this->getDateOfBirth($id);

$citizen = new Citizen();
$citizen->setGender($gender);
$citizen->setDateOfBirth($dateOfBirth);

// BIS numbers: month + 20 = gender unknown, month + 40 = gender known
// Regular NRN: always has gender
if (!$this->isBisNumber($id) || $this->isBisGenderKnown($id)) {
$citizen->setGender($this->getGender($id));
}

// Extract DOB if birthdate is known (month is not 00, 20, or 40)
if (!$this->isBirthdateUnknown($id)) {
$citizen->setDateOfBirth($this->getDateOfBirth($id));
}

return $citizen;
}
Expand All @@ -40,7 +47,31 @@ private function sanitize(string $id): string
return str_replace(['-', ' ', '.'], '', $id);
}

private function getGender(int $id): Gender
private function isBisNumber(string $id): bool
{
$month = (int) substr($id, 2, 2);

return $month > 12;
}

private function isBisGenderKnown(string $id): bool
{
$month = (int) substr($id, 2, 2);

// Month + 40 means gender is known, month + 20 means gender is unknown
return $month >= 40;
}

private function isBirthdateUnknown(string $id): bool
{
$month = (int) substr($id, 2, 2);

// For BIS numbers only: month 20 or 40 means birthdate is unknown
// Regular NRN with month 00 still extracts DOB (defaults to January)
return $month === 20 || $month === 40;
}

private function getGender(string $id): Gender
{
return (substr($id, 6, 3) % 2) ? Gender::Male : Gender::Female;
}
Expand All @@ -54,6 +85,13 @@ private function getDateOfBirth(string $id): DateTime
$month = (int) $month;
$day = (int) $day;

// BIS numbers have 20 or 40 added to the month
if ($month >= 40) {
$month -= 40;
} elseif ($month >= 20) {
$month -= 20;
}

// use first day or month if unknown
$month = $month === 0 ? 1 : $month;
$day = $day === 0 ? 1 : $day;
Expand Down
9 changes: 8 additions & 1 deletion src/Core/Europe/Belgium/BelgiumIdValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,13 @@ private function validDateOfBirth(string $id, bool $after2000): bool
$month = (int) $month;
$day = (int) $day;

// BIS numbers have 20 or 40 added to the month
if ($month >= 40) {
$month -= 40;
} elseif ($month >= 20) {
$month -= 20;
}

$month = $month === 0 ? 1 : $month;
$day = $day === 0 ? 1 : $day;

Expand All @@ -95,6 +102,6 @@ private function validDateOfBirth(string $id, bool $after2000): bool

$dateOfBirth = new DateTime("$year-$month-$day");

return (new DateTime())->diff($dateOfBirth)->y >= 12;
return new DateTime()->diff($dateOfBirth)->y >= 12;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ class BosniaAndHerzegovinaCitizenInformationExtractor implements CitizenInformat
{
public function extract(string $id): Citizen
{
if (! (new BosniaAndHerzegovinaIdValidator())->validate($id)) {
if (! new BosniaAndHerzegovinaIdValidator()->validate($id)) {
throw new InvalidIdException();
}

try {
$citizen = YugoslaviaCitizenInformationExtractor::extract($id);
} catch (InvalidLengthException $e) {
throw new InvalidLengthException('Bosnian JMBG', $e->getRequiredCharacters(), $e->getGivenCharacters());
throw new InvalidLengthException('Bosnian JMBG', $e->requiredCharacters, $e->givenCharacters);
}

return $citizen;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public function validate(string $id): bool
try {
$result = YugoslaviaIdValidator::validate($id);
} catch (InvalidLengthException $e) {
throw new InvalidLengthException('Bosnian JMBG', $e->getRequiredCharacters(), $e->getGivenCharacters());
throw new InvalidLengthException('Bosnian JMBG', $e->requiredCharacters, $e->givenCharacters);
}

$regionDigits = (int) substr($id, 7, 2);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class BulgariaCitizenInformationExtractor implements CitizenInformationExtractor
{
public function extract(string $id): Citizen
{
if (! (new BulgariaIdValidator())->validate($id)) {
if (! new BulgariaIdValidator()->validate($id)) {
throw new InvalidIdException();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ class CroatiaCitizenInformationExtractor implements CitizenInformationExtractor
{
public function extract(string $id): Citizen
{
if (! (new CroatiaIdValidator())->validate($id)) {
if (! new CroatiaIdValidator()->validate($id)) {
throw new InvalidIdException();
}

try {
$citizen = YugoslaviaCitizenInformationExtractor::extract($id);
} catch (InvalidLengthException $e) {
throw new InvalidLengthException('Croatian JMBG', $e->getRequiredCharacters(), $e->getGivenCharacters());
throw new InvalidLengthException('Croatian JMBG', $e->requiredCharacters, $e->givenCharacters);
}

return $citizen;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ class CzechRepublicCitizenInformationExtractor implements CitizenInformationExtr
{
public function extract(string $id): Citizen
{
if (! (new CzechRepublicIdValidator())->validate($id)) {
if (! new CzechRepublicIdValidator()->validate($id)) {
throw new InvalidIdException();
}

try {
$result = CzechoslovakiaCitizenInformationExtractor::extract($id);
} catch (InvalidLengthException $e) {
throw new InvalidLengthException('Czech RC', $e->getRequiredCharacters(), $e->getGivenCharacters());
throw new InvalidLengthException('Czech RC', $e->requiredCharacters, $e->givenCharacters);
}

return $result;
Expand Down
2 changes: 1 addition & 1 deletion src/Core/Europe/CzechRepublic/CzechRepublicIdValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public function validate(string $id): bool
try {
$result = CzechoslovakiaIdValidator::validate($id);
} catch (InvalidLengthException $e) {
throw new InvalidLengthException('Czech RC', $e->getRequiredCharacters(), $e->getGivenCharacters());
throw new InvalidLengthException('Czech RC', $e->requiredCharacters, $e->givenCharacters);
}

return $result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public static function extract(string $id): Citizen
{
$id = str_replace('/', '', $id);

if (! (new CzechoslovakiaIdValidator())::validate($id)) {
if (! new CzechoslovakiaIdValidator()::validate($id)) {
throw new InvalidIdException();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public function extract(string $id): Citizen
{
$id = $this->sanitize($id);

if (! (new DenmarkIdValidator())->validate($id)) {
if (! new DenmarkIdValidator()->validate($id)) {
throw new InvalidIdException();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class EstoniaCitizenInformationExtractor implements CitizenInformationExtractor
{
public function extract(string $id): Citizen
{
if (! (new EstoniaIdValidator())->validate($id)) {
if (! new EstoniaIdValidator()->validate($id)) {
throw new InvalidIdException();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class FinlandCitizenInformationExtractor implements CitizenInformationExtractor
{
public function extract(string $id): Citizen
{
if (! (new FinlandIdValidator())->validate($id)) {
if (! new FinlandIdValidator()->validate($id)) {
throw new InvalidIdException();
}

Expand Down
4 changes: 2 additions & 2 deletions src/Core/Europe/France/FranceCitizenInformationExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public function extract(string $id): Citizen
{
$id = $this->sanitize($id);

if (! (new FranceIdValidator())->validate($id)) {
if (! new FranceIdValidator()->validate($id)) {
throw new InvalidIdException();
}

Expand Down Expand Up @@ -47,7 +47,7 @@ private function getDateOfBirth(string $id): DateTime
{
$dateDigits = substr($id, 1, 4);
[$year, $month] = str_split($dateDigits, 2);
$currentYear = (int) (new DateTime())->format('y');
$currentYear = (int) new DateTime()->format('y');


$year = $year > $currentYear ? $year + 1900 : $year + 2000;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public function extract(string $id): Citizen
{
$id = $this->sanitize($id);

if (! (new HungaryIdValidator())->validate($id)) {
if (! new HungaryIdValidator()->validate($id)) {
throw new InvalidIdException();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public function extract(string $id): Citizen
{
$id = $this->sanitize($id);

if (! (new IcelandIdValidator())->validate($id)) {
if (! new IcelandIdValidator()->validate($id)) {
throw new InvalidIdException();
}

Expand Down
4 changes: 2 additions & 2 deletions src/Core/Europe/Italy/ItalyCitizenInformationExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class ItalyCitizenInformationExtractor implements CitizenInformationExtractor
{
public function extract(string $id): Citizen
{
if (! (new ItalyIdValidator())->validate($id)) {
if (! new ItalyIdValidator()->validate($id)) {
throw new InvalidIdException();
}

Expand Down Expand Up @@ -50,7 +50,7 @@ private function getDateOfBirth(string $id): DateTime
$monthChar = $id[8];
$yearDigits = substr($id, 6, 2);
$months = 'ABCDEHLMPRST';
$currentYear = (int) (new DateTime())->format('y');
$currentYear = (int) new DateTime()->format('y');

$day = (int) $dayDigits > 31 ? (int) $dayDigits - 40 : (int) $dayDigits;
$month = strpos($months, $monthChar) + 1;
Expand Down
4 changes: 2 additions & 2 deletions src/Core/Europe/Kosovo/KosovoCitizenInformationExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ class KosovoCitizenInformationExtractor implements CitizenInformationExtractor
{
public function extract(string $id): Citizen
{
if (! (new KosovoIdValidator())->validate($id)) {
if (! new KosovoIdValidator()->validate($id)) {
throw new InvalidIdException();
}

try {
$citizen = YugoslaviaCitizenInformationExtractor::extract($id);
} catch (InvalidLengthException $e) {
throw new InvalidLengthException('Kosovan JMBG', $e->getRequiredCharacters(), $e->getGivenCharacters());
throw new InvalidLengthException('Kosovan JMBG', $e->requiredCharacters, $e->givenCharacters);
}

return $citizen;
Expand Down
2 changes: 1 addition & 1 deletion src/Core/Europe/Kosovo/KosovoIdValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public function validate(string $id): bool
try {
$result = YugoslaviaIdValidator::validate($id);
} catch (InvalidLengthException $e) {
throw new InvalidLengthException('Kosovan JMBG', $e->getRequiredCharacters(), $e->getGivenCharacters());
throw new InvalidLengthException('Kosovan JMBG', $e->requiredCharacters, $e->givenCharacters);
}

$regionDigits = (int) substr($id, 7, 2);
Expand Down
Loading