Last active
May 22, 2018 11:24
-
-
Save holantomas/e2f51069d72e5625928b9b89ac07b5b6 to your computer and use it in GitHub Desktop.
Nette/Forms rodné číslo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Holabs\Utils; | |
use Nette\InvalidArgumentException; | |
use Nette\Utils\Strings; | |
/** | |
* @author Tomáš Holan <[email protected]> | |
* @copyright Copyright © 2017, Tomáš Holan [www.tomasholan.eu] | |
*/ | |
class BirthNumber { | |
const REGEXP = '~^\s*(\d\d)(\d\d)(\d\d)[ /]*(\d\d)(\d)(\d?)\s*$~'; | |
/** @var string */ | |
private $number; | |
/** @var int */ | |
private $year; | |
/** @var int */ | |
private $month; | |
/** @var int */ | |
private $day; | |
/** @var int */ | |
private $hospital; | |
/** @var int */ | |
private $order; | |
/** @var int */ | |
private $checker; | |
/** @var bool */ | |
private $male; | |
public function __construct(string $number) { | |
if (!$matches = self::explode($number)) { | |
throw new InvalidArgumentException("{$number} is not valid birth number"); | |
} | |
list($this->number, $this->year, $this->month, $this->day, $this->hospital, $this->order, $this->checker, $this->male) = $matches; | |
} | |
/** | |
* @return int | |
*/ | |
public function getYear(): int { | |
return $this->year; | |
} | |
/** | |
* @return int | |
*/ | |
public function getMonth(): int { | |
return $this->month; | |
} | |
/** | |
* @return int | |
*/ | |
public function getDay(): int { | |
return $this->day; | |
} | |
/** | |
* @return int | |
*/ | |
public function getHospital(): int { | |
return $this->hospital; | |
} | |
/** | |
* @return int | |
*/ | |
public function getOrder(): int { | |
return $this->order; | |
} | |
/** | |
* @return int | |
*/ | |
public function getChecker(): int { | |
return $this->checker; | |
} | |
/** | |
* @return bool | |
*/ | |
public function isMale(): bool { | |
return $this->male; | |
} | |
/** | |
* @return string | |
*/ | |
public function toString(): string { | |
return (string)$this; | |
} | |
/** | |
* @return string | |
*/ | |
public function __toString() { | |
return $this->number; | |
} | |
/** | |
* @param string $number | |
* @return bool | |
*/ | |
public static function validate(string $number): bool { | |
return self::explode($number) !== NULL; | |
} | |
/** | |
* @param string $number | |
* @return array|null [int|string $number, int year, int $month, int $day, int $hospital, int $order, int $checker, bool $male] | |
*/ | |
public static function explode(string $number): ?array { | |
// be liberal in what you receive | |
if (!$matches = Strings::match($number, self::REGEXP)) { | |
return NULL; | |
} | |
list(, $year, $month, $day, $hospital, $order, $c) = $matches; | |
$male = TRUE; | |
$tmp = "{$year}{$month}{$day}/{$hospital}{$order}{$c}"; | |
if ($c === '') { | |
$year += $year < 54 ? 1900 : 1800; | |
} else { | |
// kontrolní číslice | |
$mod = ($year . $month . $day . $hospital . $order) % 11; | |
if ($mod === 10) { | |
$mod = 0; | |
} | |
if ($mod !== (int)$c) { | |
return NULL; | |
} | |
$year += $year < 54 ? 2000 : 1900; | |
} | |
// k měsíci může být připočteno 20, 50 nebo 70 | |
if ($month > 70 && $year > 2003) { | |
$month -= 70; | |
$male = FALSE; | |
} elseif ($month > 50) { | |
$month -= 50; | |
$male = FALSE; | |
} elseif ($month > 20 && $year > 2003) { | |
$month -= 20; | |
} | |
// kontrola data | |
if (!checkdate($month, $day, $year)) { | |
return NULL; | |
} | |
return [$tmp, (int) $year, (int) $month, (int) $day, (int) $hospital, (int) $order, (int) $c, $male]; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Holabs\UI\Forms\Controls; | |
use Holabs\UI\Forms\Form; | |
use Holabs\UI\Forms\Validator; | |
use Holabs\Utils\BirthNumber; | |
use Nette\Forms\Controls\TextInput; | |
/** | |
* @author Tomáš Holan <[email protected]> | |
* @package asis/core | |
* @copyright Copyright © 2017, Tomáš Holan [www.tomasholan.eu] | |
*/ | |
class BirthNumberInput extends TextInput { | |
/** | |
* @inheritDoc | |
*/ | |
public function __construct($label = NULL, $maxLength = NULL) { | |
parent::__construct($label, $maxLength); | |
$this->addRule(Form::BIRTH_NUMBER, Validator::$messages[Form::BIRTH_NUMBER]); | |
} | |
/** | |
* @inheritDoc | |
*/ | |
public function getValue() { | |
$value = parent::getValue(); | |
return $value === NULL ? NULL : new BirthNumber((string) $value); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Holabs\UI\Forms; | |
use Nette\Application\UI\Form as NetteForm; | |
/** | |
* @author Tomáš Holan <[email protected]> | |
* @package asis/ui | |
* @copyright Copyright © 2017, Tomáš Holan [www.tomasholan.eu] | |
*/ | |
class Form extends NetteForm { | |
/** CUSTOM VALIDATORS */ | |
const BIRTH_NUMBER = Validator::class . '::validateBirthNumber'; | |
/** | |
* @param string | |
* @param string|object | |
* @return TextInput | |
*/ | |
public function addBirthNumber($name, $label = null){ | |
return $this[$name] = (new BirthNumberInput($label)) | |
->setRequired(false); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function ($, undefined) { | |
if (typeof $ !== 'function') { | |
return console.error('jQuery is missing.'); | |
} | |
if (typeof Nette !== 'object') { | |
return console.error('Nette is missing.'); | |
} | |
function checkdate(m, d, y) { | |
return m > 0 && m < 13 && y > 0 && y < 32768 && d > 0 && d <= (new Date(y, m, 0)).getDate() | |
} | |
function isUndefined(x) { | |
return typeof x === typeof undefined; | |
} | |
var validator = { | |
// This name is important!!! | |
HolabsUIFormsValidator_validateBirthNumber: function (elem, args, val) { | |
var matches = val.match(/^\s*(\d\d)(\d\d)(\d\d)[ /]*(\d\d)(\d)(\d?)\s*$/); | |
if (matches === null) return false; | |
[,year,month,day,hosp,ord,checker] = matches; | |
checker = isUndefined(checker) ? null : parseInt(checker, 10); | |
var ext = hosp.toString() + ord.toString(); | |
if (checker === null) { | |
year = parseInt(year, 10); | |
year += year < 54 ? 1900 : 1800; | |
} else { | |
var m = parseInt(year.toString() + month.toString() + day.toString() + ext, 10) % 11; | |
if (m === 10) m = 0; | |
if (m !== checker) return false; | |
year = parseInt(year, 10); | |
year += year < 54 ? 2000 : 1900; | |
} | |
month = parseInt(month, 10); | |
day = parseInt(day, 10); | |
if (month > 70 && year > 2003)month -= 70; | |
else if (month > 50) month -= 50; | |
else if (month > 20 && year > 2003) month -= 20; | |
return checkdate(month, day, year); | |
} | |
} | |
Nette.validators = $.extend(Nette.validators, validator); | |
})(jQuery); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Holabs\UI\Forms; | |
use Holabs\Utils\Validators; | |
use Nette\Forms\IControl; | |
use Nette\StaticClass; | |
/** | |
* @author Tomáš Holan <[email protected]> | |
* @package asis/core | |
* @copyright Copyright © 2017, Tomáš Holan [www.tomasholan.eu] | |
*/ | |
class Validator { | |
use StaticClass; | |
/** @var array */ | |
public static $messages = [ | |
Form::BIRTH_NUMBER => 'Nevalidní rodné číslo.', | |
]; | |
/** | |
* @param IControl $control | |
* @param $arg | |
* @return bool | |
*/ | |
public static function validateBirthNumber(IControl $control, $arg) { | |
return Validators::isBirthNumber($control->getValue()); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Holabs\Utils; | |
use Nette\StaticClass; | |
/** | |
* @author Tomáš Holan <[email protected]> | |
* @copyright Copyright © 2017, Tomáš Holan [www.tomasholan.eu] | |
*/ | |
class Validators { | |
use StaticClass; | |
/** | |
* @param string $number | |
* @return bool | |
*/ | |
public static function isBirthNumber(string $number): bool { | |
return BirthNumber::validate($number); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment