Voici donc un petit tutoriel pour créer et appeler un filtre qui implémente Zend_Filter_Interface, et peut donc être traité comme tout Zend_Filter.
On y utilise Zend_Date et les constantes de date.
On crée le filtre (attention aux commentaires) :
class Web82_Filter_Date implements Zend_Filter_Interface { /** * format d'entrée * * @var string */ public $fromFormat ; /** * format de sortie * * @var string */ public $toFormat ; /** * contantes de formats de date * * Il est bien sûr possible d'en créer d'autre à loisir */ const DATETIME = 'yyyy-MM-dd HH:mm:ss' ; const DATE = 'yyyy-MM-dd' ; const SIMPLE_DATE = 'dd/MM/yyyy' ; const FULL_DATE = 'dd/MM/yyyy HH:mm:ss' ; const FULL_DATE_NO_SEC = 'dd/MM/yyyy HH:mm' ; const TIME = 'HH:mm:ss' ; const HOUR = 'HH:mm' ; const YEAR = 'yyyy' ; /** * constructeur * * @param string|array $fromFormat * @param string $toFormat */ public function __construct ( $fromFormat , $toFormat = NULL ) { /** * cas d'appel dans un fichier ini */ if ( is_array ( $fromFormat ) ) { $this -> fromFormat = $fromFormat[ 'from' ] ; $this -> toFormat = $fromFormat[ 'to' ] ; } /** * cas d'appel aux constantes */ else { $this -> fromFormat = $fromFormat ; $this -> toFormat = $toFormat ; } } /** * formate la date * * @param string|integer $date * @return string|integer */ public function formatConverter ( $date ) { /** * instanciation d'un objet date */ $dateObject = new Zend_Date() ; /** * on lui passe éventuellement une locale du registre */ if ( Zend_Registry::isRegistered ( 'Zend_Locale' ) ) { $dateObject -> setLocale ( Zend_Registry::get ( 'Zend_Locale' ) ) ; } /** * la date n'est pas valide, on retourne NULL * (on pourrait lancer une exception à la place) */ if ( ! $dateObject -> isDate ( $date , $this -> fromFormat ) && ! $dateObject -> isDate ( $date , $this -> toFormat ) ) { return NULL ; } /** * elle est valide */ /** * on assigne la date à l'objet Zend_Date */ /** * dans le cas où la date est déjà dans le format de sortie */ if ( $dateObject -> isDate ( $date , $this -> toFormat ) ) { $dateObject -> setDate ( $date , $this -> toFormat ) ; } /** * sinon, nous avons déjà vérifié que la date était soit au format d'entrée, soit au format de sortie */ else { $dateObject -> setDate ( $date , $this -> fromFormat ) ; } /** * et on retourne la chaîne date formatée */ return $dateObject -> toString ( $this -> toFormat ) ; } /** * filtre * * @param mixed $date * @throws Zend_Filter_Exception If filtering $value is impossible * @return mixed * @see Zend_Filter_Interface::filter() */ public function filter ( $date ) { return $this -> formatConverter ( $date ) ; } }
On peut ensuite appeler ce filtre au sein de l'application, même dans la définition d'un formulaire. Par exemple pour convertir un DATETIME ou TIMESTAMP MySql en jj/mm/aaaa, on utilise le format d'entrée DATETIME et le format de sortie SIMPLE_DATE (voir les formats dans la classe du filtre) :
$dateFilter = new Web82_Filter_Date ( Web82_Filter_Date :: DATETIME , Web82_Filter_Date :: SIMPLE_DATE ) ; /** * Si $dateFromDb est '2011-08-26 14:00:00' * alors $dateToDisplay sera '26/08/2011' */ $dateToDisplay = $dateFilter -> filter ( $dateFromDb ) ;
On peut aussi le définir directement avec les formats dans un .ini de formulaire :
... myForm.elements.dateElement.options.filters.Date.filter = "Date" myForm.elements.dateElement.options.filters.Date.options.from = "yyyy-MM-dd HH:mm:ss" myForm.elements.dateElement.options.filters.Date.options.to = "dd/MM/yyyy" ...
Le premier argument du constructeur du filtre sera alors traité comme un tableau, et les clés "from" et "to" seront assignées respectivement au variables $fromFormat et $toFormat.
Voilà, c'est tout !
Pour créer d'autres constantes dans votre filtre, voir celles qui sont dans la documentation de ZF
Merci de laisser vos commentaires !
Edit: j'ai remplacé tous les "YYYY" par des "yyyy" afin de supprimer les problèmes d'année dus à l'ISO 8601
RépondreSupprimerIl y a un souci avec le test des lignes 103 à 106, dans le cas où on souhaiterait passer d'une date anglo-saxonne (MM/dd/yyyy) à une date française (dd/MM/yyyy) ou l'inverse. Certaines dates (ex: 12/11/2012) peuvent être considérées à tort comme étant déjà dans le format de sortie.
RépondreSupprimerAh oui, c'est pas faux ;)
SupprimerIl est vrai que j'avais plutôt pensé la chose en entrée ou sortie de BDD.
Je vais y réfléchir.