Hello,
Dans les derniers plugins que j’ai réalisé j’ai pris l’habitude de créer des API d’objets pour lire un objet et pour répertorier une liste d’objets éventuellement filtrée.
Au fil du temps j’ai donc écrit les mêmes fonctions à quelques améliorations près, mais le code est rigoureusement le même dans le fond.
L’objet de ce mail est de discuter de la première fonction soit objet_lire().
J’ai donc écrit une fonction générique objet_lire() qui permet de lire un objet par son id ou par un autre identifiant unique (comme prefixe pour les plugins) et d’utiliser ou pas une sauvegarde statique pour limiter les accès SQL quand on est dans un traitement qui le nécessite.
Il est possible de choisir les champs à récupérer et un pipeline post_relecture permet de compléter la description brute.
C’est donc une fonction très générique (peut-être trop mais finalement si ça marche pourquoi pas) et qui pourrait remplacer pas mal d’appels SQL récurrents qui à la longue nuisent un peu à la lisibilité du code ou à la maintenance (enfin c’est mon avis).
Je vous mets le code ci-dessous. Pensez-vous qu’on aurait intérêt à ajouter cette fonction à l’API objet ?
Si oui, on pourrait se poser la question pour les fonctions objet_supprimer et objet_repertorier.
function objet_lire($objet, $champ_id, $valeur_id, $informations = array(), $stockage = false) {
// Initialisation du tableau des descriptions et des id d'objet (au sens id_xxx).
// Le tableau des descriptions est toujours indexé par l'objet et l'id objet.
static $descriptions = array();
static $ids = array();
// On détermine le nom du champ id de la table.
include_spip('base/objets');
$table_id = id_table_objet($objet);
// On détermine si on a passé l'id objet ou un autre identifiant unique de la table :
if ($champ_id != $table_id) {
// on a passé un identifiant différent que l'id de l'objet, on cherche si cet objet a déjà été rencontré
// car dans ce cas on a déjà stocké son id objet.
$index = isset($ids[$valeur_id]) ? $ids[$valeur_id] : 0;
} else {
$index = $valeur_id;
}
// Même si on a pas demandé le stockage sur l'appel en cours, on vérifie si l'objet demandé
// n'est pas déjà stocké.
if (isset($descriptions[$objet][$index])) {
$description = $descriptions[$objet][$index];
} else {
$description = array();
}
// Si l'objet n'a pas encore été stocké, il faut le récupérer sa description complète.
if (!$description) {
// On récupère la table SQL à partir du type d'objet.
$table = table_objet_sql($objet);
// La condition est appliquée sur le champ désigné par l'utilisateur. Si ce champ n'est pas l'id objet
// on considère qu'il est de type chaine.
$where = ($champ_id != $table_id)
? array("${champ_id}=" . sql_quote($valeur_id))
: array("${champ_id}=" . intval($valeur_id));
// Acquisition de tous les champs de l'objet : si l'accès SQL retourne une erreur on renvoie un tableau vide.
if (!$description = sql_fetsel('*', $table, $where)) {
$description = array();
} else {
// On complète éventuellement la description brute de l'objet via le pipeline post_lecture.
$description = pipeline('post_lecture', $description);
}
// Si on a demandé le stockage statique on sauvegarde la description à l'index correspondant à l'id objet.
if ($stockage) {
if (!$index) {
// Première sauvegarde de l'objet qui est forcément lu via un champ qui n'est pas l'id objet.
// Il faut donc stocker l'index pour un futur appel si la description est non vide.
if ($description) {
$index = $description[$table_id];
$ids[$valeur_id] = $index;
}
}
// Si l'index a bien été trouvé, on stocke la description à cet index.
if ($index) {
$descriptions[$objet][$index] = $description;
}
}
}
// On ne retourne maintenant que les champs demandés.
if ($description and $informations) {
// Extraction des seules informations demandées.
// -- si on demande une information unique on renvoie la valeur simple, sinon on renvoie un tableau.
// -- si une information n'est pas un champ valide elle n'est pas renvoyée sans renvoyer d'erreur.
if (is_array($informations)) {
if (count($informations) == 1) {
// Tableau d'une seule information : on revient à une chaine unique.
$informations = array_shift($informations);
} else {
// Tableau des informations valides
$description = array_intersect_key($description, array_flip($informations));
}
}
if (is_string($informations)) {
// Valeur unique demandée.
$description = isset($description[$informations]) ? $description[$informations] : '';
}
}
return $description;
}
A vous lire.
