2011-04-18 54 views
3

我創建的支付形式的symfony 1.4,我的形式有這樣定義的日期窗口小部件,使用戶可以選擇他的信用卡到期日期:如何使用sfForm無日期驗證日期?

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

通知沒有%像大多數付款表格那樣格式化。

現在我的問題是,sfValidatorDate需要'天'字段不能爲空。要解決這個問題,我創建使用回調自定義驗證,效果很好:

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; 
} 

我覺得有可能是實現這個簡單的方法。你怎麼看?你是否已經以更清晰的方式解決了這個問題?

回答

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); 
    } 
} 
+0

目前,我不存儲它,但我將它作爲未來存儲,很可能作爲一個字符串,因爲我發送給它的Web服務只需要一個字符串。或者,如果我想用它在他的信用卡到期時提醒用戶,可能是時間戳。無論如何,我(和你的)配置方法中的代碼會創建兩個選擇框。我的觀點是我想在本月或以後有一個有效的日期。這就是我們的代碼所做的,但是你的配置更加可配置,所以+1 :) – greg0ire 2011-04-18 14:57:48

1

沒有必要使用自定義的驗證類:你可以簡單地覆蓋傳遞到你綁定的污點值()方法:

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

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

似乎很簡單。 +1 – greg0ire 2011-06-09 14:29:59

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); 

希望這有助於某人。

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。

+0

+1,這是def最好的解決方案。保持表單層的邏輯,而不需要自定義驗證。但是你仍然要確保一致的驗證和存儲。 – 2013-10-17 23:47:51