From c41988f206ac9739c7a79347e5d731d35c1d4705 Mon Sep 17 00:00:00 2001
From: "Committo,Ergo:sum" <esj@rezo.net>
Date: Tue, 10 Jan 2006 10:47:59 +0000
Subject: [PATCH] permettre l'acces aux champs d'une table de jointure
 explicite; ca reste lacunaire mais c'est tout de meme plus homogene que de
 faire la jointure et n'y avoir acces qu'en partie

---
 inc-compilo-api.php3   |   3 +-
 inc-compilo-index.php3 | 114 ++++++++++++++++++++++-------------------
 inc-compilo.php3       |   8 ++-
 inc-html-squel.php3    |   8 ++-
 4 files changed, 72 insertions(+), 61 deletions(-)

diff --git a/inc-compilo-api.php3 b/inc-compilo-api.php3
index 75031442be..dfb0489b87 100644
--- a/inc-compilo-api.php3
+++ b/inc-compilo-api.php3
@@ -42,10 +42,11 @@ class Boucle {
 	var $lang_select;
 	var $type_requete;
 	var $sql_serveur;
-	var $jointures;
 	var $param = array();
 	var $criteres = array();
 	var $separateur = array();
+	var $jointures = array();
+	var $jointures_explicites = false;
 	var $doublons;
 	var $partie, $total_parties,$mode_partie;
 	var $externe = ''; # appel a partir d'une autre boucle (recursion)
diff --git a/inc-compilo-index.php3 b/inc-compilo-index.php3
index 6a3247ead3..654d323bee 100644
--- a/inc-compilo-index.php3
+++ b/inc-compilo-index.php3
@@ -39,80 +39,88 @@ function index_pile($idb, $nom_champ, &$boucles, $explicite='') {
 	}
 
 #	spip_log("Cherche: $nom_champ a partir de '$idb'");
-	$c = strtolower($nom_champ);
+	$nom_champ = strtolower($nom_champ);
 	// attention: entre la boucle nommee 0, "" et le tableau vide,
 	// il y a incoherences qu'il vaut mieux eviter
 	while ($boucles[$idb]) {
-		$r = $boucles[$idb]->type_requete;
-		$s = $boucles[$idb]->sql_serveur;
-		if (!$s) 
-		  { $s = 'localhost';
+		list ($t, $c) = index_tables_en_pile($idb, $nom_champ, $boucles);
+		if ($t) {
+		  if (!in_array($t, $boucles[$idb]->select))
+		    $boucles[$idb]->select[] = $t;
+		  return '$Pile[$SP' . ($i ? "-$i" : "") . '][\'' . $c . '\']';
+		}
+#		spip_log("On remonte vers $i");
+		// Sinon on remonte d'un cran
+		$idb = $boucles[$idb]->id_parent;
+		$i++;
+	}
+
+#	spip_log("Pas vu $nom_champ");
+	// esperons qu'il y sera
+	return('$Pile[0][\''. strtolower($nom_champ) . '\']');
+}
+
+function index_tables_en_pile($idb, $nom_champ, &$boucles)
+{
+	global $exceptions_des_tables, $table_des_tables, $tables_des_serveurs_sql;
+	$r = $boucles[$idb]->type_requete;
+	$s = $boucles[$idb]->sql_serveur;
+	if (!$s) 
+		{ $s = 'localhost';
     // indirection (pour les rares cas ou le nom de la table!=type)
 		    $t = $table_des_tables[$r];
 		  }
 		// pour les tables non Spip
-		if (!$t) {$nom_table = $t = $r; }
-		else $nom_table = 'spip_' . $t;
+	if (!$t) {$nom_table = $t = $r; } else $nom_table = 'spip_' . $t;
 
-		$desc = $tables_des_serveurs_sql[$s][$nom_table];
-#		spip_log("Go: idb='$idb' r='$r' c='$c' nom='$nom_champ' s=$s t=$t desc=" . array_keys($desc));
+	$desc = $tables_des_serveurs_sql[$s][$nom_table];
+#		spip_log("Go: idb='$idb' r='$r' nom='$nom_champ' s=$s t=$t desc=" . array_keys($desc));
 
-		if (!isset($desc['field'])) {
-			$desc = $table_des_tables[$r] ?  (($GLOBALS['table_prefix'] ? $GLOBALS['table_prefix'] : 'spip') . '_' . $t) : $nom_table;
+	if (!isset($desc['field'])) {
+		$desc = $table_des_tables[$r] ?  (($GLOBALS['table_prefix'] ? $GLOBALS['table_prefix'] : 'spip') . '_' . $t) : $nom_table;
 
-			$desc = spip_abstract_showtable($desc, $boucles[$idb]->sql_serveur);
-			if (!isset($desc['field'])) {
-			  erreur_squelette(_T('zbug_table_inconnue', array('table' => $r)),
+		$desc = spip_abstract_showtable($desc, $boucles[$idb]->sql_serveur);
+		if (!isset($desc['field'])) {
+			erreur_squelette(_T('zbug_table_inconnue', array('table' => $r)),
 					   "'$idb'");
-			# continuer pour chercher l'erreur suivante
-			  return  "'#" . $r . ':' . $nom_champ . "'";
-			}
-			$tables_des_serveurs_sql[$s][$nom_table] = $desc;
+# continuer pour chercher l'erreur suivante
+			return  array("'#" . $r . ':' . $nom_champ . "'",'');
 		}
-		$excep = $exceptions_des_tables[$r][$c];
-		if ($excep) {
+		$tables_des_serveurs_sql[$s][$nom_table] = $desc;
+	}
+	
+	$excep = $exceptions_des_tables[$r][$nom_champ];
+	if ($excep) {
 			// entite SPIP alias d'un champ SQL
-			if (!is_array($excep)) {
-				$e = $excep;
-				$c = $excep;
-			} 
+		if (!is_array($excep)) {
+			$e = $excep;
+			$c = $excep;
+		} 
 			// entite SPIP alias d'un champ dans une jointure
-			else {
-			  if (!$t = array_search($excep[0], $boucles[$idb]->from)) {
+		else {
+			if (!$t = array_search($excep[0], $boucles[$idb]->from)) {
 			    $t = 'J' . count($boucles[$idb]->from);
 			    $boucles[$idb]->from[$t] = $excep[0];
-			  }
-			  $e = $excep[1];
-			  if ($e != $c) $e .= ' AS '.$c;
 			}
+			$e = $excep[1];
+			if ($e != $c) $e .= ' AS '.$c;
 		}
-		else {
-			// $e est le type SQL de l'entree
-			// entite SPIP homonyme au champ SQL
-			if ($desc['field'][$c])
-				$e = $c;
-			else
-				unset($e);
-		}
+		return array("$t.$e", $c);
 
-#		spip_log("Dans $idb ('$t' '$e' '$c'): $desc");
-
-		// On l'a trouve
-		if ($e) {
-		  $t .= ".$e";
-		  if (!in_array($t, $boucles[$idb]->select))
-		    $boucles[$idb]->select[] = $t;
-		  return '$Pile[$SP' . ($i ? "-$i" : "") . '][\'' . $c . '\']';
+	} else {
+		if ($desc['field'][$nom_champ])
+			return array("$t.$nom_champ", $nom_champ);
+		else {
+		  if ($boucles[$idb]->jointures_explicites) {
+		    $t = trouver_champ_exterieur($nom_champ, 
+						 $boucles[$idb]->jointures,
+						 $boucles[$idb]);
+		    if ($t) $t = array_search($t[0], $boucles[$idb]->from);
+		    if ($t) return array($t .'.' . $nom_champ, $nom_champ);
+		  }
+		  return array('','');
 		}
-#		spip_log("On remonte vers $i");
-		// Sinon on remonte d'un cran
-		$idb = $boucles[$idb]->id_parent;
-		$i++;
 	}
-
-#	spip_log("Pas vu $nom_champ");
-	// esperons qu'il y sera
-	return('$Pile[0][\''. strtolower($nom_champ) . '\']');
 }
 
 // cette fonction sert d'API pour demander le champ '$champ' dans la pile
diff --git a/inc-compilo.php3 b/inc-compilo.php3
index 42befb44fc..188e9db5ed 100644
--- a/inc-compilo.php3
+++ b/inc-compilo.php3
@@ -612,11 +612,9 @@ function calculer_squelette($squelette, $nom, $gram, $sourcefile) {
 		  if ($x = $table_des_tables[$type]) {
 		    $boucles[$id]->id_table = $x;
 		    $boucles[$id]->primary = $tables_principales["spip_$x"]['key']["PRIMARY KEY"];
-		    if (is_array($x = $tables_jointures['spip_' . $x])) {
-		      foreach($x as $j) {
-			$boucles[$id]->jointures[]= $j;
-		      }
-		    }
+		    if ((!$boucles[$id]->jointures)
+			AND (is_array($x = $tables_jointures['spip_' . $x])))
+		      $boucles[$id]->jointures = $x;
 		  } else {
 			// table non Spip.
 		    $boucles[$id]->id_table = $type;
diff --git a/inc-html-squel.php3 b/inc-html-squel.php3
index 5171cbb12d..bff7a3775b 100644
--- a/inc-html-squel.php3
+++ b/inc-html-squel.php3
@@ -515,8 +515,12 @@ function phraser($texte, $id_parent, &$boucles, $nom, $ligne=1) {
 		preg_match(SPEC_BOUCLE, $milieu, $match);
                 $milieu = substr($milieu, strlen($match[0]));
 		$type = $match[1];
-		$jointures = $match[2];
-		$result->jointures = preg_split("/\s+/",trim($match[2]));
+		$jointures = trim($match[2]);
+		if ($jointures) {
+			$result->jointures = preg_split("/\s+/",$jointures);
+			$result->jointures_explicites = $jointures;
+		}
+
 		if ($p = strpos($type, ':'))
 		  {
 		    $result->sql_serveur = substr($type,0,$p);
-- 
GitLab