Skip to content

Commit 8b93bd6

Browse files
authored
[RELEASE] Socrates v2.0.0 (#116)
* WIP * README.md updates * PhpDoc fix on Citizen class * Fix Github Actions yml file branch reference from 'master' to 'main' * Remove Laravel references
1 parent 6a94fe5 commit 8b93bd6

File tree

111 files changed

+828
-1302
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

111 files changed

+828
-1302
lines changed

.github/workflows/php.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
strategy:
1717
fail-fast: false
1818
matrix:
19-
php: ['8.0', '7.4', '7.3', '7.2']
19+
php: ['8.1']
2020
dependency-version: [prefer-lowest, prefer-stable]
2121

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

CONTRIBUTING.md

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ contribute with a new country from scratch.
1212
1. Fork the project
1313
1. Create a new branch
1414
1. Code, test, commit and push
15-
1. Open a pull request detailing your changes.
15+
1. Open a pull request detailing your changes (do not forget to assign yourself to the PR).
1616
1. Describe what your pull request is (change, bugfix, new country implementation, etc.)
1717

1818
### Guidelines
@@ -28,7 +28,7 @@ Clone your fork, then install the dev dependencies:
2828
composer install
2929
```
3030

31-
It is advised to run a Laravel/Vanilla PHP application locally, and pull in your local fork of the package to test.
31+
It is advised to run a PHP application locally, and pull in your local fork of the package to test.
3232
Check [this post](https://johnbraun.blog/posts/creating-a-laravel-package-1) for a guide on how to do it.
3333

3434
## How to implement a country from scratch
@@ -191,22 +191,22 @@ abstract class Countries
191191
//...
192192
```
193193

194-
Let's also add a constant to `Country.php` with our country code for convenience:
194+
Let's also add an entry to `Country.php` with our country code for convenience:
195195

196196
```php
197197
<?php
198198

199199
namespace Reducktion\Socrates\Constants;
200200

201-
abstract class Country
201+
enum Country: string
202202
{
203203
/**
204204
* European countries
205205
*/
206-
public const ALBANIA = 'AL';
206+
case Albania = 'AL';
207207
//...
208-
public const SOCRATIA = 'SC';
209-
public const SWEDEN = 'SE';
208+
case Socratia = 'SC';
209+
case Sweden = 'SE';
210210
// ...
211211
```
212212

@@ -278,14 +278,13 @@ public function extract(string $id): Citizen
278278
}
279279
```
280280

281-
Let us do each in order. Getting the gender is simple. Because we have already validated the ID we
281+
Let us do each in order. Getting the gender is simple. We can return the Gender enum. Because we have already validated the ID we
282282
can be confident that the gender character is safe to check:
283283

284284
```php
285-
public function getGender(string $id): string
285+
public function getGender(string $id): Gender
286286
{
287-
// Use our internal "enum"
288-
return $id[0] === 'M' ? Gender::MALE : Gender::FEMALE;
287+
return $id[0] === 'M' ? Gender::Male : Gender::Female;
289288
}
290289
```
291290

@@ -313,7 +312,7 @@ namespace Reducktion\Socrates\Core\Europe\Socratia;
313312

314313
class SocratiaRegionsList
315314
{
316-
public static $regions = [
315+
public static array $regions = [
317316
'P' => 'Phpilia',
318317
'J' => 'Javardia',
319318
'R' => 'Rustaria',
@@ -405,7 +404,7 @@ protected function setUp(): void
405404
$this->people = [
406405
'alexandre' => [
407406
'id' => 'MR-19940916-4',
408-
'gender' => Gender::MALE,
407+
'gender' => Gender::Male,
409408
'dob' => new DateTime('1994-09-16'),
410409
'age' => 26, // as of 2021
411410
'pob' => 'Rustaria',
@@ -426,44 +425,44 @@ protected function setUp(): void
426425
}
427426
```
428427

429-
Now for each of those two data sets we run our validator and extractor classes and check if all is well:
428+
Now for each of those two data sets we run our validator and extractor classes and check if all is well.
429+
Because we are extending our own `TestCase` class, we have access to an instance of Socrates via the `$this->socrates` call:
430430

