diff --git a/ecrire/inc_filtres.php3 b/ecrire/inc_filtres.php3 index 9a2018162831f448d42cfa9db38eb3bf56a114e8..e521db6e4ede6e9d841a1e3b0f6b4dd90b62143b 100644 --- a/ecrire/inc_filtres.php3 +++ b/ecrire/inc_filtres.php3 @@ -208,6 +208,19 @@ function vider_url($url) { return $url; } +// +// Ajouter le &var_recherche=toto dans les boucles de recherche +// +function url_var_recherche($url) { + if ($GLOBALS['HTTP_GET_VARS']['recherche'] + AND !ereg("var_recherche", $url)) { + $url .= strpos($url, '?') ? '&' : '?'; + $url .= "var_recherche=".urlencode($GLOBALS['recherche']); + } + return $url; +} + + // Extraire une date de n'importe quel champ (a completer...) function extraire_date($texte) { // format = 2001-08 diff --git a/ecrire/inc_texte.php3 b/ecrire/inc_texte.php3 index 117eb81077abe294b1cdf2f6278686edf94d9fc6..579d9d46d3b917dcd80fefd8e1c59731709ef01b 100644 --- a/ecrire/inc_texte.php3 +++ b/ecrire/inc_texte.php3 @@ -478,6 +478,8 @@ function typo($letexte) { // de la regexp ci-dessous, et elle retourne le texte a inserer a la place // et le lien "brut" a usage eventuel de redirection... function extraire_lien ($regs) { + global $flag_ecrire; + $lien_texte = $regs[1]; $lien_url = trim($regs[3]); @@ -485,13 +487,12 @@ function extraire_lien ($regs) { $lien_interne = false; if (ereg('^[[:space:]]*(art(icle)?|rub(rique)?|br(.ve)?|aut(eur)?|mot|site|doc(ument)?|im(age|g))?[[:space:]]*([[:digit:]]+)(#.*)?[[:space:]]*$', $lien_url, $match)) { // Traitement des liens internes - if (@file_exists('inc-urls.php3')) { + if ($flag_ecrire) + include_ecrire('inc_urls.php3'); + else if (@file_exists('inc-urls.php3')) include_local('inc-urls.php3'); - } elseif (@file_exists('inc-urls-dist.php3')) { + else if (@file_exists('inc-urls-dist.php3')) include_local('inc-urls-dist.php3'); - } else { - include_ecrire('inc_urls.php3'); - } $id_lien = $match[8]; $ancre = $match[9]; diff --git a/ecrire/inc_version.php3 b/ecrire/inc_version.php3 index 0c4201251c56d59930f24db9fb241483cd1abd86..ed8b94e415e560772ac4bb460b72726f312700ab 100644 --- a/ecrire/inc_version.php3 +++ b/ecrire/inc_version.php3 @@ -1099,7 +1099,14 @@ function spip_log($message, $logname='spip') { @rename($logfile.'.2',$logfile.'.3'); @rename($logfile.'.1',$logfile.'.2'); @rename($logfile,$logfile.'.1'); + #if (function_exists('logrotate')) + # logrotate($logfile); } + + // recopier les spip_log mysql (ce sont uniquement des erreurs) + // dans le spip_log general + if ($logname == 'mysql') + spip_log($message); } // diff --git a/inc-admin.php3 b/inc-admin.php3 index 7c5df9b46ee5a3675fff7d6852a2e0f037825104..7b84e58e5f1e7f42b362ca526ef53e0476460fda 100644 --- a/inc-admin.php3 +++ b/inc-admin.php3 @@ -265,7 +265,8 @@ function erreur_requete_boucle($query, $id_boucle, $type) { // function erreur_squelette($message, $fautif, $lieu) { global $auteur_session, $debug_messages; - + static $runs; + // Drapeau pour interdire d'ecrire les fichiers dans le cache # define('spip_erreur_fatale', 'erreur_squelette'); # En fait, a partir du moment ou l'erreur est dans le squelette, @@ -289,6 +290,9 @@ function erreur_squelette($message, $fautif, $lieu) { $debug_messages .= "<div style='position: fixed; top: 10px; left: 10px; z-index: 10000; background-color: pink;'>$message</div>"; } + + // Eviter les boucles infernales + if (++$runs > 4) die ($debug_messages); } ?> diff --git a/inc-balises.php3 b/inc-balises.php3 new file mode 100644 index 0000000000000000000000000000000000000000..f7a0da647569ab154e3f78e2bd12a9b2adca69a5 --- /dev/null +++ b/inc-balises.php3 @@ -0,0 +1,687 @@ +<?php + +// +// Ce fichier regroupe la quasi totalite des definitions de #BALISES de spip +// Pour chaque balise, il est possible de surcharger, dans mes_fonctions.php3, +// la fonction balise_TOTO_dist par une fonction balise_TOTO() respectant la +// meme API : recoit en entree plein de donnees, les modifie et les retourne. +// Le format du bloc de donnees $p est un objet de la class ParamChamp, +// definie dans inc-compilo-index.php3 +// + +## NB: les fonctions de forum sont definies dans inc-forum.php3 + + +// Ce fichier ne sera execute qu'une fois +if (defined("_INC_BALISES")) return; +define("_INC_BALISES", "1"); + + +function balise_NOM_SITE_SPIP_dist($p) { + $p->code = "lire_meta('nom_site')"; + $p->type = 'php'; + return $p; +} + +function balise_EMAIL_WEBMASTER_dist($p) { + $p->code = "lire_meta('email_webmaster')"; + $p->type = 'php'; + return $p; +} + +function balise_CHARSET_dist($p) { + $p->code = "lire_meta('charset')"; + $p->type = 'php'; + return $p; +} + + +function balise_LANG_LEFT_dist($p) { + $p->code = "lang_dir(\$spip_lang,'left','right')"; + $p->type = 'php'; + return $p; +} + +function balise_LANG_RIGHT_dist($p) { + $p->code = "lang_dir(\$spip_lang,'right','left')"; + $p->type = 'php'; + return $p; +} + +function balise_LANG_DIR_dist($p) { + $p->code = "lang_dir(\$spip_lang,'ltr','rtl')"; + $p->type = 'php'; + return $p; +} + +function balise_PUCE_dist($p) { + $p->code = "propre('- ')"; + $p->type = 'php'; + return $p; +} + + +// #DATE +// Cette fonction sait aller chercher dans le contexte general +// quand #DATE est en dehors des boucles +// http://www.spip.net/fr_article1971.html +function balise_DATE_dist ($p) { + $_date = champ_sql('date', $p); + $p->code = "$_date"; + $p->process = 'vider_date(%s)'; + $p->type = 'php'; + return $p; +} + +// #DATE_REDAC +// http://www.spip.net/fr_article1971.html +function balise_DATE_REDAC_dist ($p) { + $_date = champ_sql('date_redac', $p); + $p->code = "$_date"; + $p->process = 'vider_date(%s)'; + $p->type = 'php'; + return $p; +} + +// #DATE_MODIF +// http://www.spip.net/fr_article1971.html +function balise_DATE_MODIF_dist ($p) { + $_date = champ_sql('date_modif', $p); + $p->code = "$_date"; + $p->process = 'vider_date(%s)'; + $p->type = 'php'; + return $p; +} + +// #DATE_NOUVEAUTES +// http://www.spip.net/fr_article1971.html +function balise_DATE_NOUVEAUTES_dist($p) { + $p->code = "((lire_meta('quoi_de_neuf') == 'oui' AND lire_meta('majnouv')) ? normaliser_date(lire_meta('majnouv')) : \"'0000-00-00'\")"; + $p->process = 'vider_date(%s)'; + $p->type = 'php'; + return $p; +} + +function balise_URL_SITE_SPIP_dist($p) { + $p->code = "lire_meta('adresse_site')"; + $p->type = 'php'; + return $p; +} + + +function balise_URL_ARTICLE_dist($p) { + $_type = $p->type_requete; + + // Cas particulier des boucles (SYNDIC_ARTICLES) + if ($_type == 'syndic_articles') { + $p->code = champ_sql('url', $p); + } + + // Cas general : chercher un id_article dans la pile + else { + $_id_article = champ_sql('id_article', $p); + $p->code = "generer_url_article($_id_article)"; + + if ($p->boucles[$p->id_boucle]->hash) + $p->code = "url_var_recherche(" . $p->code . ")"; + } + + $p->type = 'html'; + return $p; +} + +function balise_URL_RUBRIQUE_dist($p) { + $p->code = "generer_url_rubrique(" . + champ_sql('id_rubrique',$p) . + ")" ; + if ($p->boucles[$p->id_boucle]->hash) + $p->code = "url_var_recherche(" . $p->code . ")"; + + $p->type = 'html'; + return $p; +} + +function balise_URL_BREVE_dist($p) { + $p->code = "generer_url_breve(" . + champ_sql('id_breve',$p) . + ")"; + if ($p->boucles[$p->id_boucle]->hash) + $p->code = "url_var_recherche(" . $p->code . ")"; + + $p->type = 'html'; + return $p; +} + +function balise_URL_MOT_dist($p) { + $p->code = "generer_url_mot(" . + champ_sql('id_mot',$p) . + ")"; + $p->code = "url_var_recherche(" . $p->code . ")"; + + $p->type = 'html'; + return $p; +} + +function balise_URL_FORUM_dist($p) { + $p->code = "generer_url_forum(" . + champ_sql('id_forum',$p) .")"; + + $p->type = 'html'; + return $p; +} + +function balise_URL_DOCUMENT_dist($p) { + $p->code = "generer_url_document(" . + champ_sql('id_document',$p) . ")"; + + $p->type = 'html'; + return $p; +} + +function balise_URL_AUTEUR_dist($p) { + $p->code = "generer_url_auteur(" . + champ_sql('id_auteur',$p) .")"; + if ($p->boucles[$p->id_boucle]->hash) + $p->code = "url_var_recherche(" . $p->code . ")"; + + $p->type = 'html'; + return $p; +} + +function balise_NOTES_dist($p) { + // Recuperer les notes + $p->code = '$GLOBALS["les_notes"]'; + // Vider ensuite les globales des notes recuperees + // avec une formule qui renvoit toujours "" + $p->code .= '. ($GLOBALS["les_notes"] = $GLOBALS["compt_note"] = ' + . '($GLOBALS["marqueur_notes"]++)?"":"")'; + $p->type = 'html'; + return $p; +} + +function balise_RECHERCHE_dist($p) { + $p->code = 'htmlspecialchars($GLOBALS["recherche"])'; + $p->type = 'php'; + return $p; +} + +function balise_COMPTEUR_BOUCLE_dist($p) { + $p->code = '$compteur_boucle'; + $p->type = 'php'; + return $p; +} + +function balise_TOTAL_BOUCLE_dist($p) { + if ($p->id_mere === '') { + include_local("inc-admin.php3"); + erreur_squelette(_L("Champ #TOTAL_BOUCLE hors boucle"), '', $p->id_boucle); + } + $p->code = "\$Numrows['$p->id_mere']"; + $p->boucles[$p->id_mere]->numrows = true; + $p->type = 'php'; + return $p; +} + +function balise_POINTS_dist($p) { + $n = 0; + $b = $p->id_boucle; + $p->code = ''; + while ($b != '') { + if ($s = $p->boucles[$b]->param) { + foreach($s as $v) { + if (strpos($v,'recherche') !== false) { + $p->code = '$Pile[$SP' . (($n==0) ? "" : "-$n") . + '][points]'; + $b = ''; + break; + } + } + } + $n++; + $b = $p->boucles[$b]->id_parent; + } + if (!$p->code) { + include_local("inc-admin.php3"); + erreur_squelette(_L("Champ #POINTS hors d'une recherche"), '', $p->id_boucle); + } + $p->type = 'php'; + return $p; +} + +function balise_POPULARITE_ABSOLUE_dist($p) { + $p->code = 'ceil(' . + champ_sql('popularite', $p) . + ')'; + $p->type = 'php'; + return $p; +} + +function balise_POPULARITE_SITE_dist($p) { + $p->code = 'ceil(lire_meta(\'popularite_total\'))'; + $p->type = 'php'; + return $p; +} + +function balise_POPULARITE_MAX_dist($p) { + $p->code = 'ceil(lire_meta(\'popularite_max\'))'; + $p->type = 'php'; + return $p; +} + +function balise_EXPOSER_dist($p) { + global $table_primary; + $on = 'on'; + $off= ''; + if ($p->fonctions) { + // Gerer la notation [(#EXPOSER|on,off)] + reset($p->fonctions); + list(, $onoff) = each($p->fonctions); + ereg("([^,]*)(,(.*))?", $onoff, $regs); + $on = addslashes($regs[1]); + $off = addslashes($regs[3]); + + // autres filtres + $filtres=Array(); + while (list(, $nom) = each($p->fonctions)) + $filtres[] = $nom; + $p->fonctions = $filtres; + } + + $type_boucle = $p->type_requete; + $primary_key = $table_primary[$type_boucle]; + + $p->code = '(calcul_exposer(' + .champ_sql($primary_key, $p) + .', "'.$primary_key.'", $Pile[0]) ?'." '$on': '$off')"; + $p->type = 'php'; + return $p; +} + + +// +// Inserer directement un document dans le squelette +// +function balise_EMBED_DOCUMENT_dist($p) { + $_id_document = champ_sql('id_document',$p); + $p->code = "embed_document($_id_document, '" . + texte_script($p->fonctions ? join($p->fonctions, "|") : "") . + "', false)"; + unset ($p->fonctions); + $p->type = 'html'; + return $p; +} + +// Debut et fin de surlignage auto des mots de la recherche +// on insere une balise Span avec une classe sans spec: +// c'est transparent s'il n'y a pas de recherche, +// sinon elles seront remplacees par les fontions de inc_surligne +// flag_pcre est juste une flag signalant que preg_match est dispo. + +function balise_DEBUT_SURLIGNE_dist($p) { + global $flag_pcre; + $p->code = ($flag_pcre ? ('\'<span class="spip_surligneconditionnel">\'') : "''"); + return $p; +} +function balise_FIN_SURLIGNE_dist($p) { + global $flag_pcre; + $p->code = ($flag_pcre ? ('\'</span class="spip_surligneconditionnel">\'') : "''"); + return $p; +} + +// Formulaire de changement de langue +function balise_MENU_LANG_dist($p) { + $p->code = '"<"."?php +include_ecrire(\"inc_lang.php3\"); +echo menu_langues(\"var_lang\", \$menu_lang); +?".">"'; + $p->type = 'php'; + return $p; +} + +// Formulaire de changement de langue / page de login +function balise_MENU_LANG_ECRIRE_dist($p) { + $p->code = '"<"."?php +include_ecrire(\"inc_lang.php3\"); +echo menu_langues(\"var_lang_ecrire\", \$menu_lang); +?".">"'; + $p->type = 'php'; + return $p; +} + +// +// Formulaires de login +// +function balise_LOGIN_PRIVE_dist($p) { + $p->code = '"<"."?php include(\'inc-login.php3\'); login(\'\', \'prive\'); ?".">"'; + $p->type = 'php'; + return $p; +} + +function balise_LOGIN_PUBLIC_dist($p) { + if ($nom = $p->fonctions[0]) + $lacible = "new Link('".$nom."')"; + else + $lacible = '\$GLOBALS[\'clean_link\']'; + $p->code = '"<"."?php include(\'inc-login.php3\'); login(' . $lacible . ', false); ?".">"'; + $p->fonctions = array(); + $p->type = 'php'; + return $p; +} + +function balise_URL_LOGOUT_dist($p) { + if ($p->fonctions) { + $url = "&url=".$p->fonctions[0]; + $p->fonctions = array(); + } else { + $url = '&url=\'.urlencode(\$clean_link->getUrl()).\''; + } + $p->code = '"<"."?php if (\$GLOBALS[\'auteur_session\'][\'login\']) +{ echo \'spip_cookie.php3?logout_public=\'.\$GLOBALS[\'auteur_session\'][\'login\'].\'' . $url . '\'; } ?".">"'; + $p->type = 'php'; + return $p; +} + +function balise_INTRODUCTION_dist ($p) { + $_type = $p->type_requete; + $_texte = champ_sql('texte', $p); + $_chapo = champ_sql('chapo', $p); + $_descriptif = champ_sql('descriptif', $p); + $p->code = "calcul_introduction('$_type', $_texte, $_chapo, $_descriptif)"; + + $p->type = 'html'; + return $p; +} + + +// #LANG +// non documente ? +function balise_LANG_dist ($p) { + $_lang = champ_sql('lang', $p); + $p->code = "($_lang ? $_lang : \$GLOBALS['spip_lang'])"; + $p->type = 'php'; + return $p; +} + + +// #LESAUTEURS +// les auteurs d'un article (ou d'un article syndique) +// http://www.spip.net/fr_article902.html +// http://www.spip.net/fr_article911.html +function balise_LESAUTEURS_dist ($p) { + // Cherche le champ 'lesauteurs' dans la pile + $_lesauteurs = champ_sql('lesauteurs', $p); + + // Si le champ n'existe pas (cas de spip_articles), on donne la + // construction speciale sql_auteurs(id_article) ; + // dans le cas contraire on prend le champ 'les_auteurs' (cas de + // spip_syndic_articles) + if ($_lesauteurs AND $_lesauteurs != '$Pile[0][lesauteurs]') { + $p->code = $_lesauteurs; + } else { + $_id_article = champ_sql('id_article', $p); + + # On pourrait mieux faire qu'utiliser cette fonction assistante ? + $p->code = "sql_auteurs($_id_article)"; + } + + $p->type = 'html'; + return $p; +} + + +// #PETITION +// Champ testant la presence d'une petition +// non documente ??? +function balise_PETITION_dist ($p) { + $_id_article = champ_sql('id_article', $p); + $p->code = 'sql_petitions($_id_article)'; + $p->type = 'php'; + return $p; +} + + +// #POPULARITE +// http://www.spip.net/fr_article1846.html +function balise_POPULARITE_dist ($p) { + $_popularite = champ_sql('popularite', $p); + $p->code = "ceil(min(100, 100 * $_popularite + / max(1 , 0 + lire_meta('popularite_max'))))"; + $p->type = 'php'; + return $p; +} + + +// +// Fonction commune aux balises #LOGO_XXXX +// (les balises portant ce type de nom sont traitees en bloc ici) +// +function calcul_balise_logo ($p) { + + // analyser la balise LOGO_xxx + eregi("^LOGO_(([A-Z]+)(_.*)?)", $p->nom_champ, $regs); + $type_logo = $regs[1]; // ARTICLE_RUBRIQUE + $type_objet = $regs[2]; // ARTICLE + $suite_logo = $regs[3]; // _RUBRIQUE + $_id_objet = champ_sql("id_$type_objet", $p); + + // analyser les filtres + $flag_fichier = 'false'; + $filtres = ''; + if (is_array($p->fonctions)) { + foreach($p->fonctions as $nom) { + 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 = 'true'; + $flag_stop = true; + } + // double || signifie "on passe aux filtres" + else if ($nom == '') + $flag_stop = true; + else if (!$flag_stop) { + $lien = $nom; + $flag_stop = true; + } + // apres un URL ou || ou |fichier ce sont + // des filtres (sauf left...lien...fichier) + else + $filtres[] = $nom; + } + // recuperer les autres filtres s'il y en a + $p->fonctions = $filtres; + } + + // + // Preparer le code du lien + // + // 1. filtre |lien + if ($flag_lien_auto AND !$lien) + $code_lien = '($lien = generer_url_'.$type_objet.'('.$_id_objet.')) ? $lien : ""'; + // 2. lien indique en clair (avec des balises : imprimer#ID_ARTICLE.html) + else if ($lien) { + $code_lien = "'".texte_script(trim($lien))."'"; + while (ereg("^([^#]*)#([A-Za-z_]+)(.*)$", $code_lien, $match)) { + $c = calculer_champ(array(), $match[2], $p->id_boucle, $p->boucles, $p->id_mere); + $code_lien = str_replace('#'.$match[2], "'.".$c.".'", $code_lien); + } + // supprimer les '' disgracieux + $code_lien = ereg_replace("^''\.|\.''$", "", $code_lien); + } + if (!$code_lien) + $code_lien = "''"; + + switch ($suite_logo) { + case '_NORMAL': + $onoff = 'true, false'; + break; + case '_SURVOL': + $onoff = 'false, true'; + break; + case '': + default: + $onoff = 'true, true'; + break; + } + + // cas des documents + if ($type_objet == 'DOCUMENT') + $code_logo = + "array(integre_image($_id_objet,'','fichier_vignette'), '')"; + else + $code_logo = "cherche_logo_objet('$type_objet', + $_id_objet, $onoff)"; + + // cas des logo #BREVE_RUBRIQUE et #ARTICLE_RUBRIQUE + if ($suite_logo == '_RUBRIQUE') { + $_id_rubrique = champ_sql("id_rubrique", $p); + $code_logo = "(\$logo = $code_logo) ? \$logo : ". + "cherche_logo_objet('RUBRIQUE', $_id_rubrique, $onoff)"; + } + + $p->code = "affiche_logos($code_logo, $code_lien, '$align', $flag_fichier)"; + + $p->type = 'php'; + return $p; +} + +// #EXTRA [(#EXTRA|isbn)] +// Champs extra +// Non documentes, en voie d'obsolescence, cf. ecrire/inc_extra.php3 +function balise_EXTRA_dist ($p) { + $_extra = champ_sql('extra', $p); + $p->code = $_extra; + + // Gerer la notation [(#EXTRA|isbn)] + if ($p->fonctions) { + include_ecrire("inc_extra.php3"); + list ($key, $champ_extra) = each($p->fonctions); // le premier filtre + $type_extra = $p->type_requete; + // ci-dessus est sans doute un peu buggue : si on invoque #EXTRA + // depuis un sous-objet sans champ extra d'un objet a champ extra, + // on aura le type_extra du sous-objet (!) + if (extra_champ_valide($type_extra, $champ_extra)) { + unset($p->fonctions[$key]); + $p->code = "extra($p->code, '".addslashes($champ_extra)."')"; + + // Appliquer les filtres definis par le webmestre + $filtres = extra_filtres($type_extra, $champ_extra); + if ($filtres) foreach ($filtres as $f) + $p->code = "$f($p->code)"; + } + } + + $p->type = 'html'; + return $p; +} + + + +// +// Traduction des champs "formulaire" +// + +// +// Note : les balises de gestion de forums (FORMULAIRE_FORUM et +// PARAMETRES_FORUM) sont definies dans le fichier inc-forum.php3 +// qui centralise toute la gestion des forums +// + +// +// Formulaire de recherche +// +function balise_FORMULAIRE_RECHERCHE_dist($p) { + if ($p->fonctions) { + list(, $lien) = each($p->fonctions); // le premier est un url + while (list(, $filtre) = each($p->fonctions)) + $filtres[] = $filtre; // les suivants sont des filtres + $p->fonctions = $filtres; + } + if (!$lien) $lien = 'recherche.php3'; + + $formulaire_recherche = "\"<form action='$lien' method='get' class='formrecherche'><input type='text' id='formulaire_recherche' size='20' class='formrecherche' name='recherche' value='\" . _T('info_rechercher') . \"' /></form>\""; + + $p->code = "((lire_meta('activer_moteur') != 'oui') ? '' : + $formulaire_recherche)"; + + $p->type = 'html'; + return $p; +} + + +// +// Formulaire d'inscription comme redacteur (dans inc-formulaires.php3) +// +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(); ?".">")'; + + $p->type = 'php'; + return $p; +} + +// +// Formulaire ecrire auteur +// +function balise_FORMULAIRE_ECRIRE_AUTEUR_dist($p) { + $_id_auteur = champ_sql('id_auteur', $p); + $_mail_auteur = champ_sql('email', $p); + + $p->code = '!email_valide('.$_mail_auteur.') ? "" : + ("<'.'?php include(\'inc-formulaires.php3\'); + lang_select(\'$spip_lang\'); + formulaire_ecrire_auteur(".'.$_id_auteur.'.", \'".texte_script('.$_mail_auteur.')."\'); + lang_dselect(); ?'.'>")'; + + $p->type = 'php'; + return $p; +} + +// +// Formulaire signature de petition +// +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\'); + lang_select(\'$spip_lang\'); + echo formulaire_signature(".'.$_id_article.'.", + \'".texte_script(serialize($petition))."\'); + lang_dselect(); ?".">")'; + + $p->type = 'php'; + return $p; +} + +// Formulaire d'inscription de site dans l'annuaire +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\'); + lang_select(\'".$GLOBALS[\'spip_lang\']."\'); + formulaire_site(".'.$_id_rubrique.'."); + lang_dselect(); ?".">"'; + + $p->type = 'php'; + return $p; +} + + + +// +// Boutons d'administration: +// +function balise_FORMULAIRE_ADMIN_dist($p) { + $p->code = "'<!-- @@formulaire_admin@@45609871@@ -->'"; + $p->type = "php"; + return $p; +} + + +?> diff --git a/inc-calcul_mysql3.php b/inc-calcul-outils.php3 similarity index 50% rename from inc-calcul_mysql3.php rename to inc-calcul-outils.php3 index ed83467e5fc5c0459ce8e7be31bc74ea3d93e682..1a3cf524483482776ff638879bad87a74ce42905 100644 --- a/inc-calcul_mysql3.php +++ b/inc-calcul-outils.php3 @@ -1,63 +1,176 @@ <?php - -# Ce fichier concentre tous les appels SQL lors de l'execution d'un squelette. - -# Cette fonction est syste'matiquement appelee par les squelettes -# pour constuire une requete SQL a` partir de la boucle SPIP originale. -# Elle construit et exe'cute une reque^te SQL correspondant a` une balise Boucle -# Elle notifie une erreur SQL dans le flux de sortie et termine le processus. -# Sinon, retourne la ressource interrogeable par fetch_row ou fetch_array. -# Elle peut etre re'de'finie pour s'interfacer avec d'autres serveurs SQL -# Recoit en argument: -# - le tableau des champs a` ramener -# - le tableau des tables a` consulter -# - le tableau des conditions a` remplir -# - le crite`re de regroupement -# - le crite`re de classement -# - le crite`re de limite -# - une sous-requete e'ventuelle (MySQL > 4.1) -# - un compteur de sous-requete -# - le nom de la table -# - le nom de la boucle (pour le message d'erreur e'ventuel) - -## NB : le traitement des SQL de forums est defini dans inc-forum.php3 - -function spip_abstract_select ( - $select = array(), $from = array(), $where = '', - $groupby = '', $orderby = '', $limit = '', - $sousrequete = '', $cpt = '', - $table = '', $id = '') { - - $DB = 'spip_'; - $q = " FROM $DB" . join(", $DB", $from) - . (is_array($where) ? ' WHERE ' . join(' AND ', $where) : '') - . ($groupby ? " GROUP BY $groupby" : '') - . ($orderby ? "\nORDER BY $orderby" : '') - . ($limit ? "\nLIMIT $limit" : ''); - - if (!$sousrequete) - $q = " SELECT ". join(", ", $select) . $q; - else - $q = " SELECT S_" . join(", S_", $select) - . " FROM (" . join(", ", $select) - . ", COUNT(".$sousrequete.") AS compteur " . $q - .") AS S_$table WHERE compteur=" . $cpt; - - // - // Erreur ? C'est du debug, ou une erreur du serveur - // - if (!($result = @spip_query($q))) { - include_local('inc-admin.php3'); - echo erreur_requete_boucle($q, $id, $table); + +// +// Des fonctions diverses utilisees lors du calcul d'une page ; ces fonctions +// bien pratiques n'ont gu俊e de logique organisationnelle ; elles sont +// appelees par certaines balises au moment du calcul des pages. (Peut-on +// trouver un modele de donnees qui les associe physiquement au fichier +// definissant leur balise ??? +// + +// ON TROUVERA EN QUEUE DE FICHIER LES FONCTIONS FAISANT DES APPELS SQL + + +// Ce fichier ne sera execute qu'une fois +if (defined("_INC_CALCUL_OUTILS")) return; +define("_INC_CALCUL_OUTILS", "1"); + + +# +# AFFREUX !! Passer tout ca en CSS au plus vite ! +# +tester_variable('espace_logos',3); +// HSPACE=xxx VSPACE=xxx pour les logos (#LOGO_ARTICLE) +tester_variable('espace_images',3); +// HSPACE=xxx VSPACE=xxx pour les images integrees + +// +// Retrouver le logo d'un objet (et son survol) +// + + +function cherche_image($id_objet, $type_objet) { + // cherche l'image liee a l'objet + $on = cherche_image_nommee($type_objet.'on'.$id_objet); + + // cherche un survol + $off =(!$on ? '' : + cherche_image_nommee($type_objet.'off'.$id_objet)); + + if (!$on) + return false; + + return array($on, $off); +} + +function cherche_logo_objet ($type, $id_objet, $on = false, $off = false, $flag_fichier=false) { + + # spip_log("cherche logo $type $id_objet $on $off $flag_fichier"); + switch($type) { + case 'ARTICLE': + $logo = cherche_image($id_objet, 'art'); + break; + case 'AUTEUR': + $logo = cherche_image($id_objet, 'aut'); + break; + case 'BREVE': + $logo = cherche_image($id_objet, 'breve'); + break; + case 'SITE': + $logo = cherche_image($id_objet, 'site'); + break; + case 'MOT': + $logo = cherche_image($id_objet, 'mot'); + break; + // recursivite + case 'RUBRIQUE': + if (!($logo = cherche_image ($id_objet, 'rub')) + AND $id_objet > 0) + $logo = cherche_logo_objet('RUBRIQUE', + sql_parent($id_objet), true, true); + break; + default: + spip_log("cherche_logo_objet: type '$type' inconnu"); + } + + // Quelles images sont demandees ? + if (!$on) unset($logo[0]); + if (!$off) unset($logo[1]); + + if ($logo[0] OR $logo[1]) + return $logo; +} + +// Renvoie le code html pour afficher le logo, avec ou sans survol, avec ou sans lien, etc. +function affiche_logos($logo, $lien, $align, $flag_fichier) { + global $num_survol; + global $espace_logos; + + list($arton,$artoff) = $logo; + + // Pour les documents comme pour les logos, le filtre |fichier donne + // le chemin du fichier apres 'IMG/' ; peut-etre pas d'une purete + // remarquable, mais a conserver pour compatibilite ascendante. + // -> http://www.spip.net/fr_article901.html + if ($flag_fichier) { + $on = ereg_replace("^IMG/","",$arton); + $off = ereg_replace("^IMG/","",$artoff); + return $on ? $on : $off; + } + + $num_survol++; + if ($arton) { + //$imgsize = @getimagesize("$arton"); + //$taille_image = ereg_replace("\"","'",$imgsize[3]); + if ($align) $align="align='$align' "; + + $milieu = "<img src='$arton' $align". + " name='image$num_survol' ".$taille_image." border='0' alt=''". + " hspace='$espace_logos' vspace='$espace_logos' class='spip_logos' />"; + + if ($artoff) { + if ($lien) { + $afflien = "<a href='$lien'"; + $afflien2 = "a>"; + } + else { + $afflien = "<div"; + $afflien2 = "div>"; + } + $milieu = "$afflien onMouseOver=\"image$num_survol.src=". + "'$artoff'\" onMouseOut=\"image$num_survol.src=". + "'$arton'\">$milieu</$afflien2"; + } + else if ($lien) { + $milieu = "<a href='$lien'>$milieu</a>"; + } + } else { + $milieu=""; } + return $milieu; +} - # spip_log(spip_num_rows($result)); - return $result; + + +// +// fonction standard de calcul de la balise #INTRODUCTION +// on peut la surcharger en definissant dans mes_fonctions.php3 : +// function introduction($type,$texte,$descriptif) {...} +// +function calcul_introduction ($type, $texte, $chapo='', $descriptif='') { + if (function_exists("introduction")) + return introduction ($type, $texte, $chapo, $descriptif); + + switch ($type) { + case 'articles': + if ($descriptif) + return propre($descriptif); + else if (substr($chapo, 0, 1) == '=') // article virtuel + return ''; + else + return PtoBR(propre(supprimer_tags(couper_intro($chapo."\n\n\n".$texte, 500)))); + break; + case 'breves': + return PtoBR(propre(supprimer_tags(couper_intro($texte, 300)))); + break; + case 'forums': + return PtoBR(propre(supprimer_tags(couper_intro($texte, 600)))); + break; + case 'rubriques': + if ($descriptif) + return propre($descriptif); + else + return PtoBR(propre(supprimer_tags(couper_intro($texte, 600)))); + break; + } } -# toutes les fonctions avec requete SQL, necessaires aux squelettes. +// +// FONCTIONS FAISANT DES APPELS SQL +// +# NB : a l'exception des fonctions de forum regroupees dans inc-forum. function calcul_exposer ($id, $type, $reference) { static $exposer; @@ -233,4 +346,5 @@ function sql_rubrique_fond($contexte, $lang) { } -?> + +?> \ No newline at end of file diff --git a/inc-calcul.php3 b/inc-calcul.php3 index 30404573909cc85294b7da59ca0c651b9aab34c6..d10df149a8f073b32ca3bfa133393e6ee2e4bcc4 100644 --- a/inc-calcul.php3 +++ b/inc-calcul.php3 @@ -15,8 +15,10 @@ include_ecrire("inc_filtres.php3"); include_ecrire("inc_lang.php3"); include_ecrire("inc_documents.php3"); include_ecrire("inc_forum.php3"); -include_local("inc-calcul_mysql3.php"); -include_local("inc-calcul_html4.php"); +include_local("inc-calcul-outils.php3"); + +#include_local("inc-calcul_html"); # anciens noms des fichiers +#include_local("inc-calcul_mysql"); // Ce fichier peut contenir une affectation de $dossier_squelettes indiquant @@ -66,7 +68,12 @@ function charger_squelette ($squelette) { } // sinon le compiler - include_local("inc-calcul-squel.php3"); + if ($GLOBALS['tradition']) { + include_local("inc-calcul-squel.php3"); + } + else { + include_local("inc-compilo.php3"); + } if (!lire_fichier ($sourcefile, $skel)) { // erreur webmaster : $fond ne correspond a rien include_ecrire ("inc_presentation.php3"); @@ -152,6 +159,7 @@ function cherche_page ($cache, $contexte, $fond, $id_rubrique, $lang='') { // Calculer la page a partir du main() du skel compile $page = $fonc(array('cache' =>$cache), array($contexte), + /* obsolete avec les doublons de inc-compilo */ array( 'articles' => '0', 'rubriques' => '0', @@ -295,7 +303,7 @@ function calculer_page($chemin_cache, $elements, $delais, $inclusion=false) { serialize($page['signal']))." -->\n"; // Enregistrer le fichier cache - if ($delais > 0) + if ($delais > 0 AND empty($GLOBALS['HTTP_POST_VARS'])) ecrire_fichier($chemin_cache, $signal.$page['texte']); return $page; @@ -303,66 +311,6 @@ function calculer_page($chemin_cache, $elements, $delais, $inclusion=false) { -# Fonctions appelees par les squelettes (insertion dans le code trop lourde) - -tester_variable('espace_logos',3); // HSPACE=xxx VSPACE=xxx pour les logos (#LOGO_ARTICLE) -tester_variable('espace_images',3); // HSPACE=xxx VSPACE=xxx pour les images integrees - -// -// Retrouver le logo d'un objet (et son survol) -// - -function cherche_image($id_objet, $type_objet) { - // cherche l'image liee a l'objet - $on = cherche_image_nommee($type_objet.'on'.$id_objet); - - // cherche un survol - $off =(!$on ? '' : - cherche_image_nommee($type_objet.'off'.$id_objet)); - - if (!$on) - return false; - - return array($on, $off); -} - -function cherche_logo_objet ($type, $id_objet, $on = false, $off = false, $flag_fichier=false) { - -spip_log("cherche logo $type $id_objet $on $off $flag_fichier"); - switch($type) { - case 'ARTICLE': - $logo = cherche_image($id_objet, 'art'); - break; - case 'AUTEUR': - $logo = cherche_image($id_objet, 'aut'); - break; - case 'BREVE': - $logo = cherche_image($id_objet, 'breve'); - break; - case 'SITE': - $logo = cherche_image($id_objet, 'site'); - break; - case 'MOT': - $logo = cherche_image($id_objet, 'mot'); - break; - // recursivite - case 'RUBRIQUE': - if (!($logo = cherche_image ($id_objet, 'rub')) - AND $id_objet > 0) - $logo = cherche_logo_objet('RUBRIQUE', - sql_parent($id_objet), true, true); - break; - default: - spip_log("cherche_logo_objet: type '$type' inconnu"); - } - - // Quelles images sont demandees ? - if (!$on) unset($logo[0]); - if (!$off) unset($logo[1]); - - if ($logo[0] OR $logo[1]) - return $logo; -} // Fonction appelee par le skel pour assembler les balises @@ -383,4 +331,59 @@ function _f($push = false, $texte='') { return $texte; } +### A passer peut-etre dans inc_db_mysql +// Cette fonction est systematiquement appelee par les squelettes +// pour constuire une requete SQL de type "lecture" (SELECT) a partir +// de chaque boucle. +// Elle construit et exe'cute une reque^te SQL correspondant a` une balise +// Boucle ; elle notifie une erreur SQL dans le flux de sortie et termine +// le processus. +// Sinon, retourne la ressource interrogeable par fetch_row ou fetch_array. +// Elle peut etre re'de'finie pour s'interfacer avec d'autres serveurs SQL +// Recoit en argument: +// - le tableau des champs a` ramener +// - le tableau des tables a` consulter +// - le tableau des conditions a` remplir +// - le crite`re de regroupement +// - le crite`re de classement +// - le crite`re de limite +// - une sous-requete e'ventuelle (MySQL > 4.1) +// - un compteur de sous-requete +// - le nom de la table +// - le nom de la boucle (pour le message d'erreur e'ventuel) + + +function spip_abstract_select ( + $select = array(), $from = array(), $where = '', + $groupby = '', $orderby = '', $limit = '', + $sousrequete = '', $cpt = '', + $table = '', $id = '') { + + $DB = 'spip_'; + $q = " FROM $DB" . join(", $DB", $from) + . (is_array($where) ? ' WHERE ' . join(' AND ', $where) : '') + . ($groupby ? " GROUP BY $groupby" : '') + . ($orderby ? "\nORDER BY $orderby" : '') + . ($limit ? "\nLIMIT $limit" : ''); + + if (!$sousrequete) + $q = " SELECT ". join(", ", $select) . $q; + else + $q = " SELECT S_" . join(", S_", $select) + . " FROM (" . join(", ", $select) + . ", COUNT(".$sousrequete.") AS compteur " . $q + .") AS S_$table WHERE compteur=" . $cpt; + + // + // Erreur ? C'est du debug, ou une erreur du serveur + // + if (!($result = @spip_query($q))) { + include_local('inc-admin.php3'); + echo erreur_requete_boucle($q, $id, $table); + } + + # spip_log(spip_num_rows($result)); + return $result; +} + ?> diff --git a/inc-calcul_html4.php b/inc-calcul_html4.php deleted file mode 100644 index ee1db983c92fa150e20351de0c5417d65b38c8ca..0000000000000000000000000000000000000000 --- a/inc-calcul_html4.php +++ /dev/null @@ -1,107 +0,0 @@ -<?php -// Ce fichier ne sera execute qu'une fois -if (defined("_CALCUL_HTML4")) return; -define("_CALCUL_HTML4", "1"); - -// Renvoie le code html pour afficher le logo, avec ou sans survol, avec ou sans lien, etc. -function affiche_logos($logo, $lien, $align, $flag_fichier) { - global $num_survol; - global $espace_logos; - - list($arton,$artoff) = $logo; - - // Pour les documents comme pour les logos, le filtre |fichier donne - // le chemin du fichier apres 'IMG/' ; peut-etre pas d'une purete - // remarquable, mais a conserver pour compatibilite ascendante. - // -> http://www.spip.net/fr_article901.html - if ($flag_fichier) { - $on = ereg_replace("^IMG/","",$arton); - $off = ereg_replace("^IMG/","",$artoff); - return $on ? $on : $off; - } - - $num_survol++; - if ($arton) { - //$imgsize = @getimagesize("$arton"); - //$taille_image = ereg_replace("\"","'",$imgsize[3]); - if ($align) $align="align='$align' "; - - $milieu = "<img src='$arton' $align". - " name='image$num_survol' ".$taille_image." border='0' alt=''". - " hspace='$espace_logos' vspace='$espace_logos' class='spip_logos' />"; - - if ($artoff) { - if ($lien) { - $afflien = "<a href='$lien'"; - $afflien2 = "a>"; - } - else { - $afflien = "<div"; - $afflien2 = "div>"; - } - $milieu = "$afflien onMouseOver=\"image$num_survol.src=". - "'$artoff'\" onMouseOut=\"image$num_survol.src=". - "'$arton'\">$milieu</$afflien2"; - } - else if ($lien) { - $milieu = "<a href='$lien'>$milieu</a>"; - } - } else { - $milieu=""; - } - return $milieu; -} - - - -// -// Ajouter le &var_recherche=toto dans les boucles de recherche -// -function url_var_recherche($url) { - if ($GLOBALS['HTTP_GET_VARS']['recherche'] && !ereg("var_recherche", $url)) { - $url .= strpos($url, '?') ? '&' : '?'; - $url .= "var_recherche=".urlencode($GLOBALS['recherche']); - } - return $url; -} - -// -// fonction standard de calcul de la balise #INTRODUCTION -// on peut la surcharger en definissant dans mes_fonctions.php3 : -// function introduction($type,$texte,$descriptif) {...} -// -function calcul_introduction ($type, $texte, $chapo='', $descriptif='') { - if (function_exists("introduction")) - return introduction ($type, $texte, $chapo, $descriptif); - - switch ($type) { - case 'articles': - if ($descriptif) - return propre($descriptif); - else if (substr($chapo, 0, 1) == '=') // article virtuel - return ''; - else - return PtoBR(propre(supprimer_tags(couper_intro($chapo."\n\n\n".$texte, 500)))); - break; - case 'breves': - return PtoBR(propre(supprimer_tags(couper_intro($texte, 300)))); - break; - case 'forums': - return PtoBR(propre(supprimer_tags(couper_intro($texte, 600)))); - break; - case 'rubriques': - if ($descriptif) - return propre($descriptif); - else - return PtoBR(propre(supprimer_tags(couper_intro($texte, 600)))); - break; - } -} - -function calcul_form_rech($lien) -{ - return - "<form action='$lien' method='get' class='formrecherche'><input type='text' id='formulaire_recherche' size='20' class='formrecherche' name='recherche' value='" . _T('info_rechercher') . "' /></form>"; -} - -?> diff --git a/inc-compilo-debug.php3 b/inc-compilo-debug.php3 new file mode 100644 index 0000000000000000000000000000000000000000..d52631899131e64eff1bd0bca7bffea042445061 --- /dev/null +++ b/inc-compilo-debug.php3 @@ -0,0 +1,85 @@ +<?php + +// +// Outils pour debugguer le compilateur (pas inclus) +// + +// +// Ce fichier ne sera execute qu'une fois +if (defined("_INC_COMPILO_DEBUG")) return; +define("_INC_COMPILO_DEBUG", "1"); + +// +// Fonctions debug +// + +function affval($val) { + + echo "“" . entites_html($val) . "”"; + +} + +function afftable($table) { + + if (!$table) return; + reset($table); + echo "<UL>"; + while (list($key, $val) = each($table)) { + echo "<LI>"; + affobject($val); + echo "</LI>"; + } + echo "</UL>\n"; +} + + +function affobject($val) +{ + if (!is_object($val)) + affval($val); + else + switch ($val->type) { + case 'boucle': + echo "<font color='red'><b>Boucle".$val->id_boucle."</b>"; + echo "<br><i><small>".affval($val->requete)."</small></i></font>"; + break; + case 'texte': + echo affval($val->texte); + break; + case 'include': + echo affval($val->fichier); + afftable($params); + break; + case 'champ': + echo "<font color='blue'><i>#".$val->nom_champ; + if ($val->fonctions) echo " <small>(".join(',', $val->fonctions).")</small>"; + echo "</i></font>"; + echo "<ul><li>"; + echo afftable($val->cond_avant); + echo "</li><li>"; + echo afftable($val->cond_apres); + echo "</li></ul>"; + break; + } +} + + +function affboucle($val) { + echo "<hr><ul>"; + foreach(get_object_vars($val) as $k => $v) + { + echo "<li><b>$k : </b>"; + if (is_array($v)) + if (!$v) echo "<i>Tableau vide</i>"; else afftable($v); + elseif (is_object($v)) + echo afftable($v); + else affval($v); + echo "</li>"; } + echo "</ul>\n"; +} + +function affboucles($boucles) { + while (list($key, $val) = each($boucles)) affboucle($val); +} + +?> diff --git a/inc-compilo-index.php3 b/inc-compilo-index.php3 new file mode 100644 index 0000000000000000000000000000000000000000..e7180f73f56da33a8a96e3e0e2bea1c66441693e --- /dev/null +++ b/inc-compilo-index.php3 @@ -0,0 +1,314 @@ +<?php + +// Definition des classes Boucle, Texte, Inclure, etc., +// et fonctions de recherche et de reservation +// dans l'arborescence des boucles + +// Ce fichier ne sera execute qu'une fois +if (defined("_INC_COMPILO_INDEX")) return; +define("_INC_COMPILO_INDEX", "1"); + +// +// encodage d'une boucle SPIP en un objet PHP +// +class Boucle { + var $type = 'boucle'; + var $id_boucle, $id_parent; + var $cond_avant, $milieu, $cond_apres, $cond_altern; + var $lang_select; + var $type_requete; + var $param; + var $separateur; + var $doublons; + var $partie, $total_parties,$mode_partie; + var $externe = ''; # appel a partir d'une autre boucle (recursion) + // champs pour la construction de la requete SQL + var $tout = false; + var $plat = false; + var $select; + var $from; + var $where; + var $limit; + var $group = ''; + var $order = ''; + var $date = 'date' ; + var $hash = false ; + var $lien = false; + var $sous_requete = false; + var $compte_requete = 1; + var $hierarchie = ''; + // champs pour la construction du corps PHP + var $return; + var $numrows = false; +} + +class Texte { + var $type = 'texte'; + var $texte; +} + +class Inclure { + var $type = 'include'; + var $fichier; + var $params; +} + +class Champ { + var $type = 'champ'; + var $nom_champ; + var $cond_avant, $cond_apres; // tableaux d'objets + var $fonctions; +} + +// +// Structure de donnees pour parler aux fonctions calcul_champ_TOTO +// +class ParamChamp { + var $fonctions; + var $nom_champ; + var $id_boucle; + var $boucles; + var $id_mere; + var $type_requete; + var $code; // code du calcul + var $process; // processeurs standards, exemple 'propre(%s)' + var $etoile; // le champ a ete appele avec une etoile (booleen) + var $type; // 'num'erique, 'h'=texte (html) ou 'p'=script (php) ? + // -> definira les pre et post-traitements obligatoires + + function retour() { + // Annuler les traitements si le champ est etoile + if ($this->etoile) unset($this->process); + + $code_filtre = applique_filtres( + $this->fonctions, + $this->code, + $this->id_boucle, + $this->boucles, + $this->id_mere, + $this->type, + $this->process + ); + return $code_filtre; + } +} + + + +// index_pile retourne la position dans la pile du champ SQL $nom_champ +// en prenant la boucle la plus proche du sommet de pile (indique par $idb). +// Si on ne trouve rien, on considere que ca doit provenir du contexte +// (par l'URL ou l'include) qui a ete recopie dans Pile[0] +// (un essai d'affinage a debouche sur un bug vicieux) +// Si ca reference un champ SQL, on le memorise dans la structure $boucles +// afin de construire un requete SQL minimale (plutot qu'un brutal 'SELECT *') + +include_ecrire('inc_serialbase.php3'); + +function index_pile($idb, $nom_champ, &$boucles) { + global $exceptions_des_tables, $table_des_tables, $tables_principales; + + // Recherche d'un champ dans un etage superieur + $i = 0; + if ($c=strpos($nom_champ, ':')) { + $idbs = substr($nom_champ, 0, $c); + $nom_champ = substr($nom_champ, $c+1); + while (($idb != $idbs) && $idb) { + $i++; + $idb = $boucles[$idb]->id_parent; + } + } + + $c = strtolower($nom_champ); + // attention a la boucle nommee 0 .... + while ($idb!== '') { + #spip_log("Cherche: $nom_champ '$idb' '$c'"); + $r = $boucles[$idb]->type_requete; + // indirection (pour les rares cas ou le nom de la table est /= du type) + $t = $table_des_tables[$r]; + if (!$t) + $t = $r; // pour les tables non Spip + // $t est le nom PHP de cette table + #spip_log("Go: idb='$idb' r='$r' c='$c' nom='$nom_champ'"); + $desc = $tables_principales[$t]; + if (!$desc) { + include_local("inc-admin.php3"); + erreur_squelette(_L("Table SQL absente de \$tables_principales dans inc_serialbase"), $r, "'$idb'"); + } + $excep = $exceptions_des_tables[$r][$c]; + if ($excep) { + // entite SPIP alias d'un champ SQL + if (!is_array($excep)) { + $e = $excep; + } + // entite SPIP alias d'un champ dans une autre table SQL + else { + $t = $excep[0]; + $e = $excep[1]; + } + } + else { + // $e est le type SQL de l'entree (ici utile comme booleen) + // entite SPIP homonyme au champ SQL + if ($desc['field'][$c]) + $e = $c; + else + $e = ''; + } + + #spip_log("Dans $idb ($t $e): $desc"); + + // On l'a trouve + if ($e) { + $boucles[$idb]->select[] = $t . "." . $e; + return '$Pile[$SP' . ($i ? "-$i" : "") . '][\'' . $e . '\']'; + } + + // Sinon on remonte d'un cran + $idb = $boucles[$idb]->id_parent; + $i++; + } + + #spip_log("Pas vu $nom_champ dans les " . count($boucles) . " boucles"); + // esperons qu'il y sera + return('$Pile[0][\''.$nom_champ.'\']'); +} + +// cette fonction sert d'API pour demander le champ '$champ' dans la pile +function champ_sql($champ, $p) { + return index_pile($p->id_boucle, $champ, $p->boucles); +} + +# calculer_champ genere le code PHP correspondant a la balise Spip $nom_champ +# Retourne une EXPRESSION php +function calculer_champ($fonctions, $nom_champ, $id_boucle, &$boucles, $id_mere, $etoile = false) { + // Preparer les parametres + $p = new ParamChamp; + $p->fonctions = $fonctions; + $p->nom_champ = $nom_champ; + $p->id_boucle = $id_boucle; + $p->boucles = &$boucles; + $p->id_mere = $id_mere; + $p->type = 'html'; + $p->process = ''; + $p->type_requete = $boucles[$id_boucle]->type_requete; + + // regarder s'il existe une fonction personnalisee balise_NOM() + $f = 'balise_' . $nom_champ; + if (function_exists($f)) + $p = $f($p); + + else { + // regarder s'il existe une fonction standard balise_NOM_dist() + $f = 'balise_' . $nom_champ . '_dist'; + if (function_exists($f)) + $p = $f($p); + + else { + // S'agit-il d'un logo ? Une fonction speciale les traite tous + if (ereg('^LOGO_', $nom_champ)) + $p = calcul_balise_logo($p); + + else { + // On regarde ensuite s'il y a un champ SQL homonyme, + // et on definit le type et les traitements + $p->code = champ_sql($nom_champ, $p); + if (($p->code) && ($p->code != '$Pile[0][\''.$nom_champ.'\']')) { + + // Par defaut basculer en numerique pour les #ID_xxx + if (substr($nom_champ,0,3) == 'ID_') $p->type = 'num'; + } + + else { + // si index_pile a ramene le choix par defaut, + // ca doit plutot etre un champ SPIP non SQL, + // ou ni l'un ni l'autre => on le renvoie sous la forme brute '#TOTO' + $p->code = "'#$nom_champ'"; + $p->type = 'php'; // pas de traitement + + }}}} + + // Aller chercher les processeurs standards definis dans inc-champ-squel + if (!$etoile) + $p->process = champs_traitements($nom_champ); + + // Retourner l'expression php correspondant au champ + ses filtres + return $p->retour(); +} + + +// Genere l'application d'une liste de filtres +function applique_filtres ($fonctions, $code, $id_boucle, $boucles, $id_mere, $type ='html', $process='') { + + // pretraitements standards + switch ($type) { + case 'num': + $code = "intval($code)"; + break; + case 'php': + break; + case 'html': + default: + $code = "trim($code)"; + break; + } + + // traitements standards + if (strpos($process, '%s') !== false) + $code = str_replace('%s', $code, $process); + + // Appliquer les filtres perso + if ($fonctions) { + foreach($fonctions as $fonc) { + if ($fonc) { + $arglist = ''; + if (ereg('([^\{\}]*)\{(.+)\}$', $fonc, $regs)) { + $fonc = $regs[1]; + $args = $regs[2]; + while (ereg('([^,]+),?(.*)$', $args, $regs)) { + $args = $regs[2]; + $arg = trim($regs[1]); + if ($arg) { + if ($arg[0] =='#') + $arg = calculer_champ(array(), substr($arg,1), + $id_boucle, $boucles, $id_mere); + else if ($arg[0] =='$') + $arg = '$Pile[0][\'' . substr($arg,1) . "']"; + $arglist .= ','.$arg; + } + } + } + if (function_exists($fonc)) + $code = "$fonc($code$arglist)"; + else + $code = "'".texte_script( + _T('erreur_filtre', array('filtre' => $fonc)) + )."'"; + } + } + } + + // post-traitement securite + if ($type == 'html') + $code = "interdire_scripts($code)"; + + return $code; +} + + +// +// Reserve les champs necessaires a la comparaison avec le contexte donne par +// la boucle parente ; attention en recursif il faut les reserver chez soi-meme +// ET chez sa maman +// +function calculer_argument_precedent($idb, $nom_champ, &$boucles) { + + // recursif ? + if ($boucles[$idb]->externe) + index_pile ($idb, $nom_champ, $boucles); // reserver chez soi-meme + + // reserver chez le parent et renvoyer l'habituel $Pile[$SP]['nom_champ'] + return index_pile ($boucles[$idb]->id_parent, $nom_champ, $boucles); +} + +?> diff --git a/inc-calcul-squel.php3 b/inc-compilo.php3 similarity index 78% rename from inc-calcul-squel.php3 rename to inc-compilo.php3 index e00279e6f1f2d51b173f490c70af0b9b6177e4ad..0fe72e3afb3d9577808feebe69a06c950ab8935b 100644 --- a/inc-calcul-squel.php3 +++ b/inc-compilo.php3 @@ -1,27 +1,140 @@ <?php +// +// Fichier principal du compilateur de squelettes +// + // Ce fichier ne sera execute qu'une fois -if (defined("_INC_CALCUL_SQUEL")) return; -define("_INC_CALCUL_SQUEL", "1"); +if (defined("_INC_COMPILO")) return; +define("_INC_COMPILO", "1"); + + +// Definition de la structure $p, et fonctions de recherche et de reservation +// dans l'arborescence des boucles +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 balises +include_local("inc-balises.php3"); +#include_local("inc-logo-squel.php3"); +#include_local("inc-vrac-squel.php3"); +#include_local("inc-form-squel.php3"); -// Fichier principal du compilateur de squelettes, incluant tous les autres. +// definition des criteres +include_local("inc-criteres.php3"); +#include_local("inc-arg-squel.php3"); -include_local("inc-bcl-squel.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"); -include_local("inc-logo-squel.php3"); -include_local("inc-form-squel.php3"); -include_local("inc-vrac-squel.php3"); -include_local("inc-index-squel.php3"); -include_local("inc-text-squel.php3"); -include_local("inc-debug.php3"); -include_local("inc-forum.php3"); -// Produit le corps PHP d'une boucle Spip, + + +// outils pour debugguer le compilateur +#include_local("inc-compilo-debug.php3"); # desactive + + +// +// Calculer un <INCLURE()> +// +function calculer_inclure($fichier, $params, $id_boucle, &$boucles) { + global $dossier_squelettes; + + $criteres = ''; + if ($params) { + foreach($params as $param) { + if (ereg("^([_0-9a-zA-Z]+)[[:space:]]*(=[[:space:]]*([^}]+))?$", $param, $args)) { + $var = $args[1]; + $val = ereg_replace('^["\'](.*)["\']$', "\\1", trim($args[3])); + $val = addslashes(addslashes($val)); + + // Cas de la langue : passer $spip_lang + // et non table.lang (car depend de {lang_select}) + if ($var =='lang') { + if ($val) + $l[] = "\'lang\' => \'$val\'"; + else + $l[] = "\'lang\' => \''.\$GLOBALS[spip_lang].'\'"; + } + + // Cas normal {var=val} + else + if ($val) + $l[] = "\'$var\' => \'$val\'"; + else + $l[] = "\'$var\' => \'' . addslashes(" . index_pile($id_boucle, $var, $boucles) . ") .'\'"; + } + $criteres = join(", ",$l); + } + } + return "\n'<". + "?php\n\t\$contexte_inclus = array($criteres);\n\t". + "\$fichier_inclus = \'$fichier\';\n" . + (($dossier_squelettes) ? + (" + if (@file_exists(\'$dossier_squelettes/$fichier\')){ + include(\'$dossier_squelettes/$fichier\'); + } else { + include(\'$fichier\'); + } " ) : + ("\tinclude(\'$fichier\');")) . + "\n?'." . "'>'"; +} + + +// +// Traite une partie "texte" d'un squelette (c'est-a-dire tout element +// qui ne contient ni balise, ni boucle, ni <INCLURE()> ; le transforme +// en une EXPRESSION php (qui peut etre l'argument d'un Return ou la +// partie droite d'une affectation). Ici sont analyses les elements +// multilingues des squelettes : <:xxx:> et <multi>[fr]coucou</multi> +// +function calculer_texte($texte, $id_boucle, &$boucles, $id_mere) { + $code = "'".ereg_replace("([\\\\'])", "\\\\1", $texte)."'"; + + // 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_]+)(\|[^>]*)?:>", $code, $match)) { + // + // Traiter la balise de traduction multilingue + // + $chaine = strtolower($match[3]); + if (!($module = $match[2])) + // ordre standard des modules a explorer + $module = 'local/public/spip'; + $c = applique_filtres(explode('|', + substr($match[4],1)), + "_T('$module:$chaine')", + $id_boucle, + $boucles, + $id_mere, + 'php'); // ne pas manger les espaces avec trim() + $code = str_replace($match[0], "'$ferme_multi.$c.$ouvre_multi'", $code); + } + + return $ouvre_multi . $code . $ferme_multi; +} + + +// +// calculer_boucle() produit le corps PHP d'une boucle Spip, // essentiellement une boucle while (ou une double en cas de hierarchie) // remplissant une variable $t0 retourne'e en valeur - +// function calculer_boucle($id_boucle, &$boucles) { global $table_primary, $table_des_tables; @@ -92,13 +205,14 @@ function calculer_boucle($id_boucle, &$boucles) { if ($lang_select AND !$constant) $debut .= ' - if ($x = $Pile[$SP]["lang"]) $spip_lang = $x; // langue'; + if ($x = $Pile[$SP]["lang"]) $spip_lang = $x; // lang_select'; $debut .= $invalide; if ($boucle->doublons) - $debut .= "\n \$doublons['$type_boucle'] .= ','. " . - index_pile($id_boucle, $primary_key, $boucles) . "; // doublons"; + $debut .= "\n \$doublons['".$boucle->doublons."'] .= ','. " . + index_pile($id_boucle, $primary_key, $boucles) + . "; // doublons"; // @@ -205,6 +319,10 @@ function calculer_boucle($id_boucle, &$boucles) { } +// +// fonction traitant les criteres {1,n} (analyses dans inc-criteres) +// +## a deplacer dans inc-criteres ?? function calculer_parties($partie, $mode_partie, $total_parties, $id_boucle) { // Notes : @@ -442,7 +560,7 @@ function calculer_squelette($squelette, $nom, $gram, $sourcefile) { if ($boucles) foreach($boucles as $id => $boucle) { if ($boucle->type_requete != 'boucle') { - $res = calculer_params($id, $boucles); + calculer_criteres($id, $boucles); $boucles[$id]->return = calculer_liste($boucle->milieu, $nom, $id, @@ -505,7 +623,7 @@ $code // // Fonction principale du squelette $sourcefile // -function $nom (\$Cache, \$Pile, \$doublons, \$Numrows='', \$SP=0) { +function $nom (\$Cache, \$Pile, \$ignore_les_doublons_inc_calcul_php3, \$Numrows='', \$SP=0) { $corps \$t0 = $return; diff --git a/inc-arg-squel.php3 b/inc-criteres.php3 similarity index 55% rename from inc-arg-squel.php3 rename to inc-criteres.php3 index a4fc502e9536398b95a1d8569743d4a4031ee17a..867ddf785fe6c75bfe8f94094753885dd215a53f 100644 --- a/inc-arg-squel.php3 +++ b/inc-criteres.php3 @@ -1,25 +1,268 @@ <?php -# Traduction des arguments d'une boucle par affectation du tableau $boucles -# retourne un tableau en cas d'erreur +// +// Definition des {criteres} d'une boucle +// + +// Ce fichier ne sera execute qu'une fois +if (defined("_INC_CRITERES")) return; +define("_INC_CRITERES", "1"); + + +// {racine} +// http://www.spip.net/@racine +function critere_racine_dist($param, $not, &$boucle, $infos) { + global $table_des_tables; + + if ($param != 'racine' OR $not) + return "erreur"; + + $boucle->where[] = $infos['id_table'].".id_parent='0'"; + +} + +// {exclus} +// http://www.spip.net/@exclus +function critere_exclus_dist($param, $not, &$boucle, $infos) { + + if ($param != 'exclus' OR $not) + return "erreur"; + + $boucle->where[] = $infos['id_field']."!='\"." + . calculer_argument_precedent($infos['idb'], + $infos['primary'], $infos['boucles']) . ".\"'"; + +} + +// {doublons} ou {unique} +// http://www.spip.net/@doublons +function critere_doublons_dist($param, $not, &$boucle, $infos) { + + if (!preg_match("/(doublons|unique)[[:space:]]*([a-z_0-9]*)/i", + $param, $match)) + return "erreur"; -function calculer_params($idb, &$boucles) { + $boucle->doublons = $infos['type'].$match[2]; + $boucle->where[] = '" .' . + "calcul_mysql_in('".$infos['id_field']."', " + .'"0".$doublons[\''.$boucle->doublons."'], 'NOT') . \""; +} + +// {lang_select} +// http://www.spip.net/@lang_select +function critere_lang_select_dist($param, $not, &$boucle, $infos) { + if (preg_match('/lang_select(=(oui|non))?$/i', $param, $match)) { + if (!$lang_select = $match[3]) + $lang_select = 'oui'; + if ($not) + $lang_select = ($lang_select=='oui')?'non':'oui'; + $boucle->lang_select = $lang_select; + } + else return "erreur"; +} + +// {debut_xxx} +// http://www.spip.net/@debut_ +function critere_debut_dist($param, $not, &$boucle, $infos) { + if (ereg('^debut([-_a-zA-Z0-9]+),([0-9]*)$', $param, $match)) { + $debut_lim = "debut".$match[1]; + $boucle->limit = + 'intval($GLOBALS["'.$debut_lim.'"]).",'.$match[2] .'"' ; + } + else return "erreur"; +} + +// {recherche} +// http://www.spip.net/@recherche +function critere_recherche_dist($param, $not, &$boucle, $infos) { + $boucle->from[] = "index_".$infos['id_table']." AS rec"; + $boucle->select[] = 'SUM(rec.points + 100*(" .' . + 'calcul_mysql_in("rec.hash", + calcul_branche($hash_recherche_strict),"") . ")) + AS points'; + + // horrible hack du aux id_forum = spip_forum et id_article=spip_articleS + // en fait il faudrait la fonction inverse de table_objet() + $id = 'id_'.preg_replace('/s$/', '', $infos['id_table']); + + // rec.id_article = articles.id_article + $boucle->where[] = "rec.".$id + . "=" . $infos['id_table'].'.'.$id; + + // group by articles.id_article + $boucle->group = $infos['id_field']; + + // et la recherche trouve + $boucle->where[] = '" .' . 'calcul_mysql_in("rec.hash", + calcul_branche($hash_recherche),"") . "'; + + // oui cette boucle est une boucle recherche, le noter dans la pile + // (certes, c'est un peu lourd comme ecriture) + $infos['boucles'][$infos['idb']]->hash = true; +} + +// {inverse} +// http://www.spip.net/@inverse +function critere_inverse_dist($param, $not, &$boucle, $infos) { + // Classement par ordre inverse + if ($param == 'inverse' AND !$not) { + if ($boucle->order) + $boucle->order .= ".' DESC'"; + else + return _L(" : inversion d'un ordre inexistant"); + } else + return 'erreur'; +} + +// {traduction} +// http://www.spip.net/@traduction +function critere_traduction_dist($param, $not, &$boucle, $infos) { + if ($param == 'traduction') { + $boucle->where[] = $infos['id_table'].".id_trad > 0"; + $boucle->where[] = $infos['id_table'].".id_trad ='\"." + . calculer_argument_precedent($infos['idb'], 'id_trad', + $infos['boucles']) + . ".\"'"; + + } else + return 'erreur'; +} + +// {origine_traduction} +// http://www.spip.net/@origine_traduction +function critere_origine_traduction_dist($param, $not, &$boucle, $infos) { + if ($param == 'origine_traduction') + $boucle->where[] = $infos['id_table'].".id_trad = " + . $infos['id_field']; + else + return "erreur"; +} + + +// {meme_parent} +// http://www.spip.net/@meme_parent +function critere_meme_parent_dist($param, $not, &$boucle, $infos) { + if ($param != 'meme_parent') + return "erreur"; + else { + if ($infos['type'] == 'rubriques') { + $boucle->where[] = $infos['id_table'].".id_parent='\"." + . calculer_argument_precedent($infos['idb'], 'id_parent', + $infos['boucles']) + . ".\"'"; + } else if ($infos['type'] == 'forums') { + $boucle->where[] = $infos['id_table'].".id_parent='\"." + . calculer_argument_precedent($infos['idb'], 'id_parent', + $infos['boucles']) + . ".\"'"; + $boucle->where[] = $infos['id_table'].".id_parent > 0"; + $boucle->plat = true; + } else + return _L("erreur {meme_parent} ne s'applique pas à + d'autres boucles que (FORUMS) ou (RUBRIQUES)"); + } +} + +// {branche ?} +// http://www.spip.net/@branche +function critere_branche_dist($param, $not, &$boucle, $infos) { + if (preg_match('/branche[[:space:]]*([?])?$/i', $param, $regs)) { + $c = "calcul_mysql_in('".$infos['id_table'].".id_rubrique', + calcul_branche(" . calculer_argument_precedent($infos['idb'], + 'id_rubrique', $infos['boucles']) . "), '')"; + if (!$regs[1]) + $where = "\". $c .\"" ; + else + $where = "\".(" + . calculer_argument_precedent($infos['idb'], 'id_rubrique', + $infos['boucles'])."? $c : 1).\""; + + if ($not) + $boucle->where[] = "NOT($where)"; + else + $boucle->where[] = "$where"; + } else + return "erreur"; +} + +// Tri : {par xxxx} +// http://www.spip.net/@par +function critere_par_dist($param, $not, &$boucle, $infos) { + if ($not) + return "erreur"; + + preg_match('/par[[:space:]]*(.*)/ims', $param, $regs); + $tri = trim($regs[1]); + + // par hasard + if ($tri == 'hasard') { + // on pourrait peut-etre passer a "RAND() AS alea" ? + $boucle->select[] = "MOD(".$infos['id_field']." * UNIX_TIMESTAMP(), + 32767) & UNIX_TIMESTAMP() AS alea"; + $boucle->order = "'alea'"; + } + + // par titre_mot + else if ($tri == 'titre_mot') { + $boucle->order= "'mots.titre'"; + } + + // par type_mot + else if ($tri == 'type_mot'){ + $boucle->order= "'mots.type'"; + } + // par points + else if ($tri == 'points'){ + $boucle->order= "'points'"; + } + // par num champ(, suite) + else if (ereg("^num[[:space:]]+([^,]*)(,.*)?",$tri, $match2)) { + $boucle->select[] = "0+".$infos['id_table'].".".$match2[1]." AS num"; + $boucle->order = "'num".texte_script($match2[2])."'"; + } + // par champ + else if (ereg("^[a-z0-9]+$", $tri)) { + if ($tri == 'date') + $tri = $GLOBALS['table_date'][$infos['type']]; + $boucle->order = "'".$infos['id_table'].".".$tri."'"; + } + // tris par critere bizarre + // (formule composee, virgules, etc). + else { + $boucle->order = "'".texte_script($tri)."'"; + } +} + + + +function calculer_criteres ($idb, &$boucles) { global $tables_relations, $table_primary, $table_des_tables, $table_date; - $boucle = &$boucles[$idb]; - $type = $boucle->type_requete; + $boucle = &$boucles[$idb]; # nom de la boucle + $type = $boucle->type_requete; # articles $params = $boucle->param; - $id_table = $table_des_tables[$type]; - $id_field = $id_table . "." . $table_primary[$type]; + $id_table = $table_des_tables[$type]; # articles -> 'table' + $primary = $table_primary[$type]; # id_article -> 'id' + $id_field = $id_table . "." . $primary; # articles.id_article -> 'table_id' + + // les infos complementaires a passer aux fonctions critere_xxx + $infos = array( + 'type' => $type, # (articles) + 'id_table' => $id_table, # 'table' + 'id_field' => $id_field, # 'table_id' + 'primary' => $primary, # 'id' + 'boucles' => &$boucles, # boucles + 'idb' => $idb # 'nom_boucle' + ); - // Cas de la hierarchie : on cree des params supplementaires - // $hierarchie sera calculee par un ajout dans + // 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'; - if (!$boucle->order) - $boucle->order = 'rang'; + $boucle->order = 'rang'; // Supprimer le parametre id_article/id_rubrique/id_syndic + // qui est superfetatoire (mais indique dans la doc) $params2 = array(); foreach($params as $param) if (!ereg('^id_(article|syndic|rubrique)$', $param)) @@ -31,26 +274,39 @@ function calculer_params($idb, &$boucles) { .', false);'; } - + // + // Traitement de la liste des criteres + // if (is_array($params)) { foreach($params as $param) { - if ($param == 'exclus') { - $boucle->where[] = "$id_field!='\"." . - calculer_argument_precedent($idb, $table_primary[$type], $boucles) . - ".\"'"; - } - else if ($param == 'unique' OR $param == 'doublons') { - $boucle->doublons = true; - $boucle->where[] = '" .' . - "calcul_mysql_in('$id_field', \$doublons['$type'], 'NOT') . \""; - } - 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'; - $boucles[$idb]->lang_select = $lang_select; + + // 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(" : 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]; @@ -70,71 +326,7 @@ function calculer_params($idb, &$boucles) { (($match[1]=='n')?'-':'+').(($match[5]=='n')?'-':'+'); } } - else if (ereg('^debut([-_a-zA-Z0-9]+),([0-9]*)$', $param, $match)) { - $debut_lim = "debut".$match[1]; - $boucle->limit = - 'intval($GLOBALS["'.$debut_lim.'"]).",'.$match[2] .'"' ; - } - else if ($param == 'recherche') { - $boucle->from[] = "index_$id_table AS rec"; - $boucle->select[] = 'SUM(rec.points + 100*(" .' . - 'calcul_mysql_in("rec.hash", - calcul_branche($hash_recherche_strict),"") . ")) - AS points'; - # a cause des exceptions forum{s}? et syndic - # NB: utiliser table_objet() ? - if (!($r = $table_primary[$id_table])) - $r = $table_primary[$type]; - - $boucle->where[] = "rec.$r=$id_field"; - $boucle->group = $id_field; - $boucle->where[] = '" .' . 'calcul_mysql_in("rec.hash", - calcul_branche($hash_recherche),"") . "'; - $boucles[$idb]->hash = true; - } - - // Classement par ordre inverse - else if ($param == 'inverse') { - if ($boucle->order) { - $boucle->order .= ' DESC'; - } else { - include_local('inc-admin.php3'); - erreur_squelette(_T('info_erreur_squelette'), - _L(" : inversion d'un ordre inexistant"), $idb); - } - } - // Gerer les traductions - else if ($param == 'traduction') { - $boucle->where[] = "$id_table.id_trad > 0 - AND $id_table.id_trad ='\"." . - calculer_argument_precedent($idb, 'id_trad', $boucles) . ".\"'"; - } - else if ($param == 'origine_traduction') { - $boucle->where[] = "$id_table.id_trad = $id_table.id_article"; - } - - // 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 ($param == 'racine') { - $boucle->where[] = "$id_table.id_parent='0'"; - } - 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).\""; - } // Restriction de valeurs (implicite ou explicite) else if (eregi('^([a-z_]+) *(\??)((!?)(<=?|>=?|==?|IN) *"?([^<>=!"]*))?"?$', $param, $match)) { // Variable comparee @@ -310,27 +502,6 @@ function calculer_params($idb, &$boucles) { if ($col_table) $col = "$col_table.$col"; - /* - // Pas bon : les criteres sont des ET logiques - $vu = 0; - if (($op == '=') && (!$match[4]) && ($boucle->where)) { - // reperer un parametre repete - {id_mot=1}{id_mot=2} - // pour cre'er une sous-requete - foreach ($boucle->where as $k => $v) { - if (ereg("^ *$col *(=|IN) *['\(](.*)['\)]",$v, $m)) { - $boucle->where[$k] = "$col IN ($m[2],$val)"; - // esperons que c'est le meme ! - $boucle->sous_requete = $col; - $boucle->compte_requete++; - $vu=1; - break; - } - } - } - - if (!$vu) { - */ - if ($op) { if ($match[4] == '!') $where = "NOT ($col $op '$val')"; @@ -348,6 +519,24 @@ function calculer_params($idb, &$boucles) { } // 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).\""; + } // Selection du classement else if (ereg('^par[[:space:]]+([^}]*)$', $param, $match)) { $tri = trim($match[1]); @@ -431,19 +620,5 @@ function calculer_param_dynamique($val, &$boucles, $idb) { } } -// -// Reserve les champs necessaires a la comparaison avec le contexte donne par -// la boucle parente ; attention en recursif il faut les reserver chez soi-meme -// ET chez sa maman -// -function calculer_argument_precedent($idb, $nom_champ, &$boucles) { - - // recursif ? - if ($boucles[$idb]->externe) - index_pile ($idb, $nom_champ, $boucles); // reserver chez soi-meme - - // reserver chez le parent et renvoyer l'habituel $Pile[$SP]['nom_champ'] - return index_pile ($boucles[$idb]->id_parent, $nom_champ, $boucles); -} ?> diff --git a/inc-form-squel.php3 b/inc-form-squel.php3 deleted file mode 100644 index 5614ffd5c75bcc4c7f5763ec75cceea70d4537fe..0000000000000000000000000000000000000000 --- a/inc-form-squel.php3 +++ /dev/null @@ -1,99 +0,0 @@ -<?php - -// -// Traduction des champs "formulaire" et "parametres" -// - - -// Formulaire de recherche -function balise_FORMULAIRE_RECHERCHE_dist($p) { - if ($p->fonctions) { - list(, $lien) = each($p->fonctions); // le premier est un url - while (list(, $filtre) = each($p->fonctions)) - $filtres[] = $filtre; // les suivants sont des filtres - $p->fonctions = $filtres; - } - if (!$lien) $lien = 'recherche.php3'; - - $p->code = "((lire_meta('activer_moteur') != 'oui') ? '' : calcul_form_rech('$lien'))"; - - $p->type = 'html'; - return $p; -} - - -// Formulaire d'inscription comme redacteur (dans inc-formulaires.php3) -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(); ?".">")'; - - $p->type = 'php'; - return $p; -} - -// Formulaire ecrire auteur -function balise_FORMULAIRE_ECRIRE_AUTEUR_dist($p) { - $_id_auteur = champ_sql('id_auteur', $p); - $_mail_auteur = champ_sql('email', $p); - - $p->code = '!email_valide('.$_mail_auteur.') ? "" : - ("<'.'?php include(\'inc-formulaires.php3\'); - lang_select(\'$spip_lang\'); - formulaire_ecrire_auteur(".'.$_id_auteur.'.", \'".texte_script('.$_mail_auteur.')."\'); - lang_dselect(); ?'.'>")'; - - $p->type = 'php'; - return $p; -} - -// Formulaire signature de petition -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\'); - lang_select(\'$spip_lang\'); - echo formulaire_signature(".'.$_id_article.'.", - \'".texte_script(serialize($petition))."\'); - lang_dselect(); ?".">")'; - - $p->type = 'php'; - return $p; -} - -// Formulaire d'inscription de site dans l'annuaire -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\'); - lang_select(\'".$GLOBALS[\'spip_lang\']."\'); - formulaire_site(".'.$_id_rubrique.'."); - lang_dselect(); ?".">"'; - - $p->type = 'php'; - return $p; -} - -// -// Formulaires de gestion de forums : les balises sont definies -// dans le fichier inc-forum.php3 qui centralise toute la gestion des forums -// -// Formulaire de reponse a un forum -# function balise_FORMULAIRE_FORUM_dist($p) {} -// Parametres de reponse a un forum -# function balise_PARAMETRES_FORUM_dist($p) {} -include_local('inc-forum.php3'); - - -// -// Boutons d'administration: -// -function balise_FORMULAIRE_ADMIN_dist($p) { - $p->code = "'<!-- @@formulaire_admin@@45609871@@ -->'"; - $p->type = "php"; - return $p; -} - -?> diff --git a/inc-reqsql-squel.php3 b/inc-reqsql-squel.php3 index 8f33122d17171f7dff6687252e02c0097f7ca2b1..d013ad8f639dc2f437e371ed87a86b2cdcb7133c 100644 --- a/inc-reqsql-squel.php3 +++ b/inc-reqsql-squel.php3 @@ -134,7 +134,7 @@ function calculer_requete(&$boucle) { "', $boucle->where) . '"')) . "), # WHERE '".addslashes($boucle->group)."', # GROUP - '".addslashes($boucle->order)."', # ORDER + " . ($boucle->order ? $boucle->order : "''") .", # ORDER " . (strpos($boucle->limit, 'intval') === false ? "'$boucle->limit'" : $boucle->limit). ", # LIMIT