Valider c967bcc4 rédigé par cerdic's avatar cerdic
Parcourir les fichiers

Demi résolution de #2111 pour la partie des balises :

quand le compilateur rencontre une * catch-all dans la description d'une boucle,
au lieu de considérer comme acquis que la boucle fournira cette valeur, ce qui casse toutes les balises de facto,
il considère qu'il ne sait pas et ne le saura qu'à l'execution.
Il ajoute donc une condition isset($Pile[$SP])?... )
et continue à remonter la pile jusqu'à obetenir une fourniture sure de la balise comme valeur finale.

Pour arriver à cela, on a modifié la signature de la fonction champ_sql qui prend en troisième argument
le code par défaut à produire si aucune boucle ne fournit la balise. Si on ne fournit rien (ou pas une chaine),
c'est $Pile[0][...] comme avant.

Cela permet notamment aux balises calculées en concurence avec un champ sql de fournir leur code à utiliser (cas de la balise #URL_ et #INFO_) et par la même occasion, cela évite le code douteux qui consistait à regarder le résultat de champ_sql pour décider si on s'y fiait ou non.

Avec ce commit, les balises fonctionnement à nouveau dans une boucle DATA comme dans toute autre.
Il reste le cas des critères et jointures à règler.
parent b21b68a5
Chargement en cours
Chargement en cours
Chargement en cours
Chargement en cours
+3 −5
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -29,11 +29,9 @@ function balise_INFO__dist($p){
		return $p;
	}
	else {
		$p->code = champ_sql($info, $p, false);
		if (strpos($p->code, '@$Pile[0]') !== false) {
		$info = strtolower(substr($info,5));
			$p->code = "generer_info_entite($id_objet, $type_objet, '$info'".($p->etoile?","._q($p->etoile):"").")";
		}
		$code = "generer_info_entite($id_objet, $type_objet, '$info'".($p->etoile?","._q($p->etoile):"").")";
		$p->code = champ_sql($info, $p, $code);
		$p->interdire_scripts = true;
		return $p;
	}
+3 −6
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -73,12 +73,9 @@ function balise_URL__dist($p) {
	} elseif ($f = charger_fonction($nom, 'balise', true)) {
		return $f($p);
	}else {
		$code = champ_sql($nom, $p);
		if (strpos($code, '@$Pile[0]') !== false) {
		$nom = strtolower(substr($nom,4));
		$code = generer_generer_url($nom, $p);
			if ($code === NULL) return NULL;
		}
		$code = champ_sql($nom, $p, $code);
		if (!$p->etoile)
			$p->code = "vider_url($code)";
		$p->interdire_scripts = false;
+1 −1
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -192,7 +192,7 @@ class IterDecorator extends FilterIterator {
		}

		// Par defaut chercher en xpath dans la valeur()
		return table_valeur($this->valeur(), $nom);
		return table_valeur($this->valeur(), $nom, null);
	}

	
+48 −20
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -35,7 +35,9 @@ if (!defined('_ECRIRE_INC_VERSION')) return;
 *   indique que l'on accepte ou refuse le Champ joker * des iterateurs DATA
 * @return string
 */
function index_pile($idb, $nom_champ, &$boucles, $explicite='', $joker=true) {
function index_pile($idb, $nom_champ, &$boucles, $explicite='', $defaut=null) {
	if (!is_string($defaut))
		$defaut = '@$Pile[0][\''. strtolower($nom_champ) . '\']';

	$i = 0;
	if (strlen($explicite)) {
@@ -49,16 +51,21 @@ function index_pile($idb, $nom_champ, &$boucles, $explicite='', $joker=true) {

	#	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;
			}
		  return '$Pile[$SP' . ($i ? "-$i" : "") . '][\'' . $c . '\']';
			$champ = '$Pile[$SP' . ($i ? "-$i" : "") . '][\'' . $c . '\']';
			if (!$joker)
				return index_compose($conditionnel,$champ);

			$conditionnel[] = "isset($champ)?$champ";
		}
		#	spip_log("On remonte vers $i");
		// Sinon on remonte d'un cran
@@ -68,17 +75,34 @@ function index_pile($idb, $nom_champ, &$boucles, $explicite='', $joker=true) {

	#	spip_log("Pas vu $nom_champ");
	// esperons qu'il y sera
	return('@$Pile[0][\''. strtolower($nom_champ) . '\']');
	// on qu'on a fourni une valeur par "defaut" plus pertinent
	return index_compose($conditionnel,$defaut);
}

/**
 * Reconstuire la cascade de condition avec la valeur finale par defaut
 * pour les balises dont on ne saura qu'a l'execution si elles sont definies ou non
 * (boucle DATA)
 * 
 * @param array $conditionnel
 * @param string $defaut
 * @return string
 */
function index_compose($conditionnel,$defaut){
	while ($c = array_pop($conditionnel))
		$defaut = "($c:($defaut))";
	return $defaut;
}

// http://doc.spip.org/@index_tables_en_pile
function index_tables_en_pile($idb, $nom_champ, &$boucles, $joker=true) {
function index_tables_en_pile($idb, $nom_champ, &$boucles, &$joker) {
	global $exceptions_des_tables;

	$r = $boucles[$idb]->type_requete;

	if ($r == 'boucle') return array();
	if (!$r) {
		$joker = false; // indiquer a l'appelant
		# continuer pour chercher l'erreur suivante
		return  array("'#" . $r . ':' . $nom_champ . "'",'');
	}
@@ -88,18 +112,22 @@ function index_tables_en_pile($idb, $nom_champ, &$boucles, $joker=true) {
	if ($excep)
		$excep = isset($excep[$nom_champ]) ? $excep[$nom_champ] : '';
	if ($excep) {
		$joker = false; // indiquer a l'appelant
	  return index_exception($boucles[$idb], $desc, $nom_champ, $excep);
	} else {
	}
	else {
		if (isset($desc['field'][$nom_champ])) {
			$t = $boucles[$idb]->id_table;
			$joker = false; // indiquer a l'appelant
			return array("$t.$nom_champ", $nom_champ);
		}
		// Champ joker * des iterateurs DATA qui accepte tout
		else if ($joker AND isset($desc['field']['*'])) {
			$t = $boucles[$idb]->id_table;
		elseif (/*$joker AND */isset($desc['field']['*'])) {
			$joker = true; // indiquer a l'appelant
			return array($nom_champ, $nom_champ);
		}
		else {
			$joker = false; // indiquer a l'appelant
		  if ($boucles[$idb]->jointures_explicites) {
		    $t = trouver_champ_exterieur($nom_champ, 
						 $boucles[$idb]->jointures,
@@ -175,8 +203,8 @@ function index_exception(&$boucle, $desc, $nom_champ, $excep)
 *   flag pour autoriser ou non le champ joker * des iterateurs DATA
 * @return string
 */
function champ_sql($champ, $p, $joker=true) {
	return index_pile($p->id_boucle, $champ, $p->boucles, $p->nom_boucle, $joker);
function champ_sql($champ, $p, $defaut = null) {
	return index_pile($p->id_boucle, $champ, $p->boucles, $p->nom_boucle, $defaut);
}

// cette fonction sert d'API pour demander une balise Spip avec filtres