1. Делаем новый виджет. Создаем файл lib/widget/sfWidgetFormInputDate.class.php
addOption('date_format', 'd.m.Y'); } public function render($name, $value = null, $attributes = array(), $errors = array()) { $datepicker=sprintf(<<<EOF EOF , $this->generateId($name) ); $value=strlen($value) ? date($this->getOption('date_format',strtotime($value))) : ''; return $datepicker.parent::render($name, $value, $attributes, $errors); } }
2. Создаем новый валидатор lib/validator/sfValidatorI18n.class.php
addOption('input_date_format', 'Y-m-d'); $this->addOption('output_date_format', 'Y-m-d'); parent::configure($options, $messages); } /** * Override sfValidatorDate doClean. Quite strange : I had to copy/paste the original * code after my 'convertDateToFormat' method : a simple parent::doClean($value) would * not work ! * @see trunk/lib/vendor/symfony/lib/validator/sfValidatorDate#doClean($value) */ protected function doClean($value) { $value = $this->convertDateToFormat($value); // I had to copy/paste the rest of doClean, otherwise it wouldn't work ! I don't know why... if (is_array($value)) { $clean = $this->convertDateArrayToTimestamp($value); } else if ($regex = $this->getOption('date_format')) { if (!preg_match($regex, $value, $match)) { throw new sfValidatorError($this, 'bad_format', array('value' => $value, 'date_format' => $this->getOption('date_format_error') ? $this->getOption('date_format_error') : $this->getOption('date_format'))); } $clean = $this->convertDateArrayToTimestamp($match); } else if (!ctype_digit($value)) { $clean = strtotime($value); if (false === $clean) { throw new sfValidatorError($this, 'invalid', array('value' => $value)); } } else { $clean = (integer) $value; } if ($this->hasOption('max') && $clean > $this->getOption('max')) { throw new sfValidatorError($this, 'max', array('value' => $value, 'max' => date($this->getOption('date_format_range_error'), $this->getOption('max')))); } if ($this->hasOption('min') && $clean < $this->getOption('min')) { throw new sfValidatorError($this, 'min', array('value' => $value, 'min' => date($this->getOption('date_format_range_error'), $this->getOption('min')))); } return $clean === $this->getEmptyValue() ? $clean : date($this->getOption('with_time') ? $this->getOption('datetime_output') : $this->getOption('date_output'), $clean); } /** * converts the given date * $value must match the option 'input_date_format'. It will be convert to 'output_date_format' * For example : $value = 19/08/2009, input_date_format = DD/MM/YYYY, output_date_format = YYYY-MM-DD * Output will be 2009-08-19 * @param $value * @return unknown_type * @author Simon Hostelet */ protected function convertDateToFormat($value) { // we check if input/output_date_format are well written, // we get the date separator, and the order of year, month and day in the mask $input_details = $this->getDateAlrightSeparatorAndOrder($this->getOption('input_date_format')); foreach($input_details as $key => $val) { $key = 'input_' . $key; $$key = $val; } $output_details = $this->getDateAlrightSeparatorAndOrder($this->getOption('output_date_format')); $input_date = explode($input_date_separator, $value); // is this date valid ? if(count($input_date)!=3 or !checkdate(intval($input_date[$input_month_order]), intval($input_date[$input_day_order]), intval($input_date[$input_year_order]))) { throw new sfValidatorError($this, 'invalid', array('value' => $value)); } // let's build the output date $output_date = $this->getOption('output_date_format'); $output_date = preg_replace('/Y|y/', $input_date[$input_year_order], $output_date); $output_date = preg_replace('/m/', $input_date[$input_month_order], $output_date); $output_date = preg_replace('/d/', $input_date[$input_day_order], $output_date); return $output_date; } /** * get a date format (like d/m/Y), check the format, and returns date separator (-/_, .) * and date order * @param $format * @return array * @author Simon Hostelet */ protected function getDateAlrightSeparatorAndOrder($format) { // does the date_format looks right ? if(!preg_match('/(d|m|y|Y)([-\/_,\. ]{1})(d|m|y|Y)([-\/_,\. ]{1})(d|m|y|Y)/', $format, $matches)) { throw new sfValidatorError($this, 'invalid', array('value' => $value)); } // what is the date separator ? preg_match('/[dmyY]{1}([\/\-,\._ ]{1})[dmyY]{1}/', $format, $matches); $return_array['date_separator'] = $matches[1]; // what is the order of day, month and year in the format mask ? $date_order = explode($return_array['date_separator'], $format); foreach($date_order as $key => $val) { switch($val) { case 'd': $return_array['day_order'] = $key; break; case 'm': $return_array['month_order'] = $key; break; default: $return_array['year_order'] = $key; } } return $return_array; } }
3. Используем в классе формы
$this->widgetSchema['birthday']=new sfWidgetFormInputDate(); $this->validatorSchema['birthday']=new sfValidatorDateI18n(array( 'date_output'=>'Y-m-d', 'input_date_format'=>'d.m.Y', 'output_date_format'=>'Y-m-d', 'required'=>false, 'with_time'=>false, ), array( 'bad_format'=>'Используйте дату в формате ДД.ММ.ГГГГ', ));
Может быть, я когда-нибудь соберусь оформить это в плагин :)
Комментариев нет:
Отправить комментарий