From a936db34dad67c79e59a5059f5d1bdaf37cfcc17 Mon Sep 17 00:00:00 2001 From: Fil <fil@rezo.net> Date: Thu, 2 Sep 2004 20:40:53 +0000 Subject: [PATCH] =?UTF-8?q?attention=20m=C3=A9chant=20:=20d=C3=A9buggueur?= =?UTF-8?q?=20version=202=20+=20correction=20aide=20en=20ligne=20=3F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ecrire/aide_index.php3 | 4 +- ecrire/inc_version.php3 | 12 ++- inc-admin.php3 | 198 +++++++++++++++++++++++++++++----------- inc-balises.php3 | 8 +- inc-calcul.php3 | 21 +++-- inc-compilo.php3 | 29 +++++- inc-html-squel.php3 | 2 - inc-public-global.php3 | 14 +-- inc-public.php3 | 53 +++++++---- 9 files changed, 236 insertions(+), 105 deletions(-) diff --git a/ecrire/aide_index.php3 b/ecrire/aide_index.php3 index 497dd0f768..ad38fc4e51 100644 --- a/ecrire/aide_index.php3 +++ b/ecrire/aide_index.php3 @@ -21,7 +21,7 @@ echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3. echo "<html>"; echo "<head>"; echo "<title dir=\"".($spip_lang_rtl ? 'rtl' : 'ltr')."\">"._T('info_aide_en_ligne')."</title>"; -echo "</head><body>"; +echo "</head>\n"; $frame_menu = "<frame src=\"aide_gauche.php3?aide=$aide&les_rub=$les_rub&var_lang=$spip_lang#$ancre\" name=\"gauche\" scrolling=\"auto\" noresize>\n"; $frame_body = "<frame src=\"aide_droite.php3?aide=$aide&var_lang=$spip_lang\" name=\"droite\" scrolling=\"auto\" noresize>\n"; @@ -36,7 +36,7 @@ else { } echo '</frameset>'; -echo "</body></html>"; +echo "\n</html>"; ?> diff --git a/ecrire/inc_version.php3 b/ecrire/inc_version.php3 index fab19dd831..4235b7d100 100644 --- a/ecrire/inc_version.php3 +++ b/ecrire/inc_version.php3 @@ -148,9 +148,6 @@ $champs_extra_proposes = false; $ignore_auth_http = false; $ignore_remote_user = false; -// Faut-il afficher les boutons d'admin 'debug cache' et 'debug squelette' ? -$bouton_admin_debug = false; - // Faut-il "invalider" les caches quand on depublie ou modifie un article ? # en faire une option dans l'interface de configuration ? # NB: cette option ne concerne que articles,breves,rubriques et site @@ -164,6 +161,11 @@ $invalider_caches = true; // Si la variable vaut 0 aucun quota ne s'applique $quota_cache = 5; +// code a fournir pour obtenir le debuggueur (par defaut : &debug=oui) +// on peut mettre $code_activation_debug='' pour l'interdire carrement, +// ou $code_activation_debug='x5g8jk9' pour mettre un mot de passe. +$code_activation_debug = 'oui'; + // Serveurs externes $spip_server = array ( 'tex' => 'http://math.spip.org/tex.php', @@ -171,7 +173,7 @@ $spip_server = array ( 'ortho' => 'http://ortho.spip.net/ortho_serveur.php' ); -// Produire du TeX ou de MathML ? +// Produire du TeX ou du MathML ? $traiter_math = 'tex'; // Masquer les warning @@ -833,7 +835,7 @@ if (!defined('_DATA_META_CACHE') AND !defined('_ECRIRE_INC_META')) { eval('?'.'>'.$contenu); // en cas d'echec refaire le fichier - if (!is_array($meta)) { + if (!is_array($meta) AND @file_exists($dir_ecrire.'inc_connect.php3')) { include_ecrire('inc_meta.php3'); lire_metas(); ecrire_metas(); diff --git a/inc-admin.php3 b/inc-admin.php3 index dd5087a766..77d38635f8 100644 --- a/inc-admin.php3 +++ b/inc-admin.php3 @@ -17,31 +17,7 @@ function bouton_admin($titre, $lien) { } -function boutons_admin_debug($forcer_debug = false) { - global $debug_messages; - - if (($forcer_debug OR $GLOBALS['bouton_admin_debug'] - OR $GLOBALS['var_afficher_debug']) - AND ($GLOBALS['auteur_session']['statut'] == '0minirezo')) { - include_ecrire('inc_filtres.php3'); - - $link = $GLOBALS['clean_link']; - $link->addvar('var_afficher_debug', 'page'); - $link->addvar('recalcul', 'oui'); - $ret .= bouton_admin(_L('Debug cache'), $link->getUrl()); - - $link = $GLOBALS['clean_link']; - $link->addvar('var_afficher_debug', 'skel'); - $link->addvar('recalcul', 'oui'); - $ret .= bouton_admin(_L('Debug skel'), $link->getUrl()); - } - - $ret .= $debug_messages; - - return $ret; -} - -function afficher_boutons_admin($pop, $forcer_debug = false) { +function afficher_boutons_admin($pop='', $forcer_debug = false /* cas ou l'eval() plante dans inc-public */) { global $id_article, $id_breve, $id_rubrique, $id_mot, $id_auteur; global $var_preview; include_ecrire("inc_filtres.php3"); @@ -87,7 +63,9 @@ function afficher_boutons_admin($pop, $forcer_debug = false) { // Bouton Recalculer $link = $GLOBALS['clean_link']; $link->addVar('recalcul', 'oui'); - $link->delVar('var_afficher_debug'); + $link->delVar('var_debug'); + $link->delVar('debug_objet'); + $link->delVar('debug_affiche'); $lien = $link->getUrl(); $ret .= bouton_admin(_T('admin_recalculer').$pop, $lien); @@ -104,8 +82,21 @@ function afficher_boutons_admin($pop, $forcer_debug = false) { } } - // Boutons debug - $ret .= boutons_admin_debug($forcer_debug); + // Bouton de debug + if (($forcer_debug + OR $GLOBALS['bouton_admin_debug'] + OR (!$GLOBALS['var_debug'] + AND $GLOBALS['HTTP_COOKIE_VARS']['spip_debug'] == + $GLOBALS['code_activation_debug']) + ) AND $GLOBALS['code_activation_debug'] <> '') { + $link = $GLOBALS['clean_link']; + $link->addvar('var_debug', $GLOBALS['code_activation_debug']); + $ret .= bouton_admin(_L('Debug'), $link->getUrl()); + } + + // Messages de debug + global $debug_messages; + $ret .= $debug_messages; } $ret .= "</ul></div></div></div>"; @@ -132,27 +123,6 @@ function calcul_admin_page($cached, $texte) { } -function page_debug($type,$texte,$fichier) { - @header('Content-Type: text/html; charset='.lire_meta('charset')); - echo "<html><head><title>Debug $type : $fichier</title> - <meta http-equiv='Content-Type' content='text/html; charset=utf-8' /> - <link rel='stylesheet' href='spip_admin.css' type='text/css' />\n"; - if (@file_exists('spip_admin_perso.css')) echo "\t<link rel='stylesheet' href='spip_admin_perso.css' type='text/css' />\n"; - echo "</head><body>\n"; - echo "<p style='whitespace: nowrap;'><br /><code>$fichier</code><hr />\n"; - - $tableau = explode("\n", $texte); - $format = "%0".strlen(count($tableau))."d"; - $texte = ''; - foreach ($tableau as $ligne) - $texte .= "\n".sprintf($format, ++$i).'. '.$ligne; - highlight_string($texte); - - echo "</p>"; - echo afficher_boutons_admin('', true); - echo "</body></html>\n"; -} - // // Leve un drapeau si le squelette donne une page generant de graves erreurs php // @@ -278,9 +248,9 @@ function erreur_squelette($message, $fautif, $lieu) { // Pour un visiteur normal, ne rien afficher, si SPIP peut s'en sortir // tant mieux, sinon l'erreur se verra de toutes facons :-( - // ajouter &afficher_erreurs=1 pour discuter sur spip@rezo.net + // ajouter &var_debug=oui pour discuter sur spip@rezo.net if ($HTTP_COOKIE_VARS['spip_admin'] OR $auteur_session - OR $GLOBALS['afficher_erreurs']) { + OR $GLOBALS['var_debug']) { $message = "<h2>"._T('info_erreur_squelette')."</h2><p>$message</p>"; if ($fautif) $message .= ' (<FONT color="#FF000">' @@ -295,4 +265,130 @@ function erreur_squelette($message, $fautif, $lieu) { if (++$runs > 4) die ($debug_messages); } +// +// Le debugueur v2 +// + +// appelee a chaque sortie de boucle (inc-compilo) +function boucle_debug_resultat ($nom, $resultat) { + global $debug_objets; + + // ne pas memoriser plus de 3 tours d'une meme boucle + if (count($debug_objets['resultats'][$nom]) < 3) + $debug_objets['resultats'][$nom][] = $resultat; +} + +// appelee a chaque compilation de boucle (inc-compilo) +function boucle_debug_compile ($id, $nom, $pretty, $sourcefile, $code) { + global $debug_objets; + + $debug_objets['boucles'][$nom.$id] = $code; + $debug_objets['pretty'][$nom.$id] = $pretty; +} + +// appelee a chaque compilation de squelette (inc-compilo) +function squelette_debug_compile($nom, $sourcefile, $squelette) { + global $debug_objets; + + $debug_objets['squelettes'][$nom] = $squelette; + $debug_objets['sourcefile'][$nom] = $sourcefile; +} + +// l'environnement graphique du debuggueur +function debug_page($no_exit = false) { + global $flag_ob; + global $debug_objets, $debug_objet, $debug_affiche; + + if ($flag_ob) + ob_end_clean(); + + + @header("Content-Type: text/html; charset=".lire_meta('charset')); + echo afficher_boutons_admin(); + echo "<h3>Structure de la page</h3>\n"; + + foreach ($debug_objets['sourcefile'] as $nom_skel => $sourcefile) { + echo "<li><b>".$sourcefile."</b>"; + $link = $GLOBALS['clean_link']; + $link->addvar('debug_objet', $nom_skel); + $link->delvar('debug_affiche'); + echo " <a href='".$link->getUrl()."&debug_affiche=code'>code</a>"; + echo " <a href='".$link->getUrl()."&debug_affiche=resultat'>resultat</a>"; + echo "</li>\n<ul>\n"; + + if (is_array($debug_objets['pretty'])) + foreach ($debug_objets['pretty'] as $nom => $pretty) + if (substr($nom, 0, strlen($nom_skel)) == $nom_skel) { + echo "<li>"; + echo "<".$pretty.">"; + $link = $GLOBALS['clean_link']; + $link->addvar('debug_objet', $nom); + $link->delvar('debug_affiche'); + echo " <a href='".$link->getUrl()."&debug_affiche=code'>code</a>"; + echo " <a href='".$link->getUrl()."&debug_affiche=resultat'>resultat</a>"; + echo "</li>\n"; + } + echo "</ul>\n"; + } + + if ($debug_objet AND $debug_affiche == 'resultat' AND ($res = $debug_objets['resultats'][$debug_objet])) { + echo "<b>".$debug_objets['pretty'][$debug_objet]."</b><br />"; + echo "les premiers appels à cette boucle ont donné les résultats ci-dessous:<br />"; + foreach ($res as $view) { + echo "<hr>".interdire_scripts($view); + } + } else if ($debug_objet AND $debug_affiche == 'code' AND $res = $debug_objets['boucles'][$debug_objet]) { + echo "<b>".$debug_objets['pretty'][$debug_objet]."</b><br />"; + highlight_string("<"."?php\n".$res."\n?".">"); + } + + + if (!$no_exit) exit; +} + +function debug_dumpfile ($texte) { + global $flag_ob; + + # un peu violent : si on est un fichier inclus, + # il faut d'abord vider le ob_ + if ($flag_ob) + ob_end_clean(); + + debug_page('no exit'); + + $tableau = explode("\n", $texte); + $format = "%0".strlen(count($tableau))."d"; + $texte = ''; + foreach ($tableau as $ligne) + $texte .= "\n".sprintf($format, ++$i).'. '.$ligne; + highlight_string($texte); + + exit; +} + + +function verifie_cookie_debug() { + global $code_activation_debug; + + if ($GLOBALS['HTTP_COOKIE_VARS']['spip_debug'] + != $code_activation_debug) { + spip_setcookie('spip_debug', $code_activation_debug, time()+3600); + include_ecrire('inc_presentation.php3'); + install_debut_html(_L('Bienvenue dans le debuggueur de SPIP')); + echo "<P>"._L("Cet outil vous permet d'analyser les pages produites par + SPIP. Il est parfois de lecture difficile, mais il offre en contrepartie + une grande capacité de recherche des erreurs, et une meilleure + compréhension du fonctionnement des boucles et balises du + système.</p>"); + echo "<P>"._L("Pour entrer, il vous suffit de recharger cette page, + après avoir accepté un cookie (ce dernier permet + d'écarter les moteurs de recherche, et installe un bouton + d'administration supplémentaire «debug» sur + votre écran, pendant une heure).</p>"); + install_fin_html(); + exit; + } else + return true; +} + ?> diff --git a/inc-balises.php3 b/inc-balises.php3 index 6763442bc2..ca9dad37fa 100644 --- a/inc-balises.php3 +++ b/inc-balises.php3 @@ -257,10 +257,12 @@ 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 = "''"; + } else { + $p->code = "\$Numrows['$p->id_mere']"; + $p->boucles[$p->id_mere]->numrows = true; + $p->type = 'php'; } - $p->code = "\$Numrows['$p->id_mere']"; - $p->boucles[$p->id_mere]->numrows = true; - $p->type = 'php'; return $p; } diff --git a/inc-calcul.php3 b/inc-calcul.php3 index 0cac156d9b..702b183305 100644 --- a/inc-calcul.php3 +++ b/inc-calcul.php3 @@ -83,8 +83,11 @@ function charger_squelette ($squelette) { $skel_compile = "<"."?php\n" . calculer_squelette($skel, $nom, $ext, $sourcefile)."\n?".">"; - // Envoyer le debugguer - afficher_page_si_demande_admin ('skel', $skel_compile, _L('Fond : ').$sourcefile." ; fichier produit : ".$phpfile); + // Parler au debugguer + if ($GLOBALS['var_debug'] AND $GLOBALS['debug_objet'] == $nom + AND $GLOBALS['debug_affiche'] == 'code') + debug_dumpfile ($skel_compile); + // Evaluer le squelette eval('?'.'>'.$skel_compile); @@ -97,8 +100,7 @@ function charger_squelette ($squelette) { echo "<hr /><h2>". _L("Erreur dans la compilation du squelette")." $sourcefile</h2>"; $GLOBALS['bouton_admin_debug'] = true; - $GLOBALS['var_afficher_debug'] = 'skel'; - afficher_page_si_demande_admin ('skel', $skel_compile, _L('Fond : ').$sourcefile." ; fichier produit : ".$phpfile); + debug_dumpfile ($skel_compile); } } } @@ -154,7 +156,13 @@ 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)); - // Memoriser le nom du squelette utilise (pour le debuggueur) + // Passer la main au debuggueur) + if ($GLOBALS['var_debug'] AND $GLOBALS['debug_objet'] == $fonc + AND $GLOBALS['debug_affiche'] == 'resultat') { + debug_dumpfile ($page['texte']); + } + + # flag pour spip_error_handler(), cf inc-admin ?? $page['squelette'] = $skel; // Nettoyer le resultat si on est fou de XML @@ -283,7 +291,8 @@ function calculer_page($chemin_cache, $elements, $delais, $inclusion=false) { serialize($page['signal']))." -->\n"; // Enregistrer le fichier cache - if ($delais > 0 AND empty($GLOBALS['HTTP_POST_VARS'])) + if ($delais > 0 AND !$GLOBALS['var_debug'] + AND empty($GLOBALS['HTTP_POST_VARS'])) ecrire_fichier($chemin_cache, $signal.$page['texte']); return $page; diff --git a/inc-compilo.php3 b/inc-compilo.php3 index 3b3be3c24e..fdada54234 100644 --- a/inc-compilo.php3 +++ b/inc-compilo.php3 @@ -351,7 +351,6 @@ function calculer_boucle($id_boucle, &$boucles) { // Conclusion et retour // $conclusion = "\n @spip_free_result(\$result);"; - $conclusion .= "\n return \$t0;"; return $texte . $init . $corps . $conclusion; } @@ -633,11 +632,27 @@ function calculer_squelette($squelette, $nom, $gram, $sourcefile) { $pretty = ereg_replace("[\r\n]", " ", $pretty); // Puis envoyer son code - $code .= "\n//\n// <$pretty>\n//\n" + $codeboucle = "\n//\n// <$pretty>\n//\n" ."function $nom" . ereg_replace("-","_",$id) . '(&$Cache, &$Pile, &$doublons, &$Numrows, $SP) {' . - $boucle->return . - "\n}\n\n"; + $boucle->return; + + $fincode = "\n return \$t0;" + ."\n}\n\n"; + + ## inserer les elements pour le debuggueur, a deux niveaux : + ## 1) apres le calcul d'une boucle compilee, envoyer le code + ## compile vers boucle_debug_compile() + ## 2) le resultat de la boucle, lui, sera plus tard envoye vers + ## boucle_debug_resultat() + if ($GLOBALS['var_debug']) { + boucle_debug_compile ($id, $nom, $pretty, + $sourcefile, $codeboucle.$fincode); + $codedebug = "\n boucle_debug_resultat + ('$nom$id', \$t0);"; + } + + $code .= $codeboucle.$codedebug.$fincode; } } @@ -649,7 +664,7 @@ function calculer_squelette($squelette, $nom, $gram, $sourcefile) { else $aff_boucles = "pas de boucle"; - return " + $squelette_compile = " /* * Squelette : $sourcefile * Date : ".http_gmoddate(@filemtime($sourcefile))." GMT @@ -674,6 +689,10 @@ $corps } "; + if ($GLOBALS['var_debug']) + squelette_debug_compile($nom, $sourcefile, $squelette_compile); + + return $squelette_compile; } ?> diff --git a/inc-html-squel.php3 b/inc-html-squel.php3 index fda23b6c3e..e72cf69312 100644 --- a/inc-html-squel.php3 +++ b/inc-html-squel.php3 @@ -271,7 +271,6 @@ function parser($texte, $id_parent, &$boucles) { erreur_squelette(_T('erreur_boucle_syntaxe'), '', $id_boucle . _L(' : balise B en aval')); - exit; } // @@ -284,7 +283,6 @@ function parser($texte, $id_parent, &$boucles) { erreur_squelette(_T('erreur_boucle_syntaxe'), '', _T('erreur_boucle_fermant', array('id'=>$id_boucle))); - exit; } $texte = substr($milieu, $p + strlen($s)); $milieu = substr($milieu, 0, $p); diff --git a/inc-public-global.php3 b/inc-public-global.php3 index 3351a35b8b..8ddb3eaf7a 100644 --- a/inc-public-global.php3 +++ b/inc-public-global.php3 @@ -101,7 +101,7 @@ function obtenir_page ($contexte, $chemin_cache, $delais, $use_cache, $fond, $in // Appeler cette fonction pour obtenir la page principale // function afficher_page_globale ($fond, $delais, &$use_cache) { - global $flag_preserver, $recalcul, $lastmodified; + global $flag_preserver, $flag_dynamique, $recalcul, $lastmodified; global $var_preview; include_local ("inc-cache.php3"); @@ -140,7 +140,7 @@ function afficher_page_globale ($fond, $delais, &$use_cache) { // eventuels fichiers inclus modifies depuis la date // HTTP_IF_MODIFIED_SINCE du client) if ($GLOBALS['HTTP_IF_MODIFIED_SINCE'] AND $recalcul != oui - AND $chemin_cache) { + AND $chemin_cache AND !$flag_dynamique) { $lastmodified = @filemtime($chemin_cache); $headers_only = http_last_modified($lastmodified); } @@ -280,16 +280,6 @@ function admin_page($cached, $texte) { return false; // pas de boutons admin } -// Si l'admin a demande un affichage -function afficher_page_si_demande_admin ($type, $texte, $fichier) { - if ($GLOBALS['var_afficher_debug'] == $type - AND $GLOBALS['auteur_session']['statut'] == '0minirezo') { - include_local('inc-admin.php3'); - page_debug($type,$texte,$fichier); - exit; - } -} - function cherche_image_nommee($nom) { $dossier = 'IMG'; $formats = array ('gif', 'jpg', 'png'); diff --git a/inc-public.php3 b/inc-public.php3 index 61ecc6ab9b..722f26b34e 100644 --- a/inc-public.php3 +++ b/inc-public.php3 @@ -39,14 +39,9 @@ else { include_ecrire ("inc_session.php3"); verifier_visiteur(); } - // Faut-il preparer les boutons d'admin ? - if ($affiche_boutons_admin = (!$flag_preserver - AND $HTTP_COOKIE_VARS['spip_admin'])) { - include_local('inc-admin.php3'); - } // multilinguisme - if ($forcer_lang AND ($forcer_lang!=='non')) { + if ($forcer_lang AND ($forcer_lang!=='non') AND empty($HTTP_POST_VARS)) { include_ecrire('inc_lang.php3'); verifier_lang_url(); } @@ -55,7 +50,6 @@ else { lang_select($HTTP_GET_VARS['lang']); } - // Ajout_forum (pour les forums) et $val_confirm signalent des modifications // a faire avant d'afficher la page if ($ajout_forum) { @@ -74,31 +68,48 @@ else { reponse_confirmation($id_article); } + + // demande de debug ? + if ($var_debug == $code_activation_debug AND $code_activation_debug <> '') { + // verifier que ce n'est pas un robot, en posant un cookie, + // car ces calculs coutent trop cher pour pouvoir etre "aspires". + // (pour la securite, cf. $code_activation_debug dans inc_version) + // ce cookie ne dure qu'une heure, car il sert aussi a afficher + // le bouton 'debug' sur toutes les pages + include_local('inc-admin.php3'); + if ($var_debug = verifie_cookie_debug()) { + $recalcul = 'oui'; + $var_debug = true; + spip_log('debug !'); + } + } else + $var_debug = false; + + // Faut-il preparer les boutons d'admin ? + if ($affiche_boutons_admin = (!$flag_preserver + AND $HTTP_COOKIE_VARS['spip_admin'])) { + include_local('inc-admin.php3'); + } + include_local ("inc-public-global.php3"); $page = afficher_page_globale ($fond, $delais, $use_cache); + // Demarrer un buffer pour le content-length (ou le debug) + if ($flag_ob) + ob_start(); + // Afficher la page ; le cas PHP est assez rigolo avec le traitement // d'erreurs if ($page['process_ins'] == 'php') { - // Envoyer le debugguer ? - afficher_page_si_demande_admin ('page', $page['texte'], - _L("Fond : ").$page['squelette']." ; ".($page['cache'] ? - "fichier produit : ".$page['cache'] : "pas de fichier produit - (\$delais=0)")); - - // Demarrer un buffer pour le content-length (ou le debug) - if ($flag_ob) - ob_start(); - // Ici on va ruser pour intercepter les erreurs (meme les FATAL) // dans le eval : on envoie le bouton debug, et on le supprime // de l'autre cote ; de cette facon, si on traverse sans encombre, // on est propre, et sinon on a le bouton if ($affiche_boutons_admin) { - // recuperer les parse errors etc. + // recuperer les parse errors etc., type "FATAL" (cf. infra) if ($auteur_session['statut'] == '0minirezo') { $tableau_des_erreurs = array(); $page_principale = $page; @@ -107,7 +118,7 @@ else { } if ($flag_ob) - echo afficher_boutons_admin('', true).'<!-- @@START@@ -->'; + echo afficher_boutons_admin('', 'debug').'<!-- @@START@@ -->'; } // @@ -138,6 +149,10 @@ else { } else echo $page['texte']; // page tout 'html' + // Passer la main au debuggueur le cas echeant + if ($var_debug) + debug_page(); + // // Et l'envoyer si on est bufferise (ce qu'il faut souhaiter) // avec les entetes de cache -- GitLab