Filtro de modelo genérico de lítio
Pergunta
Atualmente, estou desenvolvendo um aplicativo de lítio que requer que várias coisas sejam adicionadas a um objeto antes que save() seja chamado.
Idealmente, eu seria capaz de escrever um filtro para aplicar à classe Model (o modelo base que outros modelos estendem), como o seguinte:
Model::applyFilter('save', function($self, $params, $chain) {
// Logic here
});
Isso é possível?Em caso afirmativo, deveria ser um arquivo inicializado?
Solução
Se não estou entendendo mal o que você está dizendo, você deseja, por exemplo, adicionar automaticamente um valor para 'criado' ou 'modificado' a um objeto antes de salvar.
Veja como eu faço isso.
Do meu extensions/data/Model.php
<?php
namespace app\extensions\data;
use lithium\security\Password;
class Model extends \lithium\data\Model {
public static function __init() {
parent::__init();
// {{{ Filters
static::applyFilter('save', function($self, $params, $chain) {
$date = date('Y-m-d H:i:s', time());
$schema = $self::schema();
//do these things only if they don't exist (i.e. on creation of object)
if (!$params['entity']->exists()) {
//hash password
if (isset($params['data']['password'])) {
$params['data']['password'] = Password::hash($params['data']['password']);
}
//if 'created' doesn't already exist and is defined in the schema...
if (empty($params['date']['created']) && array_key_exists('created', $schema)) {
$params['data']['created'] = $date;
}
}
if (array_key_exists('modified', $schema)) {
$params['data']['modified'] = $date;
}
return $chain->next($self, $params, $chain);
});
// }}}
}
}
?>
Eu tenho algum hash de senha lá também.Você pode remover isso sem afetar nenhuma funcionalidade.
Outras dicas
Os filtros não suportam herança*.
É melhor você usar OOP e ter um BaseModel
classe com um método save() substituído e da qual todos os modelos de seu aplicativo são herdados.
Uma outra maneira seria aplicar filtros preguiçosamente a cada modelo, em um arquivo inicializado.Por exemplo:
Filters::apply('app\models\Documents', 'save', $timestamp);
Filters::apply('app\models\Queries', 'save', $timestamp);
Filters::apply('app\models\Projects', 'save', $timestamp);
com $timestamp
um fechamento
* a herança dos filtros é planejado mas ainda não implementado