Symfony - Validação de datas com sfForm
Autor: Arian Maykon de Araújo Diógenes | Publicado: 2012-04-13T06:20:00-03:00

Esses dias precisei implementar uma validação de datas de início e fim com os validators de forms do Symfony, onde, obviamente, a data de fim tem que ser maior (ou igual, neste caso) a data de início. Neste caso, eu recebo as datas no formato "dd/mm/aaaa - HH:MM", portanto foi preciso configurar também o formato de datas de entrada para o validator. Validação com Symfony é muito simples, e ele já configura uma validação padrão, conforme o mapeamento das entidades, já validando por tipo entre outros.

No form de exemplo abaixo, pode ser notado os 2 campos de data início (dtini) e fim (dtfim), onde configuro inicialmente o validator de data e hora (sfValidatorDateTime) para ambos, informando nas opções que a data mínima (min) aceita é o dia atual, na primeira hora do dia, que deverá ser fornecido a hora (with_time), o formato de exibição da data inválida em caso de erro (date_format_range_error), o formato de saída da data pós validação para gravação no banco (datetime_output) e o formato de entrada de data (date_format).

Com isso já temos os 2 campos de datas sendo criticados de forma que o usuário não preencha uma data anterior a hoje, para fazer com que a data final seja validada como maior ou igual a data inicial, utilizei o método bind, já que na instanciação e configuração do form, não temos como ter acesso ao valor submetido. No bind, obtenho então o valor da data inicial, e configuro como sendo a data mínima do validator da data final, pronto!

Uma outra possível alternativa é utilizar o&nbsp;sfValidatorCallback ou talvez o hook de postValidator.

Caso visualizem formas melhores de fazer o mesmo, indiquem nos comentários.



class MyEntityForm extends MyEntityBaseForm {

&nbsp; &nbsp; public function configure() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$dtInput = new sfWidgetFormInputText(array(), array(
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'size' =&gt; 14,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'maxlength' =&gt; 10
&nbsp; &nbsp; &nbsp; &nbsp; ));
&nbsp; &nbsp; &nbsp; &nbsp; $this-&gt;setWidget('dtini', $dtInput);
&nbsp; &nbsp; &nbsp; &nbsp; $this-&gt;setWidget('dtfim', $dtInput);

&nbsp; &nbsp; &nbsp; &nbsp; // Validators
&nbsp; &nbsp; &nbsp; &nbsp; // Recebo as datas no formato dd/mm/aaaa - hh:mm (d/m/Y - H:i)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$options = array(
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'min' =&gt;&nbsp;date('Y-m-d') . ' 00:00:00',
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'with_time' =&gt; true,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'date_format_range_error' =&gt; 'd/m/Y',
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'datetime_output' =&gt; 'Y-m-d H:i:s',
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'date_format' =&gt; '~(?P\d{2})/(?P\d{2})/(?P\d{4})\ \-\ (?P\d{2}):(?P\d{2})~'
&nbsp; &nbsp; &nbsp; &nbsp; );
&nbsp; &nbsp; &nbsp; &nbsp; $dtValidator = new sfValidatorDateTime($options);
&nbsp; &nbsp; &nbsp; &nbsp; $this-&gt;setValidator('dtini', $dtValidator);
&nbsp; &nbsp; &nbsp; &nbsp; $this-&gt;setValidator('dtfim', $dtValidator);

&nbsp; &nbsp; &nbsp; &nbsp; $this-&gt;getWidgetSchema()-&gt;setLabels(array(
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'dtini' =&gt;&nbsp;'Data Início',
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'dtini' =&gt;&nbsp;'Data Fim'
&nbsp; &nbsp; &nbsp; &nbsp; ));
&nbsp; &nbsp; }

&nbsp; &nbsp; /**
&nbsp; &nbsp; &nbsp;* (non-PHPdoc)
&nbsp; &nbsp; &nbsp;* @see lib/vendor/symfony/lib/form/sfForm#bind($taintedValues, $taintedFiles)
&nbsp; &nbsp; &nbsp;*/
&nbsp; &nbsp; public function bind(array $taintedValues = null, array $taintedFiles = null) {
&nbsp; &nbsp; &nbsp; &nbsp; $dtIni = isset($taintedValues['dtini'])?$taintedValues['dtini']:null;
&nbsp; &nbsp; &nbsp; &nbsp; if ($dtIni) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $dt = DateTime::createFromFormat('d/m/Y - H:i', $dtIni);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $this-&gt;getValidator('dtfim')-&gt;setOption('min',
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$dt-&gt;format('Y-m-d H:i:s'));
&nbsp; &nbsp; &nbsp; &nbsp; }

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