如何使用sfForm验证没有日期的日期?

时间:2011-04-18 10:29:57

标签: validation forms date symfony1

我正在使用symfony 1.4创建一个付款表单,我的表单有一个这样定义的日期窗口小部件,以便用户可以选择他的信用卡的到期日期:

new sfWidgetFormDate(array(
  'format' => '%month%/%year%',
  'years'  => array_combine(range(date('Y'), date('Y') + 5), range(date('Y'), date('Y') + 5))

请注意,大多数付款表单中的格式都没有%day%。

现在我的问题是sfValidatorDate要求'day'字段不为空。为了解决这个问题,我使用回调创建了一个自定义验证器,效果很好:

public function validateExpirationDate($validator, $value)
{
  $value['day'] = '15';
  $dateValidator = new sfValidatorDate(array(
    'date_format' => '#(?P<day>\d{2})(?P<month>\d{2})(?P<year>\d{2})#',
    'required'    => false,
    'min'         => strtotime('first day of this month')));
  $dateValidator->clean($value);
  return $value;
}

我觉得可能有一种更简单的方法来实现这一目标。你怎么看?你是否已经以更清洁的方式解决了这个问题?

4 个答案:

答案 0 :(得分:3)

你如何存储日期?如果您只将月份和年份存储为整数或字符串,那么您只需制作2个选择小部件。但是如果将它存储为日期时间(时间戳),那么无论如何都需要一个有效的日期。这意味着您需要自动为“日期”(通常是该月的第一天或最后一天)分配值。

class YourForm extends BaseYourForm
{
  public function configure()
  {
    $this->widgetSchema['date'] = new sfWidgetFormDate(array(
      'format' => '%month%/%year%'
    ));
    $this->validatorSchema['date'] = new myValidatorDate(array(
      'day_default' => 1
    ));
  }
} 

class myValidatorDate extends sfValidatorDate
{
  protected function configure($options = array(), $messages = array())
  {
    $this->addOption('day_default', 1);
    parent::configure($options, $messages);
  }

  protected function doClean($value)
  {
    if (!isset($value['day']))
    {
      $value['day'] = $this->getOption('day_default');
    }
    return parent::doClean($value);
  }
}

答案 1 :(得分:1)

无需使用自定义验证类:您可以简单地覆盖传递给bind()方法的污点值:

  <?php
  // in your form class
  public function bind(array $taintedValues = null, array $taintedFiles = null)
  {
    $taintedValues['date']['day'] = 1;

    return parent::bind($taintedValues, $taintedFiles);
  }

答案 2 :(得分:1)

我用最简单的方法来验证信用卡到期日:

$post_data = $request->getParameter('my_form');
$post_data['card_exp']['day'] = 1; //sets the first day of the month
$this->form->bind($post_data);

希望这有助于某人。

答案 3 :(得分:1)

我首先在表单

中解决这个问题
    $year = range(date('Y'), date('Y') - 50);

    $this->widgetSchema['date'] = new sfWidgetFormDate(array(
      'format' => '%year%',
      'years' => array_combine($year, $year),
      'can_be_empty' => false
    ));

下一步...

    public function bind(array $taintedValues = null){
      $taintedValues['date']['day'] = '01';
      $taintedValues['date']['month'] = '01';

      parent::bind($taintedValues);
    }

数据库中的字段是日期类型DATE。