Zend_Db_Table_Row : transformer les colonnes de type date en objet Zend_Date

Logo Zend Framework

Le module Active Record de Rails convertit les colonnes de type date en instance de la class Date de Ruby. On peut très simplement faire la même chose avec Zend_Db_Table_Row. Il suffit de surcharger la méthode magique __get.

class Wiip_Db_Table_Row_Abstract extends Zend_Db_Table_Row_Abstract
{
    public function __get($columnName)
    {
        $m = $this->_table->info('metadata');
 
        if (isset($m[$columnName])) {
            $value = $this->_data[$columnName];
            switch ($m[$columnName]['DATA_TYPE']) {
                case 'date':
                    if ($value and ($value != '0000-00-00')) {
                        $date = new Wiip_Date($value, Zend_Date::ISO_8601);
                        $date->setTime('00:00:00');
                        return $date;
                    } else {
                        return null;
                    }
                    break;
 
                case 'datetime':
                    if ($value and ($value != '0000-00-00 00:00:00')) {
                        return new Zend_Date($value, Zend_Date::ISO_8601);
                    } else {
                        return null;
                    }
                    break;
 
                default:
                    return parent::__get($columnName);
            }
        } else {
            return parent::__get($columnName);
        }
    }
}

Pour les champs de type date j'utilise une classe dérivée de Zend_Date car la méthode __toString de cette dernière renvoie la date avec l'heure. La classe ci-dessous modifie ce comportement pour renvoyer uniquement la partie date.

class Wiip_Date extends Zend_Date
{
    public function __toString()
    {
        return $this->toString(Zend_Date::DATE_MEDIUM);
    }
}

Une fois ce code mis en place, on peut utiliser des objets dérivés de Wiip_Db_Table_Row_Abstract de façon très intuitive :

echo $row->date; // Affiche par exemple 6 juin 2009
 
if ($row->date->isToday()) {
  echo 'Aujourd\'hui';
} else {
  echo $row->date;
}
 
$today = new Zend_Date();
if ($row->date->isEarlier($today)) {
  echo 'En retard';
}
 
echo $row->datetime; // Affiche par exemple 6 juin 2009 15:59:33

Si vous avez besoin d'obtenir la valeur de la colonne telle qu'elle est renvoyée par la base de données, vous pouvez passer par la méthode toArray qui n'est pas affectée par notre surcharge de __get.

$data = $row->toArray();
echo $data['date']; // Affiche 2009-06-06

Comme vous vous servez certainement de cette méthode pour charger les données dans vos formulaires basés sur Zend_Form (avec par exemple $form->setDefaults($row->toArray()) ou $form->populate($row->toArray()), le fonctionnement de ces derniers ne sera pas perturbé.

A lire également

Portrait de Anonyme

Niveau performance Zend_Date

Niveau performance Zend_Date est très gourmand non ?
N'y a t il par un risque de perdre beaucoup ?

Portrait de Maxence Delannoy

Déjà, il faut activer le

Déjà, il faut activer le cache pour Zend_Date (Zend_Date::setOptions(array('cache' => $adapter));). Ensuite, tout dépend de l'application. Mais dans les cas où la performance est critique, on récupérera certainement plutôt les résultats sous la forme d'un tableau et on ne passera donc pas par Zend_Db_Table_Row. Autre alternative, on peut utiliser la classe PHP DateTime (disponible depuis PHP 5.2.0) qui devrait être plus rapide, puisque c'est en natif dans PHP (d'ailleurs, cet article semble confirmer ce point).
Portrait de Anonyme

je trouve cette astuce trés

je trouve cette astuce trés interressante ( de plus, jai fait d'autres cas propres à mes besoins). Seulement je n'arrive pas à l'utiliser. Toute mes tables sont déclarées en extend de zend_db_table_extract. Ou est ce que je lui dit d'utiliser Wiip_Db_Table_Row_Abstract (Je précise, je débute en zend)

merci de votre aide

Poster un nouveau commentaire

Le contenu de ce champ ne sera pas montré publiquement. If you have a Gravatar account, used to display your avatar.
  • Les adresses de pages web et de messagerie électronique sont transformées en liens automatiquement.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Les lignes et les paragraphes vont à la ligne automatiquement.
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>. The supported tag styles are: <foo>, [foo].

Plus d'informations sur les options de formatage

CAPTCHA
La vérification ne tient pas compte des minuscules ou des majuscules.
Image CAPTCHA
Enter the characters shown in the image.