Annotation de propriété @link
-
Cette annotation, appliquée à une propriété permet de préciser le type de lien entretenu entre un objet instance de la classe et l’objet auquel la valeur de la propriété fait référence.
Elle permet notamment d’indiquer au Framework de quelle façon ce lien devra être représenté dans le modèle de donnée du DAO utilisé.
Exemple
Cet exemple de classe intégrant des propriétés utilisant les différents types de liens est inspiré des tests unitaires présents dans le framework.
On représente ici, dans un logiciel de gestion, un bon de commande répondant à ces règles de gestion :- le bon de commande est passé par un client,
- on stocke également sa date,
- une commande comporte une ou plusieurs lignes de commande,
- dans notre configuration, la vente est réalisée par un ou plusieurs commerciaux, qui se partagent la commission s’ils ont travaillé à plusieurs à la vente.
<?php namespace ITRocks\Framework\Tests\Objects; namespace ITRocks\Framework\Tools\Date_Time; class Order { //--------------------------------------------------------------------------------------- $client /** * @link Object * @mandatory * @var Client */ public $client; //----------------------------------------------------------------------------------------- $date /** * @link DateTime * @mandatory * @var Date_Time */ public $date; //---------------------------------------------------------------------------------------- $lines /** * @link Collection * @mandatory * @var Order_Line[] */ public $lines; //--------------------------------------------------------------------------------------- $number /** * @mandatory * @var string */ public $number; //------------------------------------------------------------------------------------- $salesmen /** * @link Map * @var Salesman[] */ public $salesmen; }
@link Object
La propriété
$client
de notre exemple représente un lien vers un objet stocké indépendamment par le lien de données.Grâce à cette indication de lien, le framework saura aller chercher de lui-même le client en bases de données lorsque votre application en a besoin. Si l’on étudie son fonctionnement interne lorsque ces lignes de code sont exécutées :
$order = Dao::searchOne(['number' => '1401'], Order::class); if ($order) { echo "Le client de la commande " . $order->number . " est " . $order->client->name; }
- Lorsque le Dao trouve la commande numéro 1401 lors de l’appel à searchOne, il ne renseigne en réalité que les données sans
link
de l’objet, pour éviter des lectures en bases de données qui pourraient ne pas avoir d’utilité dans la suite du programme.
L’object$order
lu ne contient alors que la valeur de$number
, seul l’identifiant interne de$client
est stocké mais invisible du développeur. - Lors du
echo
, le programme cherchant à consulter la valeur de$order->client
, le framework va chercher le client en base de données à cette occasion et stocke l’objet de classeClient
dans$client
, permettant ainsi d’afficher la valeur de$order->client->name
sans générer d’erreur.
Vous pouvez ainsi naviguer dans vos objets métier sans vous préoccuper de leur lecture en bases de données, à partir du moment où votre objet métier est valide et respecte les règles de gestion indiquées par exemple ici par l’annotation mandatory.
Lors de l’écriture en base de données d’un objet commande avec Dao::write($order), les objets liés ne sont enregistrés que s’ils ne proviennent pas eux-même de la base de données :- un nouveau client créé de toutes pièces et non pas lu depuis le lien de données sera automatiquement créé.
- a contrario, si votre client est issu de la base de données, il ne sera pas enregistré en même temps que la commande : si vous devez modifier des données du client lui-même, il faudra l’enregistrer indépendamment par exemple via un Dao::write($order->client).
@link Collection
La propriété
L’écriture d’une classe élément de collection doit respecter ces principes :$lines
de notre exemple représente un lien vers une collection d’objets (ici des lignes de commandes) qui dépendent directement de l’objet order.
On utilise le lienCollection
uniquement pour des objets qui n’ont pas d’existence propre possible en dehors du contexte objet : ici des lignes de commandes ne peuvent pas exister sans commande.
Cela implique notamment que la suppression d’une commande stockée par le Dao entraînera la suppression automatique des lignes associées.- elles utilisent le trait Component du framework, qui contient les méthodes de gestion particulières à ce type de classe,
- elles doivent contenir une propriété composite dont le type var doit être la classe dont elles dépendent.
Exemple d’implémentation de la classe
Order_Line
:<?php namespace ITRocks\Framework\Tests\Objects; use ITRocks\Framework\Mapper\Component; class Order_Line { use Component; //----------------------------------------------------------------------------------------- $item /** * @link Object * @var Item */ public $item; //---------------------------------------------------------------------------------------- $order * @composite * @link Object * @mandatory * @var Order */ public $order; //------------------------------------------------------------------------------------- $quantity /** * @mandatory * @var integer */ public $quantity; }
Comme pour les objets unitaires, les collections d’objets ne seront consultées en bases de données que lorsque le programme en a l’utilité, lors du prochain accès en lecture à la propriété
$lines
.Il est à noter également que lors de l’enregistrement d’un objet commande en base de données avec Dao::write($order), toute modification à ses lignes sera également automatiquement répercutée, sans qu’il ne soit besoin d’appeler la méthode write pour chacune.
@link Map
La propriété
$salesmen
de notre exemple représente un lien vers une liste d’objets (ici des commerciaux) reliés à la commande mais qui n’en dépendent pas. Ainsi un commercial peut n’avoir obtenu aucun bon de commande, ou en avoir signé une multitude, et apparaîtra donc dans plusieurs objets commande.Un seul commercial peut être stocké avec un
link Object
s’il est de typeSalesman
.Dans notre exemple, comme on souhaite associer plusieurs commerciaux à la commande, on utilise
link Map
sur un tableau de commerciaux :var Salesman[]
.La classe Salesman étant indépendante des commandes, aucune référence n’y est faite. Par exemple :
<?php namespace ITRocks\Framework\Tests\Objects; class Salesman { //----------------------------------------------------------------------------------------- $name /** * @var string */ public $name; }
Comme pour les objets et collections, la lecture d’une commande ne renseigne pas la valeur des commerciaux. Cette liste sera lue automatiquement dès que le programme aura besoin d’y accéder.
Lors de l’enregistrement d’un objet commande en base de données avec Dao::write($order), les commerciaux associés ne sont enregistrés que s’il s’agit de nouveaux commerciaux qui ne proviennent pas de la base de données. Comme pour un objet lié :- un nouveau commercial créé de toutes pièces et non pas lu depuis le lien de données sera automatiquement créé.
- a contrario, si votre commercial est issu de la base de données, il ne sera pas enregistré en même temps que la commande : si vous devez modifier des données d’un ou plusieurs commerciaux liés, il faudra les enregistrer indépendamment par exemple via ce code :
foreach ($order->salesmen as $salesman) Dao::write($salesman);
.
@link DateTime
La propriété
$date
contient la date (et accessoirement ici l’heure) de la commande. L’annotationlink DateTime
permet ici de préciser au framework que le stockage doit être réalisé de façon adaptée par le lien de données.Par exemple un objet de type Date_Time est stocké en base de données MySQL dans un format dédié, s’apparentant dans les requêtes et résultats de requêtes SQL à une chaîne de caractères (par exemple ’2016-04-03 21:03:12’).
Cette précision permet également au framework de transformer automatiquement une date lue en base de données, stockée en interne dans l’objet sous forme de chaîne de caractères (par exemple ’2016-04-03 21:04:05’), en objet
Date_Time
correctement formé dès que le programme aura besoin d’accéder à cette propriété.Cet usage spécifique de l’annotation
link
est limité au stockage d’objets Date_Time, pour faciliter leur stockage en base de données et leur récupération. L’utilisation de propriétés de typeDate_Time
sans lien de donnéeslink DateTime
pourrait avoir des effets indésirables.Voir aussi
- Vous trouverez un autre exemple métier détaillé dans Décryptage de l’application Movies.