Re: [SPIP Zone] SPIP 3.3-beta
Eric Lupinacci <[email protected]>
| Newsgroups | gmane.comp.web.spip.devel |
|---|---|
| Message-ID | <CAM6W4bZ2v86uL7amKks11L=Pqcg4=LR6HopitJ6y9QfF+ng2vw@mail.gmail.com> |
Hello, Le lun. 9 déc. 2019 à 15:54, Cerdic <[email protected]> a écrit : > Hello, > > pour la fonction objet_lire() j’avais soumis mon interrogation sur le fait > qu’elle contiennent un appel à pipeline qui permet d’enrichir l’objet, > chose qui n’est pas équivalente à un sql_fetsel() en base > > C’est peut-être une direction dans laquelle on voudra aller, mais ça me > semble pas certain, et lourd de conséquence. > Donc amha on peut l’intégrer mais sans ce pipeline : la fonction est juste > un shorthand facilitateur, avec quelques automatismes/sécurités par rapport > à un sql_fetsel() mais renvoie le même résultat. > > Ça permet de l’introduire, de voir si on en s’en sert, et éventuellement > de réflechir à l’étendre, mais c’est un sujet plus gros et plus vaste. > Oui, j'avais déjà pris en compte ta remarque et enlevé le pipeline. Ce que j'avais par contre c'est un appel à une fonction spécifique pour lire les champs de l'objet si elle existe et qui se substitue au traitement standard si besoin (comme par exemple pour les plugins qui nécessite une jointure sur la table des dépots). Si ça convient pas on peut le supprimer aussi. Rasta avait fait aussi la remarque sur l'intérêt de l'argument forçant le recalcul en base : effectivement ça sert peut être à rien et on pourrait l'enlever. Le code actuel est donc le suivant, dites moi si on fait des modifications et je le commite : /** * Lit un objet donné connu par son id ou par un identifiant textuel unique et renvoie tout ou partie de sa * description. * Il est possible pour un objet donné de fournir la fonction <objet>_lire_champs qui renvoie simplement tous les * champs de l'objet concerné sans aucun autre traitement. Sinon, l'appel SQL est réalisé par l'API. * * @param string $objet Type d'objet comme article * @param string $champ_id Nom du champ utilisé comme identifiant de l'objet * @param int|string $valeur_id Valeur du champ identifiant * @param array|string $informations Liste des champs à renvoyer. Si vide la fonction renvoie tous les champs. * @param bool $forcer_lecture Permet de forcer la lecture en base de données même si l'objet a déjà été lu * sur le même hit. * * @return array|mixed */ function objet_lire($objet, $champ_id, $valeur_id, $informations = array(), $forcer_lecture = false) { // Initialisation du tableau des descriptions et des id d'objet (au sens id_xxx). // Les tableaux sont toujours indexés 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[$objet][$valeur_id]) ? $ids[$objet][$valeur_id] : 0; } else { $index = $valeur_id; } // On vérifie si l'objet demandé n'est pas déjà stocké : si oui, la description sera utilisée sauf si on a forcé // la lecture en base. if (isset($descriptions[$objet][$index])) { $description = $descriptions[$objet][$index]; } else { $description = array(); } // Si l'objet n'a pas encore été stocké, il faut récupérer sa description complète. if ($forcer_lecture or !$description) { // Il est possible pour un type d'objet de fournir une fonction de lecture de tous les champs d'un objet. if (include_spip('action/editer_' . $objet) and function_exists($lire = "${objet}_lire_champs")) { $description = $lire($objet, $champ_id, $valeur_id); } else { // 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(); } } // On stocke systématiquement la description à l'index correspondant à l'objet et l'id objet. 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[$objet][$valeur_id] = $index; } } // Si l'index a bien été déterminé, 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; } ++ Eric