-
Notifications
You must be signed in to change notification settings - Fork 0
/
Encoder.php
151 lines (124 loc) · 3.41 KB
/
Encoder.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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
<?php
namespace Zackyjack\AdvanceAI;
class EncoderException extends \RuntimeException
{
}
class UnsupportedCharsetException extends EncoderException
{
}
class EmptyArgumentException extends EncoderException
{
}
class NullArgumentException extends EncoderException
{
}
class MobileFormatException extends EncoderException
{
}
class NameFormatException extends EncoderException
{
}
class NIKFormatException extends EncoderException
{
}
abstract class Encoder
{
protected $value = "";
public function __construct($v)
{
$this->value = $v;
if ($this->value === null) {
throw new NullArgumentException("The argument is null");
}
if ($this->value === '') {
throw new EmptyArgumentException("The argument is empty");
}
if (!mb_check_encoding($this->value, 'UTF-8')) {
throw new UnsupportedCharsetException("Only Support UTF-8");
}
}
abstract public function format();
public function encodeBySha1WithSalt($salt)
{
return sha1($salt . $this->format());
}
}
class MobileEncoder extends Encoder
{
const MOBILE_REGEX = '/^\\+62\\d{3,18}$/';
public function format()
{
if (!preg_match(self::MOBILE_REGEX, $this->value)) {
throw new MobileFormatException("The mobile format is invalid: $this->value");
}
return $this->value;
}
}
class NameEncoder extends Encoder
{
const NAME_REGEX = '/^[A-Za-z][-_A-Za-z ]*[A-Za-z]$/';
public function format()
{
if (!preg_match(self::NAME_REGEX, $this->value)) {
throw new NameFormatException("The name format is invalid: $this->value");
}
return $this->value;
}
}
class NIKEncoder extends Encoder
{
const NIK_REGEX = '/^[0-9]{16}$/';
public function format()
{
if (!$this->isValidNIKFormat()) {
throw new NIKFormatException("The NIK format is invalid: $this->value");
}
return $this->value;
}
private function isValidNIKFormat()
{
return $this->isValidNumber() && $this->isValidDate() && $this->isValidBirthMonth() && $this->isValidAgeRange();
}
private function isValidNumber()
{
return preg_match(self::NIK_REGEX, $this->value);
}
private function isValidDate()
{
$highDate = substr($this->value, 6, 1);
$lowDate = substr($this->value, 7, 1);
$result = true;
if ($highDate == 3 || $highDate == 7) {
$result = $lowDate < 2;
} elseif ($highDate == 0 || $highDate == 4) {
$result = $lowDate > 0;
}
return $highDate < 8 && $result;
}
private function isValidBirthMonth()
{
$month = substr($this->value, 8, 2);
return $month > 0 && $month < 13;
}
private function isValidAgeRange()
{
$minValidAge = 16;
$maxValidAge = 80;
$age = $this->calculateAge();
return $age >= $minValidAge && $age <= $maxValidAge;
}
private function calculateAge()
{
//TODO: we do not care timezone now.
$nowYear = date('Y');
$tailOfNowYear = $nowYear % 2000;
$yearOfNik = substr($this->value, 10, 2);
$yearOfBirth = 1900;
if ($yearOfNik > $tailOfNowYear) {
$yearOfBirth += $yearOfNik;
} else {
$yearOfBirth += $yearOfNik + 100;
}
return $nowYear - $yearOfBirth;
}
}