13 de abr de 2012

Symfony - Validação de datas com sfForm

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 sfValidatorCallback ou talvez o hook de postValidator.

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


class MyEntityForm extends MyEntityBaseForm {

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

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

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

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

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

29 de jan de 2012

Enviar informações do controller para o layout no Symfony 1.x

Esses dias precisei enviar/configurar uma variável do controller para o layout, ao contrário de enviar do controller para a respectiva visão deste, que é o mais normal, após pesquisar vi que uma maneira de fazê-lo é usando os slots, como pode ser visto neste link, no exemplo da documentação, ele cita um exemplo de uso para áreas do site, o que também é interessante.

Para usar é simples, basta configurar a variável no controller conforme abaixo:

$this->getResponse()->setSlot('myKey', $myVar);

e recuperá-la no layout como abaixo:

$myVar = get_slot('myKey', 'myDefaultValue');

simples e funcional.

Fica a dica.

4 de jan de 2012

Symfony: Problema com dados na view (escape)

Dica rápida: já havia usado isso algumas vezes, mas nunca catalogava como snippet ou algo semelhante, hoje precisei novamente e encontrei o link abaixo explicando como obter valores brutos na view.

Veja o post clicando aqui.

10 de abr de 2011

Envio de e-mail com Symfony em desenvolvimento

Se você já precisou testar envios de e-mail com o Symfony, já deve ter esbarrado com as configurações do mailer no factories.yml, por padrão, a entrega de e-mails no ambiente dev é desabilitada, uma dica interessante, é usar a estratégia de entrega para somente um e-mail, assim, independente de qual endereço estiver recebendo o e-mail, sempre será entregue para o endereço configurado no factories.yml, conforme exemplo abaixo:

dev:
mailer:
param:
delivery_strategy: single_address
delivery_address: 'meu.email@meu.host.com'

"Descobri" esse single_address navegando aqui.

3 de fev de 2011

Singleton extensível

Dica rápida, se você pretende implementar um singleton para ser extendido, conforme o normalmente utilizado:


abstract class App_Model_Abstract {

protected static $_instance = null;

protected function __construct() {

}

public static function getInstance() {
if (self::$_instance === null) {
self::$_instance = new self();
}
return self::$_instance;
}

final private function __clone() {

}
}


você terá problemas, pois ao tentar recuperar uma instância das classes filhas:


ClasseFilha::getInstance();


você estará na verdade recuperando uma instância da classe pai, tirando o fato dela ser abstrata. Para que funcione conforme esperado precisariamos fazer:


abstract class App_Model_Abstract {

protected function __construct() {

}

final public static function getInstance() {
static $aoInstance = array();

$calledClassName = get_called_class();

if (!isset($aoInstance[$calledClassName])) {
$aoInstance[$calledClassName] = new $calledClassName();
}

return $aoInstance[$calledClassName];
}

final private function __clone() {

}
}



Fica a dica!

22 de set de 2009

Poster de Zend Framework da MayFlower

Esses dias (ok, faz um tempinho hehe) recebi meu poster de Zend Framework que encomendei gratuitamente no site da MayFlower, e como eles solicitam, nada mais justo, coloco aqui meus agradecimentos e a foto com o poster recebido.

Obrigado MayFlower.
Thanks MayFlower! :D

11 de jul de 2009

Zend_Form: Como renderizar individualmente label e elemento / campo.

[post_rapido]
Esses dias precisei de um layout de form mais elaborado, e pra não perder as funcionalidades do Zend_Form, pesquisei sobre formas de renderizar um label e um elemento/campo individualmente.
Segue a dica:

[code]
// Renderiza o label do elemento "meuCampo"
echo $form->meuCampo->renderLabel()
// Renderiza o input do elemento "meuCampo"
echo $form->CAMPO->renderViewHelper()
[/code]
[/post_rapido]


Malz ai que o Blogger não tem code highlight! :D

3 de abr de 2009

Net Negative Producing Programmer

Muito bom esse post do Akita, recomendo a leitura a programadores e coordenadores/gerentes.