sábado, 29 de maio de 2010

Que tal uma validação de dados "universal" para a comunidade php?

Validação de dados é um tema que sempre gera alguma controvérsia. Alguns acham que ela tem que ser feita na action, outros em uma camada de serviço ou de aplicação e outros no modelo. A maioria das pessoas também concorda que ela deva ser feita no browser. Neste texto pretendo examinar um pouco este assunto e sugerir a necessidade de se ter um componente de validação de dados para php como um projeto independente de qualquer framework ou camada.

Esses dias li um artigo interessante que diz que ao mesmo tempo que a comunidade ruby está caminhando para um único padrão forte de framework com muita convenção sobre conficuração, a comunidade php está caminhando para retirar a "mágica" dos códigos focando em padrões de projeto e OO, ter mais de um framework robusto e buscar ter interoperabilidade entre os frameworks. Achei isso muito bom. Pela minha experiência vejo que esses comportamentos "mágicos" dos frameworks costumam embaralhar muito a cabeça dos programadores mais jóvens.

Nesse rumo também vemos que algumas ferramentas estão amadurecendo muito e buscando encontrar o seu foco principal, removendo tudo aquilo que foge a esse foco. O Doctrine 2, por exemplo, que é um projeto que venho estudando, não vem com componente de validação integrado na versão 2. No início fiquei bem chateado com isso pois gostava muito de definir já algumas restrições no yml e já ter essa validação prontinha pra mim. Mais depois consegui perceber que o foco de um ORM não é esse e acho que se cada ferramente se manter no seu foco ela tem mais sucesso de prosperar.

Além disso se examinarmos um pouco mais, como já falei antes, dependendo da arquitetura uns acham melhor ter a validação no modelo, outros no JS, outros na action, etc... Não quero nesse texto ficar discutindo o que é melhor. Eu mesmo acho que isso varia de sistema pra sistema. Mas se percebemos bem essas necessidades vemos que a comunidade se beneficiará muito de ter uma ferramenta de validação de dados como sendo uma biblioteca completamente isolada. Assim ela poderá ser utilizada com qualquer framework e em qualquer camada. Claro que podem ser definidos adaptadores para integrar essa ferramenta em um lugar ou outro, mas o cerne dela deve ser "puro".

O meu pensamento é que se tivermos um arquivo de definição de dados, ele possa ser lido e usado para validar tanto um entidade na camada de modelo quanto um formulário no javascript. Com isso criamos um padrão de formato de dados que pode ser uma ótima contribuição nessa filosofia de ter ferramentas que podem ser usados nos diversos frameworks e camadas.

Algumas coisas eu acho interessante que essa ferramenta tenha:
  • Extensibilidade. Esse é um dos pontos principais. Deve ser muito fácil acrescentar um novo tipo de dados e também a classe ou método para validar este tipo. Além disso pode ser útil ter um sistema para registrar listeners que recebem eventos durante o processo de validação extendendo ou sobreescrevendo algum comportamento.
  • Facilidade de configuração. Geralmente as mensagens de erro lançados por estas ferramentas já atendem nos casos mais simples. Então é necessário poder trocar as mensagens de erro de cada validação e também poder capturar um erro e sobreescrever a mensagem para casos específicos.
  • Trabalhar com objetos/arrays multidimensionais. Esse é um dos pontos onde a maioria das ferramentas do "mercado de software livre" não atende. Acho importanto poder dizer que dentro do dado que eu quero validar pode ter um array e que cada item "nome" desse array pode ter no máximo 15 caracteres.
  • Ter um formato que pode ser compartilhado entre servidor e browser. É um fato que o servidor tem que ter validação para termos os dados íntegros. Também é um fato que uma validação no JS melhora a experiência do usuário e diminui o trafego entre cliente e servidor. E muitas vezes a validação nos dois pontos é a mesma. Por isso é importante que a definição da validação possa ser usada pelo browser em uma api semelhante à usada no servidor.
São poucos formatos que atendem a todas essas demandas. Um formato que achei bem interessante para o que já desenvolvi até agora é o Json Schema:

http://groups.google.com/group/json-schema/web/json-schema-proposal-working-draft

http://tools.ietf.org/html/draft-zyp-json-schema-02

Mas com certeza existem outros. O que quero ressaltar aqui é exatamente a necessidade da existência de uma ferramenta como essa. Tendo algo assim separado de frameworks, a comunidade pode juntar esforços para contribuir melhorando cada vez mais os algorítmos de validação e ampliando cada vez mais os tipos de dados disponíveis.

quarta-feira, 19 de maio de 2010

Alterando uma informação automáticamente antes do update no doctrine 2. (com annotations)

1 - Definimos que a classe ouve os callbacks:

/**
* @Entity
* @HasLifecycleCallbacks
*/

2 - Definimos um método para ser atualizado antes do update.

/**
* @PrePersist @PreUpdate
*/

function updateUpdatedAt() {
$this->updatedAt = new DateTime();
}


3 - Lembrar de mandar construir os modelos novamente.