431431
```php
432432
public function test_extract_behaviour(): void
433433
{
434434
foreach ($this->people as $person) {
435-
$citizen = Socrates::getCitizenDataFromId($person['id'], Country::SOCRATIA);
435+
$citizen = $this->socrates->getCitizenDataFromId($person['id'], Country::Socratia);
436436

437437
self::assertEquals($person['gender'], $citizen->getGender());
438-
self::assertEquals(Carbon::instance($person['dob']), $citizen->getDateOfBirth());
439-
self::assertEquals($person['dob'], $citizen->getDateOfBirthNative());
438+
self::assertEquals($person['dob'], $citizen->getDateOfBirth());
440439
self::assertEquals($person['age'], $citizen->getAge());
441440
self::assertEquals($person['pob'], $citizen->getPlaceOfBirth());
442441
}
443442

444443
$this->expectException(InvalidIdException::class);
445444

446445
// An invalid ID should not be able to be extracted
447-
Socrates::getCitizenDataFromId('OR-19940916-4', 'SC');
446+
$this->socrates->getCitizenDataFromId('OR-19940916-4', Country::Socratia);
448447
}
449448

450449
public function test_validation_behaviour(): void
451450
{
452451
foreach ($this->people as $person) {
453452
self::assertTrue(
454-
Socrates::validateId($person['id'], 'SC')
453+
$this->socrates->validateId($person['id'], Country::Socratia)
455454
);
456455
}
457456

458457
foreach ($this->invalidIds as $fc) {
459458
self::assertFalse(
460-
Socrates::validateId($fc, 'SC')
459+
$this->socrates->validateId($fc, Country::Socratia)
461460
);
462461
}
463462

464463
$this->expectException(InvalidLengthException::class);
465464

466-
Socrates::validateId('OR-940916-4', 'SC');
465+
$this->socrates->validateId('OR-940916-4', Country::Socratia);
467466
}
468467
```
469468

README.md

Lines changed: 22 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,50 @@
11
<p align="center">
2-
<img src="https://raw.githubusercontent.com/AlexOlival/socrates/master/docs/logo.png" alt="Socrates logo" width="480">
2+
<img src="./art/socrates.svg" alt="Socrates logo" width="480">
33
</p>
44
<p align="center">
5-
<img src="https://raw.githubusercontent.com/AlexOlival/socrates/master/docs/example.png" alt="Usage example" width="800">
5+
<img src="./art/carbon.svg" alt="Usage example" width="800">
66
</p>
77
<p align="center">
88
<img alt="Badge" src="https://github.com/AlexOlival/socrates/workflows/Build/badge.svg">
99
<img alt="Total Downloads" src="https://img.shields.io/packagist/dt/reducktion/socrates">
1010
<img alt="Latest Version" src="https://img.shields.io/packagist/v/reducktion/socrates">
1111
<img alt="License" src="https://img.shields.io/github/license/reducktion/socrates">
12-
<img alt="StyleCI" src="https://github.styleci.io/repos/238900350/shield?branch=master">
12+
<img alt="StyleCI" src="https://github.styleci.io/repos/238900350/shield?branch=main">
1313
<img alt="Contributors" src="https://img.shields.io/badge/all_contributors-1-orange.svg?style=flat-square">
1414
</p>
1515

