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.