├── .editorconfig ├── .github └── workflows │ ├── build.yml │ └── php-cs.yml ├── .gitignore ├── .php-cs-fixer.dist.php ├── LICENSE ├── README.md ├── composer.json ├── database └── database.json ├── examples └── example.php ├── src ├── Exceptions │ ├── InvalidDatabaseException.php │ ├── InvalidDateOfBirthException.php │ ├── InvalidNikNumberException.php │ └── NikReaderException.php ├── Laravel │ ├── Facade.php │ └── ServiceProvider.php └── Reader.php └── tests └── ResultTest.php /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | insert_final_newline = true 7 | indent_style = space 8 | indent_size = 4 9 | trim_trailing_whitespace = true 10 | 11 | [*.php] 12 | indent_size = 4 13 | 14 | [*.stub] 15 | indent_size = 4 -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | paths: 4 | - '**.php' 5 | pull_request: 6 | paths: 7 | - '**.php' 8 | 9 | name: build 10 | 11 | jobs: 12 | tests: 13 | name: PHP ${{ matrix.php }}-${{ matrix.os }} 14 | env: 15 | extensions: json, zip 16 | key-php5: cache-v1 17 | key-php7: cache-v2 18 | 19 | runs-on: ${{ matrix.os }} 20 | 21 | strategy: 22 | matrix: 23 | os: 24 | - ubuntu-latest 25 | 26 | php: 27 | - "5.6" 28 | - "7.0" 29 | - "7.1" 30 | - "7.2" 31 | - "7.3" 32 | - "7.4" 33 | - "8.0" 34 | 35 | steps: 36 | - name: checkout 37 | uses: actions/checkout@v2 38 | 39 | - name: setup cache for 5.4 - 5.6 40 | if: matrix.php < '7.0' 41 | id: cache-env-php5 42 | uses: shivammathur/cache-extensions@v1 43 | with: 44 | php-version: ${{ matrix.php }} 45 | extensions: ${{ env.extensions-php5 }} 46 | key: ${{ env.key-php5 }} 47 | 48 | - name: setup cache for 7.0 - 8.0 49 | if: matrix.php >= '7.0' 50 | id: cache-env-php7 51 | uses: shivammathur/cache-extensions@v1 52 | with: 53 | php-version: ${{ matrix.php }} 54 | extensions: ${{ env.extensions-php7 }} 55 | key: ${{ env.key-php7 }} 56 | 57 | - name: setup cache extensions for 5.4 - 5.6 58 | if: matrix.php < '7.0' 59 | uses: actions/cache@v1 60 | with: 61 | path: ${{ steps.cache-env-php5.outputs.dir }} 62 | key: ${{ steps.cache-env-php5.outputs.key }} 63 | restore-keys: ${{ steps.cache-env-php5.outputs.key }} 64 | 65 | - name: setup cache extensions for 7.0 - 8.0 66 | if: matrix.php >= '7.0' 67 | uses: actions/cache@v1 68 | with: 69 | path: ${{ steps.cache-env-php7.outputs.dir }} 70 | key: ${{ steps.cache-env-php7.outputs.key }} 71 | restore-keys: ${{ steps.cache-env-php7.outputs.key }} 72 | 73 | - name: install php and extensions 74 | uses: shivammathur/setup-php@v2 75 | with: 76 | php-version: ${{ matrix.php }} 77 | extensions: ${{ env.extensions }} 78 | ini-values: date.timezone='UTC' 79 | coverage: xdebug 80 | tools: composer:v2, pecl 81 | 82 | - name: find composer cache directory (linux) 83 | run: echo "COMPOSER_CACHE_DIR=$(composer config cache-dir)" >> $GITHUB_ENV 84 | 85 | - name: find composer cache directory (windows) 86 | if: matrix.os == 'windows-latest' 87 | run: echo "COMPOSER_CACHE_DIR=~\AppData\Local\Composer" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append 88 | 89 | - name: install cache dependencies with composer 90 | uses: actions/cache@v1 91 | with: 92 | path: ${{ env.COMPOSER_CACHE_DIR }} 93 | key: php${{ matrix.php }}-composer-${{ hashFiles('**/composer.json') }} 94 | restore-keys: | 95 | php${{ matrix.php }}-composer- 96 | - name: update dependencies with composer 97 | run: composer update --no-interaction --no-progress --optimize-autoloader --ansi 98 | 99 | - name: run tests with phpunit 5.7.27 100 | run: ./vendor/bin/phpunit tests 101 | -------------------------------------------------------------------------------- /.github/workflows/php-cs.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | paths: 4 | - '**.php' 5 | pull_request: 6 | paths: 7 | - '**.php' 8 | 9 | name: phpcs 10 | 11 | jobs: 12 | phpcs: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v2 16 | with: 17 | ref: ${{ github.head_ref }} 18 | 19 | - name: check php version 20 | run: php -v 21 | 22 | - name: download phpcs 23 | run: wget -O phpcs.phar https://cs.symfony.com/download/php-cs-fixer-v3.phar 24 | 25 | - name: make phpcs executable 26 | run: chmod +x phpcs.phar 27 | 28 | - name: apply coding style 29 | run: php phpcs.phar fix 30 | 31 | - name: remove phpcs 32 | run: rm -f phpcs.phar 33 | 34 | - uses: stefanzweifel/git-auto-commit-action@v4 35 | with: 36 | commit_message: 'phpcs: apply coding style' 37 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | vendor 2 | composer.lock 3 | -------------------------------------------------------------------------------- /.php-cs-fixer.dist.php: -------------------------------------------------------------------------------- 1 | in(__DIR__) 9 | ->exclude($directories); 10 | 11 | return (new Config()) 12 | ->setRiskyAllowed(true) 13 | ->setUsingCache(false) 14 | ->setFinder($finder); 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Zeros Developer 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

