| [ Index ] |
|
Code source de SPIP 1.9.2c |
1 <?php 2 3 /***************************************************************************\ 4 * SPIP, Systeme de publication pour l'internet * 5 * * 6 * Copyright (c) 2001-2007 * 7 * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James * 8 * * 9 * Ce programme est un logiciel libre distribue sous licence GNU/GPL. * 10 * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. * 11 \***************************************************************************/ 12 13 if (!defined("_ECRIRE_INC_VERSION")) return; 14 15 // 16 // Gestion des inclusions et infos repertoires 17 // 18 19 // Cette inclusion est destine aux extensions de Spip qui n'ont pas suivi 20 // son evolution. Si vous n'en utilisez pas, neutraliser cette ligne pour 21 // gagner du temps au chargement. 22 23 include(_DIR_RESTREINT . 'inc/vieilles_defs.php'); 24 25 // charge un fichier perso ou, a defaut, standard 26 // et retourne si elle existe le nom de la fonction homonyme (exec_$nom), 27 // ou de suffixe _dist 28 // Peut etre appelee plusieurs fois, donc optimiser 29 // http://doc.spip.org/@charger_fonction 30 function charger_fonction($nom, $dossier='exec', $continue=false) { 31 32 if (substr($dossier,-1) != '/') $dossier .= '/'; 33 34 if (function_exists($f = str_replace('/','_',$dossier) . $nom)) 35 return $f; 36 if (function_exists($g = $f . '_dist')) 37 return $g; 38 39 // Sinon charger le fichier de declaration si plausible 40 41 if (!preg_match(',^\w+$,', $f)) 42 die(htmlspecialchars($nom)." pas autorise"); 43 44 // passer en minuscules (cf les balises de formulaires) 45 $inc = include_spip($d = ($dossier . strtolower($nom))); 46 47 if (function_exists($f)) return $f; 48 if (function_exists($g)) return $g; 49 if ($continue) return false; 50 51 // Echec : message d'erreur 52 spip_log("fonction $nom ($f ou $g) indisponible" . 53 ($inc ? "" : " (fichier $d absent)")); 54 55 include_spip('inc/minipres'); 56 echo minipres(_T('forum_titre_erreur'), 57 _T('fichier_introuvable', array('fichier'=> '<b>'.htmlentities($d).'</b>'))); 58 exit; 59 } 60 61 // 62 // une fonction cherchant un fichier dans une liste de repertoires 63 // 64 // http://doc.spip.org/@include_spip 65 function include_spip($f, $include = true) { 66 67 // Dans le noyau ? 68 if (isset($GLOBALS['noyau'][$f])) { 69 $s = $GLOBALS['noyau'][$f]; 70 } 71 // Sinon le chercher et mettre a jour le noyau 72 else { 73 if (!$s = find_in_path($f . '.php') 74 AND (!_EXTENSION_PHP OR !$s = find_in_path($f . '.php3'))) { 75 return $GLOBALS['noyau'][$f] = false; 76 } else 77 $GLOBALS['noyau'][$f] = $s; 78 } 79 80 // On charge le fichier (sauf si on ne voulait que son chemin) 81 if ($include && $s) { 82 include_once $s; 83 } 84 85 return $s; 86 } 87 88 // un pipeline est lie a une action et une valeur 89 // chaque element du pipeline est autorise a modifier la valeur 90 // 91 // le pipeline execute les elements disponibles pour cette action, 92 // les uns apres les autres, et retourne la valeur finale 93 // 94 // Cf. compose_filtres dans references.php, qui est la 95 // version compilee de cette fonctionnalite 96 97 // appel unitaire d'une fonction du pipeline 98 // utilisee dans le script pipeline precompile 99 // http://doc.spip.org/@minipipe 100 function minipipe($fonc,$val){ 101 102 // fonction 103 if (function_exists($fonc)) 104 $val = call_user_func($fonc, $val); 105 106 // Class::Methode 107 else if (preg_match("/^(\w*)::(\w*)$/", $fonc, $regs) 108 AND $methode = array($regs[1], $regs[2]) 109 AND is_callable($methode)) 110 $val = call_user_func($methode, $val); 111 else 112 spip_log("Erreur - '$fonc' non definie !"); 113 return $val; 114 } 115 116 // chargement du pipeline sous la forme d'un fichier php prepare 117 // http://doc.spip.org/@pipeline 118 function pipeline($action,$val) { 119 static $charger; 120 121 // chargement initial des fonctions mises en cache, ou generation du cache 122 if (!$charger) { 123 if (!($ok = @is_readable($charger = _DIR_TMP."charger_pipelines.php"))) { 124 include_spip('inc/plugin'); 125 // generer les fichiers php precompiles 126 // de chargement des plugins et des pipelines 127 verif_plugin(); 128 if (!($ok = @is_readable($charger))) 129 spip_log("fichier $charger pas cree"); 130 } 131 132 if ($ok) 133 include_once $charger; 134 } 135 136 // appliquer notre fonction si elle existe 137 $fonc = 'execute_pipeline_'.$action; 138 if (function_exists($fonc)) { 139 $val = $fonc($val); 140 } 141 // plantage ? 142 else { 143 include_spip('inc/plugin'); 144 // on passe $action en arg pour creer la fonction meme si le pipe 145 // n'est defini nul part ; vu qu'on est la c'est qu'il existe ! 146 verif_plugin($action); 147 spip_log("fonction $fonc absente : pipeline desactive"); 148 } 149 // si le flux est une table qui encapsule donnees et autres 150 // on ne ressort du pipe que les donnees 151 // array_key_exists pour php 4.1.0 152 if (is_array($val) && in_array('data', array_keys($val))) 153 $val = $val['data']; 154 return $val; 155 } 156 157 // 158 // Enregistrement des evenements 159 // 160 // http://doc.spip.org/@spip_log 161 function spip_log($message, $logname='spip') { 162 static $compteur; 163 if ($compteur++ > 100) return; 164 165 $pid = '(pid '.@getmypid().')'; 166 167 // accepter spip_log( Array ) 168 if (!is_string($message)) $message = var_export($message, true); 169 170 $message = date("M d H:i:s").' '.$GLOBALS['ip'].' '.$pid.' ' 171 .preg_replace("/\n*$/", "\n", $message); 172 173 $logfile = _DIR_TMP . $logname . '.log'; 174 if (@is_readable($logfile) 175 AND (!$s = @filesize($logfile) OR $s > 10*1024)) { 176 $rotate = true; 177 $message .= "[-- rotate --]\n"; 178 } else $rotate = ''; 179 $f = @fopen($logfile, "ab"); 180 if ($f) { 181 fputs($f, htmlspecialchars($message)); 182 fclose($f); 183 } 184 if ($rotate) { 185 @unlink($logfile.'.3'); 186 @rename($logfile.'.2',$logfile.'.3'); 187 @rename($logfile.'.1',$logfile.'.2'); 188 @rename($logfile,$logfile.'.1'); 189 } 190 191 // recopier les spip_log mysql (ce sont uniquement des erreurs) 192 // dans le spip_log general 193 if ($logname == 'mysql') 194 spip_log($message); 195 } 196 197 // API d'appel a la base de donnees: 198 // on charge le fichier du repertoire base/ donne en argument 199 // et on execute la fonction homonyme censee initaliser la connexion 200 // et renvoyer le nom de la fonction a connexion persistante. 201 // On memorise ce nom dans une statique pour n'appeler qu'une fois. 202 // On echoue si la connexion SPIP est morte (spip_meta pas lue) 203 // http://doc.spip.org/@spip_connect 204 function spip_connect($serveur='') { 205 static $t = array(); 206 207 // Assimiler spip_connect() et spip_connect('') [PHP les distingue]. 208 // Tous deux designent le serveur SQL std "db_mysql" (obscur mais historique) 209 210 if (!$serveur) $serveur = 'db_mysql'; 211 212 if (isset($t[$serveur])) return $t[$serveur]; 213 214 $base_serveur = charger_fonction($serveur, 'base', true); 215 216 if (!$base_serveur) { 217 spip_log("serveur inconnu $serveur"); 218 return $t[$serveur] = false; 219 } 220 return $t[$serveur] = $base_serveur(); 221 } 222 223 // http://doc.spip.org/@spip_query 224 function spip_query($query, $serveur='') { 225 226 if (!($f = spip_connect($serveur))) return; // Erreur de connexion 227 228 // executer la requete 229 return $f($query); 230 } 231 232 // a demenager dans base/abstract_sql a terme 233 // http://doc.spip.org/@_q 234 function _q($a) { 235 return (is_int($a)) ? strval($a) : ("'" . addslashes($a) . "'"); 236 } 237 238 // Renvoie le _GET ou le _POST emis par l'utilisateur 239 // ou pioche dans $c si c'est un array() 240 // http://doc.spip.org/@_request 241 function _request($var, $c=false) { 242 243 if (is_array($c)) 244 return isset($c[$var]) ? $c[$var] : NULL; 245 246 if (isset($_GET[$var])) $a = $_GET[$var]; 247 elseif (isset($_POST[$var])) $a = $_POST[$var]; 248 else return NULL; 249 250 // temporaire: si on est en ajax et en POST tout a ete encode 251 // via encodeURIComponent, il faut donc repasser 252 // dans le charset local.... on le connait grace 253 // a la variable var_ajaxcharset ajoutee dans layer.js 254 255 if (isset($_POST['var_ajaxcharset']) 256 AND isset($GLOBALS['meta']['charset']) 257 AND $GLOBALS['meta']['charset'] != $_POST['var_ajaxcharset'] 258 AND is_string($a) 259 AND preg_match(',[\x80-\xFF],', $a)) { 260 include_spip('inc/charsets'); 261 return importer_charset($a, $_POST['var_ajaxcharset']); 262 } 263 264 return $a; 265 } 266 267 // Methode set de la fonction _request() 268 // Attention au cas ou l'on fait set_request('truc', NULL); 269 // http://doc.spip.org/@set_request 270 function set_request($var, $val = NULL, $c=false) { 271 if (is_array($c)) { 272 unset($c[$var]); 273 if ($val !== NULL) 274 $c[$var] = $val; 275 return $c; 276 } 277 278 unset($_GET[$var]); 279 unset($_POST[$var]); 280 if ($val !== NULL) 281 $_GET[$var] = $val; 282 283 return false; # n'affecte pas $c 284 } 285 286 // 287 // Prend une URL et lui ajoute/retire un parametre. 288 // Exemples : [(#SELF|parametre_url{suite,18})] (ajout) 289 // [(#SELF|parametre_url{suite,''})] (supprime) 290 // [(#SELF|parametre_url{suite})] (prend $suite dans la _request) 291 // http://www.spip.net/@parametre_url 292 // 293 // http://doc.spip.org/@parametre_url 294 function parametre_url($url, $c, $v=NULL, $sep='&') { 295 296 // lever l'#ancre 297 if (preg_match(',^([^#]*)(#.*)$,', $url, $r)) { 298 $url = $r[1]; 299 $ancre = $r[2]; 300 } else 301 $ancre = ''; 302 303 // eclater 304 $url = preg_split(',[?]|&|&,', $url); 305 306 // recuperer la base 307 $a = array_shift($url); 308 if (!$a) $a= './'; 309 310 // ajout de la globale ? 311 if ($v === NULL) 312 $v = _request($c); 313 314 // lire les variables et agir 315 foreach ($url as $n => $val) { 316 if (preg_match(',^'.preg_quote($c,',').'(=.*)?$,', urldecode($val))) { 317 // suppression 318 if (!$v) { 319 unset($url[$n]); 320 } else { 321 $url[$n] = $c.'='.rawurlencode($v); 322 $v = ''; 323 } 324 } 325 } 326 327 // ajouter notre parametre si on ne l'a pas encore trouve 328 if ($v) 329 $url[] = $c.'='.rawurlencode($v); 330 331 // eliminer les vides 332 $url = array_filter($url); 333 334 // recomposer l'adresse 335 if ($url) 336 $a .= '?' . join($sep, $url); 337 338 return $a . $ancre; 339 } 340 341 // 342 // Prend une URL et lui ajoute/retire une ancre. 343 // http://doc.spip.org/@ancre_url 344 function ancre_url($url, $ancre) { 345 // lever l'#ancre 346 if (preg_match(',^([^#]*)(#.*)$,', $url, $r)) { 347 $url = $r[1]; 348 } 349 return $url .'#'. $ancre; 350 } 351 352 // 353 // pour calcul du nom du fichier cache et autres 354 // 355 // http://doc.spip.org/@nettoyer_uri 356 function nettoyer_uri() { 357 $uri1 = $GLOBALS['REQUEST_URI']; 358 do { 359 $uri = $uri1; 360 $uri1 = preg_replace 361 (',([?&])(PHPSESSID|(var_[^=&]*))=[^&]*(&|$),i', 362 '\1', $uri); 363 } while ($uri<>$uri1); 364 365 return preg_replace(',[?&]$,', '', $uri1); 366 } 367 368 // 369 // donner l'URL de base d'un lien vers "soi-meme", modulo 370 // les trucs inutiles 371 // 372 // http://doc.spip.org/@self 373 function self($root = false) { 374 $url = nettoyer_uri(); 375 if (!$root) 376 $url = preg_replace(',^[^?]*/,', '', $url); 377 378 // ajouter le cas echeant les variables _POST['id_...'] 379 foreach ($_POST as $v => $c) 380 if (substr($v,0,3) == 'id_') 381 $url = parametre_url($url, $v, $c, '&'); 382 383 // supprimer les variables sans interet 384 if (!_DIR_RESTREINT) { 385 $url = preg_replace (',([?&])(' 386 .'lang|set_options|set_couleur|set_disp|set_ecran|show_docs|' 387 .'changer_lang|var_lang|action)=[^&]*,i', '\1', $url); 388 $url = preg_replace(',([?&])[&]+,', '\1', $url); 389 $url = preg_replace(',[&]$,', '\1', $url); 390 } 391 392 // eviter les hacks 393 $url = htmlspecialchars($url); 394 395 // Si c'est vide, donner './' 396 $url = preg_replace(',^$,', './', $url); 397 398 return $url; 399 } 400 401 // 402 // Traduction des textes de SPIP 403 // 404 // http://doc.spip.org/@_T 405 function _T($texte, $args=array()) { 406 407 static $traduire=false ; 408 409 if (!$traduire) 410 $traduire = charger_fonction('traduire', 'inc'); 411 $text = $traduire($texte,$GLOBALS['spip_lang']); 412 413 if (!$text) 414 // pour les chaines non traduites 415 $text = str_replace('_', ' ', 416 (($n = strpos($texte,':')) === false ? $texte : 417 substr($texte, $n+1))); 418 419 while (list($name, $value) = @each($args)) 420 $text = str_replace ("@$name@", $value, $text); 421 return $text; 422 423 } 424 425 // chaines en cours de traduction 426 // http://doc.spip.org/@_L 427 function _L($text, $args=array()) { 428 while (list($name, $value) = @each($args)) 429 $text = str_replace ("@$name@", $value, $text); 430 if ($GLOBALS['test_i18n']) 431 return "<span style='color:red;'>$text</span>"; 432 else 433 return str_replace('_', ' ',$text); 434 } 435 436 // Afficher "ecrire/data/" au lieu de "data/" dans les messages 437 // ou tmp/ au lieu de ../tmp/ 438 // http://doc.spip.org/@joli_repertoire 439 function joli_repertoire($rep) { 440 $a = substr($rep,0,1); 441 if ($a<>'.' AND $a<>'/') 442 $rep = (_DIR_RESTREINT?'':_DIR_RESTREINT_ABS).$rep; 443 $rep = preg_replace(',(^\.\.\/),', '', $rep); 444 return $rep; 445 } 446 447 // Nommage bizarre des tables d'objets 448 // http://doc.spip.org/@table_objet 449 function table_objet($type) { 450 static $surnoms = array( 451 'article' => 'articles', 452 'auteur' => 'auteurs', 453 'breve' => 'breves', 454 'document' => 'documents', 455 'doc' => 'documents', # pour les modeles 456 'img' => 'documents', 457 'emb' => 'documents', 458 'forum' => 'forum', # hum 459 'groupe_mots' => 'groupes_mots', # hum 460 'message' => 'messages', 461 'mot' => 'mots', 462 'petition' => 'petitions', 463 'rubrique' => 'rubriques', 464 'signature' => 'signatures', 465 'syndic' => 'syndic', 466 'site' => 'syndic', # hum hum 467 'syndic_article' => 'syndic_articles', 468 'type_document' => 'types_documents' # hum 469 ); 470 return isset($surnoms[$type]) ? $surnoms[$type] : $type."s"; 471 } 472 473 // http://doc.spip.org/@id_table_objet 474 function id_table_objet($type) { 475 if ($type == 'site' OR $type == 'syndic') 476 return 'id_syndic'; 477 else if ($type == 'forum') 478 return 'id_forum'; 479 else if ($type=='doc' OR $type=='img' OR $type=='emb') # pour les modeles 480 return 'id_document'; 481 else 482 return 'id_'.$type; 483 } 484 485 486 // 487 // spip_timer : on l'appelle deux fois et on a la difference, affichable 488 // 489 // http://doc.spip.org/@spip_timer 490 function spip_timer($t='rien') { 491 static $time; 492 $a=time(); $b=microtime(); 493 494 if (isset($time[$t])) { 495 $p = $a + $b - $time[$t]; 496 unset($time[$t]); 497 return sprintf("%.2fs", $p); 498 } else 499 $time[$t] = $a + $b; 500 } 501 502 503 // spip_touch : verifie si un fichier existe et n'est pas vieux (duree en s) 504 // et le cas echeant le touch() ; renvoie true si la condition est verifiee 505 // et fait touch() sauf si ca n'est pas souhaite 506 // (regle aussi le probleme des droits sur les fichiers touch()) 507 // http://doc.spip.org/@spip_touch 508 function spip_touch($fichier, $duree=0, $touch=true) { 509 if (!($exists = @is_readable($fichier)) 510 || ($duree == 0) 511 || (@filemtime($fichier) < time() - $duree)) { 512 if ($touch) { 513 if (!@touch($fichier)) { @unlink($fichier); @touch($fichier); }; 514 if (!$exists) @chmod($fichier, _SPIP_CHMOD & ~0111); 515 } 516 return true; 517 } 518 return false; 519 } 520 521 // Ce declencheur de tache de fond, de l'espace prive (cf inc_presentation) 522 // et de l'espace public (cf #SPIP_CRON dans inc_balise), est appelee 523 // par un background-image car contrairement a un iframe vide, 524 // les navigateurs ne diront pas qu'ils n'ont pas fini de charger, 525 // c'est plus rassurant. 526 // C'est aussi plus discret qu'un <img> sous un navigateur non graphique. 527 528 // http://doc.spip.org/@action_cron 529 function action_cron() { 530 include_spip('inc/headers'); 531 envoie_image_vide(); 532 cron (1); 533 } 534 535 // 536 // cron() : execution des taches de fond 537 // quand il est appele par public.php il n'est pas gourmand; 538 // quand il est appele par ?action=cron, il est gourmand 539 540 // http://doc.spip.org/@cron 541 function cron ($gourmand=false) { 542 543 // Si on est gourmand, ou si le fichier gourmand n'existe pas 544 // (ou est trop vieux -> 60 sec), on va voir si un cron est necessaire. 545 // Au passage si on est gourmand on le dit aux autres 546 if (spip_touch(_DIR_TMP.'cron.lock-gourmand', 60, $gourmand) 547 OR $gourmand) { 548 549 // Faut-il travailler ? Pas tous en meme temps svp 550 // Au passage si on travaille on bloque les autres 551 if (spip_touch(_DIR_TMP.'cron.lock', 2)) { 552 include_spip('inc/cron'); 553 spip_cron(); 554 } 555 } 556 } 557 558 559 // transformation XML des "&" en "&" 560 // http://doc.spip.org/@quote_amp 561 function quote_amp($u) { 562 return preg_replace( 563 "/&(?![a-z]{0,4}\w{2,3};|#x?[0-9a-f]{2,5};)/i", 564 "&",$u); 565 } 566 567 // Transforme n'importe quel champ en une chaine utilisable 568 // en PHP ou Javascript en toute securite 569 // < ? php $x = '[(#TEXTE|texte_script)]'; ? > 570 // http://doc.spip.org/@texte_script 571 function texte_script($texte) { 572 return str_replace('\'', '\\\'', str_replace('\\', '\\\\', $texte)); 573 } 574 575 // 576 // find_in_path() : chercher un fichier nomme x selon le chemin rep1:rep2:rep3 577 // 578 // http://doc.spip.org/@creer_chemin 579 function creer_chemin() { 580 static $path_a = array(); 581 static $c = ''; 582 583 // on calcule le chemin si le nombre de plugins a change 584 if ($c != count($GLOBALS['plugins']).$GLOBALS['dossier_squelettes']) { 585 $c = count($GLOBALS['plugins']).$GLOBALS['dossier_squelettes']; 586 587 // Chemin standard depuis l'espace public 588 $path = defined('_SPIP_PATH') ? _SPIP_PATH : 589 _DIR_RACINE.':'. 590 _DIR_RACINE.'dist/:'. 591 _DIR_RESTREINT; 592 593 // Ajouter les repertoires des plugins 594 if ($GLOBALS['plugins']) 595 $path = _DIR_PLUGINS 596 . join(':'._DIR_PLUGINS, $GLOBALS['plugins']) 597 . ':' . $path; 598 599 // Ajouter squelettes/ 600 if (@is_dir(_DIR_RACINE.'squelettes')) 601 $path = _DIR_RACINE.'squelettes/:' . $path; 602 603 // Et le(s) dossier(s) des squelettes nommes 604 if ($GLOBALS['dossier_squelettes']) 605 foreach (array_reverse(explode(':', $GLOBALS['dossier_squelettes'])) as $d) 606 $path = 607 ($d[0] == '/' ? '' : _DIR_RACINE) . $d . '/:' . $path; 608 609 // nettoyer les / du path 610 $path_a = array(); 611 foreach (explode(':', $path) as $dir) { 612 if (strlen($dir) AND substr($dir,-1) != '/') 613 $dir .= "/"; 614 $path_a[] = $dir; 615 } 616 } 617 618 return $path_a; 619 } 620 621 // http://doc.spip.org/@find_in_path 622 function find_in_path ($filename) { 623 // Parcourir le chemin 624 foreach (creer_chemin() as $dir) { 625 if (@is_readable($f = "$dir$filename")) { 626 # spip_log("find_in_path trouve $f"); 627 return $f; 628 } 629 } 630 631 # spip_log("find_in_path n'a pas vu '$filename' dans " . join(':',creer_chemin())); 632 return false; 633 } 634 635 636 // http://doc.spip.org/@find_all_in_path 637 function find_all_in_path($dir,$pattern){ 638 $liste_fichiers=array(); 639 $maxfiles = 10000; 640 641 // Parcourir le chemin 642 foreach (creer_chemin() as $d) 643 if (@is_dir($f = $d.$dir)){ 644 $liste = preg_files($d.$dir,$pattern,$maxfiles-count($liste_fichiers),false); 645 foreach($liste as $chemin){ 646 $nom = basename($chemin); 647 // ne prendre que les fichiers pas deja trouves 648 // car find_in_path prend le premier qu'il trouve, 649 // les autres sont donc masques 650 if (!isset($liste_fichiers[$nom])) 651 $liste_fichiers[$nom] = $chemin; 652 } 653 } 654 655 return $liste_fichiers; 656 } 657 658 // predicat sur les scripts de ecrire qui n'authentifient pas par cookie 659 660 // http://doc.spip.org/@autoriser_sans_cookie 661 function autoriser_sans_cookie($nom) 662 { 663 static $autsanscookie = array('aide_index', 'install', 'admin_repair'); 664 $nom = preg_replace('/.php[3]?$/', '', basename($nom)); 665 return in_array($nom, $autsanscookie); 666 } 667 668 // Cette fonction charge le bon inc-urls selon qu'on est dans l'espace 669 // public ou prive, la presence d'un (old style) inc-urls.php3, etc. 670 // http://doc.spip.org/@charger_generer_url 671 function charger_generer_url() { 672 static $ok; 673 674 // espace prive 675 if (!_DIR_RESTREINT) 676 include_spip('inc/urls'); 677 678 // espace public 679 else { 680 if ($ok++) return; # fichier deja charge 681 // fichier inc-urls ? (old style) 682 if (@is_readable($f = _DIR_RACINE.'inc-urls.php3') 683 OR @is_readable($f = _DIR_RACINE.'inc-urls.php') 684 OR $f = find_in_path('inc-urls-'.$GLOBALS['type_urls'].'.php3') 685 OR $f = include_spip('urls/'.$GLOBALS['type_urls'], false) 686 ) 687 include_once($f); 688 } 689 } 690 691 // Sur certains serveurs, la valeur 'Off' tient lieu de false dans certaines 692 // variables d'environnement comme $_SERVER[HTTPS] ou ini_get(register_globals) 693 // http://doc.spip.org/@test_valeur_serveur 694 function test_valeur_serveur($truc) { 695 if (!$truc) return false; 696 if (strtolower($truc) == 'off') return false; 697 return true; 698 } 699 700 // 701 // Fonctions de fabrication des URL des scripts de Spip 702 // 703 704 // l'URL de base du site, sans se fier a meta(adresse_site) qui 705 // peut etre fausse (sites a plusieurs noms d'hotes, deplacements, erreurs) 706 // Note : la globale $profondeur_url doit etre initialisee de maniere a 707 // indiquer le nombre de sous-repertoires de l'url courante par rapport a la 708 // racine de SPIP : par exemple, sur ecrire/ elle vaut 1, sur sedna/ 1, et a 709 // la racine 0. Sur url/perso/ elle vaut 2 710 // http://doc.spip.org/@url_de_base 711 function url_de_base() { 712 713 static $url; 714 715 if ($url) 716 return $url; 717 718 // cas particulier des sites filtres par un proxy entrant 719 // cf. http://trac.rezo.net/trac/spip/ticket/401 720 // le forwarded_host peut prendre plusieurs valeurs separees par des virgules 721 // chez ovh notamment 722 if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])){ 723 $server = explode(',',$_SERVER['HTTP_X_FORWARDED_HOST']); 724 $server = trim(reset($server)); 725 } 726 else 727 $server = $_SERVER['HTTP_HOST']; 728 729 $http = ( 730 (isset($_SERVER["SCRIPT_URI"]) AND 731 substr($_SERVER["SCRIPT_URI"],0,5) == 'https') 732 OR (isset($_SERVER['HTTPS']) AND 733 test_valeur_serveur($_SERVER['HTTPS'])) 734 ) ? 'https' : 'http'; 735 # note : HTTP_HOST contient le :port si necessaire 736 $myself = $http.'://'.$server.$GLOBALS['REQUEST_URI']; 737 738 # supprimer la chaine de GET 739 $myself = preg_replace(',\?.*$,','', $myself); 740 741 # supprimer n sous-repertoires 742 $supprime_preg = '/+'; 743 for ($i=0; $i<$GLOBALS['profondeur_url']; $i++) 744 $supprime_preg .= '[^/]+/+'; 745 $url = preg_replace(','.$supprime_preg.'[^/]*$,', '/', $myself); 746 return $url; 747 } 748 749 750 // Pour une redirection, la liste des arguments doit etre separee par "&" 751 // Pour du code XHTML, ca doit etre & 752 // Bravo au W3C qui n'a pas ete capable de nous eviter ca 753 // faute de separer proprement langage et meta-langage 754 755 // Attention, X?y=z et "X/?y=z" sont completement differents! 756 // http://httpd.apache.org/docs/2.0/mod/mod_dir.html 757 758 // http://doc.spip.org/@generer_url_ecrire 759 function generer_url_ecrire($script, $args="", $no_entities=false, $rel=false) { 760 if (!$rel) 761 $rel = url_de_base() . _DIR_RESTREINT_ABS; 762 else if (!is_string($rel)) 763 $rel = _DIR_RESTREINT ? _DIR_RESTREINT : './'; 764 765 // Les anciens IIS n'acceptent pas les POST sur ecrire/ (#419) 766 // meme pb sur thttpd cf. http://forum.spip.org/fr_184153.html 767 if (preg_match(',IIS|thttpd,',$_SERVER['SERVER_SOFTWARE'])) 768 $rel .= 'index.php'; 769 770 if ($script AND $script<>'accueil') 771 $args = "?exec=$script" . (!$args ? '' : "&$args"); 772 elseif ($args) 773 $args ="?$args"; 774 775 return $rel . ($no_entities ? $args : str_replace('&', '&', $args)); 776 } 777 778 // http://doc.spip.org/@generer_url_retour 779 function generer_url_retour($script, $args="") 780 { 781 return rawurlencode(generer_url_ecrire($script, $args, true, true)); 782 } 783 784 // 785 // Adresse des scripts publics (a passer dans inc-urls...) 786 // 787 788 // Detecter le fichier de base, a la racine, comme etant spip.php ou '' 789 // dans le cas de '', un $default = './' peut servir (comme dans urls/page.php) 790 // http://doc.spip.org/@get_spip_script 791 function get_spip_script($default='') { 792 # cas define('_SPIP_SCRIPT', ''); 793 if (_SPIP_SCRIPT) 794 return _SPIP_SCRIPT; 795 else 796 return $default; 797 } 798 799 800 // http://doc.spip.org/@generer_url_public 801 function generer_url_public($script, $args="", $no_entities=false, $rel=false) { 802 803 // si le script est une action (spip_pass, spip_inscription), 804 // standardiser vers la nouvelle API 805 // [hack temporaire pour faire fonctionner #URL_PAGE{spip_pass} ] 806 807 if (preg_match(',^spip_(.*),', $script, $regs)) { 808 $args = "action=" . $regs[1] .($args ? "&$args" :''); 809 $script = ""; 810 } 811 812 $action = get_spip_script(); 813 if ($script) 814 $action = parametre_url($action, 'page', $script, '&'); 815 816 if ($args) 817 $action .= 818 (strpos($action, '?') !== false ? '&' : '?') . $args; 819 820 if (!$no_entities) 821 $action = quote_amp($action); 822 823 return ($rel ? '' : url_de_base()) . $action; 824 } 825 826 // http://doc.spip.org/@generer_url_prive 827 function generer_url_prive($script, $args="", $no_entities=false) { 828 829 $action = 'prive.php'; 830 if ($script) 831 $action = parametre_url($action, 'page', $script, '&'); 832 833 if ($args) 834 $action .= 835 (strpos($action, '?') !== false ? '&' : '?') . $args; 836 837 if (!$no_entities) 838 $action = quote_amp($action); 839 840 return url_de_base() . _DIR_RESTREINT_ABS . $action; 841 } 842 843 // http://doc.spip.org/@generer_url_action 844 function generer_url_action($script, $args="", $no_entities=false) { 845 846 return generer_url_public('', 847 "action=$script" .($args ? "&$args" : ''), 848 $no_entities); 849 850 } 851 852 853 // Dirty hack contre le register_globals a 'Off' (PHP 4.1.x) 854 // A remplacer (bientot ?) par une gestion propre des variables admissibles ;-) 855 // Attention pour compatibilite max $_GET n'est pas superglobale 856 // NB: c'est une fonction de maniere a ne pas pourrir $GLOBALS 857 // http://doc.spip.org/@spip_register_globals 858 function spip_register_globals() { 859 860 // Liste des variables dont on refuse qu'elles puissent provenir du client 861 $refuse_gpc = array ( 862 # inc-public 863 'fond', 'delais', 864 865 # ecrire/inc_auth 866 'REMOTE_USER', 867 'PHP_AUTH_USER', 'PHP_AUTH_PW' 868 ); 869 870 // Liste des variables (contexte) dont on refuse qu'elles soient cookie 871 // (histoire que personne ne vienne fausser le cache) 872 $refuse_c = array ( 873 # inc-calcul 874 'id_parent', 'id_rubrique', 'id_article', 875 'id_auteur', 'id_breve', 'id_forum', 'id_secteur', 876 'id_syndic', 'id_syndic_article', 'id_mot', 'id_groupe', 877 'id_document', 'date', 'lang' 878 ); 879 880 // Si les variables sont passees en global par le serveur, il faut 881 // faire quelques verifications de base 882 if (test_valeur_serveur(@ini_get('register_globals'))) { 883 foreach ($refuse_gpc as $var) { 884 if (isset($GLOBALS[$var])) { 885 if ( 886 // demande par le client 887 $_REQUEST[$var] !== NULL 888 // et pas modifie par les fichiers d'appel 889 AND $GLOBALS[$var] == $_REQUEST[$var] 890 ) // Alors on ne sait pas si c'est un hack 891 die ("register_globals: $var interdite"); 892 } 893 } 894 foreach ($refuse_c as $var) { 895 if (isset($GLOBALS[$var])) { 896 if ( 897 isset ($_COOKIE[$var]) 898 AND $_COOKIE[$var] == $GLOBALS[$var] 899 ) 900 define ('spip_interdire_cache', true); 901 } 902 } 903 } 904 905 // sinon il faut les passer nous-memes, a l'exception des interdites. 906 // (A changer en une liste des variables admissibles...) 907 else { 908 foreach (array('_SERVER', '_COOKIE', '_POST', '_GET') as $_table) { 909 foreach ($GLOBALS[$_table] as $var => $val) { 910 if (!isset($GLOBALS[$var]) # indispensable securite 911 AND isset($GLOBALS[$_table][$var]) 912 AND ($_table == '_SERVER' OR !in_array($var, $refuse_gpc)) 913 AND ($_table <> '_COOKIE' OR !in_array($var, $refuse_c))) 914 $GLOBALS[$var] = $val; 915 } 916 } 917 } 918 } 919 920 921 // Fonction d'initialisation, appelle dans inc_version ou mes_options 922 // Elle definit les repertoires et fichiers non partageables 923 // et indique dans $test_dirs ceux devant etre accessibles en ecriture 924 // mais ne touche pas a cette variable si elle est deja definie 925 // afin que mes_options.php puisse en specifier d'autres. 926 // Elle definit ensuite les noms des fichiers et les droits. 927 // Puis simule un register_global=on securise. 928 929 // http://doc.spip.org/@spip_initialisation 930 function spip_initialisation($pi=NULL, $pa=NULL, $ti=NULL, $ta=NULL) { 931 932 static $too_late = 0; 933 if ($too_late++) return; 934 935 define('_DIR_IMG', $pa); 936 define('_DIR_DOC', $pa); 937 define('_DIR_LOGOS', $pa); 938 define('_DIR_IMG_ICONES', $pa . "icones/"); 939 940 define('_DIR_DUMP', $ti . "dump/"); 941 define('_DIR_SESSIONS', $ti . "sessions/"); 942 define('_DIR_TRANSFERT', $ti . "upload/"); 943 define('_DIR_CACHE', $ti . "cache/"); 944 define('_DIR_CACHE_XML', $ti . "cache/xml/"); 945 define('_DIR_SKELS', $ti . "cache/skel/"); 946 define('_DIR_TMP', $ti); 947 948 define('_FILE_META', $ti . 'meta_cache.txt'); 949 950 define('_DIR_VAR', $ta); 951 952 define('_DIR_ETC', $pi); 953 954 if (!isset($GLOBALS['test_dirs'])) 955 $GLOBALS['test_dirs'] = array($pa, $ti, $ta); 956 957 // Le fichier de connexion a la base de donnees 958 define('_FILE_CONNECT_INS', _DIR_ETC . 'connect'); 959 define('_FILE_CONNECT', 960 (@is_readable($f = _FILE_CONNECT_INS . '.php') ? $f 961 : (@is_readable($f = _DIR_RESTREINT . 'inc_connect.php') ? $f 962 : (@is_readable($f = _DIR_RESTREINT . 'inc_connect.php3') ? $f 963 : false)))); 964 965 // Le fichier de connexion a la base de donnees 966 define('_FILE_CHMOD_INS', _DIR_ETC . 'chmod'); 967 define('_FILE_CHMOD', 968 (@is_readable($f = _FILE_CHMOD_INS . '.php') ? $f 969 : false)); 970 971 // Definition des droits d'acces en ecriture 972 if(!_FILE_CHMOD) 973 define('_SPIP_CHMOD', 0777); 974 else 975 include_once _FILE_CHMOD; 976 977 // la taille maxi des logos (0 : pas de limite) 978 define('_LOGO_MAX_SIZE', 0); # poids en ko 979 define('_LOGO_MAX_WIDTH', 0); # largeur en pixels 980 define('_LOGO_MAX_HEIGHT', 0); # hauteur en pixels 981 982 define('_DOC_MAX_SIZE', 0); # poids en ko 983 984 define('_IMG_MAX_SIZE', 0); # poids en ko 985 define('_IMG_MAX_WIDTH', 0); # largeur en pixels 986 define('_IMG_MAX_HEIGHT', 0); # hauteur en pixels 987 988 // Le charset par defaut lors de l'installation 989 define('_DEFAULT_CHARSET', 'utf-8'); 990 991 // qq chaines standard 992 define('_ACCESS_FILE_NAME', '.htaccess'); 993 define('_AUTH_USER_FILE', '.htpasswd'); 994 define('_SPIP_DUMP', 'dump@nom_site@@stamp@.xml'); 995 996 define('_DOCTYPE_ECRIRE', 997 // "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'>\n"); 998 "<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>\n"); 999 // "<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>\n"); 1000 // "<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.1 //EN' 'http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd'>\n"); 1001 define('_DOCTYPE_AIDE', 1002 "<!DOCTYPE html PUBLIC '-//W3C//DTD HTML 4.01 Frameset//EN' 'http://www.w3.org/TR/1999/REC-html401-19991224/frameset.dtd'>"); 1003 1004 // L'adresse de base du site ; on peut mettre '' si la racine est geree par 1005 // le script index.php 1006 define('_SPIP_SCRIPT', 'spip.php'); 1007 1008 // le nom du repertoire plugins/ 1009 define('_DIR_PLUGINS', _DIR_RACINE . "plugins/"); 1010 1011 // *********** traiter les variables ************ 1012 1013 // Recuperer les superglobales $_GET si non definies 1014 // (en theorie c'est impossible depuis PHP 4.0.3, cf. track_vars) 1015 // et les identifier aux $HTTP_XX_VARS 1016 foreach (array('_GET', '_POST', '_COOKIE', '_SERVER') as $_table) { 1017 $http_table_vars = 'HTTP'.$_table.'_VARS'; 1018 if (!is_array($GLOBALS[$_table])) { 1019 $GLOBALS[$_table] = array(); 1020 if (is_array($GLOBALS[$http_table_vars])) 1021 $GLOBALS[$_table] = & $GLOBALS[$http_table_vars]; 1022 } 1023 $GLOBALS[$http_table_vars] = & $GLOBALS[$_table]; 1024 } 1025 1026 // 1027 // Securite 1028 // 1029 1030 // Ne pas se faire manger par un bug php qui accepte ?GLOBALS[truc]=toto 1031 if (isset($_REQUEST['GLOBALS'])) die(); 1032 // nettoyer les magic quotes \' et les caracteres nuls %00 1033 spip_desinfecte($_GET); 1034 spip_desinfecte($_POST); 1035 spip_desinfecte($_COOKIE); 1036 spip_desinfecte($_REQUEST); 1037 spip_desinfecte($GLOBALS); 1038 1039 // Par ailleurs on ne veut pas de magic_quotes au cours de l'execution 1040 @set_magic_quotes_runtime(0); 1041 1042 // Remplir $GLOBALS avec $_GET et $_POST (methode a revoir pour fonctionner 1043 // completement en respectant register_globals = off) 1044 spip_register_globals(); 1045 1046 // appliquer le cookie_prefix 1047 if ($GLOBALS['cookie_prefix'] != 'spip') { 1048 include_spip('inc/cookie'); 1049 recuperer_cookies_spip($GLOBALS['cookie_prefix']); 1050 } 1051 1052 define('_SPIP_AJAX', (!isset($_COOKIE['spip_accepte_ajax'])) 1053 ? 1 1054 : (($_COOKIE['spip_accepte_ajax'] != -1) ? 1 : 0)); 1055 1056 // 1057 // Capacites php (en fonction de la version) 1058 // 1059 $GLOBALS['flag_gz'] = function_exists("gzencode"); #php 4.0.4 1060 $GLOBALS['flag_ob'] = (function_exists("ob_start") 1061 && function_exists("ini_get") 1062 && (@ini_get('max_execution_time') > 0) 1063 && !strstr(ini_get('disable_functions'), 'ob_')); 1064 $GLOBALS['flag_sapi_name'] = function_exists("php_sapi_name"); 1065 $GLOBALS['flag_revisions'] = function_exists("gzcompress"); 1066 $GLOBALS['flag_get_cfg_var'] = (@get_cfg_var('error_reporting') != ""); 1067 $GLOBALS['flag_upload'] = (!$GLOBALS['flag_get_cfg_var'] || 1068 (get_cfg_var('upload_max_filesize') > 0)); 1069 1070 1071 // Sommes-nous dans l'empire du Mal ? 1072 // (ou sous le signe du Pingouin, ascendant GNU ?) 1073 if (strpos($_SERVER['SERVER_SOFTWARE'], '(Win') !== false) 1074 define ('os_serveur', 'windows'); 1075 else 1076 define ('os_serveur', ''); 1077 1078 // Compatibilite avec serveurs ne fournissant pas $REQUEST_URI 1079 if (isset($_SERVER['REQUEST_URI'])) { 1080 $GLOBALS['REQUEST_URI'] = $_SERVER['REQUEST_URI']; 1081 } else { 1082 $GLOBALS['REQUEST_URI'] = $_SERVER['PHP_SELF']; 1083 if ($_SERVER['QUERY_STRING'] 1084 AND !strpos($_SERVER['REQUEST_URI'], '?')) 1085 $GLOBALS['REQUEST_URI'] .= '?'.$_SERVER['QUERY_STRING']; 1086 } 1087 1088 // 1089 // Module de lecture/ecriture/suppression de fichiers utilisant flock() 1090 // (non surchargeable en l'etat ; attention si on utilise include_spip() 1091 // pour le rendre surchargeable, on va provoquer un reecriture 1092 // systematique du noyau ou une baisse de perfs => a etudier) 1093 include_once _DIR_RESTREINT . 'inc/flock.php'; 1094 1095 // Lire les meta cachees et initier le noyau (espace public uniquement) 1096 $GLOBALS['noyau'] = array(); 1097 if (lire_fichier(_FILE_META, $meta)) { 1098 $GLOBALS['meta'] = @unserialize($meta); 1099 if (_DIR_RESTREINT 1100 AND isset($GLOBALS['meta']['noyau']) 1101 AND is_array($GLOBALS['meta']['noyau'])) { 1102 $GLOBALS['noyau'] = $GLOBALS['meta']['noyau']; 1103 unset ($GLOBALS['meta']['noyau']); 1104 } 1105 } 1106 1107 // en cas d'echec refaire le fichier 1108 if (!isset($GLOBALS['meta']) AND _FILE_CONNECT) { 1109 include_spip('inc/meta'); 1110 ecrire_metas(); 1111 } 1112 $GLOBALS['langue_site'] = $GLOBALS['meta']['langue_site']; 1113 1114 # nombre de pixels maxi pour calcul de la vignette avec gd 1115 define('_IMG_GD_MAX_PIXELS', isset($GLOBALS['meta']['max_taille_vignettes'])?$GLOBALS['meta']['max_taille_vignettes']:0); 1116 1117 // supprimer le noyau si on recalcule 1118 if (isset($_REQUEST['var_mode'])) 1119 $GLOBALS['noyau'] = array(); 1120 1121 // Langue principale du site 1122 1123 if (!isset($GLOBALS['langue_site'])) include_spip('inc/lang'); 1124 $GLOBALS['spip_lang'] = $GLOBALS['langue_site']; 1125 1126 // Verifier le visiteur 1127 if (_FILE_CONNECT) verifier_visiteur(); 1128 1129 } 1130 1131 // Annuler les magic quotes \' sur GET POST COOKIE et GLOBALS ; 1132 // supprimer aussi les eventuels caracteres nuls %00, qui peuvent tromper 1133 // la commande is_readable('chemin/vers/fichier/interdit%00truc_normal') 1134 // http://doc.spip.org/@spip_desinfecte 1135 function spip_desinfecte(&$t) { 1136 static $magic_quotes; 1137 if (!isset($magic_quotes)) 1138 $magic_quotes = @get_magic_quotes_gpc(); 1139 1140 foreach ($t as $key => $val) { 1141 if (is_string($t[$key])) { 1142 if ($magic_quotes) 1143 $t[$key] = stripslashes($t[$key]); 1144 $t[$key] = str_replace(chr(0), '-', $t[$key]); 1145 } 1146 // traiter aussi les "texte_plus" de articles_edit 1147 else if ($key == 'texte_plus' AND is_array($t[$key])) 1148 spip_desinfecte($t[$key]); 1149 } 1150 } 1151 1152 // retourne le statut du visiteur s'il s'annonce 1153 1154 // http://doc.spip.org/@verifier_visiteur 1155 function verifier_visiteur() { 1156 1157 if (isset($_COOKIE['spip_session']) OR 1158 (isset($_SERVER['PHP_AUTH_USER']) AND !$GLOBALS['ignore_auth_http'])) { 1159 1160 // Rq: pour que cette fonction marche depuis mes_options 1161 // il faut forcer l'init si ce n'est fait 1162 @spip_initialisation(); 1163 1164 $session = charger_fonction('session', 'inc'); 1165 if ($session()) return $GLOBALS['auteur_session']['statut']; 1166 include_spip('inc/actions'); 1167 return verifier_php_auth(); 1168 } 1169 1170 return false; 1171 } 1172 1173 // selectionner une langue 1174 // http://doc.spip.org/@lang_select 1175 function lang_select ($lang='') { 1176 if (!is_array($GLOBALS['pile_langues'])) $GLOBALS['pile_langues'] = array(); 1177 array_push($GLOBALS['pile_langues'], $GLOBALS['spip_lang']); 1178 if ($lang != $GLOBALS['spip_lang']) { 1179 include_spip('inc/lang'); 1180 changer_langue($lang); 1181 } 1182 } 1183 1184 // revenir a la langue precedente 1185 // http://doc.spip.org/@lang_dselect 1186 function lang_dselect ($rien='') { 1187 $lang = array_pop($GLOBALS['pile_langues']); 1188 if ($lang != $GLOBALS['spip_lang']) { 1189 include_spip('inc/lang'); 1190 changer_langue($lang); 1191 } 1192 } 1193 1194 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Wed Nov 21 10:20:27 2007 | par Balluche grâce à PHPXref 0.7 |
|