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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.