SALT > Manuel > Tutoriel > Affichage >
Le framework SALT permet de simplifier l'affichage des données provenants des objets mappés

Le formatage des objets fait intervenir plusieurs classes :

VIEW et FORM

Tout d'abord il faut définir le comportement global que l'on souhaite avec ViewControl
Ce format se déclare en général une fois en haut de la page et il reste en place pour la page tant qu'on n'en appelle pas un autre.
Il existe 3 formats dans ViewControl (correspondant à 3 méthodes de même nom dans les classes DAOConverter) :
Puis on a la méthode d'affichage locale de chaque champ.
Cette méthode est à écrire à chaque fois, pour chaque champ à afficher.
On peut choisir entre 2 méthodes : Lors de l'affichage d'une valeur, les méthodes de la classe fille de DAOConverter suivantes seront appelées en fonction de ViewControl et de VIEW/FORM.
 Méthode DAOConverter
ViewControl VIEW FORM
text() text($value) (A) text($value) (B)
show() show(text($value))) (C) show(text($value)) (D)
edit() show(text($value)) (E) edit(show(text($value))) (F)
Quelques cas d'utilisation permettant de comprendre comment lire le tableau :

Avec ce mécanisme qui peut paraitre un peu complexe, on peut plus facilement factoriser les pages d'affichage et de modification des données :
<?php
// ------- object_edit.php : page de modification
ViewControl::edit();
include 
'_display.php';

// ------- object_show.php : page d'affichage
ViewControl::show();
include 
'_display.php';

// ------- _display.php : page interne affichant les champs
echo $monObjet->VIEW->champEnReadOnly;  // La valeur du champ sera affichée, meme avec ViewControl::edit();
echo $monObjet->FORM->champ;            // Le formulaire du champ ne sera affichée que si ViewControl::edit(),
                                        // sinon ce sera sa valeur, comme si on avait utilisé $monObjet->VIEW->champ

Formatage par défaut

Les méthodes de formatages se trouvent dans la classe DAOConverter.
On décrit ci dessous le comportement par défaut des 3 méthodes de formatage suivantes : text(), show(), edit()

text()

<?php
class DisplayTest extends Base {
    const 
STATUS_NEW 0;
    const 
STATUS_OLD 1;

    function 
metadata() {
        
parent::MODEL()
        ->
registerFields(
            
Field::newNumber('status''Status'FALSEself::STATUS_NEW, array(
                
self::STATUS_NEW => 'Nouveau',
                
self::STATUS_OLD => 'Ancien',
            )),
            
Field::newDate('date''Date'SqlDateFormat::TIMESTAMP'd/m/Y'),
            
Field::newBoolean('response''Réponse')
        );
    }
}

$dt = new DisplayTest();
$dt->status DisplayTest::STATUS_OLD;
$dt->date 499134060;
$dt->response TRUE;

ViewControl::text();

echo 
'Object values : <br/>';
var_dump($dt->status); echo '<br/>'// affiche     int(1)
var_dump($dt->date); echo '<br/>'// affiche       int(499134060)
var_dump($dt->response); echo '<br/>'// affiche   bool(true)

echo 'Object values with text format : <br/>';
var_dump($dt->VIEW->status); echo '<br/>'// affiche    string "Ancien"
var_dump($dt->VIEW->date); echo '<br/>'// affiche      string "26/10/1985"
var_dump($dt->VIEW->response); echo '<br/>'// affiche  int(1)

show()

La méthode show() se contente d'échapper le retour de la fonction text() pour un affichage HTML. <?php
$city 
= new City();
$city->city_name='Ville <b>moderne !</b>';

ViewControl::text();
echo 
$city->VIEW->city_name.'<br/>'// affiche "Ville moderne !" avec "moderne !" en gras, les balises <b> n'étant pas échappées

ViewControl::show();
echo 
$city->VIEW->city_name.'<br/>'// affiche "Ville <b>moderne !</b>"

edit()

A noter que si la valeur du champ est présente dans $_GET ou $_POST (en fonction du type du formulaire), elle sera prioritaire par rapport à la valeur de l'objet et sera utilisée à la place, y compris pour cocher ou non une case à cocher ou pour sélectionner un élément dans une liste déroulante (SELECT).

COLUMN / column()

La méthode MonObjet::COLUMN()->column permet d'afficher un texte représentant un champ.
Cela se traduit par l'appel de la méthode column() sur le DAOConverter.

