PageRenderTime 52ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/spip/ecrire/inc/utils.php

https://github.com/eyeswebcrea/espace-couture-sittler.fr
PHP | 1853 lines | 1109 code | 244 blank | 500 comment | 248 complexity | cb86dac694f2aace388760ddc934430a MD5 | raw file
Possible License(s): LGPL-2.1, GPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /***************************************************************************\
  3. * SPIP, Systeme de publication pour l'internet *
  4. * *
  5. * Copyright (c) 2001-2011 *
  6. * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
  7. * *
  8. * Ce programme est un logiciel libre distribue sous licence GNU/GPL. *
  9. * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. *
  10. \***************************************************************************/
  11. if (!defined('_ECRIRE_INC_VERSION')) return;
  12. //
  13. // Utilitaires indispensables autour du serveur Http.
  14. //
  15. // charge un fichier perso ou, a defaut, standard
  16. // et retourne si elle existe le nom de la fonction homonyme (exec_$nom),
  17. // ou de suffixe _dist
  18. // Peut etre appelee plusieurs fois, donc optimiser
  19. // http://doc.spip.org/@charger_fonction
  20. function charger_fonction($nom, $dossier='exec', $continue=false) {
  21. if (strlen($dossier) AND substr($dossier,-1) != '/') $dossier .= '/';
  22. if (function_exists($f = str_replace('/','_',$dossier) . $nom))
  23. return $f;
  24. if (function_exists($g = $f . '_dist'))
  25. return $g;
  26. // Sinon charger le fichier de declaration si plausible
  27. if (!preg_match(',^\w+$,', $f))
  28. die(htmlspecialchars($nom)." pas autorise");
  29. // passer en minuscules (cf les balises de formulaires)
  30. // et inclure le fichier
  31. if (!$inc = include_spip($dossier.($d = strtolower($nom)))
  32. // si le fichier truc/machin/nom.php n'existe pas,
  33. // la fonction peut etre definie dans truc/machin.php qui regroupe plusieurs petites fonctions
  34. AND strlen(dirname($dossier)) AND dirname($dossier)!='.')
  35. include_spip(substr($dossier,0,-1));
  36. if (function_exists($f)) return $f;
  37. if (function_exists($g)) return $g;
  38. if ($continue) return false;
  39. // Echec : message d'erreur
  40. spip_log("fonction $nom ($f ou $g) indisponible" .
  41. ($inc ? "" : " (fichier $d absent de $dossier)"));
  42. include_spip('inc/minipres');
  43. echo minipres(_T('forum_titre_erreur'),
  44. _T('fichier_introuvable', array('fichier'=> '<b>'.htmlentities($d).'</b>')));
  45. exit;
  46. }
  47. //
  48. // la fonction cherchant un fichier PHP dans le SPIP_PATH
  49. //
  50. // http://doc.spip.org/@include_spip
  51. function include_spip($f, $include = true) {
  52. return find_in_path($f . '.php', '', $include);
  53. }
  54. // un pipeline est lie a une action et une valeur
  55. // chaque element du pipeline est autorise a modifier la valeur
  56. //
  57. // le pipeline execute les elements disponibles pour cette action,
  58. // les uns apres les autres, et retourne la valeur finale
  59. //
  60. // Cf. compose_filtres dans references.php, qui est la
  61. // version compilee de cette fonctionnalite
  62. // appel unitaire d'une fonction du pipeline
  63. // utilisee dans le script pipeline precompile
  64. // on passe $val par reference pour limiter les allocations memoire
  65. // http://doc.spip.org/@minipipe
  66. function minipipe($fonc,&$val){
  67. // fonction
  68. if (function_exists($fonc))
  69. $val = call_user_func($fonc, $val);
  70. // Class::Methode
  71. else if (preg_match("/^(\w*)::(\w*)$/S", $fonc, $regs)
  72. AND $methode = array($regs[1], $regs[2])
  73. AND is_callable($methode))
  74. $val = call_user_func($methode, $val);
  75. else
  76. spip_log("Erreur - '$fonc' non definie !");
  77. return $val;
  78. }
  79. // chargement du pipeline sous la forme d'un fichier php prepare
  80. // http://doc.spip.org/@pipeline
  81. function pipeline($action, $val=null) {
  82. static $charger;
  83. // chargement initial des fonctions mises en cache, ou generation du cache
  84. if (!$charger) {
  85. if (!($ok = @is_readable($charger = _CACHE_PIPELINES))) {
  86. include_spip('inc/plugin');
  87. // generer les fichiers php precompiles
  88. // de chargement des plugins et des pipelines
  89. actualise_plugins_actifs();
  90. if (!($ok = @is_readable($charger)))
  91. spip_log("fichier $charger pas cree");
  92. }
  93. if ($ok)
  94. include_once $charger;
  95. }
  96. // appliquer notre fonction si elle existe
  97. $fonc = 'execute_pipeline_'.strtolower($action);
  98. if (function_exists($fonc)) {
  99. $val = $fonc($val);
  100. }
  101. // plantage ?
  102. else {
  103. include_spip('inc/plugin');
  104. // on passe $action en arg pour creer la fonction meme si le pipe
  105. // n'est defini nul part ; vu qu'on est la c'est qu'il existe !
  106. actualise_plugins_actifs(strtolower($action));
  107. spip_log("fonction $fonc absente : pipeline desactive");
  108. }
  109. // si le flux est une table qui encapsule donnees et autres
  110. // on ne ressort du pipe que les donnees
  111. // array_key_exists pour php 4.1.0
  112. if (is_array($val)
  113. AND count($val)==2
  114. AND (array_key_exists('data',$val)))
  115. $val = $val['data'];
  116. return $val;
  117. }
  118. //
  119. // Enregistrement des evenements
  120. //
  121. // http://doc.spip.org/@spip_log
  122. function spip_log($message, $logname=NULL, $logdir=NULL, $logsuf=NULL) {
  123. $log = charger_fonction('log', 'inc');
  124. $log( $message, $logname, $logdir, $logsuf);
  125. }
  126. // Renvoie le _GET ou le _POST emis par l'utilisateur
  127. // ou pioche dans $c si c'est un array()
  128. // http://doc.spip.org/@_request
  129. function _request($var, $c=false) {
  130. if (is_array($c))
  131. return isset($c[$var]) ? $c[$var] : NULL;
  132. if (isset($_GET[$var])) $a = $_GET[$var];
  133. elseif (isset($_POST[$var])) $a = $_POST[$var];
  134. else return NULL;
  135. // Si on est en ajax et en POST tout a ete encode
  136. // via encodeURIComponent, il faut donc repasser
  137. // dans le charset local...
  138. if (defined('_AJAX')
  139. AND _AJAX
  140. AND isset($GLOBALS['meta']['charset'])
  141. AND $GLOBALS['meta']['charset'] != 'utf-8'
  142. AND is_string($a)
  143. AND preg_match(',[\x80-\xFF],', $a)) {
  144. include_spip('inc/charsets');
  145. return importer_charset($a, 'utf-8');
  146. }
  147. return $a;
  148. }
  149. // Methode set de la fonction _request()
  150. // Attention au cas ou l'on fait set_request('truc', NULL);
  151. // http://doc.spip.org/@set_request
  152. function set_request($var, $val = NULL, $c=false) {
  153. if (is_array($c)) {
  154. unset($c[$var]);
  155. if ($val !== NULL)
  156. $c[$var] = $val;
  157. return $c;
  158. }
  159. unset($_GET[$var]);
  160. unset($_POST[$var]);
  161. if ($val !== NULL)
  162. $_GET[$var] = $val;
  163. return false; # n'affecte pas $c
  164. }
  165. /**
  166. * Tester si une url est absolue
  167. * @param $url
  168. * @return bool
  169. */
  170. function tester_url_absolue($url){
  171. return preg_match(";^([a-z]+:)?//;Uims",trim($url))?true:false;
  172. }
  173. //
  174. // Prend une URL et lui ajoute/retire un parametre.
  175. // Exemples : [(#SELF|parametre_url{suite,18})] (ajout)
  176. // [(#SELF|parametre_url{suite,''})] (supprime)
  177. // [(#SELF|parametre_url{suite})] (prend $suite dans la _request)
  178. // [(#SELF|parametre_url{suite[],1})] (tableaux valeurs multiples)
  179. // http://doc.spip.org/@parametre_url
  180. function parametre_url($url, $c, $v=NULL, $sep='&amp;') {
  181. // lever l'#ancre
  182. if (preg_match(',^([^#]*)(#.*)$,', $url, $r)) {
  183. $url = $r[1];
  184. $ancre = $r[2];
  185. } else
  186. $ancre = '';
  187. // eclater
  188. $url = preg_split(',[?]|&amp;|&,', $url);
  189. // recuperer la base
  190. $a = array_shift($url);
  191. if (!$a) $a= './';
  192. $regexp = ',^(' . str_replace('[]','\[\]',$c) . '[[]?[]]?)(=.*)?$,';
  193. $ajouts = array_flip(explode('|',$c));
  194. $u = is_array($v) ? $v : rawurlencode($v);
  195. // lire les variables et agir
  196. foreach ($url as $n => $val) {
  197. if (preg_match($regexp, urldecode($val), $r)) {
  198. if ($v === NULL) {
  199. return $r[2]?substr($r[2],1):'';
  200. }
  201. // suppression
  202. elseif (!$v) {
  203. unset($url[$n]);
  204. }
  205. // Ajout. Pour une variable, remplacer au meme endroit,
  206. // pour un tableau ce sera fait dans la prochaine boucle
  207. elseif (substr($r[1],-2) != '[]') {
  208. $url[$n] = $r[1].'='.$u;
  209. unset($ajouts[$r[1]]);
  210. }
  211. }
  212. }
  213. // traiter les parametres pas encore trouves
  214. if ($v === NULL
  215. AND $args = func_get_args()
  216. AND count($args)==2)
  217. return $v;
  218. elseif ($v) {
  219. foreach($ajouts as $k => $n) {
  220. if (!is_array($v))
  221. $url[] = $k .'=' . $u;
  222. else {
  223. $id = (substr($k,-2) == '[]') ? $k : ($k ."[]");
  224. foreach ($v as $w) $url[]= $id .'=' . $w;
  225. }
  226. }
  227. }
  228. // eliminer les vides
  229. $url = array_filter($url);
  230. // recomposer l'adresse
  231. if ($url)
  232. $a .= '?' . join($sep, $url);
  233. return $a . $ancre;
  234. }
  235. // Prend une URL et lui ajoute/retire une ancre apres l'avoir nettoyee
  236. // pour l'ancre on translitere, vire les non alphanum du debut,
  237. // et on remplace ceux a l'interieur ou au bout par -
  238. // http://doc.spip.org/@ancre_url
  239. function ancre_url($url, $ancre) {
  240. include_spip('inc/charsets');
  241. // lever l'#ancre
  242. if (preg_match(',^([^#]*)(#.*)$,', $url, $r)) {
  243. $url = $r[1];
  244. }
  245. $ancre = preg_replace(array('/^[^-_a-zA-Z0-9]+/', '/[^-_a-zA-Z0-9]/'), array('', '-'),
  246. translitteration($ancre));
  247. return $url . (strlen($ancre) ? '#'. $ancre : '');
  248. }
  249. //
  250. // pour le nom du cache, les types_urls et self
  251. //
  252. // http://doc.spip.org/@nettoyer_uri
  253. function nettoyer_uri($reset = null)
  254. {
  255. static $done = false;
  256. static $propre = '';
  257. if (!is_null($reset)) return $propre=$reset;
  258. if ($done) return $propre;
  259. $done = true;
  260. $uri1 = $GLOBALS['REQUEST_URI'];
  261. do {
  262. $uri = $uri1;
  263. $uri1 = preg_replace
  264. (',([?&])(PHPSESSID|(var_[^=&]*))=[^&]*(&|$),i',
  265. '\1', $uri);
  266. } while ($uri<>$uri1);
  267. return $propre = (preg_replace(',[?&]$,', '', $uri1));
  268. }
  269. //
  270. // donner l'URL de base d'un lien vers "soi-meme", modulo
  271. // les trucs inutiles
  272. //
  273. // http://doc.spip.org/@self
  274. function self($amp = '&amp;', $root = false) {
  275. $url = nettoyer_uri();
  276. if (!$root AND (!defined('_SET_HTML_BASE') OR !_SET_HTML_BASE OR !$GLOBALS['profondeur_url']))
  277. $url = preg_replace(',^[^?]*/,', '', $url);
  278. // ajouter le cas echeant les variables _POST['id_...']
  279. foreach ($_POST as $v => $c)
  280. if (substr($v,0,3) == 'id_')
  281. $url = parametre_url($url, $v, $c, '&');
  282. // supprimer les variables sans interet
  283. if (test_espace_prive()) {
  284. $url = preg_replace (',([?&])('
  285. .'lang|show_docs|'
  286. .'changer_lang|var_lang|action)=[^&]*,i', '\1', $url);
  287. $url = preg_replace(',([?&])[&]+,', '\1', $url);
  288. $url = preg_replace(',[&]$,', '\1', $url);
  289. }
  290. // eviter les hacks
  291. $url = htmlspecialchars($url);
  292. // &amp; ?
  293. if ($amp != '&amp;')
  294. $url = str_replace('&amp;', $amp, $url);
  295. // Si ca demarre par ? ou vide, donner './'
  296. $url = preg_replace(',^([?].*)?$,', './\1', $url);
  297. return $url;
  298. }
  299. // Indique si on est dans l'espace prive
  300. // http://doc.spip.org/@test_espace_prive
  301. function test_espace_prive() {
  302. return defined('_ESPACE_PRIVE') ? _ESPACE_PRIVE : false;
  303. }
  304. /**
  305. * Verifie la presence d'un plugin active, identifie par son prefix
  306. *
  307. *
  308. * @param string $plugin
  309. * @return bool
  310. */
  311. function test_plugin_actif($plugin){
  312. return ($plugin AND defined('_DIR_PLUGIN_'.strtoupper($plugin)))? true:false;
  313. }
  314. //
  315. // Traduction des textes de SPIP
  316. //
  317. // http://doc.spip.org/@_T
  318. function _T($texte, $args=array(), $class='') {
  319. static $traduire=false ;
  320. if (!$traduire) {
  321. $traduire = charger_fonction('traduire', 'inc');
  322. include_spip('inc/lang');
  323. }
  324. $text = $traduire($texte,$GLOBALS['spip_lang']);
  325. if (!strlen($text))
  326. // pour les chaines non traduites, assurer un service minimum
  327. $text = str_replace('_', ' ',
  328. (($n = strpos($texte,':')) === false ? $texte :
  329. substr($texte, $n+1)));
  330. return _L($text, $args, $class);
  331. }
  332. // Remplacer les variables @....@ par leur valeur dans une chaine de langue.
  333. // Aussi appelee quand une chaine n'est pas encore dans les fichiers de langue
  334. // http://doc.spip.org/@_L
  335. function _L($text, $args=array(), $class=NULL) {
  336. $f = $text;
  337. if (is_array($args)) {
  338. foreach ($args as $name => $value) {
  339. if ($class)
  340. $value = "<span class='$class'>$value</span>";
  341. $t = str_replace ("@$name@", $value, $text);
  342. if ($text !== $t) {unset($args[$name]); $text = $t;}
  343. }
  344. // Si des variables n'ont pas ete inserees, le signaler
  345. // (chaines de langues pas a jour)
  346. // NOTE: c'est du debug, gere comme tel pour SPIP >= 2.3
  347. ## if ($args) spip_log("$f: variables inutilisees " . join(', ', array_keys($args)));
  348. }
  349. if ($GLOBALS['test_i18n'] AND $class===NULL)
  350. return "<span style='color:red;'>$text</span>";
  351. else
  352. return $text;
  353. }
  354. // Afficher "ecrire/data/" au lieu de "data/" dans les messages
  355. // ou tmp/ au lieu de ../tmp/
  356. // http://doc.spip.org/@joli_repertoire
  357. function joli_repertoire($rep) {
  358. $a = substr($rep,0,1);
  359. if ($a<>'.' AND $a<>'/')
  360. $rep = (_DIR_RESTREINT?'':_DIR_RESTREINT_ABS).$rep;
  361. $rep = preg_replace(',(^\.\.\/),', '', $rep);
  362. return $rep;
  363. }
  364. //
  365. // spip_timer : on l'appelle deux fois et on a la difference, affichable
  366. //
  367. // http://doc.spip.org/@spip_timer
  368. function spip_timer($t='rien', $raw = false) {
  369. static $time;
  370. $a=time(); $b=microtime();
  371. // microtime peut contenir les microsecondes et le temps
  372. $b=explode(' ',$b);
  373. if (count($b)==2) $a = end($b); // plus precis !
  374. $b = reset($b);
  375. if (!isset($time[$t])) {
  376. $time[$t] = $a + $b;
  377. } else {
  378. $p = ($a + $b - $time[$t]) * 1000;
  379. unset($time[$t]);
  380. # echo "'$p'";exit;
  381. if ($raw) return $p;
  382. if ($p < 1000)
  383. $s = '';
  384. else {
  385. $s = sprintf("%d ", $x = floor($p/1000));
  386. $p -= ($x*1000);
  387. }
  388. return $s . sprintf("%.3f ms", $p);
  389. }
  390. }
  391. // Renvoie False si un fichier n'est pas plus vieux que $duree secondes,
  392. // sinon renvoie True et le date sauf si ca n'est pas souhaite
  393. // http://doc.spip.org/@spip_touch
  394. function spip_touch($fichier, $duree=0, $touch=true) {
  395. if ($duree) {
  396. clearstatcache();
  397. if ((@$f=filemtime($fichier)) AND ($f >= time() - $duree))
  398. return false;
  399. }
  400. if ($touch!==false) {
  401. if (!@touch($fichier)) { spip_unlink($fichier); @touch($fichier); };
  402. @chmod($fichier, _SPIP_CHMOD & ~0111);
  403. }
  404. return true;
  405. }
  406. // Ce declencheur de tache de fond, de l'espace prive (cf inc_presentation)
  407. // et de l'espace public (cf #SPIP_CRON dans inc_balise), est appelee
  408. // par un background-image car contrairement a un iframe vide,
  409. // les navigateurs ne diront pas qu'ils n'ont pas fini de charger,
  410. // c'est plus rassurant.
  411. // C'est aussi plus discret qu'un <img> sous un navigateur non graphique.
  412. // http://doc.spip.org/@action_cron
  413. function action_cron() {
  414. include_spip('inc/headers');
  415. http_status(204); // No Content
  416. header("Connection: close");
  417. cron (2);
  418. }
  419. // cron() : execution des taches de fond
  420. // Le premier argument indique l'intervalle demande entre deux taches
  421. // par defaut, 60 secondes (quand il est appele par public.php)
  422. // il vaut 2 quand il est appele par ?action=cron, voire 0 en urgence
  423. // On peut lui passer en 2e arg le tableau de taches attendu par inc_genie()
  424. // Retourne Vrai si un tache a pu etre effectuee
  425. // http://doc.spip.org/@cron
  426. function cron ($gourmand=false, $taches= array()) {
  427. if (!defined(_CRON_DELAI_GOURMAND))
  428. define('_CRON_DELAI_GOURMAND',60);
  429. if (!defined(_CRON_DELAI))
  430. define('_CRON_DELAI',is_int($gourmand) ? $gourmand : 2);
  431. // Si on est gourmand, ou si le fichier gourmand n'existe pas
  432. // ou est trop vieux (> 60 sec), on va voir si un cron est necessaire.
  433. // Au passage si on est gourmand on le dit aux autres
  434. if (!_CRON_DELAI_GOURMAND
  435. OR spip_touch(_DIR_TMP.'cron.lock-gourmand', _CRON_DELAI_GOURMAND, $gourmand)
  436. OR ($gourmand!==false)) {
  437. // Le fichier cron.lock indique la date de la derniere tache
  438. // Il permet d'imposer qu'il n'y ait qu'une tache a la fois
  439. // et 2 secondes minimum entre chaque:
  440. // ca soulage le serveur et ca evite
  441. // les conflits sur la base entre taches.
  442. if (!_CRON_DELAI
  443. OR spip_touch(_DIR_TMP.'cron.lock',_CRON_DELAI)) {
  444. // Si base inaccessible, laisser tomber.
  445. if (!spip_connect()) return false;
  446. $genie = charger_fonction('genie', 'inc', true);
  447. if ($genie) {
  448. $genie($taches);
  449. // redater a la fin du cron
  450. // car il peut prendre plus de 2 secondes.
  451. spip_touch(_DIR_TMP.'cron.lock', 0);
  452. return true;
  453. }
  454. }# else spip_log("busy");
  455. }
  456. return false;
  457. }
  458. // transformation XML des "&" en "&amp;"
  459. // http://doc.spip.org/@quote_amp
  460. function quote_amp($u) {
  461. return preg_replace(
  462. "/&(?![a-z]{0,4}\w{2,3};|#x?[0-9a-f]{2,5};)/i",
  463. "&amp;",$u);
  464. }
  465. // Production d'une balise Script valide
  466. // http://doc.spip.org/@http_script
  467. function http_script($script, $src='', $noscript='') {
  468. static $done = array();
  469. if ($src && !isset($done[$src])){
  470. $done[$src] = true;
  471. $src = find_in_path($src, _JAVASCRIPT);
  472. $src = " src='$src'";
  473. }
  474. else $src = '';
  475. if ($script)
  476. $script = ("<!--\n" .
  477. preg_replace(',</([^>]*)>,','<\/\1>', $script) .
  478. "\n//-->\n");
  479. if ($noscript)
  480. $noscript = "<noscript>\n\t$noscript\n</noscript>\n";
  481. return ($src OR $script OR $noscript)
  482. ? "<script type='text/javascript'$src>$script</script>$noscript"
  483. : '';
  484. }
  485. // Transforme n'importe quel champ en une chaine utilisable
  486. // en PHP ou Javascript en toute securite
  487. // < ? php $x = '[(#TEXTE|texte_script)]'; ? >
  488. // http://doc.spip.org/@texte_script
  489. function texte_script($texte) {
  490. return str_replace('\'', '\\\'', str_replace('\\', '\\\\', $texte));
  491. }
  492. // la fonction _chemin ajoute un repertoire au chemin courant si un repertoire lui est passe en parametre
  493. // retourne le chemin courant sinon, sous forme de array
  494. // seul le dossier squelette peut etre modifie en dehors de cette fonction, pour raison historique
  495. // http://doc.spip.org/@_chemin
  496. function _chemin($dir_path=NULL){
  497. static $path_base = NULL;
  498. static $path_full = NULL;
  499. if ($path_base==NULL){
  500. // Chemin standard depuis l'espace public
  501. $path = defined('_SPIP_PATH') ? _SPIP_PATH :
  502. _DIR_RACINE.':'.
  503. _DIR_RACINE.'squelettes-dist/:'.
  504. _DIR_RACINE.'prive/:'.
  505. _DIR_RESTREINT.':';
  506. // Ajouter squelettes/
  507. if (@is_dir(_DIR_RACINE.'squelettes'))
  508. $path = _DIR_RACINE.'squelettes/:' . $path;
  509. foreach (explode(':', $path) as $dir) {
  510. if (strlen($dir) AND substr($dir,-1) != '/')
  511. $dir .= "/";
  512. $path_base[] = $dir;
  513. }
  514. $path_full = $path_base;
  515. // Et le(s) dossier(s) des squelettes nommes
  516. if (strlen($GLOBALS['dossier_squelettes']))
  517. foreach (array_reverse(explode(':', $GLOBALS['dossier_squelettes'])) as $d)
  518. array_unshift($path_full, ($d[0] == '/' ? '' : _DIR_RACINE) . $d . '/');
  519. $GLOBALS['path_sig'] = md5(serialize($path_full));
  520. }
  521. if ($dir_path===NULL) return $path_full;
  522. if (strlen($dir_path)){
  523. $tete = "";
  524. if (reset($path_base)==_DIR_RACINE.'squelettes/')
  525. $tete = array_shift($path_base);
  526. $dirs = array_reverse(explode(':',$dir_path));
  527. foreach($dirs as $dir_path){
  528. #if ($dir_path{0}!='/')
  529. # $dir_path = $dir_path;
  530. if (substr($dir_path,-1) != '/')
  531. $dir_path .= "/";
  532. if (!in_array($dir_path,$path_base))
  533. array_unshift($path_base,$dir_path);
  534. }
  535. if (strlen($tete))
  536. array_unshift($path_base,$tete);
  537. }
  538. $path_full = $path_base;
  539. // Et le(s) dossier(s) des squelettes nommes
  540. if (strlen($GLOBALS['dossier_squelettes']))
  541. foreach (array_reverse(explode(':', $GLOBALS['dossier_squelettes'])) as $d)
  542. array_unshift($path_full, ($d[0] == '/' ? '' : _DIR_RACINE) . $d . '/');
  543. $GLOBALS['path_sig'] = md5(serialize($path_full));
  544. return $path_full;
  545. }
  546. // http://doc.spip.org/@creer_chemin
  547. function creer_chemin() {
  548. $path_a = _chemin();
  549. static $c = '';
  550. // on calcule le chemin si le dossier skel a change
  551. if ($c != $GLOBALS['dossier_squelettes']) {
  552. // assurer le non plantage lors de la montee de version :
  553. $c = $GLOBALS['dossier_squelettes'];
  554. $path_a = _chemin(''); // forcer un recalcul du chemin
  555. }
  556. return $path_a;
  557. }
  558. // Cherche une image dans les dossiers images
  559. // definis par _NOM_IMG_PACK et _DIR_IMG_PACK
  560. // http://doc.spip.org/@chemin_image
  561. function chemin_image($file){
  562. return _DIR_IMG_PACK . $file;
  563. #return find_in_path ($file, _NOM_IMG_PACK);
  564. }
  565. // Alias de find_in_path
  566. // http://doc.spip.org/@chemin
  567. function chemin($file, $dirname='', $include=false){
  568. return find_in_path ($file, $dirname, $include);
  569. }
  570. //
  571. // chercher un fichier $file dans le SPIP_PATH
  572. // si on donne un sous-repertoire en 2e arg optionnel, il FAUT le / final
  573. // si 3e arg vrai, on inclut si ce n'est fait.
  574. $GLOBALS['path_sig'] = '';
  575. $GLOBALS['path_files'] = null;
  576. // http://doc.spip.org/@find_in_path
  577. function find_in_path ($file, $dirname='', $include=false) {
  578. static $dirs=array();
  579. static $inc = array(); # cf http://trac.rezo.net/trac/spip/changeset/14743
  580. static $c = '';
  581. // on calcule le chemin si le dossier skel a change
  582. if ($c != $GLOBALS['dossier_squelettes']){
  583. // assurer le non plantage lors de la montee de version :
  584. $c = $GLOBALS['dossier_squelettes'];
  585. creer_chemin(); // forcer un recalcul du chemin et la mise a jour de path_sig
  586. }
  587. if (isset($GLOBALS['path_files'][$GLOBALS['path_sig']][$dirname][$file])) {
  588. if (!$GLOBALS['path_files'][$GLOBALS['path_sig']][$dirname][$file])
  589. return false;
  590. if ($include AND !isset($inc[$dirname][$file])) {
  591. include_once _ROOT_CWD . $GLOBALS['path_files'][$GLOBALS['path_sig']][$dirname][$file];
  592. $inc[$dirname][$file] = $inc[''][$dirname . $file] = true;
  593. }
  594. return $GLOBALS['path_files'][$GLOBALS['path_sig']][$dirname][$file];
  595. }
  596. $a = strrpos($file,'/');
  597. if ($a !== false) {
  598. $dirname .= substr($file, 0, ++$a);
  599. $file = substr($file, $a);
  600. }
  601. foreach(creer_chemin() as $dir) {
  602. if (!isset($dirs[$a = $dir . $dirname]))
  603. $dirs[$a] = (is_dir(_ROOT_CWD . $a) || !$a) ;
  604. if ($dirs[$a]) {
  605. if (file_exists(_ROOT_CWD . ($a .= $file))) {
  606. if ($include AND !isset($inc[$dirname][$file])) {
  607. include_once _ROOT_CWD . $a;
  608. $inc[$dirname][$file] = $inc[''][$dirname . $file] = true;
  609. }
  610. if (!defined('_SAUVER_CHEMIN'))
  611. define('_SAUVER_CHEMIN',true);
  612. return $GLOBALS['path_files'][$GLOBALS['path_sig']][$dirname][$file] = $GLOBALS['path_files'][$GLOBALS['path_sig']][''][$dirname . $file] = $a;
  613. }
  614. }
  615. }
  616. if (!defined('_SAUVER_CHEMIN'))
  617. define('_SAUVER_CHEMIN',true);
  618. return $GLOBALS['path_files'][$GLOBALS['path_sig']][$dirname][$file] = $GLOBALS['path_files'][$GLOBALS['path_sig']][''][$dirname . $file] = false;
  619. }
  620. function clear_path_cache(){
  621. $GLOBALS['path_files'] = array();
  622. spip_unlink(_CACHE_CHEMIN);
  623. }
  624. function load_path_cache(){
  625. // charger le path des plugins
  626. if (@is_readable(_CACHE_PLUGINS_PATH)){
  627. include_once(_CACHE_PLUGINS_PATH);
  628. }
  629. $GLOBALS['path_files'] = array();
  630. // si le visiteur est admin,
  631. // on ne recharge pas le cache pour forcer sa mise a jour
  632. // le cache de chemin n'est utilise que dans le public
  633. if (_DIR_RESTREINT
  634. // la session n'est pas encore chargee a ce moment, on ne peut donc pas s'y fier
  635. //AND (!isset($GLOBALS['visiteur_session']['statut']) OR $GLOBALS['visiteur_session']['statut']!='0minirezo')
  636. // utiliser le cookie est un pis aller qui marche 'en general'
  637. // on blinde par un second test au moment de la lecture de la session
  638. AND !isset($_COOKIE[$GLOBALS['cookie_prefix'].'_admin'])
  639. // et en ignorant ce cache en cas de recalcul explicite
  640. AND _request('var_mode')!=='recalcul'
  641. ){
  642. // on essaye de lire directement sans verrou pour aller plus vite
  643. if ($contenu = spip_file_get_contents(_CACHE_CHEMIN)){
  644. // mais si semble corrompu on relit avec un verrou
  645. if (!$GLOBALS['path_files']=unserialize($contenu)){
  646. lire_fichier(_CACHE_CHEMIN,$contenu);
  647. if (!$GLOBALS['path_files']=unserialize($contenu))
  648. $GLOBALS['path_files'] = array();
  649. }
  650. }
  651. }
  652. // pas de sauvegarde du chemin si on est pas dans le public
  653. if (!_DIR_RESTREINT)
  654. define('_SAUVER_CHEMIN',false);
  655. }
  656. function save_path_cache(){
  657. if (defined('_SAUVER_CHEMIN')
  658. AND _SAUVER_CHEMIN)
  659. ecrire_fichier(_CACHE_CHEMIN,serialize($GLOBALS['path_files']));
  660. }
  661. /**
  662. * Trouve tous les fichiers du path correspondants a un pattern
  663. * pour un nom de fichier donne, ne retourne que le premier qui sera trouve
  664. * par un find_in_path
  665. *
  666. * @param string $dir
  667. * @param string $pattern
  668. * @param bool $recurs
  669. * @return array
  670. */
  671. // http://doc.spip.org/@find_all_in_path
  672. function find_all_in_path($dir,$pattern, $recurs=false){
  673. $liste_fichiers=array();
  674. $maxfiles = 10000;
  675. // Parcourir le chemin
  676. foreach (creer_chemin() as $d) {
  677. $f = $d.$dir;
  678. if (@is_dir($f)){
  679. $liste = preg_files($f,$pattern,$maxfiles-count($liste_fichiers),$recurs);
  680. foreach($liste as $chemin){
  681. $nom = basename($chemin);
  682. // ne prendre que les fichiers pas deja trouves
  683. // car find_in_path prend le premier qu'il trouve,
  684. // les autres sont donc masques
  685. if (!isset($liste_fichiers[$nom]))
  686. $liste_fichiers[$nom] = $chemin;
  687. }
  688. }
  689. }
  690. return $liste_fichiers;
  691. }
  692. // predicat sur les scripts de ecrire qui n'authentifient pas par cookie
  693. // http://doc.spip.org/@autoriser_sans_cookie
  694. function autoriser_sans_cookie($nom)
  695. {
  696. static $autsanscookie = array('aide_index', 'install', 'admin_repair');
  697. $nom = preg_replace('/.php[3]?$/', '', basename($nom));
  698. return in_array($nom, $autsanscookie);
  699. }
  700. // Fonction codant et decodant les URLS des objets SQL mis en page par SPIP
  701. // $id = numero de la cle primaire si nombre, URL a decoder si pas numerique
  702. // $entite = surnom de la table SQL (donne acces au nom de cle primaire)
  703. // $args = query_string a placer apres cle=$id&....
  704. // $ancre = ancre a mettre a la fin de l'URL a produire
  705. // $public = produire l'URL publique ou privee (par defaut: selon espace)
  706. // $type = fichier dans le repertoire ecrire/urls determinant l'apparence
  707. // @return string : url codee
  708. // @return string : fonction de decodage
  709. // http://doc.spip.org/@generer_url_entite
  710. function generer_url_entite($id='', $entite='', $args='', $ancre='', $public=NULL, $type=NULL)
  711. {
  712. if ($public === NULL) $public = !test_espace_prive();
  713. if (!$public) {
  714. if (!$entite) return '';
  715. include_spip('inc/urls');
  716. $f = 'generer_url_ecrire_' . $entite;
  717. $res = !function_exists($f) ? '' : $f($id, $args, $ancre, ' ');
  718. } else {
  719. if (is_string($public)) {
  720. include_spip('base/connect_sql');
  721. $id_type = id_table_objet($entite,$public);
  722. return _DIR_RACINE . get_spip_script('./')
  723. . "?"._SPIP_PAGE."=$entite&$id_type=$id&connect=$public"
  724. . (!$args ? '' : "&$args")
  725. . (!$ancre ? '' : "#$ancre");
  726. } else {
  727. if ($type === NULL) {
  728. $type = ($GLOBALS['type_urls'] === 'page'
  729. AND $GLOBALS['meta']['type_urls'])
  730. ? $GLOBALS['meta']['type_urls']
  731. : $GLOBALS['type_urls']; // pour SPIP <2
  732. }
  733. $f = charger_fonction($type, 'urls', true);
  734. // si $entite='', on veut la fonction de passage URL ==> id
  735. if (!$entite) return $f;
  736. // sinon on veut effectuer le passage id ==> URL
  737. $res = !$f ? '' : $f(intval($id), $entite, $args, $ancre);
  738. }
  739. }
  740. if ($res) return $res;
  741. // Sinon c'est un raccourci ou compat SPIP < 2
  742. include_spip('inc/lien');
  743. if (!function_exists($f = 'generer_url_' . $entite)) {
  744. if (!function_exists($f .= '_dist')) $f = '';
  745. }
  746. if ($f) {
  747. $url = $f($id, $args, $ancre);
  748. if (strlen($args))
  749. $url .= strstr($url, '?')
  750. ? '&amp;'.$args
  751. : '?'.$args;
  752. return $url;
  753. }
  754. // On a ete gentil mais la ....
  755. spip_log("generer_url_entite: entite $entite ($f) inconnue $type $public");
  756. return '';
  757. }
  758. // Transformer les caracteres utf8 d'une URL (farsi par ex) selon la RFC 1738
  759. function urlencode_1738($url) {
  760. $uri = '';
  761. for ($i=0; $i < strlen($url); $i++) {
  762. if (ord($a = $url[$i]) > 127)
  763. $a = rawurlencode($a);
  764. $uri .= $a;
  765. }
  766. return quote_amp($uri);
  767. }
  768. // http://doc.spip.org/@generer_url_entite_absolue
  769. function generer_url_entite_absolue($id='', $entite='', $args='', $ancre='', $connect=NULL)
  770. {
  771. if (!$connect) $connect = true;
  772. $h = generer_url_entite($id, $entite, $args, $ancre, $connect);
  773. if (!preg_match(',^\w+:,', $h)) {
  774. include_spip('inc/filtres_mini');
  775. $h = url_absolue($h);
  776. }
  777. return $h;
  778. }
  779. // Sur certains serveurs, la valeur 'Off' tient lieu de false dans certaines
  780. // variables d'environnement comme $_SERVER[HTTPS] ou ini_get(register_globals)
  781. // http://doc.spip.org/@test_valeur_serveur
  782. function test_valeur_serveur($truc) {
  783. if (!$truc) return false;
  784. return (strtolower($truc) !== 'off');
  785. }
  786. //
  787. // Fonctions de fabrication des URL des scripts de Spip
  788. //
  789. // l'URL de base du site, sans se fier a meta(adresse_site) qui
  790. // peut etre fausse (sites a plusieurs noms d'hotes, deplacements, erreurs)
  791. // Note : la globale $profondeur_url doit etre initialisee de maniere a
  792. // indiquer le nombre de sous-repertoires de l'url courante par rapport a la
  793. // racine de SPIP : par exemple, sur ecrire/ elle vaut 1, sur sedna/ 1, et a
  794. // la racine 0. Sur url/perso/ elle vaut 2
  795. // http://doc.spip.org/@url_de_base
  796. function url_de_base($profondeur=null) {
  797. static $url = array();
  798. if (is_array($profondeur)) return $url = $profondeur;
  799. if ($profondeur===false) return $url;
  800. if (is_null($profondeur)) $profondeur = $GLOBALS['profondeur_url'];
  801. if (isset($url[$profondeur]))
  802. return $url[$profondeur];
  803. $http = (
  804. (isset($_SERVER["SCRIPT_URI"]) AND
  805. substr($_SERVER["SCRIPT_URI"],0,5) == 'https')
  806. OR (isset($_SERVER['HTTPS']) AND
  807. test_valeur_serveur($_SERVER['HTTPS']))
  808. ) ? 'https' : 'http';
  809. # note : HTTP_HOST contient le :port si necessaire
  810. if (!$GLOBALS['REQUEST_URI']){
  811. if (isset($_SERVER['REQUEST_URI'])) {
  812. $GLOBALS['REQUEST_URI'] = $_SERVER['REQUEST_URI'];
  813. } else {
  814. $GLOBALS['REQUEST_URI'] = $_SERVER['PHP_SELF'];
  815. if ($_SERVER['QUERY_STRING']
  816. AND !strpos($_SERVER['REQUEST_URI'], '?'))
  817. $GLOBALS['REQUEST_URI'] .= '?'.$_SERVER['QUERY_STRING'];
  818. }
  819. }
  820. $url[$profondeur] = url_de_($http,$_SERVER['HTTP_HOST'],$GLOBALS['REQUEST_URI'],$profondeur);
  821. return $url[$profondeur];
  822. }
  823. /**
  824. * fonction testable de construction d'une url appelee par url_de_base()
  825. * @param string $http
  826. * @param string $host
  827. * @param string $request
  828. * @param int $prof
  829. * @return string
  830. */
  831. function url_de_($http,$host,$request,$prof=0){
  832. $prof = max($prof,0);
  833. $myself = ltrim($request,'/');
  834. # supprimer la chaine de GET
  835. list($myself) = explode('?', $myself);
  836. $url = join('/', array_slice(explode('/', $myself), 0, -1-$prof)).'/';
  837. $url = $http.'://'.rtrim($host,'/').'/'.ltrim($url,'/');
  838. return $url;
  839. }
  840. function tester_url_ecrire($nom){
  841. // tester si c'est une page en squelette
  842. if (find_in_path('prive/exec/' . $nom . '.' . _EXTENSION_SQUELETTES))
  843. return 'fond';
  844. // attention, il ne faut pas inclure l'exec ici car sinon on modifie l'environnement
  845. // par un simple #URL_ECRIRE dans un squelette (cas d'un define en debut d'exec/nom )
  846. return (find_in_path("{$nom}.php",'exec/') OR charger_fonction($nom,'exec',true))?$nom:'';
  847. }
  848. // Pour une redirection, la liste des arguments doit etre separee par "&"
  849. // Pour du code XHTML, ca doit etre &amp;
  850. // Bravo au W3C qui n'a pas ete capable de nous eviter ca
  851. // faute de separer proprement langage et meta-langage
  852. // Attention, X?y=z et "X/?y=z" sont completement differents!
  853. // http://httpd.apache.org/docs/2.0/mod/mod_dir.html
  854. // http://doc.spip.org/@generer_url_ecrire
  855. function generer_url_ecrire($script='', $args="", $no_entities=false, $rel=false) {
  856. if (!$rel)
  857. $rel = url_de_base() . _DIR_RESTREINT_ABS . _SPIP_ECRIRE_SCRIPT;
  858. else if (!is_string($rel))
  859. $rel = _DIR_RESTREINT ? _DIR_RESTREINT :
  860. ('./' . _SPIP_ECRIRE_SCRIPT);
  861. @list($script, $ancre) = explode('#', $script);
  862. if ($script AND ($script<>'accueil' OR $rel))
  863. $args = "?exec=$script" . (!$args ? '' : "&$args");
  864. elseif ($args)
  865. $args ="?$args";
  866. if ($ancre) $args .= "#$ancre";
  867. return $rel . ($no_entities ? $args : str_replace('&', '&amp;', $args));
  868. }
  869. // http://doc.spip.org/@generer_url_retour
  870. function generer_url_retour($script, $args="")
  871. {
  872. return rawurlencode(generer_url_ecrire($script, $args, true, true));
  873. }
  874. //
  875. // Adresse des scripts publics (a passer dans inc-urls...)
  876. //
  877. // Detecter le fichier de base, a la racine, comme etant spip.php ou ''
  878. // dans le cas de '', un $default = './' peut servir (comme dans urls/page.php)
  879. // http://doc.spip.org/@get_spip_script
  880. function get_spip_script($default='') {
  881. # cas define('_SPIP_SCRIPT', '');
  882. if (_SPIP_SCRIPT)
  883. return _SPIP_SCRIPT;
  884. else
  885. return $default;
  886. }
  887. // http://doc.spip.org/@generer_url_public
  888. function generer_url_public($script='', $args="", $no_entities=false, $rel=false, $action='') {
  889. // si le script est une action (spip_pass, spip_inscription),
  890. // standardiser vers la nouvelle API
  891. if (!$action) $action = get_spip_script();
  892. if ($script)
  893. $action = parametre_url($action, _SPIP_PAGE, $script, '&');
  894. if ($args) {
  895. if (is_array($args)) {
  896. $r = '';
  897. foreach($args as $k => $v) $r .= '&' . $k . '=' . $v;
  898. $args = substr($r,1);
  899. }
  900. $action .=
  901. (strpos($action, '?') !== false ? '&' : '?') . $args;
  902. }
  903. if (!$no_entities)
  904. $action = quote_amp($action);
  905. // ne pas generer une url avec /./?page= en cas d'url absolue et de _SPIP_SCRIPT vide
  906. return ($rel ? _DIR_RACINE . $action : rtrim(url_de_base(),'/') . preg_replace(",^/[.]/,","/","/$action"));
  907. }
  908. // http://doc.spip.org/@generer_url_prive
  909. function generer_url_prive($script, $args="", $no_entities=false) {
  910. return generer_url_public($script, $args, $no_entities, false, _DIR_RESTREINT_ABS . 'prive.php');
  911. }
  912. // Pour les formulaires en methode POST,
  913. // mettre le nom du script a la fois en input-hidden et dans le champ action:
  914. // 1) on peut ainsi memoriser le signet comme si c'etait un GET
  915. // 2) ca suit http://en.wikipedia.org/wiki/Representational_State_Transfer
  916. // http://doc.spip.org/@generer_form_ecrire
  917. function generer_form_ecrire($script, $corps, $atts='', $submit='') {
  918. global $spip_lang_right;
  919. $script1 = array_shift(explode('&', $script));
  920. return "<form action='"
  921. . ($script ? generer_url_ecrire($script) : '')
  922. . "' "
  923. . ($atts ? $atts : " method='post'")
  924. . "><div>\n"
  925. . "<input type='hidden' name='exec' value='$script1' />"
  926. . $corps
  927. . (!$submit ? '' :
  928. ("<div style='text-align: $spip_lang_right'><input type='submit' value=\"".entites_html($submit)."\" /></div>"))
  929. . "</div></form>\n";
  930. }
  931. // Attention, JS/Ajax n'aime pas le melange de param GET/POST
  932. // On n'applique pas la recommandation ci-dessus pour les scripts publics
  933. // qui ne sont pas destines a etre mis en signets
  934. // http://doc.spip.org/@generer_form_action
  935. function generer_form_action($script, $corps, $atts='', $public=false) {
  936. // si l'on est dans l'espace prive, on garde dans l'url
  937. // l'exec a l'origine de l'action, qui permet de savoir si il est necessaire
  938. // ou non de proceder a l'authentification (cas typique de l'install par exemple)
  939. $h = (_DIR_RACINE AND !$public)
  940. ? generer_url_ecrire(_request('exec'))
  941. : generer_url_public();
  942. return "\n<form action='" .
  943. $h .
  944. "'" .
  945. $atts .
  946. ">\n" .
  947. "<div>" .
  948. "\n<input type='hidden' name='action' value='$script' />" .
  949. $corps .
  950. "</div></form>";
  951. }
  952. // http://doc.spip.org/@generer_url_action
  953. function generer_url_action($script, $args="", $no_entities=false , $public = false) {
  954. // si l'on est dans l'espace prive, on garde dans l'url
  955. // l'exec a l'origine de l'action, qui permet de savoir si il est necessaire
  956. // ou non de proceder a l'authentification (cas typique de l'install par exemple)
  957. $url = (_DIR_RACINE AND !$public)
  958. ? generer_url_ecrire(_request('exec'))
  959. : generer_url_public();
  960. $url = parametre_url($url,'action',$script);
  961. if ($args) $url .= quote_amp('&'.$args);
  962. if ($no_entities) $url = str_replace('&amp;','&',$url);
  963. return $url;
  964. }
  965. /**
  966. * Fonction d'initialisation groupee pour compatibilite ascendante
  967. *
  968. * @param string $pi
  969. * @param string $pa
  970. * @param string $ti
  971. * @param string $ta
  972. */
  973. function spip_initialisation($pi=NULL, $pa=NULL, $ti=NULL, $ta=NULL) {
  974. spip_initialisation_core($pi,$pa,$ti,$ta);
  975. spip_initialisation_suite();
  976. }
  977. /**
  978. * Fonction d'initialisation, appellee dans inc_version ou mes_options
  979. * Elle definit les repertoires et fichiers non partageables
  980. * et indique dans $test_dirs ceux devant etre accessibles en ecriture
  981. * mais ne touche pas a cette variable si elle est deja definie
  982. * afin que mes_options.php puisse en specifier d'autres.
  983. * Elle definit ensuite les noms des fichiers et les droits.
  984. * Puis simule un register_global=on securise.
  985. *
  986. * @param string $pi
  987. * @param string $pa
  988. * @param string $ti
  989. * @param string $ta
  990. */
  991. function spip_initialisation_core($pi=NULL, $pa=NULL, $ti=NULL, $ta=NULL) {
  992. static $too_late = 0;
  993. if ($too_late++) return;
  994. // Declaration des repertoires
  995. // le nom du repertoire plugins/ activables/desactivables
  996. define('_DIR_PLUGINS', _DIR_RACINE . "plugins/");
  997. // le nom du repertoire des extensions/ permanentes du core, toujours actives
  998. define('_DIR_EXTENSIONS', _DIR_RACINE . "extensions/");
  999. define('_DIR_IMG', $pa);
  1000. define('_DIR_LOGOS', $pa);
  1001. define('_DIR_IMG_ICONES', _DIR_LOGOS . "icones/");
  1002. define('_DIR_DUMP', $ti . "dump/");
  1003. define('_DIR_SESSIONS', $ti . "sessions/");
  1004. define('_DIR_TRANSFERT', $ti . "upload/");
  1005. define('_DIR_CACHE', $ti . "cache/");
  1006. define('_DIR_CACHE_XML', _DIR_CACHE . "xml/");
  1007. define('_DIR_SKELS', _DIR_CACHE . "skel/");
  1008. define('_DIR_AIDE', _DIR_CACHE . "aide/");
  1009. define('_DIR_TMP', $ti);
  1010. define('_DIR_VAR', $ta);
  1011. define('_DIR_ETC', $pi);
  1012. define('_DIR_CONNECT', $pi);
  1013. define('_DIR_CHMOD', $pi);
  1014. if (!isset($GLOBALS['test_dirs']))
  1015. // Pas $pi car il est bon de le mettre hors ecriture apres intstall
  1016. // il sera rajoute automatiquement si besoin a l'etape 2 de l'install
  1017. $GLOBALS['test_dirs'] = array($pa, $ti, $ta);
  1018. // Declaration des fichiers
  1019. define('_CACHE_PLUGINS_PATH', _DIR_CACHE . "charger_plugins_chemins.php");
  1020. define('_CACHE_PLUGINS_OPT', _DIR_CACHE . "charger_plugins_options.php");
  1021. define('_CACHE_PLUGINS_FCT', _DIR_CACHE . "charger_plugins_fonctions.php");
  1022. define('_CACHE_PLUGINS_VERIF', _DIR_CACHE . "verifier_plugins.txt");
  1023. define('_CACHE_PIPELINES', _DIR_CACHE."charger_pipelines.php");
  1024. define('_CACHE_CHEMIN', _DIR_CACHE."chemin.txt");
  1025. # attention .php obligatoire pour ecrire_fichier_securise
  1026. define('_FILE_META', $ti . 'meta_cache.php');
  1027. define('_DIR_LOG', _DIR_TMP);
  1028. define('_FILE_LOG', 'spip');
  1029. define('_FILE_LOG_SUFFIX', '.log');
  1030. // Le fichier de connexion a la base de donnees
  1031. // tient compte des anciennes versions (inc_connect...)
  1032. define('_FILE_CONNECT_INS', 'connect');
  1033. define('_FILE_CONNECT',
  1034. (@is_readable($f = _DIR_CONNECT . _FILE_CONNECT_INS . '.php') ? $f
  1035. : (@is_readable($f = _DIR_RESTREINT . 'inc_connect.php') ? $f
  1036. : (@is_readable($f = _DIR_RESTREINT . 'inc_connect.php3') ? $f
  1037. : false))));
  1038. // Le fichier de reglages des droits
  1039. define('_FILE_CHMOD_INS', 'chmod');
  1040. define('_FILE_CHMOD',
  1041. (@is_readable($f = _DIR_CHMOD . _FILE_CHMOD_INS . '.php') ? $f
  1042. : false));
  1043. define('_FILE_LDAP', 'ldap.php');
  1044. define('_FILE_TMP_SUFFIX', '.tmp.php');
  1045. define('_FILE_CONNECT_TMP', _DIR_CONNECT . _FILE_CONNECT_INS . _FILE_TMP_SUFFIX);
  1046. define('_FILE_CHMOD_TMP', _DIR_CHMOD . _FILE_CHMOD_INS . _FILE_TMP_SUFFIX);
  1047. // Definition des droits d'acces en ecriture
  1048. if (!defined('_SPIP_CHMOD') AND _FILE_CHMOD)
  1049. include_once _FILE_CHMOD;
  1050. // Se mefier des fichiers mal remplis!
  1051. if (!defined('_SPIP_CHMOD')) define('_SPIP_CHMOD', 0777);
  1052. // Le charset par defaut lors de l'installation
  1053. define('_DEFAULT_CHARSET', 'utf-8');
  1054. define('_ROOT_PLUGINS', _ROOT_RACINE . "plugins/");
  1055. define('_ROOT_EXTENSIONS', _ROOT_RACINE . "extensions/");
  1056. // La taille des Log
  1057. define('_MAX_LOG', 100);
  1058. // Sommes-nous dans l'empire du Mal ?
  1059. // (ou sous le signe du Pingouin, ascendant GNU ?)
  1060. if (strpos($_SERVER['SERVER_SOFTWARE'], '(Win') !== false){
  1061. define ('_OS_SERVEUR', 'windows');
  1062. define('_SPIP_LOCK_MODE',1); // utiliser le flock php
  1063. }
  1064. else {
  1065. define ('_OS_SERVEUR', '');
  1066. define('_SPIP_LOCK_MODE',1); // utiliser le flock php
  1067. #define('_SPIP_LOCK_MODE',2); // utiliser le nfslock de spip mais link() est tres souvent interdite
  1068. }
  1069. //
  1070. // Module de lecture/ecriture/suppression de fichiers utilisant flock()
  1071. // (non surchargeable en l'etat ; attention si on utilise include_spip()
  1072. // pour le rendre surchargeable, on va provoquer un reecriture
  1073. // systematique du noyau ou une baisse de perfs => a etudier)
  1074. include_once _ROOT_RESTREINT . 'inc/flock.php';
  1075. // charger tout de suite le path et son cache
  1076. load_path_cache();
  1077. // *********** traiter les variables ************
  1078. //
  1079. // Securite
  1080. //
  1081. // Ne pas se faire manger par un bug php qui accepte ?GLOBALS[truc]=toto
  1082. if (isset($_REQUEST['GLOBALS'])) die();
  1083. // nettoyer les magic quotes \' et les caracteres nuls %00
  1084. spip_desinfecte($_GET);
  1085. spip_desinfecte($_POST);
  1086. spip_desinfecte($_COOKIE);
  1087. spip_desinfecte($_REQUEST);
  1088. // Par ailleurs on ne veut pas de magic_quotes au cours de l'execution
  1089. @set_magic_quotes_runtime(0);
  1090. // Si les variables sont passees en global par le serveur,
  1091. // ou si on veut la compatibilite php3
  1092. // il faut faire quelques verifications de base
  1093. if ($x = test_valeur_serveur(@ini_get('register_globals'))
  1094. OR _FEED_GLOBALS) {
  1095. // ne pas desinfecter les globales en profondeur car elle contient aussi les
  1096. // precedentes, qui seraient desinfectees 2 fois.
  1097. spip_desinfecte($GLOBALS,false);
  1098. include_spip('inc/php3');
  1099. spip_register_globals($x);
  1100. }
  1101. // appliquer le cookie_prefix
  1102. if ($GLOBALS['cookie_prefix'] != 'spip') {
  1103. include_spip('inc/cookie');
  1104. recuperer_cookies_spip($GLOBALS['cookie_prefix']);
  1105. }
  1106. //
  1107. // Capacites php (en fonction de la version)
  1108. //
  1109. $GLOBALS['flag_ob'] = (function_exists("ob_start")
  1110. && function_exists("ini_get")
  1111. && !strstr(@ini_get('disable_functions'), 'ob_'));
  1112. $GLOBALS['flag_sapi_name'] = function_exists("php_sapi_name");
  1113. $GLOBALS['flag_get_cfg_var'] = (@get_cfg_var('error_reporting') != "");
  1114. $GLOBALS['flag_upload'] = (!$GLOBALS['flag_get_cfg_var'] ||
  1115. (get_cfg_var('upload_max_filesize') > 0));
  1116. // Compatibilite avec serveurs ne fournissant pas $REQUEST_URI
  1117. if (isset($_SERVER['REQUEST_URI'])) {
  1118. $GLOBALS['REQUEST_URI'] = $_SERVER['REQUEST_URI'];
  1119. } else {
  1120. $GLOBALS['REQUEST_URI'] = $_SERVER['PHP_SELF'];
  1121. if ($_SERVER['QUERY_STRING']
  1122. AND !strpos($_SERVER['REQUEST_URI'], '?'))
  1123. $GLOBALS['REQUEST_URI'] .= '?'.$_SERVER['QUERY_STRING'];
  1124. }
  1125. // Duree de validite de l'alea pour les cookies et ce qui s'ensuit.
  1126. define('_RENOUVELLE_ALEA', 12 * 3600);
  1127. // charger les meta si possible et renouveller l'alea au besoin
  1128. // charge aussi effacer_meta et ecrire_meta
  1129. $inc_meta = charger_fonction('meta', 'inc');
  1130. $inc_meta();
  1131. // nombre de repertoires depuis la racine
  1132. // on compare a l'adresse de spip.php : $_SERVER["SCRIPT_NAME"]
  1133. // ou a defaut celle donnee en meta ; (mais si celle-ci est fausse
  1134. // le calcul est faux)
  1135. if (!_DIR_RESTREINT)
  1136. $GLOBALS['profondeur_url'] = 1;
  1137. else {
  1138. $uri = isset($_SERVER['REQUEST_URI']) ? explode('?', $_SERVER['REQUEST_URI']) : '';
  1139. $uri_ref = $_SERVER["SCRIPT_NAME"];
  1140. if (!$uri_ref
  1141. // si on est appele avec un autre ti, on est sans doute en mutu
  1142. // si jamais c'est de la mutu avec sous rep, on est perdu si on se fie
  1143. // a spip.php qui est a la racine du spip, et vue qu'on sait pas se reperer
  1144. // s'en remettre a l'adresse du site. alea jacta est.
  1145. OR $ti!==_NOM_TEMPORAIRES_INACCESSIBLES){
  1146. if (isset($GLOBALS['meta']['adresse_site'])) {
  1147. $uri_ref = parse_url($GLOBALS['meta']['adresse_site']);
  1148. $uri_ref = $uri_ref['path'].'/';
  1149. }
  1150. else
  1151. $uri_ref = "";
  1152. }
  1153. if (!$uri OR !$uri_ref)
  1154. $GLOBALS['profondeur_url'] = 0;
  1155. else {
  1156. $GLOBALS['profondeur_url'] = max(0,
  1157. substr_count($uri[0], '/')
  1158. - substr_count($uri_ref,'/'));
  1159. }
  1160. }
  1161. // s'il y a un cookie ou PHP_AUTH, initialiser visiteur_session
  1162. if (_FILE_CONNECT) {
  1163. if (verifier_visiteur()=='0minirezo'
  1164. // si c'est un admin sans cookie admin, il faut ignorer le cache chemin !
  1165. AND !isset($COOKIE['spip_admin']))
  1166. clear_path_cache();
  1167. }
  1168. }
  1169. /**
  1170. * Complements d'initialisation non critiques pouvant etre realises
  1171. * par les plugins
  1172. *
  1173. */
  1174. function spip_initialisation_suite() {
  1175. static $too_late = 0;
  1176. if ($too_late++) return;
  1177. // taille mini des login
  1178. define('_LOGIN_TROP_COURT', 4);
  1179. // la taille maxi des logos (0 : pas de limite)
  1180. define('_LOGO_MAX_SIZE', 0); # poids en ko
  1181. define('_LOGO_MAX_WIDTH', 0); # largeur en pixels
  1182. define('_LOGO_MAX_HEIGHT', 0); # hauteur en pixels
  1183. define('_DOC_MAX_SIZE', 0); # poids en ko
  1184. define('_IMG_MAX_SIZE', 0); # poids en ko
  1185. define('_IMG_MAX_WIDTH', 0); # largeur en pixels
  1186. define('_IMG_MAX_HEIGHT', 0); # hauteur en pixels
  1187. define('_COPIE_LOCALE_MAX_SIZE',16777216); // poids en octet
  1188. // qq chaines standard
  1189. define('_ACCESS_FILE_NAME', '.htaccess');
  1190. define('_AUTH_USER_FILE', '.htpasswd');
  1191. define('_SPIP_DUMP', 'dump@nom_site@@stamp@.xml');
  1192. define('_CACHE_RUBRIQUES', _DIR_TMP.'menu-rubriques-cache.txt');
  1193. define('_CACHE_RUBRIQUES_MAX', 500);
  1194. define('_EXTENSION_SQUELETTES', 'html');
  1195. define('_DOCTYPE_ECRIRE',
  1196. // "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'>\n");
  1197. //"<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>\n");
  1198. "<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>\n");
  1199. // "<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.1 //EN' 'http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd'>\n");
  1200. define('_DOCTYPE_AIDE',
  1201. "<!DOCTYPE html PUBLIC '-//W3C//DTD HTML 4.01 Frameset//EN' 'http://www.w3.org/TR/1999/REC-html401-19991224/frameset.dtd'>");
  1202. // L'adresse de base du site ; on peut mettre '' si la racine est geree par
  1203. // le script de l'espace public, alias index.php
  1204. define('_SPIP_SCRIPT', 'spip.php');
  1205. // argument page, personalisable en cas de conflit avec un autre script
  1206. define('_SPIP_PAGE', 'page');
  1207. // le script de l'espace prive
  1208. // Mettre a "index.php" si DirectoryIndex ne le fait pas ou pb connexes:
  1209. // les anciens IIS n'acceptent pas les POST sur ecrire/ (#419)
  1210. // meme pb sur thttpd cf. http://forum.spip.org/fr_184153.html
  1211. define('_SPIP_ECRIRE_SCRIPT', // true ? #decommenter ici et commenter la
  1212. preg_match(',IIS|thttpd,',$_SERVER['SERVER_SOFTWARE']) ?
  1213. 'index.php' : '');
  1214. // Gestion AJAX sauf pour le mode oo (et en espace prive)
  1215. if (isset($GLOBALS['visiteur_session']['prefs'])AND !_DIR_RESTREINT) {
  1216. $x = $GLOBALS['visiteur_session']['prefs'];
  1217. if (!is_array($x)) $x = unserialize($x); // prive.php l'a fait
  1218. if ($x['display'] == 4) {
  1219. define('_SPIP_AJAX', -1);
  1220. if (isset($_COOKIE['spip_accepte_ajax']))
  1221. spip_setcookie('spip_accepte_ajax', -1, 0);
  1222. }
  1223. }
  1224. if (!defined('_SPIP_AJAX'))
  1225. define('_SPIP_AJAX', ((!isset($_COOKIE['spip_accepte_ajax']))
  1226. ? 1
  1227. : (($_COOKIE['spip_accepte_ajax'] != -1) ? 1 : 0)));
  1228. // La requete est-elle en ajax ?
  1229. define('_AJAX',
  1230. (isset($_SERVER['HTTP_X_REQUESTED_WITH']) # ajax jQuery
  1231. OR @$_REQUEST['var_ajax_redir'] # redirection 302 apres ajax jQuery
  1232. OR @$_REQUEST['var_ajaxcharset'] # compat ascendante pour plugins
  1233. )
  1234. AND !@$_REQUEST['var_noajax'] # horrible exception, car c'est pas parce que la requete est ajax jquery qu'il faut tuer tous les formulaires ajax qu'elle contient
  1235. );
  1236. # nombre de pixels maxi pour calcul de la vignette avec gd
  1237. # au dela de 5500000 on considere que php n'est pas limite en memoire pour cette operation
  1238. # les configurations limitees en memoire ont un seuil plutot vers 1MPixel
  1239. define('_IMG_GD_MAX_PIXELS', (isset($GLOBALS['meta']['max_taille_vignettes'])&&$GLOBALS['meta']['max_taille_vignettes']<5500000)?$GLOBALS['meta']['max_taille_vignettes']:0);
  1240. define('_IMG_GD_QUALITE', 85);
  1241. if (!defined('_MEMORY_LIMIT_MIN')) define('_MEMORY_LIMIT_MIN', 16);
  1242. // si on est dans l'espace prive et si le besoin est superieur a 8Mo (qui est vraiment le standard)
  1243. // on verifie que la memoire est suffisante pour le compactage css+js pour eviter la page blanche
  1244. // il y aura d'autres problemes et l'utilisateur n'ira pas tres loin, mais ce sera plus comprehensible qu'une page blanche
  1245. if (test_espace_prive() AND _MEMORY_LIMIT_MIN>8){
  1246. if ($memory = trim(ini_get('memory_limit'))){
  1247. $unit = strtolower(substr($memory,strlen($memory/1),1));
  1248. switch($unit) {
  1249. // Le modifieur 'G' est disponible depuis PHP 5.1.0
  1250. case 'g': $memory *= 1024;
  1251. case 'm': $memory *= 1024;
  1252. case 'k': $memory *= 1024;
  1253. }
  1254. if ($memory<_MEMORY_LIMIT_MIN*1024*1024){
  1255. ini_set('memory_limit',$m=_MEMORY_LIMIT_MIN.'M');
  1256. if (trim(ini_get('memory_limit'))!=$m){
  1257. define('_INTERDIRE_COMPACTE_HEAD_ECRIRE',true); // evite une page blanche car on ne saura pas calculer la css dans ce hit
  1258. }
  1259. }
  1260. }
  1261. else
  1262. define('_INTERDIRE_COMPACTE_HEAD_ECRIRE',true); // evite une page blanche car on ne saura pas calculer la css dans ce hit
  1263. }
  1264. init_var_mode();
  1265. }
  1266. // Reperer les variables d'URL qui conditionnent la perennite du cache, des urls
  1267. // ou d'autres petit caches (trouver_table, css et js compactes ...)
  1268. // http://doc.spip.org/@init_var_mode
  1269. function init_var_mode(){
  1270. static $done = false;
  1271. if (!$done) {
  1272. // On fixe $GLOBALS['var_mode']
  1273. $GLOBALS['var_mode'] = false;
  1274. $GLOBALS['var_preview'] = false;
  1275. $GLOBALS['var_images'] = false;
  1276. $GLOBALS['var_inclure'] = false;
  1277. $GLOBALS['var_urls'] = false;
  1278. if (isset($_GET['var_mode'])) {
  1279. // tout le monde peut calcul/recalcul
  1280. if ($_GET['var_mode'] == 'calcul'
  1281. OR $_GET['var_mode'] == 'recalcul')
  1282. $GLOBALS['var_mode'] = $_GET['var_mode'];
  1283. // preview, debug, blocs, urls et images necessitent une autorisation
  1284. else if (in_array($_GET['var_mode'],array('preview','debug','inclure','urls','images'))) {
  1285. include_spip('inc/autoriser');
  1286. if (autoriser(
  1287. ($_GET['var_mode'] == 'preview')
  1288. ? 'previsualiser'
  1289. : 'debug'
  1290. )) {
  1291. switch($_GET['var_mode']){
  1292. case 'preview':
  1293. // forcer le compilo et ignorer les caches existants
  1294. $GLOBALS['var_mode'] = 'recalcul';
  1295. // truquer les boucles
  1296. $GLOBALS['var_preview'] = true;
  1297. // et ne pas enregistrer de cache
  1298. $GLOBALS['var_nocache'] = true;
  1299. break;
  1300. case 'inclure':
  1301. // forcer le compilo et ignorer les caches existants
  1302. $GLOBALS['var_mode'] = 'calcul';
  1303. $GLOBALS['var_inclure'] = true;
  1304. // et ne pas enregistrer de cache
  1305. $GLOBALS['var_nocache'] = true;
  1306. break;
  1307. case 'urls':
  1308. // forcer le compilo et ignorer les caches existants
  1309. $GLOBALS['var_mode'] = 'calcul';
  1310. $GLOBALS['var_urls'] = true;
  1311. break;
  1312. case 'images':
  1313. // forcer le compilo et ignorer les caches existants
  1314. $GLOBALS['var_mode'] = 'calcul';
  1315. // indiquer qu'on doit recalculer les images
  1316. $GLOBALS['var_images'] = true;
  1317. break;
  1318. case 'debug':
  1319. $GLOBALS['var_mode'] = 'debug';
  1320. // et ne pas enregistrer de cache

Large files files are truncated, but you can click here to view the full file