Personnaliser ses formulaires issus des vues par défaut
-
Vues par défaut
Le framework fourni des vues par défaut (préparation des données + visualisation standardisée) pour éviter de reprogrammer des vues pour chacun de vos objets métier. Ces vues ont du coup un nombre de fonctionnalités pré-établies limitées, et s’appuient substantiellement sur les annotations qui accompagnent vos classes et objets métier.
Prenons pour exemple deux classes métier minimales mais présentant de nombreuses propriétés, qui dévrivent un véhicule et ses éléments :
Voiture :
<?php namespace ITRocks\Framework\Examples; use ITRocks\Framework\Dao\File; use ITRocks\Framework\Examples\Car\Element; use ITRocks\Framework\Traits\Has_Creation_Date_Time; use ITRocks\Framework\Traits\Has_Name; /** * An example car class */ class Car { use Has_Creation_Date_Time; use Has_Name; /** * @multiline * @var string */ public $description; /** * @link Map * @var Element[] */ public $elements; /** * @var File */ public $image; /** * @var File */ public $video; }
Élément :
<?php namespace ITRocks\Framework\Examples\Car; use Bappli\Sfkgroup\Webshop\Has_Code; use ITRocks\Framework\Traits\Has_Name; /** * A car element */ class Element { use Has_Code; use Has_Name; /** * @values front, rear * @var string */ public $position; /** * @values left, right * @var string */ public $side; }
Le formulaire d’ajout / modification proposé en standard, tenant compte des rares règles de gestion (typage) données par les propriétés concernées, sera :
/ITRocks/Framework/Examples/Car/add
Application des règles de gestion pour personnaliser la vue
Ajouter des annotations au niveau classe permet d’indiquer de quelle manière on souhaite organiser les données les unes par rapport aux autres, en créant des regroupements logiques dans le cas de classes comportant des propriétés aux usages diverses.
Par exemple :
Annotations pour
Car
:
/** * @display_order name, creation, description, elements, image, video * @group _top name * @group Description description, elements * @group Media image, video * @group Info creation */
On va ici :- indiquer quel est l’ordre d’affichage générique pour les champs dans un formulaire avec @display_order,
- proposer des regroupements de champs dans différents groupes avec @group :
_top
est le groupe principal, les “top-informations” seront mises à l’endroit le plus visible et accessible : en haut des formulaires,- Les trois autres groupes ont un nommage libre, on va donc classer nos propriétés par catégories. Dans le formulaire ça se traduira par la création d’onglets de regroupement.
- L’ordre des groupes va des données prioritaires aux moins importantes : on a mis par exemple Info en dernier, parce que ce groupe contient les données les moins importantes. S’agissant d’un groupe à nom libre, ce sera le dernier onglet dans le formulaire.
Le résultat suite à ces modifications est un formulaire hiérarchisé :
Les annotations au niveau propriété ajoutent également des comportements au niveau formulaire pour appliquer à ce niveau les règles de gestion qu’elles décrivent.
Ici on voit nettement l’application de l’annotation @var, la plus commune, par la présentation de composants adaptés au type de chaque propriété.
Pour
$description
à qui on a adjoint @multiline, on voit bien que le composant généré permet l’écriture sur plusieurs lignes. On a donc un<textarea>
alors que les autres propriétés en@var string
se traduisent en<input>
dans le formulaire.Autre exemple d’action sur l’affichage dans un formulaire : on peut choisir d’afficher un texte différent que le nom de la propriété sur le formulaire. Par exemple si on modifie la propriété
$image
:
/** * @alias web image * @var File */ public $image;
L’annotation @alias va modifier le nom affiché pour la propriété dans toutes les vues qui l’utilisent. Par exemple dans le formulaire de modification :
Conclusion
L’utilisation des annotations permet de s’affranchir du développement de vues / gabarits dans la plupart des cas : en décrivant précisémment les règles de gestion régissant l’organisation de vos propriétés et objets d’un point de vue métier, vous donnez au framework les clés pour que les vues standard s’approchent au mieux de la traduction visuelle du métier.Ces réglages au niveau annotations constituent le tronc commun à toutes les vues.
Application de règles par exception
Dans certains cas, on peut vouloir appliquer des règles de gestion ou d’organisation des données dans la vue différentes de celles énoncées dans les annotations de classes ou de propriétés.
On peut agir en modifiant les valeurs des annotations à la volée, dans le code, et activer ces modifications pour tout le reste de l’exécution du contexte (contrôleur) courant.
Par exemple si l’on veut que l’@alias “web_image” sur la propriété
$image
ne soit employé que dans le cas des formulaires, et n’affecte pas les autres contrôleurs, il faut le retirer de la déclaration de la propriété pour que les vues dans leur ensemble ne soient plus affectées :
/** * @var File */ public $image;
On peut alors programmer le contrôleur où l’on souhaite appliquer la personnalisation, par exemple le Add_Controller, pour modifier l’affichage et appliquer l’alias uniquement quand on est en formulaire d’ajout :
<?php namespace ITRocks\Framework\Examples\Car; use ITRocks\Framework\Controller\Parameters; use ITRocks\Framework\Reflection\Annotation\Property\Alias_Annotation; use ITRocks\Framework\Reflection\Reflection_Property; use ITRocks\Framework\Widget\Edit; /** * Car add controller */ class Add_Controller extends Add\Add_Controller { //----------------------------------------------------------------------------- getViewParameters /** * @param $parameters Parameters * @param $form array * @param $class_name string * @return mixed[] */ protected function getViewParameters(Parameters $parameters, array $form, $class_name) { $image = new Reflection_Property($class_name, 'image'); $image->setAnnotation('alias', new Alias_Annotation('web image', $image)); return parent::getViewParameters($parameters, $form, $class_name); } }
C’est la méthode getViewParameters du contrôleur standard qui fouille dans les annotations des propriétés pour en déduire les paramètres nécessaires à la génération de l’affichage. Modifier comme ici les annotations des classes ou des propriétés juste avant l’appel à getViewParameters@ permet d’affecter l’affichage.
Note : attention, on n’a modifié que le formulaire d’ajout. Dans l’absolu il serait cohérent, d’un point de vue métier, de faire la même personnalisation dans le formulaire d’affichage et le formulaire de modification. Pensez à mutualiser votre code et appliquez-le aux différents contrôleurs, donc, dans un cas comme celui-ci.
Voir aussi : [Reflection_Property, setAnnotation
Il est également possible de modifier une annotation existante. Prenons l’exemple du formulaire d’affichage d’un élément de voiture :
/ITRocks/Framework/Examples/Car/Element/add :
Exemple de contrôleur qui restreint les noms qu’on peut donner à un élément depuis un formulaire, alors que dans toutes les autres vues cette restriction ne s’applique pas, et que dans l’absolu en programmant on pourra rajouter d’autres noms (c’est un exemple, d’un point de vue métier il n’est pas conseillé de faire ce genre de choses).
<?php namespace ITRocks\Framework\Examples\Car; use ITRocks\Framework\Controller\Parameters; use ITRocks\Framework\Reflection\Annotation\Property\Values_Annotation; use ITRocks\Framework\Reflection\Reflection_Property; use ITRocks\Framework\Widget\Add; /** * Car element edit controller */ class Element_Add_Controller extends Add\Add_Controller { //----------------------------------------------------------------------------- getViewParameters /** * @param $parameters Parameters * @param $form array * @param $class_name string * @return mixed[] */ protected function getViewParameters(Parameters $parameters, array $form, $class_name) { $name = new Reflection_Property($class_name, 'name'); $name_values = Values_Annotation::of($name); $name_values->add('door'); $name_values->add('motor'); $name_values->add('wheel'); $name_values->add('window'); $name->setAnnotation($name_values); return parent::getViewParameters($parameters, $form, $class_name); } }
Le résultat sera :
Note : pour des raisons d’implémentation du cache d’annotations, dans le cas de la modification d’une annotation existante comme ici, l’annotation sera modifiée même si on n’écrit pas la ligne de code
$name->setAnnotation($name_values);
:- il ne faut donc jamais modifier une annotation au niveau global si on ne souhaite pas que cette modification ait des effets de bord sur la suite de l’exécution du script courant. Voir setAnnotationLocal pour ne modifier que des versions locales à l’objet de réflexion courant d’une annotation.
- Même si cet appel semble optionnel, il est impératif d’exécuter
$name->setAnnotation($name_values);
dans ce cas, donc setAnnotation de façon générale. D’une part l’implémentation du cache peut changer à l’avenir, d’autre part cela permet de repérer de manière explicite vos modifications d’annotations globales, qui doivent toujours être réfléchies en terme d’effets de bord car agissent sur le comportement jusqu’à la fin de l’exécution du clic courant.
S’agissant de modifications dynamiques des valeurs d’annotations, les comportements programmés ici sont donc prioritaires sur les annotations déclarées de manière statiques dans le phpdoc des classes et des propriétés.
Personnalisation des règles de gestion par l’utilisateur
Enfin les utilisateurs avancés de votre logiciel, si vous les y avez autorisé, peuvent personnaliser certaines vues à la volée, directement depuis le logiciel.
Ces modifications ne sont pas traduites en modification de valeurs d’annotations des propriétés, et elles sont prioritaires sur les deux manières vues ci-dessus de définir vos règles de gestion.
Les vues par défaut (et vos vues si vous avez programmé ces comportements) utilisent les classes héritées de Custom_Settings pour personnaliser l’affichage. Les données stockées dans les objets de ces classes doivent être issues de la personnalisation par l’utilisateur final du logiciel, et ne doivent donc pas être modifiées dans le logiciel ! Pour personnaliser les règles de gestion dans le logiciel, il faut rester sur le niveau traitement des annotations, à moins que vous ne souhaitiez explicitement contredire les personnalisations voulues par les utilisateurs qui ont accès à ces fonctionnalités (ce qui est déconseillé).
Remarques et informations complémentaires
- Les exemples présentés ici concernent des modifications de règles de gestion pour des formulaires. Dans l’absolu la même méthode peut être employée pour lancer des traitements exécutés par vos contrôleurs avec des règles de gestion différentes de celles définies en standard par vos annotations, à titre exceptionnel dans le contexte de votre contrôleur (notamment section “Application des règles de gestion pour personnaliser la vue”).