Par défaut, la méthode column() renvoi le texte associé au champ, c'est-à-dire le 2ème paramètre des méthodes Field::newXXX() utilisées dans la méthode metadata() pour décrire l'objet mappé.
<?php
class DisplayTest extends Base {
    function 
metadata() {
        
parent::MODEL()->registerFields(
            
// Définition du texte correspondant au champ
            
Field::newDate('date''Date de modification'SqlDateFormat::TIMESTAMP'd/m/Y'),
        );
    }
}

// Plusieurs possibilités existent pour l'appel à COLUMN, qui affichera "Date de modification" :
echo DisplayTest::COLUMN()->date// Utilisation de la méthode statique, mais on doit spécifier les parenthèses
echo DisplayTest::singleton()->COLUMN->date// Utilisation de l'accesseur, les parenthèses sont facultatives mais on doit réaliser l'appel sur une instance de l'objet
On peut également passer un 2ème paramètre $format : DisplayTest::COLUMN($format)->$fieldName qui sera propagé jusqu'à la méthode formatage qu'on peut surcharger : public function column(Base $object, Field $field, $value, $format, $params)

SQL / sql()

La méthode MonObjet->SQL->column permet de convertir le champ pour une utilisation dans une requête SQL avec l'API SQL.
Cela se traduit par l'appel de la méthode sql() sur le DAOConverter.
Par défaut les seules conversions effectuées sont : Un exemple est disponible dans l'API SQL.

set avec FORM / setterInput()

Il est également possible d'appeler la méthode MonObjet->FORM->column = ... pour modifier la valeur d'un objet à partir d'une valeur provenant d'un formulaire.
Cela se traduit par l'appel de la méthode setterInput() sur le DAOConverter.
Par défaut les conversions effectuées sont : Il est conseillé d'utiliser cette méthode lorsqu'on modifie une valeur depuis un formulaire, cela permet d'éviter de faire des conversions dans la page du formulaire.
Par exemple, pour un champ date : <?php
if ($Input->P->ISSET->submit) {
    
$monObjet->date $Input->P->RAW->date// ne fonctionne pas : la valeur saisie est au format DD/MM/YYYY, alors que la valeur
                                            // stockée dans l'objet est au format TIMESTAMP
    
$monObjet->FORM->date $Input->P->RAW->date// fonctionne correctement, le champ sera converti en TIMESTAMP avant d'être affecté à l'objet

    
$monObjet->FORM('Y/m/d')->date2$Input->P->RAW->date2// Si on utilise un format spécifique, il suffit d'utiliser le même format
                                                            // et la conversion en tiendra compte
}
?>
...
Date : <?= $monObjet->FORM->date// affichage de l'input date ?>
Date2 : <?= $monObjet->FORM('Y/m/d')->date2// affichage d'un input date avec un format spécifique ?>

chargement d'objet / setterDB()

Lorsqu'on charge un objet depuis la base de données, chaque valeur est convertie avec un appel à la méthode setterDB.
Par défaut, on réalise les opérations suivantes :

set / setter()

Lorsqu'on modifie la valeur d'un champ directement, chaque valeur est convertie avec un appel à la méthode setter.
Par défaut on ne réalise aucune conversion.

Spécification du format

On peut passer un paramètre à la méthode VIEW, FORM, SQL ou COLUMN afin de surcharger le format d'affichage.
Ce qu'on appelle format d'affichage ici est une nouvelle notion qui n'a rien à voir avec text/show/edit ou form/view.

Le format d'affichage est un paramètre qui est propagé jusqu'aux méthodes de formatage et qui peut influencer leur comportement.

Il existe 2 types de formats d'affichage qui influencent le formatage par défaut présenté dans les méthodes précédentes: <?php
class DisplayTest extends Base {
    const 
STATUS_NEW 0;
    const 
STATUS_OLD 1;

    function 
metadata() {
        
parent::MODEL()
        ->
registerFields(
            
Field::newNumber('status''Status'FALSEself::STATUS_NEW, array(
                    
self::STATUS_NEW => 'Nouveau',
                    
self::STATUS_OLD => 'Ancien',
            )),
            
Field::newDate('date''Date'SqlDateFormat::TIMESTAMP'd/m/Y'),
            
Field::newText('text''Texte')
        );
    }
}

ViewControl::show();

$dt = new DisplayTest();
$dt->status DisplayTest::STATUS_OLD;
$dt->text 'OLD<NEW';
$dt->date 499134060;

