Blame | Last modification | View Log | RSS feed
<?php
//
// Ce fichier ne sera execute qu'une fois
if (defined("_INC_CALCUL_SQUEL")) return;
define("_INC_CALCUL_SQUEL", "1");
include_local("inc-champ-squel.php3");
//////////////////////////////////////////////////////////////////////////////
//
// Parsing des squelettes
//
//////////////////////////////////////////////////////////////////////////////
class Texte {
var $type = 'texte';
var $texte;
}
class Champ {
var $type = 'champ';
var $nom_champ, $id_champ;
var $cond_avant, $cond_apres; // tableaux d'objets
var $fonctions;
}
class Boucle {
var $type = 'boucle';
var $id_boucle, $id_parent;
var $avant, $cond_avant, $milieu, $cond_apres, $cond_altern, $apres; // tableaux d'objets
var $commande;
var $requete;
var $type_requete;
var $separateur;
var $doublons;
var $lang_select;
var $partie, $total_parties;
}
function parser_boucle($texte, $id_parent) {
global $rubriques_publiques;
global $recherche;
global $tables_relations;
//
// Detecter et parser la boucle
//
$p = strpos($texte, '<BOUCLE');
if (!$p && (substr($texte, 0, strlen('<BOUCLE')) != '<BOUCLE')) {
$result = new Texte;
$result->texte = $texte;
return $result;
}
$result = new Boucle;
$debut = substr($texte, 0, $p);
$milieu = substr($texte, $p);
if (!ereg("^(<BOUCLE([0-9]+|[-_][-_.a-zA-Z0-9]*)[[:space:]]*(\([^)]*\)([[:space:]]*\{[^}]*\})*)[[:space:]]*>)", $milieu, $match)) {
include_ecrire ("inc_presentation.php3");
install_debut_html(_T('erreur_boucle_syntaxe'));
$milieu = entites_html($milieu);
echo '<p>'._T('erreur_boucle_syntaxe2', array('milieu' => $milieu));
install_fin_html();
exit;
}
$commande = $match[1];
$id_boucle = $match[2];
$suite_commande = $match[3];
//
// Decomposer les structures conditionnelles
//
$s = "<B$id_boucle>";
$p = strpos($debut, $s);
if ($p || (substr($debut, 0, strlen($s)) == $s)) {
$cond_avant = substr($debut, $p + strlen($s));
$debut = substr($debut, 0, $p);
}
$milieu = substr($milieu, strlen($commande));
$s = "</BOUCLE$id_boucle>";
$p = strpos($milieu, $s);
if ((!$p) && (substr($milieu, 0, strlen($s)) != $s)) {
include_ecrire ("inc_presentation.php3");
install_debut_html(_T('erreur_boucle_syntaxe'));
echo '<p>'._T('erreur_boucle_fermant', array('id'=>$id_boucle));
install_fin_html();
exit;
}
$fin = substr($milieu, $p + strlen($s));
$milieu = substr($milieu, 0, $p);
$s = "</B$id_boucle>";
$p = strpos($fin, $s);
if ($p || (substr($fin, 0, strlen($s)) == $s)) {
$cond_fin = substr($fin, 0, $p);
$fin = substr($fin, $p + strlen($s));
}
$s = "<//B$id_boucle>";
$p = strpos($fin, $s);
if ($p || (substr($fin, 0, strlen($s)) == $s)) {
$cond_altern = substr($fin, 0, $p);
$fin = substr($fin, $p + strlen($s));
}
$id_boucle = ereg_replace("-","_",$id_boucle);
//
// Parser la commande de la boucle
//
if (ereg('\(([^)]*)\)', $suite_commande, $regs)) {
$_type = $regs[1];
$s = "($_type)";
$p = strpos($suite_commande, $s);
// Exploser les parametres
$params = substr($suite_commande, $p + strlen($s));
if (ereg('^[[:space:]]*\{(.*)\}[[:space:]]*$', $params, $match)) $params = $match[1];
$params = split('\}[[:space:]]*\{', $params);
$type = strtolower($_type);
//
// Type boucle (recursion)
//
if ($type == 'sites') $type = 'syndication';
if (substr($type, 0, 6) == 'boucle') {
$requete = substr($_type, 6);
$type = 'boucle';
}
else {
//
// Initialisation separee par type
//
switch($type) {
case 'articles':
$table = "articles";
$req_from[] = "spip_articles AS $table";
$id_objet = "id_article";
break;
case 'auteurs':
$table = "auteurs";
$req_from[] = "spip_auteurs AS $table";
$id_objet = "id_auteur";
break;
case 'breves':
$table = "breves";
$req_from[] = "spip_breves AS $table";
$id_objet = "id_breve";
$col_date = "date_heure";
break;
case 'forums':
$table = "forums";
$req_from[] = "spip_forum AS $table";
$id_objet = "id_forum";
$col_date = "date_heure";
break;
case 'signatures':
$table = "signatures";
$req_from[] = "spip_signatures AS $table";
$id_objet = "id_signature";
$col_date = "date_time";
break;
case 'documents':
$table = "documents";
$req_select[] = "$table.*";
$req_select[] = "types_d.titre AS type_document";
$req_select[] = "types_d.extension AS extension_document";
$req_from[] = "spip_documents AS $table";
$req_from[] = "spip_types_documents AS types_d";
$req_where[] = "$table.id_type = types_d.id_type";
$id_objet = "id_document";
break;
case 'types_documents':
$table = "types_documents";
$req_from[] = "spip_types_documents AS $table";
$id_objet = "id_type";
break;
case 'groupes_mots':
$table = "groupes_mots";
$req_from[] = "spip_groupes_mots AS $table";
$id_objet = "id_groupe";
break;
case 'mots':
$table = "mots";
$req_from[] = "spip_mots AS $table";
$id_objet = "id_mot";
break;
case 'rubriques':
$table = "rubriques";
$req_from[] = "spip_rubriques AS $table";
$id_objet = "id_rubrique";
break;
case 'syndication':
$table = "syndic";
$req_from[] = "spip_syndic AS $table";
$req_where[] = "$table.statut='publie'";
$id_objet = "id_syndic";
break;
case 'syndic_articles':
$table = "articles";
$req_from[] = "spip_syndic_articles AS $table";
$req_from[] = "spip_syndic AS source";
$req_where[] = "$table.id_syndic=source.id_syndic";
$req_where[] = "$table.statut='publie'";
$req_where[] = "source.statut='publie'";
$id_objet = "id_syndic_article";
break;
}
if ($table) {
if ($type == 'articles') {
$s = "$table.id_article,$table.id_rubrique,$table.id_secteur,".
"$table.surtitre,$table.titre,$table.soustitre,$table.date,$table.date_redac,$table.date_modif,".
"$table.visites,$table.popularite,$table.statut,$table.accepter_forum,$table.lang,$table.id_trad";
if (ereg('\#(TEXTE|INTRODUCTION)', $milieu))
$s .= ",$table.texte";
if (ereg('\#(CHAPO|INTRODUCTION)', $milieu))
$s .= ",$table.chapo";
if (ereg('\#(DESCRIPTIF|INTRODUCTION)', $milieu))
$s .= ",$table.descriptif";
if (ereg('\#(PS)', $milieu))
$s .= ",$table.ps";
if (ereg('\#(EXTRA)', $milieu))
$s .= ",$table.extra";
if (ereg("\#(NOM_SITE|URL_SITE)", $milieu))
$s .= ",$table.nom_site,$table.url_site";
$req_select[] = $s;
}
else $req_select[] = "$table.*";
}
if (!$col_date) $col_date = "date";
//
// Parametres : premiere passe
//
unset($params2);
if ($params) {
reset($params);
while (list(, $param) = each($params)) {
$param = trim($param);
if ($param == 'exclus') {
$req_where[] = "$table.$id_objet!=\$$id_objet";
}
else if ($param == 'tout' OR $param == 'tous') {
$tout = true;
}
else if ($param == 'plat') {
$plat = true;
}
else if ($param == 'unique' OR $param == 'doublons') {
$doublons = 'oui';
$req_where[] = "$table.$id_objet NOT IN (\$id_doublons[$type])";
}
else if (ereg('^(!)? *lang_select(=(oui|non))?$', $param, $match)) {
if (!$lang_select = $match[3]) $lang_select = 'oui';
if ($match[1]) $lang_select = ($lang_select=='oui')?'non':'oui';
}
else if (ereg('^ *"([^"]*)" *$', $param, $match)) {
$separateur = ereg_replace("'","\'",$match[1]);
}
else if (ereg('^([0-9]+),([0-9]*)', $param, $match)) {
$req_limit = $match[1].','.$match[2];
}
else if (ereg('^debut([-_a-zA-Z0-9]+),([0-9]*)$', $param, $match)) {
$debut_lim = "debut".$match[1];
$req_limit = '".intval($GLOBALS[\'HTTP_GET_VARS\'][\''.$debut_lim.'\']).",'.$match[2];
}
else if (ereg('^([0-9]+)/([0-9]+)$', $param, $match)) {
$partie = $match[1];
$total_parties = $match[2];
}
else if ($param == 'recherche') {
if ($type == 'syndication') $req_from[] = "spip_index_syndic AS rec";
else if ($type == 'forums') $req_from[] = "spip_index_forum AS rec";
else $req_from[] = "spip_index_$type AS rec";
$req_select[] = "SUM(rec.points + 100*(rec.hash IN (\$hash_recherche_strict))) AS points";
$req_where[] = "rec.$id_objet=$table.$id_objet";
$req_group = " GROUP BY $table.$id_objet";
$req_where[] = "rec.hash IN (\$hash_recherche)";
}
else $params2[] = $param;
}
}
$params = $params2;
//
// Parametres : deuxieme passe
//
if ($params) {
reset($params);
while (list(, $param) = each($params)) {
// Classement par ordre inverse
if ($param == 'inverse') {
if ($req_order) $req_order .= ' DESC';
}
// Gerer les traductions
else if ($param == 'traduction') {
$req_where[] = "$table.id_trad > 0 AND $table.id_trad = \$id_trad";
}
else if ($param == 'origine_traduction') {
$req_where[] = "$table.id_trad = $table.id_article";
}
// Special rubriques
else if ($param == 'meme_parent') {
$req_where[] = "$table.id_parent=\$id_parent";
if ($type == 'forums') {
$req_where[] = "$table.id_parent > 0";
$plat = true;
}
}
else if ($param == 'racine') {
$req_where[] = "$table.id_parent=0";
}
else if (ereg("^branche *(\??)", $param, $regs)) {
if (!$regs[1])
$req_where[] = "$table.id_rubrique IN (\".calcul_branche(\$id_rubrique).\")";
else
$req_where[] = "('\$id_rubrique'='' OR $table.id_rubrique IN (\".calcul_branche(\$id_rubrique).\"))";
}
// Restriction de valeurs (implicite ou explicite)
else if (ereg('^([a-zA-Z_]+) *(\??) *((!?)(<=?|>=?|==?|\?) *"?([^<>=!"?]*))?"?$', $param, $match)) {
// Variable comparee
$col = $match[1];
$col_table = $table;
// Valeur de comparaison
if ($match[3])
$val = $match[6];
else {
$val = $match[1];
// Si id_parent, comparer l'id_parent avec l'id_objet de la boucle superieure
if ($val == 'id_parent')
$val = $id_objet;
// Si id_enfant, comparer l'id_objet avec l'id_parent de la boucle superieure
else if ($val == 'id_enfant')
$val = 'id_parent';
$val = '$'.$val;
}
// operateur optionnel {lang?}
$ou_rien = ($match[2]) ? "'$val'='' OR " : '';
// Traitement general des relations externes
if ($s = $tables_relations[$type][$col]) {
$col_table = "rel_$type";
$req_from[] = "$s AS $col_table";
$req_where[] = "$table.$id_objet=$col_table.$id_objet";
$req_group = " GROUP BY $table.$id_objet";
$flag_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 = "spip_mots_forum";
else if ($type == 'syndication')
$col_lien = "spip_mots_syndic";
else
$col_lien = 'spip_mots_'.$type;
$req_from[] = "$col_lien AS lien_mot";
$req_from[] = 'spip_mots AS mots';
$req_where[] = "$table.$id_objet=lien_mot.$id_objet";
$req_where[] = "lien_mot.id_mot=mots.id_mot";
$req_group = " GROUP BY $table.$id_objet";
$col_table = 'mots';
$flag_lien = true;
if ($col == 'type_mot')
$col = 'type';
else if ($col == 'titre_mot')
$col = 'titre';
else if ($col == 'id_groupe')
$col = 'id_groupe';
}
// Cas particulier : selection des documents selon l'extension
if ($type == 'documents' AND $col == 'extension') {
$col_table = 'types_d';
}
// 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 = 'source';
// Cas particulier : id_enfant => utiliser la colonne id_objet
if ($col == 'id_enfant')
$col = $id_objet;
// Cas particulier : id_secteur = id_rubrique pour certaines tables
else 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 = "$table.date_redac";
$date_compare = 'date_redac';
}
else {
$date_orig = "$table.$col_date";
$date_compare = 'date';
}
if ($col == 'date') {
$col = $date_orig;
$col_table = '';
}
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 = "(LEAST((UNIX_TIMESTAMP(now())-UNIX_TIMESTAMP($date_orig))/86400, TO_DAYS(now())-TO_DAYS($date_orig), DAYOFMONTH(now())-DAYOFMONTH($date_orig)+30.4368*(MONTH(now())-MONTH($date_orig))+365.2422*(YEAR(now())-YEAR($date_orig))))";
$col_table = '';
}
else if ($col == 'age_relatif') {
$col = "LEAST((UNIX_TIMESTAMP('\$$date_compare')-UNIX_TIMESTAMP($date_orig))/86400, 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 == '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'))
$plat = true;
// Operateur de comparaison
if ($match[5]) {
$op = $match[5];
if ($op == '==') $op = ' REGEXP ';
}
else {
$op = '=';
}
if ($col_table) $col_table .= '.';
$where = "($ou_rien$col_table$col$op'".addslashes($val)."')";
if ($match[4] == '!') $where = "NOT ($where)";
$req_where[] = $where;
}
// Selection du classement
else if (ereg('^par[[:space:]]+([^}]*)$', $param, $match)) {
$tri = trim($match[1]);
if ($tri == 'hasard') { // par hasard
$req_select[] = "MOD($table.$id_objet * UNIX_TIMESTAMP(), 32767) & UNIX_TIMESTAMP() AS alea";
$req_order = " ORDER BY alea";
}
else if ($tri == 'titre_mot'){ // par titre_mot
$req_order= " ORDER BY mots.titre";
}
else if ($tri == 'type_mot'){ // par type_mot
$req_order= " ORDER BY mots.type";
}
else if ($tri == 'points'){ // par points
$req_order= " ORDER BY points";
}
else if (ereg("^num[[:space:]]+([^,]*)(,.*)?",$tri, $match2)) { // par num champ
$req_select[] = "0+$table.".$match2[1]." AS num";
$req_order = " ORDER BY num".$match2[2];
}
else if (ereg("^[a-z0-9]+$", $tri)) { // par champ
$col = $tri;
if ($col == 'date') $col = $col_date;
$req_order = " ORDER BY $table.$col";
}
else { // tris bizarres, par formule composee, virgules, etc.
$req_order = " ORDER BY ".$tri;
}
}
}
}
//
// Post-traitement separe par type
//
switch($type) {
case 'articles':
$post_dates = lire_meta("post_dates");
if ($post_dates == 'non') $req_where[] = "$table.date<NOW()";
$req_where[] = "$table.statut='publie'";
break;
case 'groupes_mots':
// pas de restriction sur les groupes de_mots
break;
case 'mots':
// pas de restriction sur les mots
break;
case 'breves':
$req_where[] = "$table.statut='publie'";
break;
case 'rubriques':
if (!$tout) $req_where[] = "$table.statut='publie'";
break;
case 'forums':
// Par defaut, selectionner uniquement les forums sans pere
if (!$plat) $req_where[] = "$table.id_parent=0";
$req_where[] = "$table.statut='publie'";
break;
case 'signatures':
$req_from[] = 'spip_petitions AS petitions';
$req_from[] = 'spip_articles AS articles';
$req_where[] = "petitions.id_article=articles.id_article";
$req_where[] = "petitions.id_article=$table.id_article";
$req_where[] = "$table.statut='publie'";
$req_group = " GROUP BY $table.$id_objet";
break;
case 'syndic_articles':
$req_select[]='syndic.nom_site AS nom_site';
$req_select[]='syndic.url_site AS url_site';
$req_from[]='spip_syndic AS syndic';
$req_where[] = "syndic.id_syndic=$table.id_syndic";
break;
case 'documents':
$req_where[] = "$table.taille > 0";
break;
case 'auteurs':
// Si pas de lien avec un article, selectionner
// uniquement les auteurs d'un article publie
if (!$tout AND !$flag_lien) {
$req_from[] = 'spip_auteurs_articles AS lien';
$req_from[] = 'spip_articles AS articles';
$req_where[] = "lien.id_auteur=$table.id_auteur";
$req_where[] = "lien.id_article=articles.id_article";
$req_where[] = "articles.statut='publie'";
$req_group = " GROUP BY $table.$id_objet";
}
// pas d'auteurs poubellises
$req_where[] = "NOT($table.statut='5poubelle')";
break;
}
}
//
// Construire la requete
//
if ($type == 'hierarchie')
$requete = $req_limit;
else if ($req_select) {
$requete = 'SELECT '.join(',', $req_select)." FROM ".join(',', $req_from);
if ($req_where) $requete .= " WHERE ".join(" AND ", $req_where);
$requete .= $req_group;
$requete .= $req_order;
if ($req_limit) $requete .= " LIMIT ".$req_limit;
}
$result->type_requete = $type;
$result->requete = $requete;
$result->doublons = $doublons;
$result->lang_select = $lang_select;
$result->separateur = $separateur;
}
//
// Stocker le tout dans le resultat de la fonction
//
$result->id_boucle = $id_boucle;
$result->id_parent = $id_parent;
$result->commande = $commande;
$result->avant = $debut;
$result->cond_avant = parser_texte($cond_avant, $id_parent);
$result->cond_apres = parser_texte($cond_fin, $id_parent);
$result->cond_altern = parser_texte($cond_altern, $id_parent);
$result->milieu = parser_texte($milieu, $id_boucle);
$result->apres = $fin;
$result->partie = $partie;
$result->total_parties = $total_parties;
return $result;
}
function parser_champs($texte) {
global $champs;
global $champs_count;
global $champs_valides;
global $champs_traitement;
global $champs_pretraitement;
global $champs_posttraitement;
$debut = '';
$result=Array();
while ($texte) {
$r = ereg('(#([a-zA-Z_]+)(\*?))', $texte, $regs);
if ($r) {
unset($champ);
$nom_champ = $regs[2];
$flag_brut = $regs[3];
$s = $regs[1];
$p = strpos($texte, $s);
if ($champs_valides[$nom_champ]) {
$debut .= substr($texte, 0, $p);
if ($debut) {
$champ = new Texte;
$champ->texte = $debut;
$result[] = $champ;
}
$champ = new Champ;
$champ->nom_champ = $nom_champ;
$champ->fonctions = $champs_pretraitement[$nom_champ];
if (!$flag_brut AND $champs_traitement[$nom_champ]) {
reset($champs_traitement[$nom_champ]);
while (list(, $f) = each($champs_traitement[$nom_champ])) {
$champ->fonctions[] = $f;
}
}
if ($champs_posttraitement[$nom_champ]) {
reset($champs_posttraitement[$nom_champ]);
while (list(, $f) = each($champs_posttraitement[$nom_champ])) {
$champ->fonctions[] = $f;
}
}
$champs_count++;
$champ->id_champ = $champs_count;
$champs[$champs_count] = $champ;
$result[] = $champ;
$debut = '';
}
else {
$debut .= substr($texte, 0, $p + strlen($s));
}
$texte = substr($texte, $p + strlen($s));
}
else {
$champ = new Texte;
$champ->texte = $debut.$texte;
if ($champ->texte) $result[] = $champ;
break;
}
}
return $result;
}
function parser_champs_etendus($texte) {
global $champs;
global $champs_count;
global $champs_valides;
global $champs_traitement;
global $champs_pretraitement;
global $champs_posttraitement;
$debut = '';
while ($texte) {
$r = ereg('(\[([^\[]*)\(#([a-zA-Z_]+)(\*?)([^])]*)\)([^]]*)\])', $texte, $regs);
if ($r) {
$cond_avant = $regs[2];
$nom_champ = $regs[3];
$flag_brut = $regs[4];
$fonctions = $regs[5];
$cond_apres = $regs[6];
$s = $regs[1];
$p = strpos($texte, $s);
if ($champs_valides[$nom_champ]) {
$debut .= substr($texte, 0, $p);
if ($debut) {
$c = parser_champs($debut);
reset($c);
while (list(, $val) = each($c)) $result[] = $val;
}
$champ = new Champ;
$champ->nom_champ = $nom_champ;
$champ->cond_avant = parser_champs($cond_avant);
$champ->cond_apres = parser_champs($cond_apres);
$champ->fonctions = $champs_pretraitement[$nom_champ];
if (!$flag_brut AND $champs_traitement[$nom_champ]) {
reset($champs_traitement[$nom_champ]);
while (list(, $f) = each($champs_traitement[$nom_champ])) {
$champ->fonctions[] = $f;
}
}
if ($fonctions) {
$fonctions = explode('|', ereg_replace("^\|", "", $fonctions));
reset($fonctions);
while (list(, $f) = each($fonctions)) $champ->fonctions[] = $f;
}
if ($champs_posttraitement[$nom_champ]) {
reset($champs_posttraitement[$nom_champ]);
while (list(, $f) = each($champs_posttraitement[$nom_champ])) {
$champ->fonctions[] = $f;
}
}
$champs_count++;
$champ->id_champ = $champs_count;
$champs[$champs_count] = $champ;
$result[] = $champ;
$debut = '';
}
else {
$debut .= substr($texte, 0, $p + strlen($s));
}
$texte = substr($texte, $p + strlen($s));
}
else {
$c = parser_champs($debut.$texte);
reset($c);
while (list(, $val) = each($c)) $result[] = $val;
break;
}
}
return $result;
}
function parser_texte($texte, $id_boucle) {
global $boucles;
$i = 0;
while ($texte) {
$boucle = parser_boucle($texte, $id_boucle);
if ($boucle->type == 'texte') {
if ($c = parser_champs_etendus($boucle->texte)) {
reset($c);
while (list(, $val) = each($c)) {
$result[$i] = $val;
$i++;
}
}
$texte = '';
}
else {
if ($c = parser_champs_etendus($boucle->avant)) {
reset($c);
while (list(, $val) = each($c)) {
$result[$i] = $val;
$i++;
}
}
$texte = $boucle->apres;
$boucle->avant = '';
$boucle->apres = '';
$result[$i] = $boucle;
$i++;
if (!$boucles[$boucle->id_boucle])
$boucles[$boucle->id_boucle] = $boucle;
else {
include_ecrire ("inc_presentation.php3");
install_debut_html(_T('erreur_boucle_syntaxe'));
$id = $boucle->id_boucle;
echo '<p>'._T('erreur_boucle_double', array('id'=>$id));
install_fin_html();
exit;
}
}
}
return $result;
}
function parser($texte) {
global $racine;
// Parser le texte et retourner le tableau racine
$racine = parser_texte($texte, '');
}
//////////////////////////////////////////////////////////////////////////////
//
// Calcul des squelettes
//
//////////////////////////////////////////////////////////////////////////////
//
// appliquer les filtres a un champ
//
function applique_filtres ($fonctions, $code) {
if ($fonctions) {
while (list(, $fonc) = each($fonctions)) {
if ($fonc) {
$arglist = '';
if (ereg('([^\{\}]*)\{(.+)\}$', $fonc, $regs)) {
$fonc = $regs[1];
if (trim($regs[2]))
$arglist = ','.$regs[2];
}
if (function_exists($fonc))
$code = "$fonc($code$arglist)";
else
$code = "'"._T('erreur_filtre', array('filtre' => $fonc))."'";
}
}
}
return $code;
}
//
// Generer le code PHP correspondant a un champ SPIP
//
function calculer_champ($id_champ, $id_boucle, $nom_var)
{
global $les_notes;
global $boucles;
global $champs;
global $flag_ob;
global $flag_pcre;
$idb = $id_boucle;
//
// Calculer $id_row en prenant la boucle la plus proche
// (i.e. la plus profonde) qui autorise le champ demande
//
$offset_boucle = 0;
while (strlen($idb)) {
// $rows_articles, etc. : tables pregenerees contenant les correspondances
// (nom du champ -> numero de colonne mysql) en fonction du type de requete
$id_row = $GLOBALS['rows_'.$boucles[$idb]->type_requete][$champs[$id_champ]->nom_champ];
if ($id_row) break;
$idb = $boucles[$idb]->id_parent;
$offset_boucle++;
}
//
// Si cas general (le plus simple), generation
// du code php effectuant le calcul du champ
//
if ($id_row) {
$fonctions = $champs[$id_champ]->fonctions;
if ($offset_boucle) $code = "\$pile_boucles[\$id_instance-$offset_boucle]->row[$id_row]";
else $code = "\$row[$id_row]";
$code = applique_filtres ($fonctions, $code);
return " \$$nom_var = $code;\n";
}
//
// Ici traitement des cas particuliers
//
/* $milieu = '<blink>#'.$champs[$id_champ]->nom_champ.'</blink>'; // pour debugger les squelettes
$milieu = " \$$nom_var = '$milieu';\n";*/
$fonctions = $champs[$id_champ]->fonctions;
switch($nom_champ = $champs[$id_champ]->nom_champ) {
//
// Les logos (rubriques, articles...)
//
case 'LOGO_ARTICLE':
case 'LOGO_ARTICLE_NORMAL':
case 'LOGO_ARTICLE_RUBRIQUE':
case 'LOGO_ARTICLE_SURVOL':
case 'LOGO_AUTEUR':
case 'LOGO_AUTEUR_NORMAL':
case 'LOGO_AUTEUR_SURVOL':
case 'LOGO_SITE':
case 'LOGO_BREVE':
case 'LOGO_BREVE_RUBRIQUE':
case 'LOGO_MOT':
case 'LOGO_RUBRIQUE':
case 'LOGO_RUBRIQUE_NORMAL':
case 'LOGO_RUBRIQUE_SURVOL':
case 'LOGO_DOCUMENT':
$milieu = '';
ereg("^LOGO_(([a-zA-Z]+).*)$", $nom_champ, $regs);
$type_logo = $regs[1];
$type_objet = strtolower($regs[2]);
$filtres = '';
if ($fonctions) {
while (list(, $nom) = each($fonctions)) {
if (ereg('^(left|right|center|top|bottom)$', $nom))
$align = $nom;
else if ($nom == 'lien') {
$flag_lien_auto = 'oui';
$flag_stop = true;
}
else if ($nom == 'fichier') {
$flag_fichier = 'oui';
$flag_stop = true;
}
else if ($nom == '') // double || signifie "on passe aux filtres"
$flag_stop = true;
else if (!$flag_stop) {
$lien = $nom;
$flag_stop = true;
}
else // apres un URL ou || ou |fichier ce sont des filtres (sauf left...lien...fichier)
$filtres[] = $nom;
}
// recuperer les filtres s'il y en a
$fonctions = $filtres;
}
if ($flag_lien_auto && !$lien) {
$milieu .= "
\$lien = generer_url_$type_objet(\$contexte['id_$type_objet']);
";
}
else {
$milieu .= '
$lien = transformer_lien_logo($contexte, \''.addslashes($lien).'\');
';
}
if ($type_logo == 'RUBRIQUE') {
$milieu .= '
list($logon, $logoff) = IMG_image(image_rubrique($contexte["id_rubrique"]));
';
}
else if ($type_logo == 'RUBRIQUE_NORMAL') {
$milieu .= '
list($logon,) = IMG_image(image_rubrique($contexte["id_rubrique"]));
$logoff = "";
';
}
else if ($type_logo == 'RUBRIQUE_SURVOL') {
$milieu .= '
list(,$logon) = IMG_image(image_rubrique($contexte["id_rubrique"]));
$logoff = "";
';
}
else if ($type_logo == 'DOCUMENT'){
$milieu .= '
$logon = integre_image($contexte["id_document"],"","fichier_vignette");
$logoff = "";
';
}
else if ($type_logo == 'AUTEUR') {
$milieu .= '
list($logon, $logoff) = IMG_image(image_auteur($contexte["id_auteur"]));
';
}
else if ($type_logo == 'AUTEUR_NORMAL') {
$milieu .= '
list($logon,) = IMG_image(image_auteur($contexte["id_auteur"]));
$logoff = "";
';
}
else if ($type_logo == 'AUTEUR_SURVOL') {
$milieu .= '
list(,$logon) = IMG_image(image_auteur($contexte["id_auteur"]));
$logoff = "";
';
}
else if ($type_logo == 'BREVE') {
$milieu .= '
list($logon, $logoff) = IMG_image(image_breve($contexte["id_breve"]));
';
}
else if ($type_logo == 'BREVE_RUBRIQUE') {
$milieu .= '
list($logon, $logoff) = IMG_image(image_breve($contexte["id_breve"]));
if (!$logon)
list($logon, $logoff) = IMG_image(image_rubrique($contexte["id_rubrique"]));
';
}
else if ($type_logo == 'SITE') {
$milieu .= '
list($logon, $logoff) = IMG_image(image_site($contexte["id_syndic"]));
';
}
else if ($type_logo == 'MOT') {
$milieu .= '
list($logon, $logoff) = IMG_image(image_mot($contexte["id_mot"]));
';
}
else if ($type_logo == 'ARTICLE') {
$milieu .= '
list($logon, $logoff) = IMG_image(image_article($contexte["id_article"]));
';
}
else if ($type_logo == 'ARTICLE_NORMAL') {
$milieu .= '
list($logon,) = IMG_image(image_article($contexte["id_article"]));
$logoff = "";
';
}
else if ($type_logo == 'ARTICLE_SURVOL') {
$milieu .= '
list(,$logon) = IMG_image(image_article($contexte["id_article"]));
$logoff = "";
';
}
else if ($type_logo == 'ARTICLE_RUBRIQUE') {
$milieu .= '
list($logon, $logoff) = IMG_image(image_article($contexte["id_article"]));
if (!$logon)
list($logon, $logoff) = IMG_image(image_rubrique($contexte["id_rubrique"]));
';
}
if ($flag_fichier)
$milieu .= " \$$nom_var = ereg_replace('^/?IMG/','',\$logon);\n"; // compatibilite ascendante : pas de 'IMG/'
else
$milieu .= " \$$nom_var = affiche_logos(\$logon, \$logoff, \$lien, '".addslashes($align)."');\n";
break;
//
// Liste des auteurs d'un article
//
case 'LESAUTEURS':
$milieu = '
if ($i = $contexte["id_article"]) {
$query_auteurs = "SELECT auteurs.nom, auteurs.email FROM spip_auteurs AS auteurs, spip_auteurs_articles AS lien WHERE lien.id_article=$i AND auteurs.id_auteur=lien.id_auteur";
$result_auteurs = spip_query($query_auteurs);
$auteurs = "";
while($row_auteur = spip_fetch_array($result_auteurs)) {
$nom_auteur = typo($row_auteur["nom"]);
$email_auteur = $row_auteur["email"];
if ($email_auteur) {
$auteurs[] = "<A HREF=\"mailto:$email_auteur\">$nom_auteur</A>";
}
else {
$auteurs[] = "$nom_auteur";
}
}
if ($auteurs) $'.$nom_var.' = join($auteurs, ", ");
else $'.$nom_var.' = "";
}
';
break;
//
// Introduction (d'un article, d'une breve ou d'un message de forum)
//
case 'INTRODUCTION':
$code = 'calcul_introduction($pile_boucles[$id_instance]->type_requete,
$pile_boucles[$id_instance]->row[\'texte\'],
$pile_boucles[$id_instance]->row[\'chapo\'],
$pile_boucles[$id_instance]->row[\'descriptif\'])';
break;
//
// Divers types de champs
//
case 'URL_SITE_SPIP':
$code = "lire_meta('adresse_site')";
break;
case 'NOM_SITE_SPIP':
$code = "lire_meta('nom_site')";
break;
case 'EMAIL_WEBMASTER':
$code = "lire_meta('email_webmaster')";
break;
case 'CHARSET':
$code = "lire_meta('charset')";
break;
case 'LANG':
$code = "\$GLOBALS['spip_lang']";
break;
case 'LANG_LEFT':
$code = "lang_dir(\$GLOBALS['spip_lang'],'left','right')";
break;
case 'LANG_RIGHT':
$code = "lang_dir(\$GLOBALS['spip_lang'],'right','left')";
break;
case 'LANG_DIR':
$code = "lang_dir(\$GLOBALS['spip_lang'],'ltr','rtl')";
break;
case 'PUCE':
$code = '$GLOBALS["puce"]';
break;
case 'DATE':
// Uniquement hors-boucles, pour la date passee dans l'URL ou le contexte inclusion
$code = "\$contexte['date']";
break;
case 'DATE_NOUVEAUTES':
$milieu = "if (lire_meta('quoi_de_neuf') == 'oui' AND lire_meta('majnouv'))
\$$nom_var = normaliser_date(lire_meta('majnouv'));
else
\$$nom_var = \"'0000-00-00'\";
";
break;
case 'URL_ARTICLE':
$code = "url_var_recherche(generer_url_article(\$contexte['id_article']), \$contexte['activer_url_recherche'])";
break;
case 'URL_RUBRIQUE':
$code = "url_var_recherche(generer_url_rubrique(\$contexte['id_rubrique']), \$contexte['activer_url_recherche'])";
break;
case 'URL_BREVE':
$code = "url_var_recherche(generer_url_breve(\$contexte['id_breve']), \$contexte['activer_url_recherche'])";
break;
case 'URL_FORUM':
$code = "url_var_recherche(generer_url_forum(\$contexte['id_forum']), \$contexte['activer_url_recherche'])";
break;
case 'URL_MOT':
$code = "url_var_recherche(generer_url_mot(\$contexte['id_mot']), \$contexte['activer_url_recherche'])";
break;
case 'URL_AUTEUR':
$code = "url_var_recherche(generer_url_auteur(\$contexte['id_auteur']), \$contexte['activer_url_recherche'])";
break;
case 'URL_DOCUMENT':
$code = "generer_url_document(\$contexte['id_document'])";
break;
case 'NOTES':
$milieu = '$'.$nom_var.' = $GLOBALS["les_notes"];
$GLOBALS["les_notes"] = "";
$GLOBALS["compt_note"] = 0;
$GLOBALS["marqueur_notes"] ++;
';
break;
case 'RECHERCHE':
$code = 'htmlspecialchars($GLOBALS["recherche"])';
break;
case 'COMPTEUR_BOUCLE':
$code = '$pile_boucles[$id_instance]->compteur_boucle';
break;
case 'TOTAL_BOUCLE':
$code = '$pile_boucles[$id_instance_cond]->total_boucle';
break;
case 'POPULARITE':
$code = 'ceil(min(100, 100 * $pile_boucles[$id_instance]->row[\'popularite\'] / max(1 , 0 + lire_meta(\'popularite_max\'))))';
break;
case 'POPULARITE_ABSOLUE':
$code = 'ceil($pile_boucles[$id_instance]->row[\'popularite\'])';
break;
case 'POPULARITE_SITE':
$code = 'ceil(lire_meta(\'popularite_total\'))';
break;
case 'POPULARITE_MAX':
$code = 'ceil(lire_meta(\'popularite_max\'))';
break;
case 'EXTRA':
$code = 'trim($pile_boucles[$id_instance]->row[\'extra\'])';
if ($fonctions) {
// Gerer la notation [(#EXTRA|isbn)]
include_ecrire("inc_extra.php3");
reset($fonctions);
list($key, $champ_extra) = each($fonctions);
$type_extra = $boucles[$id_boucle]->type_requete;
if (extra_champ_valide($type_extra, $champ_extra)) {
unset($fonctions[$key]);
$code = "extra($code, '".addslashes($champ_extra)."')";
}
// Appliquer les filtres definis par le webmestre
$filtres = extra_filtres($type_extra, $champ_extra);
if ($filtres) {
reset($filtres);
while (list(, $f) = each($filtres)) $code = "$f($code)";
}
}
break;
case 'EXPOSER':
$on = 'on';
$off='';
if ($fonctions) {
// Gerer la notation [(#EXPOSER|on,off)]
reset($fonctions);
list(, $onoff) = each($fonctions);
ereg("([^,]*)(,(.*))?", $onoff, $regs);
$on = addslashes($regs[1]);
$off = addslashes($regs[3]);
// autres filtres
$filtres=Array();
while (list(, $nom) = each($fonctions)) {
$filtres[] = $nom;
}
$fonctions = $filtres;
}
$id_on_off = $GLOBALS['tables_doublons'][$boucles[$id_boucle]->type_requete];
if ($id_on_off)
$code = "(\$GLOBALS[contexte_inclus]['$id_on_off'] == \$contexte['$id_on_off']) ? '$on' : '$off'";
else
$code = "'$off'";
break;
//
// Inserer directement un document dans le squelette
//
case 'EMBED_DOCUMENT':
if ($fonctions) $fonctions = join($fonctions, "|");
$milieu = "
include_ecrire('inc_documents.php3');
\$$nom_var = embed_document(\$contexte['id_document'], '$fonctions', false) ;
";
$fonctions = "";
break;
//
// Formulaire de recherche sur le site
//
case 'FORMULAIRE_RECHERCHE':
if ($fonctions) {
list(, $lien) = each($fonctions); // le premier est un url
while (list(, $filtre) = each($fonctions)) {
$filtres[] = $filtre; // les suivants sont des filtres
}
$fonctions = $filtres;
}
if (!$lien) $lien = 'recherche.php3';
$milieu = "
if (lire_meta('activer_moteur') != 'oui') {
\$$nom_var = '';
}
else {
\$rech = _T('info_rechercher');
\$$nom_var = \"
<form action='$lien' method='get' name='form_rech'>
<input type='text' id='formulaire_recherche' name='recherche' value=\\\"\$rech\\\" size='20' class='formrecherche'\";
\$$nom_var .= \"></form>\";
}
";
break;
//
// Formulaire d'inscription comme redacteur
// (dans inc-formulaires.php3)
case 'FORMULAIRE_INSCRIPTION':
$milieu = '
$request_uri = $GLOBALS["REQUEST_URI"];
$spip_lang = $GLOBALS["spip_lang"];
$accepter_inscriptions = lire_meta("accepter_inscriptions");
if ($accepter_inscriptions == "oui") {
$'.$nom_var.' = "<"."?php
include_local(\"inc-formulaires.php3\");
lang_select(\"$spip_lang\");
formulaire_inscription(\"redac\");
lang_dselect(); ?".">";
}
else {
$'.$nom_var.' = "";
}
';
break;
//
// Formulaire de changement de langue
case 'MENU_LANG':
$milieu = '
$'.$nom_var.' = "<"."?php
include_ecrire(\"inc_lang.php3\");
echo menu_langues(\"var_lang\", \$menu_lang);
?".">";
';
break;
//
// Formulaire de changement de langue / page de login
case 'MENU_LANG_ECRIRE':
$milieu = '
$'.$nom_var.' = "<"."?php
include_ecrire(\"inc_lang.php3\");
echo menu_langues(\"var_lang_ecrire\", \$menu_lang);
?".">";
';
break;
//
// Formulaire pour ecrire a l'auteur
//
case 'FORMULAIRE_ECRIRE_AUTEUR':
$milieu = '
if (email_valide($row[\'email\'])) {
$email = trim($row[\'email\']);
$spip_lang = $GLOBALS["spip_lang"];
$'.$nom_var.' = "<'.'?php
include (\'inc-formulaires.php3\');
lang_select(\"$spip_lang\");
formulaire_ecrire_auteur(".$row[\'id_auteur\'].",\'$email\');
lang_dselect();
?'.'>";
}
';
break;
//
// Formulaire de signature d'une petition
//
case 'FORMULAIRE_SIGNATURE':
$milieu = '
$spip_lang = $GLOBALS["spip_lang"];
$id_petition = $contexte["id_article"];
$query_petition = "SELECT id_article FROM spip_petitions WHERE id_article=$id_petition";
$result_petition = spip_query($query_petition);
if ($row_petition = spip_fetch_array($result_petition)) {
include_local("inc-formulaires.php3");
$texte_formulaire = formulaire_signature($id_petition);
$'.$nom_var.' = "<div class=\'formulaire\'><a name=\'sp$id_petition\'></a>\n";
$'.$nom_var.' .= "<"."?php
if (\$GLOBALS[\'val_confirm\']) {
include_local(\'inc-formulaires.php3\');
lang_select(\'$spip_lang\');
reponse_confirmation($id_petition);
lang_dselect();
}
else if (\$GLOBALS[\'nom_email\'] AND \$GLOBALS[\'adresse_email\']) {
include_local(\'inc-formulaires.php3\');
lang_select(\'$spip_lang\');
reponse_signature($id_petition);
lang_dselect();
}
else {?".">".$texte_formulaire."<"."?php
}
?".">";
$'.$nom_var.' .= "</div>\n";
}
else {
$'.$nom_var.' = "";
}
';
break;
//
// Formulaire de referencement d'un site
//
case 'FORMULAIRE_SITE':
$milieu = '
$request_uri = $GLOBALS["REQUEST_URI"];
$proposer_sites = lire_meta("proposer_sites");
$spip_lang = $GLOBALS["spip_lang"];
if ($proposer_sites == "2") {
$'.$nom_var.' = "<"."?php
include_local(\"inc-formulaires.php3\");
lang_select(\"$spip_lang\");
formulaire_site($contexte[id_rubrique]);
lang_dselect();
?".">";
}
else {
$'.$nom_var.' = "";
}
';
break;
//
// Champ testant la presence d'une petition
//
case 'PETITION':
$milieu = '
$query_petition = "SELECT id_article FROM spip_petitions WHERE id_article=$contexte[id_article]";
$result_petition = spip_query($query_petition);
if (spip_num_rows($result_petition) > 0) $'.$nom_var.' = " ";
else $'.$nom_var.' = "";
';
break;
//
// Formulaire de reponse a un forum
//
case 'FORMULAIRE_FORUM':
$milieu = '
$spip_lang = $GLOBALS["spip_lang"];
$'.$nom_var.' = "<"."?php include_local(\'inc-forum.php3\'); lang_select(\'$spip_lang\'); ";
$'.$nom_var.' .= "';
switch ($boucles[$id_boucle]->type_requete) {
case "articles":
$milieu .= 'echo retour_forum(0, 0, $contexte[id_article], 0, 0); ';
break;
case "breves":
$milieu .= 'echo retour_forum(0, 0, 0, $contexte[id_breve], 0); ';
break;
case "forums":
$milieu .= 'echo retour_forum(0, $contexte[id_forum], 0, 0, 0); ';
break;
case "rubriques":
$milieu .= 'echo retour_forum($contexte[id_rubrique], 0, 0, 0, 0); ';
break;
case "syndication":
$milieu .= 'echo retour_forum(0, 0, 0, 0, $contexte[id_syndic]); ';
break;
default:
$milieu .= 'echo retour_forum(\'$contexte[id_rubrique]\', \'$contexte[id_forum]\', \'$contexte[id_article]\', \'$contexte[id_breve]\', \'$contexte[id_syndic]\'); ';
break;
}
$milieu .= '"; $'.$nom_var.' .= "lang_dselect(); ?".">";
';
break;
//
// Parametres d'appel du formulaire de reponse a un forum
//
case 'PARAMETRES_FORUM':
$milieu = '
$request_uri = $GLOBALS["REQUEST_URI"];
$http_get_vars = $GLOBALS["HTTP_GET_VARS"];
$forums_publics = lire_meta("forums_publics");
if (($contexte["accepter_forum"] == "" AND $forums_publics != "non") OR ($contexte["accepter_forum"] != "" AND $contexte["accepter_forum"] != "non")) {
$lien = substr($request_uri, strrpos($request_uri, "/") + 1);
if (!$lien_retour = $http_get_vars["retour"])
$lien_retour = $lien;
$lien_retour = rawurlencode($lien_retour);
switch ($pile_boucles[$id_instance]->type_requete) {
case "articles":
$'.$nom_var.' = "id_article=$contexte[id_article]";
break;
case "breves":
$'.$nom_var.' = "id_breve=$contexte[id_breve]";
break;
case "rubriques":
$'.$nom_var.' = "id_rubrique=$contexte[id_rubrique]";
break;
case "syndication":
$'.$nom_var.' = "id_syndic=$contexte[id_syndic]";
break;
case "forums":
default:
$liste_champs = array ("id_article","id_breve","id_rubrique","id_syndic","id_forum");
unset($element);
while (list(,$champ) = each ($liste_champs)) {
if ($contexte[$champ]) $element[] = "$champ=$contexte[$champ]";
}
if ($element) $'.$nom_var.' = join("&",$element);
break;
}
$'.$nom_var.' .= "&retour=$lien_retour";
}
else {
$'.$nom_var.' = "";
}
';
break;
//
// Debut et fin de surlignage auto des mots de la recherche
//
case 'DEBUT_SURLIGNE':
if ($flag_ob AND $flag_pcre) {
$milieu = '
$'.$nom_var.' = "<"."?php if (\$var_recherche) { \$mode_surligne = debut_surligne(\$var_recherche, \$mode_surligne); } ?".">";
';
}
break;
case 'FIN_SURLIGNE':
if ($flag_ob AND $flag_pcre) {
$milieu = '
$'.$nom_var.' = "<"."?php if (\$var_recherche) { \$mode_surligne = fin_surligne(\$var_recherche, \$mode_surligne); } ?".">";
';
}
break;
//
// Formulaires de login
//
case 'LOGIN_PRIVE':
$milieu = '
$'.$nom_var.' = "<"."?php include_local (\'inc-login.php3\');
login (\'\', \'prive\'); ?".">";
';
break;
case 'LOGIN_PUBLIC':
$lacible = '\$GLOBALS[\'clean_link\']';
if ($fonctions) {
$filtres = array();
while (list(, $nom) = each($fonctions))
$lacible = "new Link('".$nom."')";
$fonctions = $filtres;
}
$milieu = '
$'.$nom_var.' = "<"."?php include_local (\'inc-login.php3\');
\$cible = ' . $lacible . ';
login (\$cible, false); ?".">";
';
break;
case 'URL_LOGOUT':
if ($fonctions) {
$url = "&url=".$fonctions[0];
$fonctions = array();
} else {
$url = '&url=\'.urlencode(\$clean_link->getUrl()).\'';
}
$milieu = '
$'.$nom_var.' = "<"."?php
if (\$GLOBALS[\'auteur_session\'][\'login\']) {
echo \'spip_cookie.php3?logout_public=\'.\$GLOBALS[\'auteur_session\'][\'login\'].\'' . $url . '\';
} ?".">";
';
break;
//
// Boutons d'administration
//
case 'FORMULAIRE_ADMIN':
$milieu = '
$'.$nom_var.' = "<"."?php \$GLOBALS[\"flag_boutons_admin\"] = true;
if (\$GLOBALS[\"HTTP_COOKIE_VARS\"][\"spip_admin\"]) {
include_local(\"inc-admin.php3\");
afficher_boutons_admin();
} ?".">";
';
break;
default:
$milieu = '<blink>#'.$champs[$id_champ]->nom_champ.'</blink>'; // pour debugger les squelettes
$milieu = " \$$nom_var = '$milieu';\n";
break;
} // switch
if (!$code) $code = "\$$nom_var";
$code = applique_filtres ($fonctions, $code);
if ($code != "\$$nom_var") $milieu .= "\t\$$nom_var = $code;\n";
return $milieu;
}
//
// Generer le code PHP correspondant a une boucle
//
function calculer_boucle($id_boucle, $prefix_boucle)
{
global $boucles;
global $tables_code_contexte, $tables_doublons;
$func = $prefix_boucle.$id_boucle;
$boucle = $boucles[$id_boucle];
//
// Ecrire le debut de la fonction
//
$texte .= "function $func".'($contexte) {
global $pile_boucles, $ptr_pile_boucles, $id_doublons, $rubriques_publiques;
';
//
// Recherche : recuperer les hash a partir de la chaine de recherche
//
if (strpos($boucle->requete, '$hash_recherche')) {
$texte .= '
global $recherche, $hash_recherche, $hash_recherche_strict;
$contexte[\'activer_url_recherche\'] = true;
if (!$hash_recherche)
list($hash_recherche, $hash_recherche_strict) = requete_hash($recherche);
';
} else
$texte .= '
$contexte[\'activer_url_recherche\'] = false;
';
if (ereg('\$date_redac[^_]', $boucle->requete)) {
$texte .= '$contexte[\'date_redac\'] = normaliser_date($contexte[\'date_redac\']);
';
}
if (ereg('\$date[^_]', $boucle->requete)) {
$texte .= '$contexte[\'date\'] = normaliser_date($contexte[\'date\']);
';
}
//
// Recuperation du contexte et creation de l'instance de boucle
//
$texte .= '
if ($contexte) {
reset($contexte);
while (list($key, $val) = each($contexte)) $$key = addslashes($val);
}
$id_instance = $ptr_pile_boucles++;
$id_instance_cond = $id_instance;
$instance = new InstanceBoucle;
$instance->id_boucle = \''.$boucle->id_boucle.'\';
$instance->type_requete = \''.$boucle->type_requete.'\';
$instance->partie = \''.$boucle->partie.'\';
$instance->total_parties = \''.$boucle->total_parties.'\';
$instance->id_instance = $id_instance;
$pile_boucles[$id_instance] = $instance;
$retour = "";
';
//
// Preparation du code de fermeture
//
$code_fin = "
\$ptr_pile_boucles--;
return \$retour;\n}\n";
$type_boucle = $boucle->type_requete;
$requete = $boucle->requete;
$doublons = $boucle->doublons;
$partie = $boucle->partie;
$total_parties = $boucle->total_parties;
$lang_select = ($boucle->lang_select != "non") &&
($type_boucle == 'articles' OR $type_boucle == 'rubriques'
OR $type_boucle == 'hierarchie' OR $type_boucle == 'breves');
//
// Boucle recursive : simplement appeler la boucle interieure
//
if ($type_boucle == 'boucle') {
$texte .= calculer_liste(array($boucles[$boucle->requete]), $prefix_boucle, $id_boucle);
$texte .= $code_fin;
return $texte;
}
//
// Boucle 'hierarchie' : preparation de la requete principale
//
else if ($type_boucle == 'hierarchie') {
$texte .= '
if ($id_article || $id_syndic) $hierarchie = construire_hierarchie($id_rubrique);
else $hierarchie = construire_hierarchie($id_parent);
if ($hierarchie) {
$hierarchie = explode("-", substr($hierarchie, 0, -1));
$hierarchie = join(",", $hierarchie);
}
else $hierarchie = "0";';
$deb_class = 0;
$fin_class = 10000;
if (ereg("([0-9]+),([0-9]*)", $boucle->requete, $match)) {
$deb_class = $match[1];
if ($match[2]) $fin_class = $match[2];
}
if ($doublons == "oui")
$requete = "SELECT *, FIELD(id_rubrique, \$hierarchie) AS _field FROM spip_rubriques WHERE id_rubrique IN (\$hierarchie) AND id_rubrique NOT IN (\$id_doublons[rubriques])";
else
$requete = "SELECT *, FIELD(id_rubrique, \$hierarchie) AS _field FROM spip_rubriques WHERE id_rubrique IN (\$hierarchie)";
$requete .= " ORDER BY _field LIMIT $deb_class,$fin_class";
}
//
// Pour les forums, ajouter le code de gestion du cache
// et de l'activation / desactivation par article
//
if ($type_boucle == 'forums') {
$texte .= '
global $fichier_cache, $requetes_cache;
if (!$id_rubrique AND !$id_article AND !$id_breve AND $id_forum)
$my_id_forum = $id_forum;
else
$my_id_forum = 0;
if (!$id_article) $id_article = 0;
if (!$id_rubrique) $id_rubrique = 0;
if (!$id_breve) $id_breve = 0;
$valeurs = "$id_article, $id_rubrique, $id_breve, $my_id_forum, \'$fichier_cache\'";
if (!$requetes_cache[$valeurs]) {
$query_cache = "INSERT INTO spip_forum_cache (id_article, id_rubrique, id_breve, id_forum, fichier) VALUES ($valeurs)";
spip_query($query_cache);
$requetes_cache[$valeurs] = 1;
}
';
} // forums
//
// Ecrire le code d'envoi de la requete, de recuperation du nombre
// de resultats et de traitement des boucles par parties (e.g. 1/2)
//
$texte .= ' $query = "'.$requete.'";
$result = @spip_query($query);
if (!$result) {
$GLOBALS["delais"]=0;
include_local("inc-debug-squel.php3");
return erreur_requete_boucle($query, $instance->id_boucle);
}
$total_boucle = @spip_num_rows($result);';
if ($partie AND $total_parties) {
$flag_parties = true;
$texte .= '
$debut_boucle = floor(($total_boucle * ($instance->partie - 1) + $instance->total_parties - 1) / $instance->total_parties) + 1;
$fin_boucle = floor(($total_boucle * ($instance->partie) + $instance->total_parties - 1) / $instance->total_parties);
$pile_boucles[$id_instance]->total_boucle = $fin_boucle - $debut_boucle + 1;';
}
else {
$flag_parties = false;
$texte .= '
$pile_boucles[$id_instance]->total_boucle = $total_boucle;';
}
$texte_debut .= '
$pile_boucles[$id_instance]->compteur_boucle = 0;
$compteur_boucle = 0;';
//
// Ecrire le code de recuperation des resultats
//
if ($lang_select)
$texte_debut .= "\n\t\$old_lang = \$GLOBALS['spip_lang'];\n";
$texte_debut .= '
while ($row = @spip_fetch_array($result)) {';
if ($flag_parties) {
$texte_debut .= '
$compteur_boucle++;
if ($compteur_boucle >= $debut_boucle AND $compteur_boucle <= $fin_boucle) {';
}
$texte_debut .= '
$pile_boucles[$id_instance]->compteur_boucle++;
$pile_boucles[$id_instance]->row = $row;';
if ($boucle->separateur)
$texte_debut .= '
if ($retour) $retour .= \''.$boucle->separateur."';";
if ($lang_select)
$texte_debut .= '
if ($row["lang"]) {
$GLOBALS["spip_lang"] = $row["lang"];
$contexte["lang"] = $row["lang"];
}';
// Traitement different selon le type de boucle
$texte_debut .= $tables_code_contexte[$type_boucle];
if ($doublons == "oui")
$texte_debut .= "\n\t\t\$id_doublons['$type_boucle'] .= ','.\$row['".$tables_doublons[$type_boucle]."'];";
// Inclusion du code correspondant a l'interieur de la boucle
$texte_liste = calculer_liste($boucle->milieu, $prefix_boucle, $id_boucle);
// On n'ecrit la boucle "while" que si elle contient du code utile,
// sinon on utlise plutot spip_num_rows() pour recuperer le nombre d'iterations
if ($texte_liste OR $doublons == 'oui') {
$texte .= $texte_debut . $texte_liste;
if ($flag_parties) {
$texte .= "\n\t\t}\n";
}
// Fermeture de la boucle spip_fetch_array et liberation des resultats
$texte .= "\n\t}\n\t@spip_free_result(\$result);\n";
if ($lang_select)
$texte .= ' $GLOBALS["spip_lang"] = $old_lang;'."\n";
}
else {
$texte .= ' $pile_boucles[$id_instance]->compteur_boucle = $pile_boucles[$id_instance]->total_boucle;'."\n";
}
$texte .= $code_fin;
return $texte;
}
//
// Generer le code PHP correspondant a un texte brut
//
function calculer_texte($texte)
{
global $dossier_squelettes;
$dossier = ($dossier_squelettes ? $dossier_squelettes.'/' : '');
$code = "";
$texte = ereg_replace("([\\\\'])", "\\\\1", $texte);
//
// Parties textuelles du squelette
//
// bloc multi
if (eregi('<multi>', $texte)) {
$ouvre_multi = 'extraire_multi(';
$ferme_multi = ')';
} else {
$ouvre_multi = $ferme_multi = '';
}
// Reperer les balises de traduction <:toto:>
while (eregi("<:(([a-z0-9_]+):)?([a-z0-9_]+)(\|[^>]*)?:>", $texte, $match)) {
$chaine = strtolower($match[3]);
if (!($module = $match[2]))
$module = 'local/public/spip'; // ordre des modules a explorer
$remplace = "_T('$module:$chaine')";
if ($filtres = $match[4]) {
$filtres = explode('|',substr($filtres,1));
$remplace = applique_filtres($filtres, $remplace);
}
$texte = str_replace($match[0], "'$ferme_multi.$remplace.$ouvre_multi'", $texte);
}
//
// Reperer les directives d'inclusion de squelette <INCLURE>
//
while (ereg("(<INCLU[DR]E[[:space:]]*\(([-_0-9a-zA-Z./ ]+)\)(([[:space:]]*\{[^}]*\})*)[[:space:]]*>)", $texte, $match)) {
$s = $match[0];
$p = strpos($texte, $s);
$debut = substr($texte, 0, $p);
$texte = substr($texte, $p + strlen($s));
if ($debut)
$code .= " \$retour .= $ouvre_multi'$debut'$ferme_multi;\n";
//
// Traiter la directive d'inclusion
//
$fichier = $match[2];
ereg('^\\{(.*)\\}$', trim($match[3]), $params);
$code .= " \$retour .= '<"."?php ';\n";
$code .= " \$retour .= '\$contexte_inclus = \'\'; ';\n";
if ($params) {
// Traiter chaque parametre de contexte
$params = split("\}[[:space:]]*\{", $params[1]);
reset($params);
while (list(, $param) = each($params)) {
if (ereg("^([_0-9a-zA-Z]+)[[:space:]]*(=[[:space:]]*([^}]+))?$", $param, $args)) {
$var = $args[1];
$val = $args[3];
// cas de la langue
if ($var == 'lang') {
$lang_inclus = "\\'".addslashes($val)."\\'";
if (! $val)
$val = $lang_inclus = '$GLOBALS[spip_lang]';
$code .= " \$retour .= '\$contexte_inclus[$var] = $val; ';\n";
}
else if ($val)
$code .= " \$retour .= '\$contexte_inclus[$var] = \'".addslashes($val)."\'; ';\n";
else
$code .= " \$retour .= '\$contexte_inclus[$var] = \''.addslashes(\$contexte[$var]).'\'; ';\n";
}
}
}
if (!$lang_inclus) $lang_inclus = 'lire_meta(\\\'langue_site\\\')';
$code .= " \$retour .= 'include_ecrire(\'inc_lang.php3\'); lang_select($lang_inclus);';\n";
// inclure en priorite dans le dossier_squelettes
if ($dossier_squelettes) {
$code .= " \$retour .= '
if (@file_exists(\'$dossier_squelettes/$fichier\')){
include(\'$dossier_squelettes/$fichier\');
} else {
include(\'$fichier\');
}';\n";
} else
$code .= " \$retour .= 'include(\'$fichier\');';\n";
$code .= " \$retour .= 'lang_dselect(); ?".">';\n";
}
if ($texte)
$code .= " \$retour .= $ouvre_multi'$texte'$ferme_multi;\n";
return $code;
}
//
// Generer le code PHP correspondant a une liste d'objets syntaxiques
//
function calculer_liste($tableau, $prefix_boucle, $id_boucle)
{
global $boucles;
global $champs;
global $nb_milieu;
$texte = '';
if (!$tableau) return $texte;
reset($tableau);
while (list(, $objet) = each($tableau)) {
$milieu = '';
switch($objet->type) {
/////////////////////
// Texte
//
case 'texte':
$texte .= calculer_texte($objet->texte);
break;
/////////////////////
// Boucle
//
case 'boucle':
$nb_milieu++;
$nom_var = "milieu$nb_milieu";
$nom_func = $prefix_boucle.$objet->id_boucle;
if ($objet->cond_avant || $objet->cond_apres || $objet->cond_altern) {
$texte .= " \$$nom_var = $nom_func(\$contexte);\n";
$texte .= " if (\$$nom_var) {\n";
if ($s = $objet->cond_avant) {
$texte .= calculer_liste($s, $prefix_boucle, $id_boucle);
}
$texte .= " \$retour .= \$$nom_var;\n";
if ($s = $objet->cond_apres) {
$texte2 = calculer_liste($s, $prefix_boucle, $id_boucle);
if (strpos($texte2, '$id_instance_cond')) {
$texte .= " \$id_instance_cond++;\n";
$texte .= $texte2;
$texte .= " \$id_instance_cond--;\n";
}
else $texte .= $texte2;
}
$texte .= " }\n";
if ($s = $objet->cond_altern) {
$texte .= " else {\n";
$texte2 = calculer_liste($s, $prefix_boucle, $id_boucle);
if (strpos($texte2, '$id_instance_cond')) {
$texte .= " \$id_instance_cond++;\n";
$texte .= $texte2;
$texte .= " \$id_instance_cond--;\n";
}
else $texte .= $texte2;
$texte .= " }\n";
}
}
else {
$texte .= " \$retour .= $nom_func(\$contexte);\n";
}
$nb_milieu--;
break;
/////////////////////
// Champ
//
case 'champ':
$nb_milieu++;
if ($objet->cond_avant || $objet->cond_apres) {
$nom_var = "milieu$nb_milieu";
$texte .= calculer_champ($objet->id_champ, $id_boucle, $nom_var);
$texte .= " if (\$$nom_var) {\n";
if ($s = $objet->cond_avant) {
$texte .= calculer_liste($s, $prefix_boucle, $id_boucle);
}
$texte .= " \$retour .= \$$nom_var;\n";
if ($s = $objet->cond_apres) {
$texte .= calculer_liste($s, $prefix_boucle, $id_boucle);
}
$texte .= " }\n";
}
else {
$nom_var = "milieu$nb_milieu";
$texte2 = calculer_champ($objet->id_champ, $id_boucle, $nom_var);
$c = count(explode("\$$nom_var", $texte2));
if ($c <= 2) {
$texte2 = str_replace("\$$nom_var = ", "\$retour .= ", $texte2);
$texte .= $texte2;
}
else {
$texte .= $texte2;
$texte .= " \$retour .= \$$nom_var;\n";
}
}
$nb_milieu--;
break;
} // switch
} // while
return $texte;
}
//
// Calculer le squelette : i.e. generer le fichier PHP correspondant
//
function calculer_squelette($squelette, $fichier) {
global $racine;
global $boucles;
$boucles = '';
$racine = '';
$html = join(file("$squelette.html"), "");
parser($html);
$squelette_nom = ereg_replace("[^a-zA-Z0-9_]", "_", $squelette);
$func = 'squelette_'.$squelette_nom.'_executer';
$prefix = $func.'_boucle';
$define = strtoupper("_SKEL_$squelette_nom");
// Debut du fichier
$texte .= "<"."?php\n\n";
$texte .= "\$func_squelette_executer = '$func';\n\n";
$texte .= "if (defined(\"$define\")) return;\n";
$texte .= "define(\"$define\", \"1\");\n\n\n";
// Calculer le code PHP des boucles
if ($boucles) {
reset($boucles);
while (list($id_boucle, ) = each($boucles)) {
$texte .= calculer_boucle($id_boucle, $prefix);
$texte .= "\n\n";
}
}
// Calculer le code PHP de la racine
$texte .= "function $func(\$contexte) {\n";
$texte .= " global \$pile_boucles, \$id_instance_cond;\n \$pile_boucles = Array();\n \$id_instance_cond = -1;\n"; // pour #TOTAL_BOUCLE
$texte .= calculer_liste($racine, $prefix, '');
$texte .= " return \$retour;\n";
$texte .= "}\n\n";
// Fin du fichier
$texte .= '?'.'>';
$f = fopen($fichier, "wb");
fwrite($f, $texte);
fclose($f);
}
?>