-
Notifications
You must be signed in to change notification settings - Fork 5
/
Socrates.php
119 lines (97 loc) · 4.21 KB
/
Socrates.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
<?php
namespace Reducktion\Socrates;
use Locale;
use Reducktion\Socrates\Exceptions\InvalidIdException;
use Reducktion\Socrates\Exceptions\InvalidLengthException;
use Reducktion\Socrates\Exceptions\UnrecognisedPlaceOfBirthException;
use Reducktion\Socrates\Models\Citizen;
use Reducktion\Socrates\Config\Countries;
use Reducktion\Socrates\Core\IdValidatorFactory;
use Reducktion\Socrates\Exceptions\InvalidCountryCodeException;
use Reducktion\Socrates\Core\CitizenInformationExtractorFactory;
use Reducktion\Socrates\Exceptions\UnrecognisedCountryException;
use Reducktion\Socrates\Exceptions\UnsupportedOperationException;
class Socrates
{
/**
* Extracts the Citizen data related to the provided Personal Identification Number.
*
* @param string $id
* @param string $countryCode
* @return Citizen
* @throws InvalidIdException if the provided National Identification Number is invalid.
* @throws UnrecognisedPlaceOfBirthException if the encoded place of birth is wrong or invalid.
* @throws UnsupportedOperationException if the version or format of the National Identification Number does
* not support a given operation.
*/
public function getCitizenDataFromId(string $id, string $countryCode = ''): Citizen
{
$id = trim($id);
$countryCode = $this->formatCountryCode($countryCode);
$this->checkIfCountrySupportsCitizenData($countryCode);
$citizenInformationExtractor = CitizenInformationExtractorFactory::getExtractor($countryCode);
return $citizenInformationExtractor->extract($id);
}
/**
* Checks if the provided Personal Identification Number is valid.
*
* @param string $id
* @param string $countryCode
* @return bool
* @throws InvalidLengthException if the provided National Identification Number has the wrong length.
*/
public function validateId(string $id, string $countryCode = ''): bool
{
$id = trim($id);
$countryCode = $this->formatCountryCode($countryCode);
$idValidator = IdValidatorFactory::getValidator($countryCode);
return $idValidator->validate($id);
}
/**
* Transforms the provided country code to the ISO 3166-2 format.
*
* @param string $countryCode
* @return string
* @throws InvalidCountryCodeException if the provided country code is not provided or is not in the right format.
* @throws UnrecognisedCountryException if the provided country code does not correspond to any country.
*/
private function formatCountryCode(string $countryCode): string
{
$runningLaravel = class_exists(\Illuminate\Support\Facades\App::class);
if (! $runningLaravel && $countryCode === '') {
throw new InvalidCountryCodeException('No country code provided.');
}
if ($runningLaravel && $countryCode === '') {
$countryCode = \Illuminate\Support\Facades\App::getLocale();
}
$countryCodeLength = strlen($countryCode);
if ($countryCodeLength !== 2 && $countryCodeLength !== 5) {
throw new InvalidCountryCodeException("The code '$countryCode' is not in ISO 3166-2 format.");
}
if ($countryCodeLength === 5) {
$countryCode = substr($countryCode, -2);
}
$countryCode = strtoupper($countryCode);
if (! in_array($countryCode, Countries::$all, true)) {
throw new UnrecognisedCountryException("Could not find the country with the code '$countryCode'.");
}
return $countryCode;
}
/**
* Verifies if a given country supports Citizen data extraction.
*
* @param string $countryCode
* @return void
* @throws UnsupportedOperationException if the provided country does not supported extracting data from
* the Personal Identification Number.
*/
private function checkIfCountrySupportsCitizenData(string $countryCode): void
{
if (! isset(Countries::$extractors[$countryCode])) {
$countryName = Locale::getDisplayRegion("-$countryCode", 'en');
throw new UnsupportedOperationException(
"$countryName does not support extracting citizen data from the ID."
);
}
}
}