NIK Reader

2 |
Identity data reader based on NIK (Nomor Induk Kependudukan)
3 | 4 |

5 | build 6 | release 7 | language 8 | license 9 | size 10 | downloads 11 | pulls 12 |

13 | 14 | ## About 15 | 16 | This library gives you a way to convert the NIK number into useful information such as: Region name (province, city, sub-district), date of birth, gender, zodiac, age, and more. This can also be used to validate whether the NIK number is valid or not. 17 | Here is the example result : 18 | 19 | ```json 20 | { 21 | "valid": true, 22 | "nik": "3502200101000001", 23 | "province_id": "35", 24 | "province": "JAWA TIMUR", 25 | "city_id": "3502", 26 | "city": "KAB. PONOROGO", 27 | "subdistrict_id": "350220", 28 | "subdistrict": "JAMBON", 29 | "postal_code": "63456", 30 | "birthday": "01-01-2000", 31 | "age": 32 | { 33 | "year": 21, 34 | "month": 9, 35 | "day": 25 36 | }, 37 | "zodiac": "Capricorn", 38 | "gender": "male", 39 | "unique_code": "0001" 40 | } 41 | ``` 42 | 43 | ## Installation 44 | 45 | 1. Run command 46 |
composer require zerosdev/nik-reader
47 | 48 | ## Usage 49 | 50 | ### Laravel 51 | 52 | ```php 53 | // ......... 54 | public function method() 55 | { 56 | $nik = '3502200101910001'; 57 | $result = \NikReader::read($nik); 58 | 59 | if (true === $result->valid) { 60 | // code 61 | } 62 | } 63 | ``` 64 | 65 | ### Non-Laravel 66 | 67 | ```php 68 | read($nik); 77 | 78 | if (true === $result->valid) { 79 | // code 80 | } 81 | ``` 82 | 83 | ### Available Methods 84 | 85 | | Method | Description | 86 | |---------------------------|----------------------------------| 87 | | read() | Start reading NIK number | 88 | | valid() | Check wether NIK is valid or not | 89 | | setDatabase() | Load database file | 90 | | getProvince() | Get province data | 91 | | getCity() | Get city data | 92 | | getSubdistrict() | Get subdistrict data | 93 | | getPostalCode() | Get postal code data | 94 | | getBornDate() | Get date of birth data | 95 | | getAge() | Get age data | 96 | | getZodiac() | Get zodiac data | 97 | | getGender() | Get gender data | 98 | | getUniqueCode() | Get unique code | 99 | | toArray() | Convert result into Array format | 100 | | toJSON() | Convert result into JSON format | 101 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "zerosdev/nik-reader", 3 | "description": "Identity data reader based on NIK (Nomor Induk Kependudukan)", 4 | "type": "library", 5 | "license": "MIT", 6 | "homepage": "https://github.com/ZerosDev/nik-reader", 7 | "support": 8 | { 9 | "issues": "https://github.com/ZerosDev/nik-reader/issues", 10 | "source": "https://github.com/ZerosDev/nik-reader" 11 | }, 12 | "authors": 13 | [ 14 | { 15 | "name": "Suyadi", 16 | "email": "suyadi.1992@gmail.com" 17 | }, 18 | { 19 | "name": "ZerosDev", 20 | "email": "admin@zeros.co.id" 21 | } 22 | ], 23 | "minimum-stability": "dev", 24 | "require": 25 | { 26 | "php": ">=5.6", 27 | "ext-json": "*" 28 | }, 29 | "autoload": 30 | { 31 | "psr-4": 32 | { 33 | "ZerosDev\\NikReader\\": "src/" 34 | } 35 | }, 36 | "extra": 37 | { 38 | "laravel": 39 | { 40 | "providers": 41 | [ 42 | "ZerosDev\\NikReader\\Laravel\\ServiceProvider" 43 | ], 44 | "aliases": 45 | { 46 | "NikReader": "ZerosDev\\NikReader\\Laravel\\Facade" 47 | } 48 | }, 49 | "composer-exit-on-patch-failure": true, 50 | "patches": { 51 | "phpunit/phpunit-mock-objects": { 52 | "Fix PHP 7 and 8 compatibility": "https://cdn.jsdelivr.net/gh/esyede/phpunit-patches/phpunit_mock_objects.patch" 53 | }, 54 | "phpunit/phpunit": { 55 | "Fix PHP 7 compatibility": "https://cdn.jsdelivr.net/gh/esyede/phpunit-patches/phpunit_php7.patch", 56 | "Fix PHP 8 compatibility": "https://cdn.jsdelivr.net/gh/esyede/phpunit-patches/phpunit_php8.patch" 57 | } 58 | } 59 | }, 60 | "require-dev": { 61 | "cweagans/composer-patches": "^1.7", 62 | "phpunit/phpunit": "4.8.34" 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /examples/example.php: -------------------------------------------------------------------------------- 1 | read($nik); 12 | 13 | print_r($result->toJSON(JSON_PRETTY_PRINT)); 14 | } catch (\Exception $e) { 15 | print_r(get_class($e) . " => " .$e->getMessage()); 16 | } 17 | -------------------------------------------------------------------------------- /src/Exceptions/InvalidDatabaseException.php: -------------------------------------------------------------------------------- 1 | app->singleton(Reader::class, function ($app) { 19 | return new Reader(); 20 | }); 21 | } 22 | 23 | /** 24 | * Bootstrap any application services. 25 | * 26 | * @return void 27 | */ 28 | public function boot() 29 | { 30 | } 31 | 32 | /** 33 | * Get the services provided by the provider. 34 | * 35 | * @return array 36 | */ 37 | public function provides() 38 | { 39 | return [Reader::class]; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Reader.php: -------------------------------------------------------------------------------- 1 | null, 29 | 'month' => null, 30 | 'day' => null 31 | ); 32 | public $gender; 33 | public $unique_code; 34 | 35 | /** 36 | * Constructor. 37 | * 38 | * @param string|null $nik 39 | * @param string|null $database 40 | */ 41 | public function __construct($nik = null) 42 | { 43 | if (! is_null($nik)) { 44 | $this->setNik($nik); 45 | } 46 | 47 | $database = dirname(__DIR__) . '/database/database.json'; 48 | 49 | $this->setDatabase($database); 50 | } 51 | 52 | /** 53 | * Set nomor NIK. 54 | * 55 | * @param string $nik 56 | */ 57 | private function setNik($nik) 58 | { 59 | $this->nik = $nik; 60 | 61 | return $this; 62 | } 63 | 64 | /** 65 | * Cek validitas nomor NIK. 66 | * 67 | * @return bool 68 | */ 69 | public function valid() 70 | { 71 | return $this->valid = ( 72 | is_string($this->nik) 73 | && preg_match("/^[0-9]+$/is", $this->nik) 74 | && strlen($this->nik) === 16 75 | && $this->getProvince() 76 | && $this->getCity() 77 | && $this->getSubdistrict() 78 | && $this->getBornDate() 79 | ); 80 | } 81 | 82 | /** 83 | * Read data 84 | */ 85 | public function read($nik = null) 86 | { 87 | $instance = $this->instanceUsed ? new self() : $this; 88 | 89 | if (! is_null($nik)) { 90 | $instance->setNik($nik); 91 | } 92 | 93 | $instance->fetchNew = true; 94 | 95 | $instance->getProvince(); 96 | $instance->getCity(); 97 | $instance->getSubdistrict(); 98 | $instance->getPostalCode(); 99 | $instance->getBornDate(); 100 | $instance->getAge(); 101 | $instance->getZodiac(); 102 | $instance->getGender(); 103 | $instance->getUniqueCode(); 104 | $instance->valid(); 105 | 106 | $instance->instanceUsed = true; 107 | 108 | return $instance; 109 | } 110 | 111 | /** 112 | * Set database dan baca isinya. 113 | * 114 | * @param string $file 115 | */ 116 | public function setDatabase($file) 117 | { 118 | if (! is_string($file) || ! is_file($file) || ! is_readable($file)) { 119 | throw new Exceptions\InvalidDatabaseException(sprintf( 120 | 'The database file cannot be found or not readable: %s', 121 | $file 122 | )); 123 | } 124 | 125 | if (static::$filemtime <= filemtime($file)) { 126 | $database = file_get_contents($file); 127 | $database = json_decode($database); 128 | 129 | if (json_last_error() !== JSON_ERROR_NONE) { 130 | throw new Exceptions\InvalidDatabaseException(sprintf( 131 | 'Unable to decode database contents: %s (%d)', 132 | $file, 133 | json_last_error() 134 | )); 135 | } 136 | 137 | static::$database = $database; 138 | static::$filemtime = filemtime($file); 139 | } 140 | 141 | return $this; 142 | } 143 | 144 | /** 145 | * Get data provinsi dari NIK. 146 | * 147 | * @return string|null 148 | */ 149 | public function getProvince() 150 | { 151 | if ($this->province && ! $this->fetchNew) { 152 | return $this->province; 153 | } 154 | 155 | $this->province_id = substr($this->nik, 0, 2); 156 | 157 | return $this->province = ( 158 | isset(static::$database->provinces->{$this->province_id}) 159 | ? static::$database->provinces->{$this->province_id} 160 | : null 161 | ); 162 | } 163 | 164 | /** 165 | * Get data kabupaten/kota dari NIK. 166 | * 167 | * @return string|null 168 | */ 169 | public function getCity() 170 | { 171 | if ($this->city && ! $this->fetchNew) { 172 | return $this->city; 173 | } 174 | 175 | $this->city_id = substr($this->nik, 0, 4); 176 | 177 | return $this->city = ( 178 | isset(static::$database->cities->{$this->city_id}) 179 | ? static::$database->cities->{$this->city_id} 180 | : null 181 | ); 182 | } 183 | 184 | /** 185 | * Get data kecamatan dari NIK. 186 | * 187 | * @return string|null 188 | */ 189 | public function getSubdistrict() 190 | { 191 | if ($this->subdistrict && ! $this->fetchNew) { 192 | return $this->subdistrict; 193 | } 194 | 195 | $this->subdistrict_id = substr($this->nik, 0, 6); 196 | 197 | $this->subdistrict = ( 198 | isset(static::$database->subdistricts->{$this->subdistrict_id}) 199 | ? static::$database->subdistricts->{$this->subdistrict_id} 200 | : null 201 | ); 202 | 203 | if (! is_null($this->subdistrict)) { 204 | $this->subdistrict = explode(' -- ', $this->subdistrict); 205 | $this->subdistrict = isset($this->subdistrict[0]) ? $this->subdistrict[0] : null; 206 | } 207 | 208 | return $this->subdistrict; 209 | } 210 | 211 | /** 212 | * Get kode pos 213 | * 214 | * @return string|null 215 | */ 216 | public function getPostalCode() 217 | { 218 | if ($this->postal_code && ! $this->fetchNew) { 219 | return $this->postal_code; 220 | } 221 | 222 | $code = substr($this->nik, 0, 6); 223 | 224 | $subdistrict = ( 225 | isset(static::$database->subdistricts->{$code}) 226 | ? static::$database->subdistricts->{$code} 227 | : null 228 | ); 229 | 230 | if (! is_null($subdistrict)) { 231 | $subdistrict = explode(' -- ', $subdistrict); 232 | $this->postal_code = isset($subdistrict[1]) ? $subdistrict[1] : null; 233 | } 234 | 235 | return $this->postal_code; 236 | } 237 | 238 | /** 239 | * Get data tanggal lahir dari NIK. 240 | * 241 | * @return string|null 242 | */ 243 | public function getBornDate() 244 | { 245 | if ($this->born_date && ! $this->fetchNew) { 246 | return $this->born_date; 247 | } 248 | 249 | $code = substr($this->nik, 6, 6); 250 | list($day, $month, $year) = str_split($code, 2); 251 | 252 | if (intval($day) > 31 && intval($day) <= 40) { 253 | return $this->born_date = null; 254 | } 255 | 256 | $day = (intval($day) > 40) ? (intval($day) - 40) : $day; 257 | 258 | $max = date('Y') - 17; 259 | $min = 1945; 260 | 261 | $temp = '20' . $year; 262 | $low = '19' . $year; 263 | $high = '20' . $year; 264 | 265 | $year = ($temp > $min) ? (($high > $max) ? $low : $high) : $low; 266 | 267 | if ($year < $min) { 268 | return $this->born_date = null; 269 | } 270 | 271 | try { 272 | $parse = DateTime::createFromFormat( 273 | 'd-m-Y', 274 | sprintf('%s-%s-%d', $day, $month, $year) 275 | ); 276 | if ($parse !== false) { 277 | return $this->born_date = $parse->format('d-m-Y'); 278 | } else { 279 | throw new Exception(); 280 | } 281 | } catch (Exception $e) { 282 | return $this->born_date = null; 283 | } 284 | } 285 | 286 | /** 287 | * Get age precision 288 | * 289 | * @return array => string|null 290 | */ 291 | public function getAge() 292 | { 293 | $born_date = $this->getBornDate(); 294 | 295 | if (! $born_date) { 296 | return $this->age = array( 297 | 'year' => null, 298 | 'month' => null, 299 | 'day' => null 300 | ); 301 | } 302 | 303 | list($day, $month, $year) = explode('-', $born_date); 304 | 305 | $age = time() - strtotime($year . "-" .$month . "-" . $day); 306 | 307 | $this->age['year'] = abs(gmdate('Y', $age) - 1970); 308 | $this->age['month'] = abs(gmdate('m', $age) - 1); 309 | $this->age['day'] = abs(gmdate('d', $age) - 1); 310 | 311 | return $this->age; 312 | } 313 | 314 | /** 315 | * Get zodiac 316 | * 317 | * @return string|null 318 | */ 319 | public function getZodiac() 320 | { 321 | if ($this->zodiac && ! $this->fetchNew) { 322 | return $this->zodiac; 323 | } 324 | 325 | list($day, $month) = str_split(substr($this->nik, 6, 4), 2); 326 | 327 | $day = intval($day); 328 | $month = intval($month); 329 | 330 | if ($day > 40) { 331 | $day = $day - 40; 332 | } 333 | 334 | foreach (static::$database->zodiacs as $data) { 335 | $range = explode('-', $data[0]); 336 | $rangeStart = explode('/', $range[0]); 337 | $rangeEnd = explode('/', $range[1]); 338 | 339 | $cd1 = intval($rangeStart[0]); 340 | $cm1 = intval($rangeStart[1]); 341 | 342 | $cd2 = intval($rangeEnd[0]); 343 | $cm2 = intval($rangeEnd[1]); 344 | 345 | $min = strtotime(date('Y').'-'.$cm1.'-'.$cd1.' 00:00:00'); 346 | $max = strtotime(date('Y').'-'.$cm2.'-'.$cd2.' 00:00:00'); 347 | 348 | $target = strtotime(date('Y').'-'.$month.'-'.$day.' 00:00:00'); 349 | 350 | if ($target >= $min && $target <= $max) { 351 | $this->zodiac = $data[1]; 352 | break; 353 | } 354 | } 355 | 356 | return $this->zodiac; 357 | } 358 | 359 | /** 360 | * Get gender type. 361 | * 362 | * @return string|null 363 | */ 364 | public function getGender() 365 | { 366 | if ($this->gender && ! $this->fetchNew) { 367 | return $this->gender; 368 | } 369 | 370 | $day = substr($this->nik, 6, 2); 371 | 372 | if ($day > 40) { 373 | $this->gender = 'female'; 374 | } else { 375 | $this->gender = 'male'; 376 | } 377 | 378 | return $this->gender; 379 | } 380 | 381 | /** 382 | * Get unique_code 383 | * 384 | * @return string|null 385 | */ 386 | public function getUniqueCode() 387 | { 388 | if ($this->unique_code && ! $this->fetchNew) { 389 | return $this->unique_code; 390 | } 391 | 392 | $code = substr($this->nik, 12, 4); 393 | 394 | return $this->unique_code = (strlen($code) === 4 ? $code : null); 395 | } 396 | 397 | /** 398 | * Convert to Array 399 | * 400 | * @return array 401 | */ 402 | public function toArray() 403 | { 404 | return [ 405 | 'valid' => $this->valid, 406 | 'nik' => $this->nik, 407 | 'province_id' => $this->province_id, 408 | 'province' => $this->province, 409 | 'city_id' => $this->city_id, 410 | 'city' => $this->city, 411 | 'subdistrict_id' => $this->subdistrict_id, 412 | 'subdistrict' => $this->subdistrict, 413 | 'postal_code' => $this->postal_code, 414 | 'born_date' => $this->born_date, 415 | 'age' => $this->age, 416 | 'zodiac' => $this->zodiac, 417 | 'gender' => $this->gender, 418 | 'unique_code' => $this->unique_code 419 | ]; 420 | } 421 | 422 | /** 423 | * Convert to JSON 424 | * 425 | * @return string 426 | */ 427 | public function toJSON($flags = 0) 428 | { 429 | return json_encode($this->toArray(), $flags); 430 | } 431 | } 432 | -------------------------------------------------------------------------------- /tests/ResultTest.php: -------------------------------------------------------------------------------- 1 | reader = new \ZerosDev\NikReader\Reader(); 10 | } 11 | 12 | protected function tearDown() 13 | { 14 | $this->reader = null; 15 | } 16 | 17 | public function testInvalidDatabase() 18 | { 19 | try { 20 | $this->reader->setDatabase(__DIR__.'/invalid-database.json'); 21 | } catch (\Exception $e) { 22 | $this->assertInstanceOf(\ZerosDev\NikReader\Exceptions\InvalidDatabaseException::class, $e); 23 | } 24 | } 25 | 26 | public function testValidNik() 27 | { 28 | $nik = '3502200101910001'; 29 | $result = $this->reader->read($nik); 30 | 31 | $this->assertTrue($result->valid); 32 | $this->assertFalse(! $result->valid); 33 | } 34 | 35 | public function testInvalidNik() 36 | { 37 | $nik = '3502203201910001'; 38 | $result = $this->reader->read($nik); 39 | 40 | $this->assertTrue(! $result->valid); 41 | $this->assertFalse($result->valid); 42 | } 43 | 44 | public function testValidBornDate() 45 | { 46 | $nik = '3502200101910001'; 47 | $result = $this->reader->read($nik); 48 | 49 | $this->assertEquals('01-01-1991', $result->born_date); 50 | } 51 | 52 | public function testInvalidBornDate() 53 | { 54 | $nik = '3502203201910001'; 55 | $result = $this->reader->read($nik); 56 | 57 | $this->assertNull($result->born_date); 58 | } 59 | 60 | public function testInvalidNikLength() 61 | { 62 | $nik = '350220320191000'; 63 | $result = $this->reader->read($nik); 64 | 65 | $this->assertTrue(! $result->valid); 66 | $this->assertFalse($result->valid); 67 | } 68 | 69 | public function testInvalidNikChars() 70 | { 71 | $nik = '350P2001Q191J00L'; 72 | $result = $this->reader->read($nik); 73 | 74 | $this->assertTrue(! $result->valid); 75 | $this->assertFalse($result->valid); 76 | } 77 | 78 | public function testReadMultipleNik() 79 | { 80 | $nik = '3502200101910001'; 81 | $nik2 = '3502201101910001'; 82 | 83 | $result = $this->reader->read($nik); 84 | $result2 = $this->reader->read($nik2); 85 | 86 | $this->assertEquals('01-01-1991', $result->born_date); 87 | $this->assertEquals('11-01-1991', $result2->born_date); 88 | } 89 | 90 | public function testRegion() 91 | { 92 | $nik = '3502200101910001'; 93 | 94 | $result = $this->reader->read($nik); 95 | 96 | $this->assertEquals('JAWA TIMUR', strtoupper($result->province)); 97 | $this->assertEquals('KAB. PONOROGO', strtoupper($result->city)); 98 | $this->assertEquals('JAMBON', strtoupper($result->subdistrict)); 99 | } 100 | } 101 | --------------------------------------------------------------------------------