php – BlackCrystal https://blackcrystal.net Show what you can. Learn what you don't Wed, 08 May 2019 17:07:08 +0000 ru-RU hourly 1 https://wordpress.org/?v=5.4.2 https://blackcrystal.net/wp-content/uploads/2015/03/cropped-bc-logo-big-32x32.png php – BlackCrystal https://blackcrystal.net 32 32 Проверка персонального кода в Synfony 1.4 sfValidatorIsikukood https://blackcrystal.net/tutorial/proverka-personal-nogo-koda-sfvalidatorisikukood/ https://blackcrystal.net/tutorial/proverka-personal-nogo-koda-sfvalidatorisikukood/#respond Wed, 25 Mar 2015 15:39:05 +0000 http://www.blackcrystal.net/?p=99 [:ru]Пример создания собственного валидатора персонального кода в Symfony.

В одном проекте потребовалось использовать эстонские личные коды (isikukood), которые даются каждому жителю этого государства и имеют возможность быть проверенными на валидность без запросов в какие-либо регистры.

Код содержит 11 цифр, 7 из которых обозначают пол, год, месяц и дату рождения, три последующие цифры – порядковый номер, и последняя цифра контрольная сумма. Ей то я и займусь.

Формула для вычисления контрольной суммы известна благодаря горячим обсуждениям в этой теме на forum.ee. Пожалуй, я использую свой вариант, так как мне он наиболее симпатичен. Кто бы сомневался ;)

В Symfony классы валидаторов имеют определённую структуру. Я, чтобы не морочаться долго, беру валидатор sfValidatorString, копирую в папку lib/validator и начинаю его изменять. Удаляю лишнее – проверку длины… Стойте-ка, длина строки здесь важна, ведь все цифры кода учавствуют в подсчёте. Пожалуй стоит просто расширить класс sfValidatorString новым функционалом, добавив проверку контрольной суммы. Так и поступаю.

Создаю файл lib/validator/sfValidatorIsikukood.class.php

class sfValidatorIsikukood extends sfValidatorString {

Конфигурация. Устанавливаю параметры max_length и min_length равному длине личного кода чтобы не передавать эти параметры каждый раз из форм. Так же добавляю сообщение об ошибке проверки контрольной суммы.

protected function configure($options = array(), $messages = array())
{
parent::configure( $options, $messages );
  $this->addOption('max_length', 11);
  $this->addOption('min_length', 11);
  $this->addMessage('not_valid_ik', '"%value%" is not valid personal code.');
}

Теперь, переопределяю главный метод, выполняющий проверку. Сначала выполнится сценарий sfValidatorString, потом сверится контрольная сумма:

protected function doClean($value)
{
  parent::doClean($value);
  if ( $value[10] != $this->getIsikukoodCC($value) )
    throw new sfValidatorError($this, 'not_valid_ik', array('value' => $value));
  return $value;
}

Собственно, функция подсчёта контрольной суммы:

protected function getIsikukoodCC($i)
{
  $s = $i[0]*1+$i[1]*2+$i[2]*3+$i[3]*4+$i[4]*5+$i[5]*6+$i[6]*7+$i[7]*8+$i[8]*9+$i[9]*1;
  if ( ( $s %= 11 ) < 10 ) return $s;
  $s = $i[0]*3+$i[1]*4+$i[2]*5+$i[3]*6+$i[4]*7+$i[5]*8+$i[6]*9+$i[7]*1+$i[8]*2+$i[9]*3;
  if ( ( $s %= 11 ) < 10 ) return $s; return 0; }
}

Пробую применить валидатор к полю isikukood своей формы:

$this->setValidator( 'isikukood', new sfValidatorIsikukood( array('required'=> true) ) );

Работает! Валидатор возвращает ошибки в случае:

  • если код не введён (required)
  • если он не 11 символов длиной (max_length, min_length)
  • если контрольная сумма не совпадает (not_valid_ik)

Вы знаете, для меня это не просто первый опыт создания своего валидатора, но и первое воплощение проверки кода в реальном проекте. Но самое главное, что эта тема — первая тема нового блога. Тройное браво![:]

]]>
https://blackcrystal.net/tutorial/proverka-personal-nogo-koda-sfvalidatorisikukood/feed/ 0