From 604ffe301cf581ba74e55e8c7053d7f1816f3d6f Mon Sep 17 00:00:00 2001
From: Fil <fil@rezo.net>
Date: Sun, 29 Aug 2004 07:30:07 +0000
Subject: [PATCH] suite de la resttructruration du code, avec un
 inc-boucle.php3 fort lisible

---
 inc-balises.php3       |  50 +++-
 inc-boucles.php3       | 274 ++++++++++++++++++
 inc-champ-squel.php3   |  73 -----
 inc-compilo-index.php3 |   2 +-
 inc-compilo.php3       |  55 +++-
 inc-criteres.php3      | 624 ++++++++++++++++++++++-------------------
 inc-reqsql-squel.php3  | 147 ----------
 7 files changed, 706 insertions(+), 519 deletions(-)
 create mode 100644 inc-boucles.php3
 delete mode 100644 inc-reqsql-squel.php3

diff --git a/inc-balises.php3 b/inc-balises.php3
index f7a0da6475..8bc1e4cb9d 100644
--- a/inc-balises.php3
+++ b/inc-balises.php3
@@ -17,6 +17,48 @@ if (defined("_INC_BALISES")) return;
 define("_INC_BALISES", "1");
 
 
+
+//
+// Pre-traitements standard de divers champs
+//
+function champs_traitements ($nom_champ) {
+	static $traitements = array (
+		'BIO' => 'traiter_raccourcis(%s)',
+		'CHAPO' => 'traiter_raccourcis(nettoyer_chapo(%s))',
+		'DATE' => 'vider_date(%s)',
+		'DATE_MODIF' => 'vider_date(%s)',
+		'DATE_NOUVEAUTES' => 'vider_date(%s)',
+		'DATE_REDAC' => 'vider_date(%s)',
+		'DESCRIPTIF' => 'traiter_raccourcis(%s)',
+		'LIEN_TITRE' => 'typo(%s)',
+		'LIEN_URL' => 'htmlspecialchars(vider_url(%s))',
+		'MESSAGE' => 'traiter_raccourcis(%s)',
+		'NOM_SITE_SPIP' => 'typo(%s)',
+		'NOM' => 'typo(%s)',
+		'PARAMETRES_FORUM' => 'htmlspecialchars(%s)',
+		'PS' => 'traiter_raccourcis(%s)',
+		'SOUSTITRE' => 'typo(%s)',
+		'SURTITRE' => 'typo(%s)',
+		'TEXTE' => 'traiter_raccourcis(%s)',
+		'TITRE' => 'typo(%s)',
+		'TYPE' => 'typo(%s)',
+		'URL_ARTICLE' => 'htmlspecialchars(vider_url(%s))',
+		'URL_BREVE' => 'htmlspecialchars(vider_url(%s))',
+		'URL_DOCUMENT' => 'htmlspecialchars(vider_url(%s))',
+		'URL_FORUM' => 'htmlspecialchars(vider_url(%s))',
+		'URL_MOT' => 'htmlspecialchars(vider_url(%s))',
+		'URL_RUBRIQUE' => 'htmlspecialchars(vider_url(%s))',
+		'URL_SITE_SPIP' => 'htmlspecialchars(vider_url(%s))',
+		'URL_SITE' => 'htmlspecialchars(vider_url(%s))',
+		'URL_SYNDIC' => 'htmlspecialchars(vider_url(%s))'
+	);
+
+	return $traitements[$nom_champ];
+}
+
+//
+// Definition des balises
+//
 function balise_NOM_SITE_SPIP_dist($p) {
 	$p->code = "lire_meta('nom_site')";
 	$p->type = 'php';
@@ -618,7 +660,7 @@ function balise_FORMULAIRE_RECHERCHE_dist($p) {
 function balise_FORMULAIRE_INSCRIPTION_dist($p) {
 
 	$p->code = '(lire_meta("accepter_inscriptions") != "oui") ? "" :
-		("<"."?php include(\'inc-formulaires.php3\'); lang_select(\"$spip_lang\"); formulaire_inscription(\"redac\"); lang_dselect(); ?".">")';
+		("<"."?php include_local(\'inc-formulaires.php3\'); lang_select(\"$spip_lang\"); formulaire_inscription(\"redac\"); lang_dselect(); ?".">")';
 
 	$p->type = 'php';
 	return $p;
@@ -632,7 +674,7 @@ function balise_FORMULAIRE_ECRIRE_AUTEUR_dist($p) {
 	$_mail_auteur = champ_sql('email', $p);
 
 	$p->code = '!email_valide('.$_mail_auteur.') ? "" :
-		("<'.'?php include(\'inc-formulaires.php3\');
+		("<'.'?php include_local(\'inc-formulaires.php3\');
 		lang_select(\'$spip_lang\');
 		formulaire_ecrire_auteur(".'.$_id_auteur.'.", \'".texte_script('.$_mail_auteur.')."\');
 		lang_dselect(); ?'.'>")';
@@ -648,7 +690,7 @@ function balise_FORMULAIRE_SIGNATURE_dist($p) {
 	$_id_article = champ_sql('id_article', $p);
 
 	$p->code = '!($petition = sql_petitions('.$_id_article.')) ? "" :
-		("<"."?php include(\'inc-formulaires.php3\');
+		("<"."?php include_local(\'inc-formulaires.php3\');
 		lang_select(\'$spip_lang\');
 		echo formulaire_signature(".'.$_id_article.'.",
 			\'".texte_script(serialize($petition))."\');
@@ -663,7 +705,7 @@ function balise_FORMULAIRE_SITE_dist($p) {
 	$_id_rubrique = champ_sql('id_rubrique', $p);
 
 	$p->code = '(lire_meta("proposer_sites") != 2) ? "":
-		"<"."?php include(\'inc-formulaires.php3\');
+		"<"."?php include_local(\'inc-formulaires.php3\');
 		lang_select(\'".$GLOBALS[\'spip_lang\']."\');
 		formulaire_site(".'.$_id_rubrique.'.");
 		lang_dselect(); ?".">"';
diff --git a/inc-boucles.php3 b/inc-boucles.php3
new file mode 100644
index 0000000000..b960509797
--- /dev/null
+++ b/inc-boucles.php3
@@ -0,0 +1,274 @@
+<?php
+
+//
+// Ce fichier definit les boucles standard de SPIP
+//
+
+
+// Ce fichier ne sera execute qu'une fois
+if (defined("_INC_BOUCLES")) return;
+define("_INC_BOUCLES", "1");
+
+
+//
+// Globales de description de la base
+//
+# le bloc qui suit est un peu sale, peut-etre faudrait-il definir
+# ces choses-la au meme endroit qu'on definit le contenu des tables
+# de la base de donnees, ie ecrire/inc_serial_base et ecrire/inc_auxbase !
+# et sous forme de fonctions
+{
+
+	global $exceptions_des_tables, $table_des_tables;
+	global $tables_relations,  $table_primary, $table_date;
+	
+
+	// champ principal des tables SQL
+	$table_primary = array(
+		'articles' => "id_article",
+		'auteurs' => "id_auteur",
+		'breves' => "id_breve",
+		'documents' => "id_document",
+		'forums' => "id_forum",
+		'groupes_mots' => "id_groupe",
+		'hierarchie' => "id_rubrique",
+		'mots' => "id_mot",
+		'rubriques' => "id_rubrique",
+		'signatures' => "id_signature",
+		'syndication' => "id_syndic",
+		'syndic_articles' => "id_syndic_article",
+		'types_documents' => "id_document"
+	);
+	
+	# cf. fonction table_objet dans inc_version
+	$table_des_tables = array(
+		'articles' => 'articles',
+		'auteurs' => 'auteurs',
+		'breves' => 'breves',
+		'forums' => 'forum',
+		'signatures' => 'signatures',
+		'documents' => 'documents',
+		'types_documents' => 'types_documents',
+		'mots' => 'mots',
+		'groupes_mots' => 'groupes_mots',
+		'rubriques' => 'rubriques',
+		'syndication' => 'syndic',
+		'syndic_articles' => 'syndic_articles',
+		'hierarchie' => 'rubriques'
+	);
+	
+	$exceptions_des_tables = array(
+		'breves' => array(
+			'id_secteur' => 'id_rubrique',
+			'date' => 'date_heure',
+			'nom_site' => 'lien_titre',
+			'url_site' => 'lien_url'
+			),
+		'forums' => array(
+			'date' => 'date_heure',
+			'nom' => 'auteur',
+			'email' => 'email_auteur'
+			),
+		'signatures' => array(
+			'date' => 'date_time',
+			'nom' => 'nom_email',
+			'email' => 'ad_email'
+		),
+		'documents' => array(
+			'type_document' => array('types_documents', 'titre'),
+			'extension_document' => array('types_documents', 'extension')
+		),
+		'syndic_articles' => array(
+			'url_article' => 'url',		  # ne sert pas ? cf balise_URL_ARTICLE
+			'lesauteurs' => 'lesauteurs', # ne sert pas ? cf balise_LESAUTEURS
+			'url_site' => array('syndic', 'url_site'),
+			'nom_site' => array('syndic', 'nom_site')
+		)
+	);
+	
+	$table_date = array (
+		'articles' => 'date',
+		'auteurs' =>  'date',
+		'breves' =>  'date_heure',
+		'forums' =>  'date_heure',
+		'signatures' => 'date_time',
+		'documents' => 'date',
+		'types_documents' => 'date',
+		'groupes_mots' => 'date',
+		'mots' => 'date',
+		'rubriques' => 'date',
+		'syndication' => 'date',
+		'syndic_articles' => 'date'
+	);
+
+}
+
+
+//
+// Boucle sur une table hors SPIP, pourquoi pas
+//
+function boucle_DEFAUT(&$boucle, &$boucles, $type, $id_table, $id_field) {
+	$boucle->from[] =  "$type AS $type";
+	$id_field = '*'; // utile a TOTAL_BOUCLE seulement
+}
+
+
+//
+// <BOUCLE(ARTICLES)>
+//
+function boucle_ARTICLES_dist(&$boucle, &$boucles, $type, $id_table, $id_field) {
+	$boucle->from[] =  "articles AS $id_table";
+	if (!$GLOBALS['var_preview']) {
+		$boucle->where[] = "$id_table.statut='publie'";
+		if (lire_meta("post_dates") == 'non')
+			$boucle->where[] = "$id_table.date < NOW()";
+	} else
+		$boucle->where[] = "$id_table.statut IN ('publie','prop')";
+}
+
+//
+// <BOUCLE(AUTEURS)>
+//
+function boucle_AUTEURS_dist(&$boucle, &$boucles, $type, $id_table, $id_field) {
+	$boucle->from[] =  "auteurs AS $id_table";
+	// Si pas de lien avec un article, selectionner
+	// uniquement les auteurs d'un article publie
+	if (!$GLOBALS['var_preview'])
+	if (!$boucle->lien AND !$boucle->tout) {
+		$boucle->from[] =  "auteurs_articles AS lien";
+		$boucle->from[] =  "articles AS articles";
+		$boucle->where[] = "lien.id_auteur=$id_table.id_auteur";
+		$boucle->where[] = 'lien.id_article=articles.id_article';
+		$boucle->where[] = "articles.statut='publie'";
+		$boucle->group =  "$id_field";
+	}
+	// pas d'auteurs poubellises
+	$boucle->where[] = "NOT($id_table.statut='5poubelle')";
+}
+
+//
+// <BOUCLE(BREVES)>
+//
+function boucle_BREVES_dist(&$boucle, &$boucles, $type, $id_table, $id_field) {
+	$boucle->from[] =  "breves AS $id_table";
+	if (!$GLOBALS['var_preview'])
+		$boucle->where[] = "$id_table.statut='publie'";
+	else
+		$boucle->where[] = "$id_table.statut IN ('publie','prop')";
+}
+
+
+//
+// <BOUCLE(FORUMS)>
+//
+function boucle_FORUMS_dist(&$boucle, &$boucles, $type, $id_table, $id_field) {
+	$boucle->from[] =  "forum AS $id_table";
+	// Par defaut, selectionner uniquement les forums sans pere
+	if (!$boucle->tout AND !$boucle->plat) 
+		{
+	$boucle->where[] = "$id_table.id_parent=0";
+		}
+	$boucle->where[] = "$id_table.statut='publie'";
+}
+
+
+//
+// <BOUCLE(SIGNATURES)>
+//
+function boucle_SIGNATURES_dist(&$boucle, &$boucles, $type, $id_table, $id_field) {
+	$boucle->from[] =  "signatures AS $id_table";
+	$boucle->from[] =  "petitions AS petitions";
+	$boucle->from[] =  "articles articles";
+	$boucle->where[] = "petitions.id_article=articles.id_article";
+	$boucle->where[] = "petitions.id_article=$id_table.id_article";
+	$boucle->where[] = "$id_table.statut='publie'";
+	$boucle->group = "$id_field";
+}
+
+
+//
+// <BOUCLE(DOCUMENTS)>
+//
+function boucle_DOCUMENTS_dist(&$boucle, &$boucles, $type, $id_table, $id_field) {
+	$boucle->from[] =  "documents AS $id_table";
+	$boucle->from[] =  "types_documents AS types_documents";
+	$boucle->where[] = "$id_table.id_type=types_documents.id_type";
+	$boucle->where[] = "$id_table.taille > 0";
+}
+
+
+//
+// <BOUCLE(TYPES_DOCUMENTS)>
+//
+function boucle_TYPES_DOCUMENTS_dist(&$boucle, &$boucles, $type, $id_table, $id_field) {
+	$boucle->from[] =  "types_documents AS $id_table";
+}
+
+
+//
+// <BOUCLE(GROUPES_MOTS)>
+//
+function boucle_GROUPES_MOTS_dist(&$boucle, &$boucles, $type, $id_table, $id_field) {
+	$boucle->from[] =  "groupes_mots AS $id_table";
+}
+
+
+//
+// <BOUCLE(MOTS)>
+//
+function boucle_MOTS_dist(&$boucle, &$boucles, $type, $id_table, $id_field) {
+	$boucle->from[] =  "mots AS $id_table";
+}
+
+
+//
+// <BOUCLE(RUBRIQUES)>
+//
+function boucle_RUBRIQUES_dist(&$boucle, &$boucles, $type, $id_table, $id_field) {
+	$boucle->from[] =  "rubriques AS $id_table";
+	if (!$GLOBALS['var_preview'])
+	if (!$boucle->tout) $boucle->where[] = "$id_table.statut='publie'";
+}
+
+
+//
+// <BOUCLE(HIERARCHIE)>
+//
+function boucle_HIERARCHIE_dist(&$boucle, &$boucles, $type, $id_table, $id_field) {
+	$boucle->from[] =  "rubriques AS $id_table";
+
+	// $hierarchie sera calculee par une fonction de inc-calcul-mysql
+	// inc-criteres supprimera le parametre {id_article/id_rubrique/id_syndic}
+	$boucle->where[] = 'id_rubrique IN ($hierarchie)';
+	$boucle->select[] = 'FIND_IN_SET(id_rubrique, \'$hierarchie\')-1 AS rang';
+	$boucle->order = 'rang';
+	$boucle->hierarchie = '$hierarchie = calculer_hierarchie('
+	. calculer_argument_precedent($boucle->id_boucle, 'id_rubrique', $boucles)
+	. ', false);';
+}
+
+
+//
+// <BOUCLE(SYNDICATION)>
+//
+function boucle_SYNDICATION_dist(&$boucle, &$boucles, $type, $id_table, $id_field) {
+	$boucle->from[] =  "syndic AS $id_table";
+	$boucle->where[] = "$id_table.statut='publie'";
+}
+
+
+//
+// <BOUCLE(SYNDIC_ARTICLES)>
+//
+function boucle_SYNDIC_ARTICLES_dist(&$boucle, &$boucles, $type, $id_table, $id_field) {
+	$boucle->from[] =  "syndic_articles  AS $id_table";
+	$boucle->from[] =  "syndic AS syndic";
+	$boucle->where[] = "$id_table.id_syndic=syndic.id_syndic";
+	$boucle->where[] = "$id_table.statut='publie'";
+	$boucle->where[] = "syndic.statut='publie'";
+	$boucle->select[]='syndic.nom_site AS nom_site'; # derogation zarbi
+	$boucle->select[]='syndic.url_site AS url_site'; # idem
+}
+
+
+?>
diff --git a/inc-champ-squel.php3 b/inc-champ-squel.php3
index aa634c95a7..9d8494432c 100755
--- a/inc-champ-squel.php3
+++ b/inc-champ-squel.php3
@@ -9,79 +9,6 @@ global $exceptions_des_tables, $table_des_tables;
 global $tables_relations,  $table_primary, $table_date;
 
 
-//
-// Construire un tableau des tables de relations
-//
-
-$tables_relations = '';
-
-$tables_relations['articles']['id_mot'] = 'mots_articles';
-$tables_relations['articles']['id_auteur'] = 'auteurs_articles';
-$tables_relations['articles']['id_document'] = 'documents_articles';
-
-$tables_relations['auteurs']['id_article'] = 'auteurs_articles';
-
-$tables_relations['breves']['id_mot'] = 'mots_breves';
-$tables_relations['breves']['id_document'] = 'documents_breves';
-
-$tables_relations['documents']['id_article'] = 'documents_articles';
-$tables_relations['documents']['id_rubrique'] = 'documents_rubriques';
-$tables_relations['documents']['id_breve'] = 'documents_breves';
-
-$tables_relations['forums']['id_mot'] = 'mots_forum';
-
-$tables_relations['mots']['id_article'] = 'mots_articles';
-$tables_relations['mots']['id_breve'] = 'mots_breves';
-$tables_relations['mots']['id_forum'] = 'mots_forum';
-$tables_relations['mots']['id_rubrique'] = 'mots_rubriques';
-$tables_relations['mots']['id_syndic'] = 'mots_syndic';
-
-$tables_relations['groupes_mots']['id_groupe'] = 'mots';
-
-$tables_relations['rubriques']['id_mot'] = 'mots_rubriques';
-$tables_relations['rubriques']['id_document'] = 'documents_rubriques';
-
-$tables_relations['syndication']['id_mot'] = 'mots_syndic';
-
-
-//
-// Construire un tableau associatif des pre-traitements de champs
-//
-
-function champs_traitements ($nom_champ) {
-	static $traitements = array (
-		'BIO' => 'traiter_raccourcis(%s)',
-		'CHAPO' => 'traiter_raccourcis(nettoyer_chapo(%s))',
-		'DATE' => 'vider_date(%s)',
-		'DATE_MODIF' => 'vider_date(%s)',
-		'DATE_NOUVEAUTES' => 'vider_date(%s)',
-		'DATE_REDAC' => 'vider_date(%s)',
-		'DESCRIPTIF' => 'traiter_raccourcis(%s)',
-		'LIEN_TITRE' => 'typo(%s)',
-		'LIEN_URL' => 'htmlspecialchars(vider_url(%s))',
-		'MESSAGE' => 'traiter_raccourcis(%s)',
-		'NOM_SITE_SPIP' => 'typo(%s)',
-		'NOM' => 'typo(%s)',
-		'PARAMETRES_FORUM' => 'htmlspecialchars(%s)',
-		'PS' => 'traiter_raccourcis(%s)',
-		'SOUSTITRE' => 'typo(%s)',
-		'SURTITRE' => 'typo(%s)',
-		'TEXTE' => 'traiter_raccourcis(%s)',
-		'TITRE' => 'typo(%s)',
-		'TYPE' => 'typo(%s)',
-		'URL_ARTICLE' => 'htmlspecialchars(vider_url(%s))',
-		'URL_BREVE' => 'htmlspecialchars(vider_url(%s))',
-		'URL_DOCUMENT' => 'htmlspecialchars(vider_url(%s))',
-		'URL_FORUM' => 'htmlspecialchars(vider_url(%s))',
-		'URL_MOT' => 'htmlspecialchars(vider_url(%s))',
-		'URL_RUBRIQUE' => 'htmlspecialchars(vider_url(%s))',
-		'URL_SITE_SPIP' => 'htmlspecialchars(vider_url(%s))',
-		'URL_SITE' => 'htmlspecialchars(vider_url(%s))',
-		'URL_SYNDIC' => 'htmlspecialchars(vider_url(%s))'
-	);
-
-	return $traitements[$nom_champ];
-}
 
 
 
diff --git a/inc-compilo-index.php3 b/inc-compilo-index.php3
index e7180f73f5..9c74ceee06 100644
--- a/inc-compilo-index.php3
+++ b/inc-compilo-index.php3
@@ -228,7 +228,7 @@ function calculer_champ($fonctions, $nom_champ, $id_boucle, &$boucles, $id_mere,
 	
 	}}}}
 	
-	// Aller chercher les processeurs standards definis dans inc-champ-squel
+	// Aller chercher les processeurs standards definis dans inc-balises.php3
 	if (!$etoile)
 		$p->process = champs_traitements($nom_champ);
 
diff --git a/inc-compilo.php3 b/inc-compilo.php3
index 3ce8024ad0..2b9ea8bc1b 100644
--- a/inc-compilo.php3
+++ b/inc-compilo.php3
@@ -15,28 +15,24 @@ include_local("inc-compilo-index.php3");  # index ? structure ? pile ?
 #include_local("inc-bcl-squel.php3");	# (anciens noms des fichiers)
 #include_local("inc-index-squel.php3");
 
+// definition des boucles
+include_local("inc-boucles.php3");
+#include_local("inc-reqsql-squel.php3");
+
 // definition des balises
 include_local("inc-balises.php3");
 #include_local("inc-logo-squel.php3");
 #include_local("inc-vrac-squel.php3");
 #include_local("inc-form-squel.php3");
+#include_local("inc-champ-squel.php3");
 
 // definition des criteres
 include_local("inc-criteres.php3");
 #include_local("inc-arg-squel.php3");
 
-
 // gestion des balises de forums
 include_local("inc-forum.php3");
 
-
-// a traiter (essentiellement, ce sont des definitions standard de spip:
-// inc-compilo-standard/spip/redac ?
-include_local("inc-reqsql-squel.php3");
-include_local("inc-champ-squel.php3");
-
-
-
 // outils pour debugguer le compilateur
 #include_local("inc-compilo-debug.php3"); # desactive
 
@@ -294,7 +290,46 @@ function calculer_boucle($id_boucle, &$boucles) {
 	if ($boucle->hash)
 		$init .= "if (\$hash_recherche) ";
 
-	$init .= "\$result = " . calculer_requete($boucle);
+	$init .= "\$result = ";
+
+
+	// Appeler la fonction de definition de la boucle
+	$f = 'boucle_'.strtoupper($boucle->type_requete);	// definition perso
+	if (!function_exists($f)) $f = $f.'_dist';			// definition spip
+	if (!function_exists($f)) $f = 'boucle_DEFAUT';		// definition par defaut
+
+	$type = $boucle->type_requete;
+	$id_table = $table_des_tables[$type];
+	$id_field = $id_table . "." . $table_primary[$type];
+
+	$f($boucle, $boucles, $type, $id_table, $id_field);
+
+
+	// En absence de champ c'est un decompte : on prend la primary pour
+	// avoir qqch (le marteau-pilon * est trop couteux, et le COUNT
+	// incompatible avec le cas general)	$init .= 
+	$init .= "spip_abstract_select(\n\t\tarray(\"". 
+		((!$boucle->select) ? $id_field :
+		join("\",\n\t\t\"", array_unique($boucle->select))) .
+		'"), # SELECT
+		array("' .
+		join('","', array_unique($boucle->from)) .
+		'"), # FROM
+		array(' .
+		(!$boucle->where ? '' : ( '"' . join('",
+		"', $boucle->where) . '"')) .
+		"), # WHERE
+		'".addslashes($boucle->group)."', # GROUP
+		" . ($boucle->order ? $boucle->order : "''") .", # ORDER
+		" . (strpos($boucle->limit, 'intval') === false ?
+			"'$boucle->limit'" :
+			$boucle->limit). ", # LIMIT
+		'".$boucle->sous_requete."', # sous
+		".$boucle->compte_requete.", # compte
+		'".$id_table."', # table
+		'".$boucle->id_boucle."'); # boucle";
+
+
 	$init .= "\n	".'$t0 = "";
 	$SP++;';
 	if ($flag_cpt)
diff --git a/inc-criteres.php3 b/inc-criteres.php3
index 867ddf785f..442fadc62b 100644
--- a/inc-criteres.php3
+++ b/inc-criteres.php3
@@ -229,12 +229,76 @@ function critere_par_dist($param, $not, &$boucle, $infos) {
 	// tris par critere bizarre
 	// (formule composee, virgules, etc).
 	else { 
-		$boucle->order = "'".texte_script($tri)."'";
+		$boucle->order = $tri;	// autorise le hack {par $GLOBALS["tri"]}
 	}
 }
 
 
 
+
+//
+// Construire un tableau des tables de relations,
+// Ex: gestion du critere {id_mot} dans la boucle(ARTICLES)
+//
+function relations_externes ($type, $col) {
+	static $tables_relations = array(
+	'articles' => array (
+		'id_mot' => 'mots_articles',
+		'id_auteur' => 'auteurs_articles',
+		'id_document' => 'documents_articles'
+		),
+
+	'auteurs' => array (
+		'id_article' => 'auteurs_articles'
+		),
+
+	'breves' => array (
+		'id_mot' => 'mots_breves',
+		'id_document' => 'documents_breves'
+		),
+
+	'documents' => array (
+		'id_article' => 'documents_articles',
+		'id_rubrique' => 'documents_rubriques',
+		'id_breve' => 'documents_breves'
+		),
+
+	'forums' => array (
+		'id_mot' => 'mots_forum',
+		),
+
+	'mots' => array (
+		'id_article' => 'mots_articles',
+		'id_breve' => 'mots_breves',
+		'id_forum' => 'mots_forum',
+		'id_rubrique' => 'mots_rubriques',
+		'id_syndic' => 'mots_syndic'
+		),
+
+	'groupes_mots' => array (
+		'id_groupe' => 'mots'
+		),
+
+	'rubriques' => array (
+		'id_mot' => 'mots_rubriques',
+		'id_document' => 'documents_rubriques'
+		),
+
+	'syndication' => array (
+		'id_mot' => 'mots_syndic'
+		)
+	);
+
+	return $tables_relations[$type][$col];
+}
+
+
+
+
+//
+// La fonction qui appelle les criteres_xxx et traite les cas specifiques
+// comme {1,4}, etc.
+//
 function calculer_criteres ($idb, &$boucles) {
 	global $tables_relations, $table_primary, $table_des_tables, $table_date;
 	$boucle = &$boucles[$idb];				# nom de la boucle
@@ -254,326 +318,318 @@ function calculer_criteres ($idb, &$boucles) {
 		'idb' => $idb				# 'nom_boucle'
 	);
 
-	// Cas specifique pour la hierarchie : on cree des criteres supplementaires
-	// $hierarchie sera calculee par une fonction de inc-calcul-mysql
-	if ($type == 'hierarchie') {
-		$boucle->where[] = 'id_rubrique IN ($hierarchie)';
-		$boucle->select[] = 'FIND_IN_SET(id_rubrique, \'$hierarchie\')-1 AS rang';
-		$boucle->order = 'rang';
 
-		// Supprimer le parametre id_article/id_rubrique/id_syndic
-		// qui est superfetatoire (mais indique dans la doc)
+	if (!is_array($params)) return;	// rien a faire
+
+	// Boucle hierarchie, supprimer le critere id_article/id_rubrique/id_syndic
+	// qui est superfetatoire (mais indique dans la doc)
+	if ($type == 'hierarchie') {
 		$params2 = array();
 		foreach($params as $param)
 			if (!ereg('^id_(article|syndic|rubrique)$', $param))
 				$params2[]=$param;
 		$params = $params2;
-
-		$boucle->hierarchie = '$hierarchie = calculer_hierarchie('
-		.calculer_argument_precedent($idb, 'id_rubrique', $boucles)
-		.', false);';
 	}
 
 	//
 	// Traitement de la liste des criteres
 	//
-	if (is_array($params)) {
-		foreach($params as $param) {
-
-			// Analyse du critere
-			preg_match("/^([!]?)[[:space:]]*(debut|([a-z_]+))/ism",
-				$param, $match);
-			$critere = $match[2];
-			$not = ($match[1] == '!');
-
-			// synonymes ?
-			$synonymes = array('unique'=>'doublons');
-			if ($synonymes[$critere]) $critere = $synonymes[$critere];
-
-
-			// critere personnalise ?
-			$f = "critere_".$critere;
-			if (!function_exists($f))
-				$f .= '_dist';
-
-			// fonction critere standard ?
-			if (function_exists($f)) {
-				if ($erreur = $f($param, $not, $boucle, $infos)) {
-					include_local('inc-admin.php3');
-					erreur_squelette(_T('info_erreur_squelette'),
-					_L("&nbsp: erreur dans le critere {$param} : $erreur"),
-					$idb);
-				}
+	foreach($params as $param) {
+
+		// Analyse du critere
+		preg_match("/^([!]?)[[:space:]]*(debut|([a-z_]+))/ism",
+			$param, $match);
+		$critere = $match[2];
+		$not = ($match[1] == '!');
+
+		// synonymes ?
+		$synonymes = array('unique'=>'doublons');
+		if ($synonymes[$critere]) $critere = $synonymes[$critere];
+
+
+		// critere personnalise ?
+		$f = "critere_".$critere;
+		if (!function_exists($f))
+			$f .= '_dist';
+
+		// fonction critere standard ?
+		if (function_exists($f)) {
+			if ($erreur = $f($param, $not, $boucle, $infos)) {
+				include_local('inc-admin.php3');
+				erreur_squelette(_T('info_erreur_squelette'),
+				_L("&nbsp: erreur dans le critere {$param} : $erreur"),
+				$idb);
+			}
+		}
+		
+		# Criteres a passer en fonction critere_xxx_dist
+		else if (ereg('^([0-9]+)/([0-9]+)$', $param, $match)) {
+			$boucle->partie = $match[1];
+			$boucle->total_parties = $match[2];
+			$boucle->mode_partie = '/';
+		}
+		else if (ereg('^(([0-9]+)|n)(-([0-9]+))?,(([0-9]+)|n)(-([0-9]+))?$', $param, $match)) {
+			if (($match[2]!='') && ($match[6]!=''))
+				$boucle->limit = $match[2].','.$match[6];
+			else {
+				$boucle->partie =
+					($match[1] != 'n') ? $match[1] :
+					($match[4] ? $match[4] : 0);
+				$boucle->total_parties =
+					($match[5] != 'n') ? $match[5] :
+					($match[8] ? $match[8] : 0);
+				$boucle->mode_partie =
+				(($match[1]=='n')?'-':'+').(($match[5]=='n')?'-':'+');
 			}
-			
-			# Criteres a passer en fonction critere_xxx_dist
-			else if (ereg('^([0-9]+)/([0-9]+)$', $param, $match)) {
-				$boucle->partie = $match[1];
-				$boucle->total_parties = $match[2];
-				$boucle->mode_partie = '/';
+		}
+
+		// Restriction de valeurs (implicite ou explicite)
+		else if (eregi('^([a-z_]+) *(\??)((!?)(<=?|>=?|==?|IN) *"?([^<>=!"]*))?"?$', $param, $match)) {
+			// Variable comparee
+			$col = $match[1];
+			$col_table = $id_table;
+			// Valeur de comparaison
+			if ($match[3])
+				$val = calculer_param_dynamique($match[6], $boucles, $idb);
+			else {
+				$val = $match[1];
+				// Si id_parent, comparer l'id_parent avec l'id_objet
+				// de la boucle superieure
+				if ($val == 'id_parent')
+					$val = $table_primary[$type];
+				// Si id_enfant, comparer l'id_objet avec l'id_parent
+				// de la boucle superieure
+				else if ($val == 'id_enfant')
+					$val = 'id_parent';
+				$val = calculer_argument_precedent($idb, $val, $boucles) ;
 			}
-			else if (ereg('^(([0-9]+)|n)(-([0-9]+))?,(([0-9]+)|n)(-([0-9]+))?$', $param, $match)) {
-				if (($match[2]!='') && ($match[6]!=''))
-					$boucle->limit = $match[2].','.$match[6];
-				else {
-					$boucle->partie =
-						($match[1] != 'n') ? $match[1] :
-						($match[4] ? $match[4] : 0);
-					$boucle->total_parties =
-						($match[5] != 'n') ? $match[5] :
-						($match[8] ? $match[8] : 0);
-					$boucle->mode_partie =
-					(($match[1]=='n')?'-':'+').(($match[5]=='n')?'-':'+');
-				}
+
+			if (ereg('^\$',$val))
+				$val = '" . addslashes(' . $val . ') . "';
+			else
+				$val = addslashes($val);
+
+			// Traitement general des relations externes
+			if ($s = relations_externes($type, $col)) {
+				$col_table = $s;
+				$boucle->from[] = "$col_table AS $col_table";
+				$boucle->where[] = "$id_field=$col_table." . $table_primary[$type];
+				$boucle->group = $id_field;
+				$boucle->lien = true;
+			}
+			// Cas particulier pour les raccourcis 'type_mot' et 'titre_mot'
+			else if ($type != 'mots'
+			AND ($col == 'type_mot' OR $col == 'titre_mot'
+			OR $col == 'id_groupe')) {
+				if ($type == 'forums')
+					$col_lien = "forum";
+				else if ($type == 'syndication')
+					$col_lien = "syndic";
+				else
+					$col_lien = $type;
+				$boucle->from[] = "mots_$col_lien AS lien_mot";
+				$boucle->from[] = 'mots AS mots';
+				$boucle->where[] = "$id_field=lien_mot." . $table_primary[$type];
+				$boucle->where[] = 'lien_mot.id_mot=mots.id_mot';
+				$boucle->group = $id_field;
+				$col_table = 'mots';
+
+				$boucle->lien = true;
+				if ($col == 'type_mot')
+					$col = 'type';
+				else if ($col == 'titre_mot')
+					$col = 'titre';
+				else if ($col == 'id_groupe')
+					$col = 'id_groupe';
 			}
 
-			// Restriction de valeurs (implicite ou explicite)
-			else if (eregi('^([a-z_]+) *(\??)((!?)(<=?|>=?|==?|IN) *"?([^<>=!"]*))?"?$', $param, $match)) {
-				// Variable comparee
-				$col = $match[1];
-				$col_table = $id_table;
-				// Valeur de comparaison
-				if ($match[3])
-					$val = calculer_param_dynamique($match[6], $boucles, $idb);
+			// Cas particulier : selection des documents selon l'extension
+			if ($type == 'documents' AND $col == 'extension')
+				$col_table = 'types_documents';
+			// HACK : selection des documents selon mode 'image'
+			// (a creer en dur dans la base)
+			else if ($type == 'documents' AND $col == 'mode'
+			AND $val == 'image')
+				$val = 'vignette';
+			// Cas particulier : lier les articles syndiques
+			// au site correspondant
+			else if ($type == 'syndic_articles' AND
+			!ereg("^(id_syndic_article|titre|url|date|descriptif|lesauteurs)$",$col))
+				$col_table = 'syndic';
+
+			// Cas particulier : id_enfant => utiliser la colonne id_objet
+			if ($col == 'id_enfant')
+				$col = $table_primary[$type];
+			// Cas particulier : id_secteur = id_rubrique pour certaines tables
+			if (($type == 'breves' OR $type == 'forums') AND $col == 'id_secteur')
+				$col = 'id_rubrique';
+
+			// Cas particulier : expressions de date
+			if (ereg("^(date|mois|annee|age|age_relatif|jour_relatif|mois_relatif|annee_relatif)(_redac)?$", $col, $regs)) {
+				$col = $regs[1];
+				if ($regs[2]) {
+					$date_orig = $id_table . ".date_redac";
+					$date_compare = '\'" . normaliser_date(' .
+					calculer_argument_precedent($idb, 'date_redac', $boucles) .
+					') . "\'';
+				}
 				else {
-					$val = $match[1];
-					// Si id_parent, comparer l'id_parent avec l'id_objet
-					// de la boucle superieure
-					if ($val == 'id_parent')
-						$val = $table_primary[$type];
-					// Si id_enfant, comparer l'id_objet avec l'id_parent
-					// de la boucle superieure
-					else if ($val == 'id_enfant')
-						$val = 'id_parent';
-					$val = calculer_argument_precedent($idb, $val, $boucles) ;
+					$date_orig = "$id_table." . $table_date[$type];
+					$date_compare = '\'" . normaliser_date(' .
+					  calculer_argument_precedent($idb, 'date', $boucles) .
+					  ') . "\'';
 				}
 
-				if (ereg('^\$',$val))
-					$val = '" . addslashes(' . $val . ') . "';
-				else
-					$val = addslashes($val);
-
-				// Traitement general des relations externes
-				if ($s = $tables_relations[$type][$col]) {
-					$col_table = $s;
-					$boucle->from[] = "$col_table AS $col_table";
-					$boucle->where[] = "$id_field=$col_table." . $table_primary[$type];
-					$boucle->group = $id_field;
-					$boucle->lien = true;
+				if ($col == 'date')
+					$col = $date_orig;
+				else if ($col == 'mois') {
+					$col = "MONTH($date_orig)";
+					$col_table = '';
 				}
-				// Cas particulier pour les raccourcis 'type_mot' et 'titre_mot'
-				else if ($type != 'mots'
-				AND ($col == 'type_mot' OR $col == 'titre_mot'
-				OR $col == 'id_groupe')) {
-					if ($type == 'forums')
-						$col_lien = "forum";
-					else if ($type == 'syndication')
-						$col_lien = "syndic";
-					else
-						$col_lien = $type;
-					$boucle->from[] = "mots_$col_lien AS lien_mot";
-					$boucle->from[] = 'mots AS mots';
-					$boucle->where[] = "$id_field=lien_mot." . $table_primary[$type];
-					$boucle->where[] = 'lien_mot.id_mot=mots.id_mot';
-					$boucle->group = $id_field;
-					$col_table = 'mots';
-
-					$boucle->lien = true;
-					if ($col == 'type_mot')
-						$col = 'type';
-					else if ($col == 'titre_mot')
-						$col = 'titre';
-					else if ($col == 'id_groupe')
-						$col = 'id_groupe';
+				else if ($col == 'annee') {
+					$col = "YEAR($date_orig)";
+					$col_table = '';
 				}
+				else if ($col == 'age') {
+					$col = calculer_param_date("now()", $date_orig);
+					$col_table = '';
+				}
+				else if ($col == 'age_relatif') {
+					$col = calculer_param_date($date_compare, $date_orig);
+					$col_table = '';
+				}
+				else if ($col == 'jour_relatif') {
+					$col = "LEAST(TO_DAYS(" .$date_compare . ")-TO_DAYS(" .
+					$date_orig . "), DAYOFMONTH(" . $date_compare .
+					")-DAYOFMONTH(" . $date_orig . ")+30.4368*(MONTH(" .
+					$date_compare . ")-MONTH(" . $date_orig .
+					"))+365.2422*(YEAR(" . $date_compare . ")-YEAR(" .
+					$date_orig . ")))";
+					$col_table = '';
+				}
+				else if ($col == 'mois_relatif') {
+					$col = "MONTH(" . $date_compare . ")-MONTH(" .
+					$date_orig . ")+12*(YEAR(" . $date_compare .
+					")-YEAR(" . $date_orig . "))";
+					$col_table = '';
+				}
+				else if ($col == 'annee_relatif') {
+					$col = "YEAR(" . $date_compare . ")-YEAR(" .
+					$date_orig . ")";
+					$col_table = '';
+				}
+			}
 
-				// Cas particulier : selection des documents selon l'extension
-				if ($type == 'documents' AND $col == 'extension')
-					$col_table = 'types_documents';
-				// HACK : selection des documents selon mode 'image'
-				// (a creer en dur dans la base)
-				else if ($type == 'documents' AND $col == 'mode'
-				AND $val == 'image')
-					$val = 'vignette';
-				// Cas particulier : lier les articles syndiques
-				// au site correspondant
-				else if ($type == 'syndic_articles' AND
-				!ereg("^(id_syndic_article|titre|url|date|descriptif|lesauteurs)$",$col))
-					$col_table = 'syndic';
-
-				// Cas particulier : id_enfant => utiliser la colonne id_objet
-				if ($col == 'id_enfant')
-					$col = $table_primary[$type];
-				// Cas particulier : id_secteur = id_rubrique pour certaines tables
-				if (($type == 'breves' OR $type == 'forums') AND $col == 'id_secteur')
-					$col = 'id_rubrique';
-
-				// Cas particulier : expressions de date
-				if (ereg("^(date|mois|annee|age|age_relatif|jour_relatif|mois_relatif|annee_relatif)(_redac)?$", $col, $regs)) {
-					$col = $regs[1];
-					if ($regs[2]) {
-						$date_orig = $id_table . ".date_redac";
-						$date_compare = '\'" . normaliser_date(' .
-						calculer_argument_precedent($idb, 'date_redac', $boucles) .
-						') . "\'';
-					}
-					else {
-						$date_orig = "$id_table." . $table_date[$type];
-						$date_compare = '\'" . normaliser_date(' .
-						  calculer_argument_precedent($idb, 'date', $boucles) .
-						  ') . "\'';
-					}
-
-					if ($col == 'date')
-						$col = $date_orig;
-					else if ($col == 'mois') {
-						$col = "MONTH($date_orig)";
-						$col_table = '';
-					}
-					else if ($col == 'annee') {
-						$col = "YEAR($date_orig)";
-						$col_table = '';
-					}
-					else if ($col == 'age') {
-						$col = calculer_param_date("now()", $date_orig);
-						$col_table = '';
-					}
-					else if ($col == 'age_relatif') {
-						$col = calculer_param_date($date_compare, $date_orig);
-						$col_table = '';
-					}
-					else if ($col == 'jour_relatif') {
-						$col = "LEAST(TO_DAYS(" .$date_compare . ")-TO_DAYS(" .
-						$date_orig . "), DAYOFMONTH(" . $date_compare .
-						")-DAYOFMONTH(" . $date_orig . ")+30.4368*(MONTH(" .
-						$date_compare . ")-MONTH(" . $date_orig .
-						"))+365.2422*(YEAR(" . $date_compare . ")-YEAR(" .
-						$date_orig . ")))";
-						$col_table = '';
-					}
-					else if ($col == 'mois_relatif') {
-						$col = "MONTH(" . $date_compare . ")-MONTH(" .
-						$date_orig . ")+12*(YEAR(" . $date_compare .
-						")-YEAR(" . $date_orig . "))";
-						$col_table = '';
-					}
-					else if ($col == 'annee_relatif') {
-						$col = "YEAR(" . $date_compare . ")-YEAR(" .
-						$date_orig . ")";
-						$col_table = '';
-					}
+			if ($type == 'forums' AND
+			($col == 'id_parent' OR $col == 'id_forum'))
+				$boucle->plat = true;
+
+			// Operateur de comparaison
+			$op = $match[5];
+			if (!$op)
+				$op = '=';
+			else if ($op == '==')
+				$op = 'REGEXP';
+			else if (strtoupper($op) == 'IN') {
+				// traitement special des valeurs textuelles
+				$val2 = split(",", $val);
+				foreach ($val2 as $v) {
+					$v = trim($v);
+					if (ereg("^[0-9]+$",$v))
+						$val3[] = $v;
+					else
+						$val3[] = "'$v'";
 				}
-	
-				if ($type == 'forums' AND
-				($col == 'id_parent' OR $col == 'id_forum'))
-					$boucle->plat = true;
-
-				// Operateur de comparaison
-				$op = $match[5];
-				if (!$op)
-					$op = '=';
-				else if ($op == '==')
-					$op = 'REGEXP';
-				else if (strtoupper($op) == 'IN') {
-					// traitement special des valeurs textuelles
-					$val2 = split(",", $val);
-					foreach ($val2 as $v) {
-						$v = trim($v);
-						if (ereg("^[0-9]+$",$v))
-							$val3[] = $v;
-						else
-							$val3[] = "'$v'";
-					}
-					$val = join(',', $val3);
-					$where = "$col IN ($val)";
-					if ($match[4] == '!') {
-						$where = "NOT ($where)";
-					} else {
-						if (!$boucle->order) {
-							$boucle->order = 'rang';
-							$boucle->select[] =
-							"FIND_IN_SET($col, \\\"$val\\\") AS rang";
-						}
+				$val = join(',', $val3);
+				$where = "$col IN ($val)";
+				if ($match[4] == '!') {
+					$where = "NOT ($where)";
+				} else {
+					if (!$boucle->order) {
+						$boucle->order = 'rang';
+						$boucle->select[] =
+						"FIND_IN_SET($col, \\\"$val\\\") AS rang";
 					}
-					$boucle->where[] = $where;
-					$op = '';
 				}
-	
-				if ($col_table)
-					$col = "$col_table.$col";
+				$boucle->where[] = $where;
+				$op = '';
+			}
 
-				if ($op) {
-					if ($match[4] == '!')
-						$where = "NOT ($col $op '$val')";
-					else
-						$where = "($col $op '$val')";
+			if ($col_table)
+				$col = "$col_table.$col";
 
-					// operateur optionnel {lang?}
-					if ($match[2]) {
-						$champ = calculer_argument_precedent($idb, $match[1], $boucles) ;
-						$where = "\".($champ ? \"$where\" : 1).\"";
-					}
+			if ($op) {
+				if ($match[4] == '!')
+					$where = "NOT ($col $op '$val')";
+				else
+					$where = "($col $op '$val')";
 
-					$boucle->where[] = $where;
+				// operateur optionnel {lang?}
+				if ($match[2]) {
+					$champ = calculer_argument_precedent($idb, $match[1], $boucles) ;
+					$where = "\".($champ ? \"$where\" : 1).\"";
 				}
 
-			} // fin du if sur les restrictions de valeurs
+				$boucle->where[] = $where;
+			}
 
-			// Special rubriques
-			else if ($param == 'meme_parent') {
-				$boucle->where[] = "$id_table.id_parent='\"." .
-					calculer_argument_precedent($idb, 'id_parent', $boucles) . ".\"'";
-				if ($type == 'forums') {
-					$boucle->where[] = "$id_table.id_parent > 0";
-					$boucle->plat = true;
-				}
+		} // fin du if sur les restrictions de valeurs
+
+		// Special rubriques
+		else if ($param == 'meme_parent') {
+			$boucle->where[] = "$id_table.id_parent='\"." .
+				calculer_argument_precedent($idb, 'id_parent', $boucles) . ".\"'";
+			if ($type == 'forums') {
+				$boucle->where[] = "$id_table.id_parent > 0";
+				$boucle->plat = true;
 			}
-			else if (ereg("^branche *(\??)", $param, $regs)) {
-				$c = "calcul_mysql_in('$id_table.id_rubrique',
-				calcul_branche(" . calculer_argument_precedent($idb, 'id_rubrique',
-				$boucles) . "), '')";
-				if (!$regs[1])
-					$boucle->where[] = "\". $c .\"" ;
-				else
-					$boucle->where[] = "\".(".calculer_argument_precedent($idb, 'id_rubrique', $boucles)."? $c : 1).\"";
+		}
+		else if (ereg("^branche *(\??)", $param, $regs)) {
+			$c = "calcul_mysql_in('$id_table.id_rubrique',
+			calcul_branche(" . calculer_argument_precedent($idb, 'id_rubrique',
+			$boucles) . "), '')";
+			if (!$regs[1])
+				$boucle->where[] = "\". $c .\"" ;
+			else
+				$boucle->where[] = "\".(".calculer_argument_precedent($idb, 'id_rubrique', $boucles)."? $c : 1).\"";
+		}
+		// Selection du classement
+		else if (ereg('^par[[:space:]]+([^}]*)$', $param, $match)) {
+			$tri = trim($match[1]);
+			if ($tri == 'hasard') { // par hasard
+				$boucle->select[] = "MOD($id_field * UNIX_TIMESTAMP(),
+				32767) & UNIX_TIMESTAMP() AS alea";
+				$boucle->order = 'alea';
 			}
-			// Selection du classement
-			else if (ereg('^par[[:space:]]+([^}]*)$', $param, $match)) {
-				$tri = trim($match[1]);
-				if ($tri == 'hasard') { // par hasard
-					$boucle->select[] = "MOD($id_field * UNIX_TIMESTAMP(),
-					32767) & UNIX_TIMESTAMP() AS alea";
-					$boucle->order = 'alea';
-				}
-				else if ($tri == 'titre_mot') { // par titre_mot
-					$boucle->order= 'mots.titre';
-				}
-				else if ($tri == 'type_mot'){ // par type_mot
-					$boucle->order= 'mots.type';
-				}
-				else if ($tri == 'points'){ // par points
-					$boucle->order= 'points';
-				}
-				else if (ereg("^num[[:space:]]+([^,]*)(,.*)?",$tri, $match2)) {
-					// par num champ
-					$boucle->select[] = "0+$id_table.".$match2[1]." AS num";
-					$boucle->order = "num".$match2[2];
-				}
-				else if (ereg("^[a-z0-9]+$", $tri)) { // par champ
-					if ($tri == 'date')
-						$tri = $table_date[$type];
-					$boucle->order = "$id_table.$tri";
-				}
-				else { 
-					// tris par critere bizarre
-					// (formule composee, virgules, etc).
-					$boucle->order = $tri;
-				}
+			else if ($tri == 'titre_mot') { // par titre_mot
+				$boucle->order= 'mots.titre';
+			}
+			else if ($tri == 'type_mot'){ // par type_mot
+				$boucle->order= 'mots.type';
+			}
+			else if ($tri == 'points'){ // par points
+				$boucle->order= 'points';
+			}
+			else if (ereg("^num[[:space:]]+([^,]*)(,.*)?",$tri, $match2)) {
+				// par num champ
+				$boucle->select[] = "0+$id_table.".$match2[1]." AS num";
+				$boucle->order = "num".$match2[2];
+			}
+			else if (ereg("^[a-z0-9]+$", $tri)) { // par champ
+				if ($tri == 'date')
+					$tri = $table_date[$type];
+				$boucle->order = "$id_table.$tri";
+			}
+			else { 
+				// tris par critere bizarre
+				// (formule composee, virgules, etc).
+				$boucle->order = $tri;
 			}
 		}
 	}
 }
 
+
 function calculer_param_date($date_compare, $date_orig) {
 	return
 	"LEAST((UNIX_TIMESTAMP(" .
diff --git a/inc-reqsql-squel.php3 b/inc-reqsql-squel.php3
deleted file mode 100644
index d013ad8f63..0000000000
--- a/inc-reqsql-squel.php3
+++ /dev/null
@@ -1,147 +0,0 @@
-<?php
-
-# Retourne l'appel a` spip_abstract_select de'finie dans inc-calcul,
-# cense'e construire et effecteur la reque^te SQL de'termine'e 
-# par les infos mises dans $boucles.
-# A ce stade, on explicite les conditions exprime'es par les crite`res.
-# L'utilisation de x AS x n'est pas une redondance:
-# spip_abstract_select accolera au premier x la valeur de table_prefix
-# qui n'a pas de raison d'apparai^tre de`s cette e'tape.
-
-function calculer_requete(&$boucle) {
- global $table_primary, $table_des_tables, $table_date;
-
- $type = $boucle->type_requete;
- $id_table = $table_des_tables[$type];
- $id_field = $id_table . "." . $table_primary[$type];
-  switch($type) {
-  case 'articles':
-    $boucle->from[] =  "articles AS $id_table";
-	if (!$GLOBALS['var_preview']) {
-		$boucle->where[] = "$id_table.statut='publie'";
-		if (lire_meta("post_dates") == 'non')
-			$boucle->where[] = "$id_table.date < NOW()";
-	} else
-		$boucle->where[] = "$id_table.statut IN ('publie','prop')";
-    break;
-
-  case 'auteurs':
-    $boucle->from[] =  "auteurs AS $id_table";
-    // Si pas de lien avec un article, selectionner
-    // uniquement les auteurs d'un article publie
-	if (!$GLOBALS['var_preview'])
-    if (!$boucle->lien AND !$boucle->tout) {
-      $boucle->from[] =  "auteurs_articles AS lien";
-      $boucle->from[] =  "articles AS articles";
-      $boucle->where[] = "lien.id_auteur=$id_table.id_auteur";
-      $boucle->where[] = 'lien.id_article=articles.id_article';
-      $boucle->where[] = "articles.statut='publie'";
-      $boucle->group =  "$id_field";
-    }
-    // pas d'auteurs poubellises
-    $boucle->where[] = "NOT($id_table.statut='5poubelle')";
-    break;
-    
-  case 'breves':
-    $boucle->from[] =  "breves AS $id_table";
-	if (!$GLOBALS['var_preview'])
-		$boucle->where[] = "$id_table.statut='publie'";
-	else
-		$boucle->where[] = "$id_table.statut IN ('publie','prop')";
-	break;
-    
-  case 'forums':
-    $boucle->from[] =  "forum AS $id_table";
-    // Par defaut, selectionner uniquement les forums sans pere
-    if (!$boucle->tout AND !$boucle->plat) 
-      {
-	$boucle->where[] = "$id_table.id_parent=0";
-      }
-    $boucle->where[] = "$id_table.statut='publie'";
-   break;
-    
-  case 'signatures':
-    $boucle->from[] =  "signatures AS $id_table";
-    $boucle->from[] =  "petitions AS petitions";
-    $boucle->from[] =  "articles articles";
-    $boucle->where[] = "petitions.id_article=articles.id_article";
-    $boucle->where[] = "petitions.id_article=$id_table.id_article";
-    $boucle->where[] = "$id_table.statut='publie'";
-    $boucle->group = "$id_field";
-    break;
-    
-  case 'documents':
-    $boucle->from[] =  "documents AS $id_table";
-    $boucle->from[] =  "types_documents AS types_documents";
-    $boucle->where[] = "$id_table.id_type=types_documents.id_type";
-    $boucle->where[] = "$id_table.taille > 0";
-    break;
-    
-  case 'types_documents':
-    $boucle->from[] =  "types_documents AS $id_table";
-    break;
-    
-  case 'groupes_mots':
-    $boucle->from[] =  "groupes_mots AS $id_table";
-    break;
-    
-  case 'mots':
-    $boucle->from[] =  "mots AS $id_table";
-    break;
-    
-  case 'rubriques':
-    $boucle->from[] =  "rubriques AS $id_table";
-	if (!$GLOBALS['var_preview'])
-    if (!$boucle->tout) $boucle->where[] = "$id_table.statut='publie'";
-    break;
-    
-  case 'hierarchie':
-    $boucle->from[] =  "rubriques AS $id_table";
-    break;
-    
-  case 'syndication':
-    $boucle->from[] =  "syndic AS $id_table";
-    $boucle->where[] = "$id_table.statut='publie'";
-    break;
-    
-  case 'syndic_articles':
-    $boucle->from[] =  "syndic_articles  AS $id_table";
-    $boucle->from[] =  "syndic AS syndic";
-    $boucle->where[] = "$id_table.id_syndic=syndic.id_syndic";
-    $boucle->where[] = "$id_table.statut='publie'";
-    $boucle->where[] = "syndic.statut='publie'";
-    $boucle->select[]='syndic.nom_site AS nom_site'; # derogation zarbi
-    $boucle->select[]='syndic.url_site AS url_site'; # idem
-    break;
-
-  default: // table hors Spip, pourquoi pas
-    $boucle->from[] =  "$type AS $type";
-    $id_field = '*'; // utile a` TOTAL_BOUCLE seulement
-  } // fin du switch
-
-	// En absence de champ c'est un decompte : on prend la primary pour
-	// avoir qqch (le marteau-pilon * est trop couteux, et le COUNT
-	// incompatible avec le cas general)
-	return "spip_abstract_select(\n\t\tarray(\"". 
-		((!$boucle->select) ? $id_field :
-		join("\",\n\t\t\"", array_unique($boucle->select))) .
-		'"), # SELECT
-		array("' .
-		join('","', array_unique($boucle->from)) .
-		'"), # FROM
-		array(' .
-		(!$boucle->where ? '' : ( '"' . join('",
-		"', $boucle->where) . '"')) .
-		"), # WHERE
-		'".addslashes($boucle->group)."', # GROUP
-		" . ($boucle->order ? $boucle->order : "''") .", # ORDER
-		" . (strpos($boucle->limit, 'intval') === false ?
-			"'$boucle->limit'" :
-			$boucle->limit). ", # LIMIT
-		'".$boucle->sous_requete."', # sous
-		".$boucle->compte_requete.", # compte
-		'".$id_table."', # table
-		'".$boucle->id_boucle."'); # boucle";
-}
-
-?>
-- 
GitLab