3 Stimmen

Wie kann man ein Datum ohne Tag mit sfForm validieren?

Ich erstelle ein Zahlungsformular mit Symfony 1.4, und mein Formular hat ein Datum-Widget wie folgt definiert, so dass der Benutzer das Ablaufdatum seiner Kreditkarte auswählen kann:

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

Beachten Sie das Fehlen von %day% im Format wie bei den meisten Zahlungsformularen.

Mein Problem ist nun, dass sfValidatorDate verlangt, dass das Feld "Tag" nicht leer sein darf. Um dies zu umgehen, habe ich einen benutzerdefinierten Validator mit einem Callback erstellt, der gut funktioniert:

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

Ich denke, dass es einen einfacheren Weg geben könnte, dies zu erreichen. Was meinen Sie dazu? Haben Sie dieses Problem bereits auf eine sauberere Weise gelöst?

3voto

Dziamid Punkte 10577

Wie speichern Sie das Datum? Wenn Sie nur Monat und Jahr als Ganzzahlen oder Strings speichern, dann können Sie nur 2 Auswahl-Widgets machen. Wenn Sie es aber als datetime (Zeitstempel) speichern, brauchen Sie sowieso ein gültiges Datum. Das bedeutet, dass Sie dem "Tag" automatisch Werte zuweisen müssen (normalerweise der erste oder letzte Tag des Monats).

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

1voto

Es besteht keine Notwendigkeit, eine eigene Validierungsklasse zu verwenden: Sie können die an Ihre bind()-Methode übergebenen Werte einfach überschreiben:

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

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

1voto

Andriy Leshchuk Punkte 466

Ich habe den einfachsten Weg gewählt, um den Verfallstag der Kreditkarte zu überprüfen:

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

Ich hoffe, das hilft jemandem.

1voto

daviz.villa Punkte 23

Ich löse dies zunächst in der Formularklasse

    $year = range(date('Y'), date('Y') - 50);

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

Nächste...

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

      parent::bind($taintedValues);
    }

Das Feld in der Datenbank hat den Datumstyp DATE.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X