/** * Retourne la position dans la pile d'un champ SQL * * Retourne le code PHP permettant de récupérer un champ SQL dans * une boucle parente, en prenant la boucle la plus proche du sommet de pile * (indiqué par $idb). * * Si on ne trouve rien, on considère que ça doit provenir du contexte * (par l'URL ou l'include) qui a été recopié dans Pile[0] * (un essai d'affinage a débouché sur un bug vicieux) * * Si ca référence un champ SQL, on le mémorise dans la structure $boucles * afin de construire un requête SQL minimale (plutôt qu'un brutal 'SELECT *') * * @param string $idb Identifiant de la boucle * @param string $nom_champ Nom du champ SQL cherché * @param array $boucles AST du squelette * @param string $explicite * Indique que le nom de la boucle est explicite dans la balise #_nomboucletruc:CHAMP * @param null|string $defaut * Code par defaut si le champ n'est pas trouvé dans l'index. * Utilise @$Pile[0][$nom_champ] si non fourni * @param bool $remonte_pile * Permettre de remonter la pile des boucles ou non (dans ce cas on * ne cherche que danss la 1ère boucle englobante) * @param bool $select * Pour ajouter au select de la boucle, par defaut true * @return string * Code PHP pour obtenir le champ SQL */ function index_pile($idb, $nom_champ, &$boucles, $explicite = '', $defaut = null, $remonte_pile = true, $select = true) { if (!is_string($defaut)) { $defaut = '@$Pile[0][\'' . strtolower($nom_champ) . '\']'; } $i = 0; if (strlen($explicite)) { // Recherche d'un champ dans un etage superieur while ($idb !== $explicite && $idb !== '') { # spip_log("Cherchexpl: $nom_champ '$explicite' '$idb' '$i'"); $i++; $idb = $boucles[$idb]->id_parent; } } # spip_log("Cherche: $nom_champ a partir de '$idb'"); $nom_champ = strtolower($nom_champ); $conditionnel = array(); // attention: entre la boucle nommee 0, "" et le tableau vide, // il y a incoherences qu'il vaut mieux eviter while (isset($boucles[$idb])) { $joker = true; // modifie $joker si tous les champs sont autorisés. // $t = le select pour le champ, si on l'a trouvé (ou si joker) // $c = le nom du champ demandé list($t, $c) = index_tables_en_pile($idb, $nom_champ, $boucles, $joker); if ($t) { if ($select and !in_array($t, $boucles[$idb]->select)) { $boucles[$idb]->select[] = $t; } $champ = '$Pile[$SP' . ($i ? "-{$i}" : "") . '][\'' . $c . '\']'; if (!$joker) { return index_compose($conditionnel, $champ); } // tant que l'on trouve des tables avec joker, on continue // avec la boucle parente et on conditionne à l'exécution // la présence du champ. Si le champ existe à l'exécution // dans une boucle, il est pris, sinon on le cherche dans le parent... $conditionnel[] = "isset({$champ})?{$champ}"; } if ($remonte_pile) { # spip_log("On remonte vers $i"); // Sinon on remonte d'un cran $idb = $boucles[$idb]->id_parent; $i++; } else { $idb = null; } } # spip_log("Pas vu $nom_champ"); // esperons qu'il y sera // ou qu'on a fourni une valeur par "defaut" plus pertinent return index_compose($conditionnel, $defaut); }
/** * index_pile retourne la position dans la pile du champ SQL $nom_champ * en prenant la boucle la plus proche du sommet de pile (indique par $idb). * Si on ne trouve rien, on considere que ca doit provenir du contexte * (par l'URL ou l'include) qui a ete recopie dans Pile[0] * (un essai d'affinage a debouche sur un bug vicieux) * Si ca reference un champ SQL, on le memorise dans la structure $boucles * afin de construire un requete SQL minimale (plutot qu'un brutal 'SELECT *') * * http://doc.spip.org/@index_pile * * @param string $idb * @param string $nom_champ * @param Object $boucles * @param string $explicite * indique que le nom de la boucle explicite dans la balise #_nomboucletruc:CHAMP * @param string $defaut * code par defaut si champ pas trouve dans l'index. @$Pile[0][$nom_champ] si non fourni * @param bool $remonte_pile * permettre de remonter la pile des boucles ou non (dans ce cas on ne cherche que ds la 1ere boucle englobante) * @return string */ function index_pile($idb, $nom_champ, &$boucles, $explicite = '', $defaut = null, $remonte_pile = true) { if (!is_string($defaut)) { $defaut = '@$Pile[0][\'' . strtolower($nom_champ) . '\']'; } $i = 0; if (strlen($explicite)) { // Recherche d'un champ dans un etage superieur while ($idb !== $explicite && $idb !== '') { # spip_log("Cherchexpl: $nom_champ '$explicite' '$idb' '$i'"); $i++; $idb = $boucles[$idb]->id_parent; } } # spip_log("Cherche: $nom_champ a partir de '$idb'"); $nom_champ = strtolower($nom_champ); $conditionnel = array(); // attention: entre la boucle nommee 0, "" et le tableau vide, // il y a incoherences qu'il vaut mieux eviter while (isset($boucles[$idb])) { $joker = true; list($t, $c) = index_tables_en_pile($idb, $nom_champ, $boucles, $joker); if ($t) { if (!in_array($t, $boucles[$idb]->select)) { $boucles[$idb]->select[] = $t; } $champ = '$Pile[$SP' . ($i ? "-{$i}" : "") . '][\'' . $c . '\']'; if (!$joker) { return index_compose($conditionnel, $champ); } $conditionnel[] = "isset({$champ})?{$champ}"; } if ($remonte_pile) { # spip_log("On remonte vers $i"); // Sinon on remonte d'un cran $idb = $boucles[$idb]->id_parent; $i++; } else { $idb = null; } } # spip_log("Pas vu $nom_champ"); // esperons qu'il y sera // on qu'on a fourni une valeur par "defaut" plus pertinent return index_compose($conditionnel, $defaut); }