1616
------
1717
## Introduction
1818
>I am a **Citizen of the World**, and my Nationality is Goodwill.
1919
20-
<i>You can now read [a blog post](https://medium.com/@alex.olival/road-to-mastery-building-an-open-source-package-3936f57aed81) about how this package was created and its goals.</i>
21-
2220
**Socrates** is a PHP Package that allows you to validate and retrieve personal data from [National Identification Numbers](https://en.wikipedia.org/wiki/National_identification_number).
23-
Most countries in Europe are supported as well as some American ones, but the goal is to eventually support as many countries in the world as possible.
21+
Most countries in Europe are supported as well as some North and South American ones, with the goal to support as many countries in the world as possible.
2422
<p>Some countries also encode personal information of the citizen, such as gender or the place of birth. This package allows you to extract that information in a consistent way.</p>
25-
<p>A Facade and Validation Rule is also available for Laravel (see below).</p>
26-
<p>This package can be useful for many things, such as validating a user's ID for finance related applications or verifying a user's age without asking for it explicitly. However, we recommend you review your country's data protection laws before storing any information.</p>
23+
24+
<p>This package can be useful for many things such as validating a user's ID for finance related applications or verifying a user's age without asking for it explicitly. We recommend you review your country's data processing and protection laws before storing any information.</p>
2725

2826
[Ports](https://github.com/reducktion/socrates#ports) of this package to other languages are currently in progress. Check further below for which ones are currently available.
2927

3028
## Installation
3129
`composer require reducktion/socrates`
3230

3331
## Usage
34-
Socrates provides two methods: `validateId` and `getCitizenDataFromId`. Both receive the ID and the country code in [ISO 3166-2 format](https://en.wikipedia.org/wiki/ISO_3166-2) as the first and second parameters respectively. Simply instantiate the class and call the method you wish:
32+
Socrates provides two methods: `validateId` and `getCitizenDataFromId`. Both receive an ID and the country code as a backed enum with the [ISO 3166-2 format](https://en.wikipedia.org/wiki/ISO_3166-2) as the first and second parameters respectively. Simply instantiate the class and call the method you wish:
3533

3634
```php
3735
use Reducktion\Socrates\Socrates;
3836
use Reducktion\Socrates\Constants\Country;
3937

4038
$socrates = new Socrates();
41-
$socrates->validateId('14349483 0 ZV3', Country::PORTUGAL);
42-
// or
43-
$socrates->validateId('14349483 0 ZV3', 'PT');
44-
```
45-
46-
If you're using Laravel a facade is also available for your convenience:
47-
48-
```php
49-
use Reducktion\Socrates\Laravel\Facades\Socrates;
50-
use Reducktion\Socrates\Constants\Country;
51-
52-
Socrates::getCitizenDataFromId('550309-6447', Country::SWEDEN);
53-
```
54-
55-
Still in Laravel you can use the `national_id:[COUNTRY CODE]` request validation rule.
56-
Here is an example checking if a request parameter is a valid latvian ID:
57-
58-
```php
59-
$request->validate([
60-
'national_id' => 'required|string|national_id:lv',
61-
]);
39+
$socrates->validateId('14349483 0 ZV3', Country::Portugal);
6240
```
6341

6442
### validateId
6543
This method will return true or false.
66-
In case the ID has the wrong character length, an `InvalidLengthException` will be thrown.
44+
In case the ID has a wrong character length an `InvalidLengthException` will be thrown.
6745

6846
```php
69-
if ($socrates->validateId('719102091', Country::NETHERLANDS)) {
47+
if ($socrates->validateId('719102091', Country::Netherlands)) {
7048
echo 'Valid ID.';
7149
} else {
7250
echo 'Invalid ID.';
@@ -79,31 +57,30 @@ If the ID is invalid, an `InvalidIdException` will be thrown.<br>
7957
If the country does not support data extraction, an `UnsupportedOperationException` will be thrown.
8058

8159
```php
82-
$citizen = $socrates->getCitizenDataFromId('3860123012', Country::ESTONIA);
60+
$citizen = $socrates->getCitizenDataFromId('3860123012', Country::Estonia);
8361
```
8462

8563
The `Citizen` class stores the extracted citizen data in a consistent format across all countries.<br>
86-
It exposes the `getGender()`, `getDateOfBirthNative()`, `getDateOfBirth()`, `getAge()` and `getPlaceOfBirth()` methods.<br><br>
87-
`getGender` and `getPlaceOfBirth` return a `string`.<br>
88-
`getAge()` returns an `int`.<br>
89-
`getDateOfBirthNative()` returns a native `DateTime` and `getDateOfBirth()` returns a `Carbon` instance.<br>
90-
**It is recommended to use `getDateOfBirthNative()` as Carbon will be removed as a dependency in a future release of Socrates.**
64+
It exposes the `getGender()`, `getDateOfBirth()`, `getAge()` and `getPlaceOfBirth()` methods.<br><br>
65+
`getGender` will return an instance of the `Gender` enum.<br>
66+
`getPlaceOfBirth` will return a city or region name as a `string`.<br>
67+
`getAge()` returns the age of the citizen as an `int`.<br>
68+
`getDateOfBirth()` returns a `DateTime` instance.<br>
9169
<p>Using the example above, Estonia only encodes the date of birth and gender of the citizen in their ID. So the above methods will return:</p>
9270

9371
```php
94-
echo $citizen->getGender(); // 'Male'
95-
echo $citizen->getDateOfBirthNative(); // DateTime instance with the date '1986-01-23'
96-
echo $citizen->getDateOfBirth(); // DEPRECATED - Carbon instance with the date '1986-01-23'
97-
echo $citizen->getAge(); // 34
98-
echo $citizen->getPlaceOfBirth(); // null
72+
echo $citizen->getGender(); // 'Gender::Male'
73+
echo $citizen->getDateOfBirth(); // DateTime instance with the date '1986-01-23'
74+
echo $citizen->getAge(); // (The current age as a number)
75+
echo $citizen->getPlaceOfBirth(); // null - Estonia does not encode place of birth on its ID numbers
9976
```
10077

10178
## Supported and Unsupported Countries
10279

10380
[Here](COUNTRIES.md) you can see the full list of supported countries and whether they support data extraction.
10481

10582
Four european countries are currently unsupported: Austria 🇦🇹, Belarus 🇧🇾, Cyprus 🇨🇾 and Luxembourg 🇱🇺.
106-
A number of countries in the Americas are also unsupproted. This is because we could not find a reliable source for the algorithm, if at all. Help would be appreciated to get these countries supported.
83+
A number of countries in the Americas are also unsupported. This is because we could not find a reliable source for the algorithm, if at all. Help would be appreciated to get these countries supported.
10784

10885
## Testing
10986
`composer test`
@@ -132,7 +109,7 @@ Socrates was made with 💖 by [Alexandre Olival](https://github.com/AlexOlival)
132109
We are Reducktion.
133110
We hope to make someone's life easier after all the hard work compiling, researching, reverse-engineering and agonizing over ID validation algorithms - many of which were very obscure and hard to find.
134111

135-
## Special thanks
112+
## Special Thanks
136113
A big thanks goes to these people who helped us either test with real life IDs or guide us in finding the algorithm for their countries:
137114
* Alexandra from 🇷🇴
138115
* Berilay from 🇹🇷

art/carbon.svg

Lines changed: 17 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)