echo 
$dt->VIEW->date.'<br/>'// affiche "26/10/1985"
echo $dt->VIEW('d/m/Y H:i:s')->date.'<br/>'// affiche "26/10/1985 01:21:00"

echo $dt->VIEW->status.'<br/>'// affiche "Ancien"
echo $dt->VIEW(FormHelper::RAW)->status.'<br/>'// affiche 1, ce qui a l'air équivalent à $dt->status

echo $dt->VIEW->text.'<br/>'// affiche "OLD<NEW"
echo $dt->VIEW(FormHelper::RAW)->text.'<br/>'// affiche "OLD<NEW" ... mais n'est PAS équivalent à $dt->text car le
                                               // texte est quand même échappé pour un affichage HTML !
echo $dt->text.'<br/>'// affiche OLD... et casse le reste de la page en affichant une balise HTML "<NEW",
                        // le champ n'étant pas échappé pour un affichage HTML

Surcharge des méthodes

Il est possible de sucharger les méthodes de la classe DAOConverter pour chaque objet mappé en définissant une classe MonObjetDAOConverter pour l'objet MonObjet
MonObjetDAOConverter doit être une classe fille de DAOConverter.
<?php
class DisplayTest extends Base {
    function 
metadata() {
        
parent::MODEL()->registerFields(
            
Field::newNumber('id''ID'FALSE),
            
Field::newText('text''Texte')
        );
    }
}

// Définition du DAOConverter
class DisplayTestDAOConverter extends DAOConverter {
    public function 
text(Base $objectField $field$value$format$params) {
        
// On peut redéfinir completement une méthode, ici on entoure chaque valeur de parenthèses
        
return '('.parent::text($object$field$value$format$params).')';
    }

    public function 
show(Base $objectField $field$value$format$params) {
        
$In In::getInstance();
        switch(
$field->name) {
            case 
'id':
                
// on peut aussi ne modifier l'affichage que d'un champ spécifique en filtrant par $field->name
                // Ici va afficher un lien vers la page de consultation d'un ID plutot que d'afficher un simple ID
                
return '<a href="'.WEB_RELATIVE.'examples/display/answer.php?id='.$In->URL($value).'">'.
                                
parent::show($object$field$value$format$params).'</a>';
            break;
        }
        return 
parent::show($object$field$value$format), $params;
    }
}

$dt = new DisplayTest();
$dt->id 42;
$dt->text 'OLD<NEW';

echo 
$dt->VIEW->text.'<br/>'// affiche "(OLD<NEW)"
echo $dt->VIEW->id// affiche un lien vers "examples/display/answer.php?id=42" avec pour texte "(42)"
Il est important de comprendre la différence entre text() et show() :
Dans l'exemple précédent, il aurait été impossible de générer un lien HTML dans la méthode text() car le retour de la méthode text() sera échappé en HTML dans show(). Il se serait donc affiché le code du lien et non un lien fonctionnel.

alert Il est fortement recommandé d'appeler les méthodes parentes parent::text(), parent::show(), parent::edit() lors de leur surcharge afin de conserver le formatage par défaut.
alert En cas de surcharge de parent::show et parent::edit le retour DOIT être une chaîne où toutes les variables sont filtrées et échappées pour un affichage HTML. La classe In est faite pour ca

Un autre exemple permettant d'introduire un 2ème niveau de condition :
Imaginons qu'on souhaite afficher un lien vers un ID, mais qu'on veux pouvoir afficher aussi l'ID tout seul sans lien :
On va utiliser le paramètre $format qui est propagé jusqu'aux méthodes de formatage : <?php
    
...
    public function 
show(Base $objectField $field$value$format$params) {
        
$In In::getInstance();
        switch(
$field->name) {
            case 
'id':
                if (
$format === 'link') {
                    return 
'<a href="'.WEB_RELATIVE.'examples/display/answer.php?id='.$In->URL($value).'">'.
                                
parent::show($object$field$value$format$params).'</a>';
                }
            break;
        }
        return 
parent::show($object$field$value$format$params);
    }
...

echo 
$dt->VIEW->id// affiche l'ID sans lien
echo $dt->VIEW('link')->id// affiche un lien vers "examples/display/answer.php?id=42" avec pour texte "(42)"

Enfin, si on souhaite accéder à plusieurs champs pour construire l'affichage d'un champ, c'est possible puisque chaque méthode à en paramètre l'objet Base sur lequel on a appliqué la méthode de formatage.

Appels internes

Le schéma ci-dessous présente les interactions de la classe DAOConverter avec les autres classes.
daoconverter