Newer
Older
<?php
/***************************************************************************\
* SPIP, Systeme de publication pour l'internet *
* *
* Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
* *
* Ce programme est un logiciel libre distribue sous licence GNU/GPL. *
* Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. *
\***************************************************************************/
if (!defined('_ECRIRE_INC_VERSION')) return;
// Definir les niveaux de log
if (!defined('_LOG_HS')) define('_LOG_HS', 0);
if (!defined('_LOG_ALERTE_ROUGE')) define('_LOG_ALERTE_ROUGE', 1);
if (!defined('_LOG_CRITIQUE')) define('_LOG_CRITIQUE', 2);
if (!defined('_LOG_ERREUR')) define('_LOG_ERREUR', 3);
if (!defined('_LOG_AVERTISSEMENT')) define('_LOG_AVERTISSEMENT', 4);
if (!defined('_LOG_INFO_IMPORTANTE')) define ('_LOG_INFO_IMPORTANTE', 5);
if (!defined('_LOG_INFO')) define('_LOG_INFO', 6);
if (!defined('_LOG_DEBUG')) define('_LOG_DEBUG', 7);
// Utilitaires indispensables autour du serveur Http.
/**
* charge un fichier perso ou, a defaut, standard
* et retourne si elle existe le nom de la fonction homonyme (exec_$nom),
* ou de suffixe _dist
* Peut etre appelee plusieurs fois, donc optimiser
*
* http://doc.spip.org/@charger_fonction
*
* @param string $nom
* @param string $dossier
* @param bool $continue
* @return string
*/
function charger_fonction($nom, $dossier='exec', $continue=false) {
static $echecs = array();
if (strlen($dossier) AND substr($dossier,-1) != '/') $dossier .= '/';
$f = str_replace('/','_',$dossier) . $nom;
if (function_exists($f))
return $f;
if (function_exists($g = $f . '_dist'))
return $g;
if (isset($echecs[$f])) return $echecs[$f];
// Sinon charger le fichier de declaration si plausible
if (!preg_match(',^\w+$,', $f))
die(htmlspecialchars($nom)." pas autorise");
// passer en minuscules (cf les balises de formulaires)
// et inclure le fichier
// si le fichier truc/machin/nom.php n'existe pas,
// la fonction peut etre definie dans truc/machin.php qui regroupe plusieurs petites fonctions
include_spip(substr($dossier,0,-1));
if (function_exists($f)) return $f;
if (function_exists($g)) return $g;
if ($continue) return $echecs[$f] = false;
spip_log("fonction $nom ($f ou $g) indisponible" .
echo minipres(_T('forum_titre_erreur'),
_T('fichier_introuvable', array('fichier'=> '<b>'.htmlentities($d).'</b>')));
/**
* Inclusion unique avec verification d'existence du fichier + log en crash sinon
* @param string $file
* @return bool
*/
function include_once_check($file){
if (file_exists($file)) {include_once $file;return true;}
$crash = (isset($GLOBALS['message_crash_plugins'])?unserialize($GLOBALS['message_crash_plugins']):'');
$crash = ($crash?$crash:array());
$crash[$file] = true;
ecrire_meta('message_crash_plugins',serialize($crash));
return false;
}
cerdic
a validé
//
// la fonction cherchant un fichier PHP dans le SPIP_PATH
//
// http://doc.spip.org/@include_spip
function include_spip($f, $include = true) {
return find_in_path($f . '.php', '', $include);
}
function require_spip($f) {
return find_in_path($f . '.php', '', 'required');
}
// un pipeline est lie a une action et une valeur
// chaque element du pipeline est autorise a modifier la valeur
//
// le pipeline execute les elements disponibles pour cette action,
// les uns apres les autres, et retourne la valeur finale
// Cf. compose_filtres dans references.php, qui est la
// version compilee de cette fonctionnalite
Fil
a validé
// appel unitaire d'une fonction du pipeline
// utilisee dans le script pipeline precompile
// on passe $val par reference pour limiter les allocations memoire
// http://doc.spip.org/@minipipe
function minipipe($fonc,&$val){
Fil
a validé
// fonction
if (function_exists($fonc))
$val = call_user_func($fonc, $val);
// Class::Methode
else if (preg_match("/^(\w*)::(\w*)$/S", $fonc, $regs)
Fil
a validé
AND $methode = array($regs[1], $regs[2])
AND is_callable($methode))
$val = call_user_func($methode, $val);
Fil
a validé
spip_log("Erreur - '$fonc' non definie !");
Fil
a validé
// chargement du pipeline sous la forme d'un fichier php prepare
// http://doc.spip.org/@pipeline
function pipeline($action, $val=null) {
static $charger;
// chargement initial des fonctions mises en cache, ou generation du cache
if (!$charger) {
if (!($ok = @is_readable($charger = _CACHE_PIPELINES))) {
include_spip('inc/plugin');
// generer les fichiers php precompiles
// de chargement des plugins et des pipelines
if (!($ok = @is_readable($charger)))
}
// appliquer notre fonction si elle existe
if (function_exists($fonc)) {
$val = $fonc($val);
}
// plantage ?
else {
spip_log("fonction $fonc absente : pipeline desactive",_LOG_ERREUR);
Fil
a validé
}
// si le flux est une table avec 2 cle args&data
// on ne ressort du pipe que les donnees dans 'data'
// array_key_exists pour php 4.1.0
if (is_array($val)
AND count($val)==2
AND (array_key_exists('data',$val)))
Fil
a validé
return $val;
}
/**
* Enregistrement des evenements
* spip_log($message)
* spip_log($message,'recherche')
* spip_log($message,_LOG_DEBUG)
* spip_log($message,'recherche.'._LOG_DEBUG)
* cette derniere notation est controversee mais le 3eme
* parametre est plante pour cause de compat ascendante.
* le niveau par defaut est _LOG_INFO
*
* http://doc.spip.org/@spip_log
*
* @param string $message
* @param string|int $name
* @param string $logdir ## inutile !! a supprimer ?
* @param string $logsuf ## inutile !! a supprimer ?
function spip_log($message=NULL, $name=NULL) {
static $pre = array();
preg_match('/^([a-z_]*)\.?(\d)?$/iS', (string) $name, $regs);
if (!$logname = $regs[1])
$logname = null;
$niveau = _LOG_INFO;
if ($niveau <=
(defined('_LOG_FILTRE_GRAVITE')?_LOG_FILTRE_GRAVITE:_LOG_DEBUG)) {
_LOG_HS=>'HS:',
_LOG_ALERTE_ROUGE=>'ALERTE:',
_LOG_CRITIQUE=>'CRITIQUE:',
_LOG_ERREUR=>'ERREUR:',
_LOG_AVERTISSEMENT=>'WARNING:',
_LOG_INFO_IMPORTANTE=>'!INFO:',
_LOG_INFO=>'info:',
_LOG_DEBUG=>'debug:');
$log = charger_fonction('log', 'inc');
}
if (!is_string($message)) $message = var_export($message, true);
$log($pre[$niveau].' '.$message, $logname);
marcimat
a validé
//
// Enregistrement des journaux
//
function journal($phrase, $opt = array()) {
$journal = charger_fonction('journal', 'inc');
$journal($phrase, $opt);
}
// Renvoie le _GET ou le _POST emis par l'utilisateur
// ou pioche dans $c si c'est un array()
// http://doc.spip.org/@_request
function _request($var, $c=false) {
if (is_array($c))
return isset($c[$var]) ? $c[$var] : NULL;
if (isset($_GET[$var])) $a = $_GET[$var];
elseif (isset($_POST[$var])) $a = $_POST[$var];
else return NULL;
// Si on est en ajax et en POST tout a ete encode
// via encodeURIComponent, il faut donc repasser
if (defined('_AJAX')
AND _AJAX
AND isset($GLOBALS['meta']['charset'])
AND $GLOBALS['meta']['charset'] != 'utf-8'
AND is_string($a)
AND preg_match(',[\x80-\xFF],', $a)) {
include_spip('inc/charsets');
return importer_charset($a, 'utf-8');
}
return $a;
}
// Methode set de la fonction _request()
// Attention au cas ou l'on fait set_request('truc', NULL);
// http://doc.spip.org/@set_request
function set_request($var, $val = NULL, $c=false) {
if (is_array($c)) {
unset($c[$var]);
if ($val !== NULL)
$c[$var] = $val;
return $c;
}
unset($_GET[$var]);
unset($_POST[$var]);
if ($val !== NULL)
$_GET[$var] = $val;
return false; # n'affecte pas $c
/**
* Tester si une url est absolue
* @param $url
* @return bool
*/
function tester_url_absolue($url){
return preg_match(";^([a-z]+:)?//;Uims",trim($url))?true:false;
}
/**
* Prend une URL et lui ajoute/retire un parametre.
* Exemples : [(#SELF|parametre_url{suite,18})] (ajout)
* [(#SELF|parametre_url{suite,''})] (supprime)
* [(#SELF|parametre_url{suite})] (prend $suite dans la _request)
* [(#SELF|parametre_url{suite[],1})] (tableaux valeurs multiples)
*
* http://doc.spip.org/@parametre_url
*
* @param string $url
* @param string $c
* @param string|array $v
* @param string $sep
* @return string
*/
function parametre_url($url, $c, $v=NULL, $sep='&') {
// requete erronnee : plusieurs variable dans $c et aucun $v
if (strpos($c,"|")!==false AND is_null($v))
return null;
// lever l'#ancre
if (preg_match(',^([^#]*)(#.*)$,', $url, $r)) {
$url = $r[1];
$ancre = $r[2];
} else
$ancre = '';
// eclater
$url = preg_split(',[?]|&|&,', $url);
// recuperer la base
$a = array_shift($url);
$regexp = ',^(' . str_replace('[]','\[\]',$c) . '[[]?[]]?)(=.*)?$,';
$ajouts = array_flip(explode('|',$c));
$u = is_array($v) ? $v : rawurlencode($v);
$testv = (is_array($v)?count($v):strlen($v));
// lire les variables et agir
foreach ($url as $n => $val) {
if (preg_match($regexp, urldecode($val), $r)) {
if ($v === NULL) {
return $r[2]?substr($r[2],1):'';
elseif (!$testv) {
unset($url[$n]);
// Ajout. Pour une variable, remplacer au meme endroit,
// pour un tableau ce sera fait dans la prochaine boucle
elseif (substr($r[1],-2) != '[]') {
$url[$n] = $r[1].'='.$u;
unset($ajouts[$r[1]]);
}
}
}
// traiter les parametres pas encore trouves
if ($v === NULL
AND $args = func_get_args()
AND count($args)==2)
elseif ($testv) {
foreach($ajouts as $k => $n) {
if (!is_array($v))
$url[] = $k .'=' . $u;
else {
foreach ($v as $w) $url[]= $id .'=' . $w;
}
}
// eliminer les vides
$url = array_filter($url);
// recomposer l'adresse
if ($url)
$a .= '?' . join($sep, $url);
return $a . $ancre;
// Prend une URL et lui ajoute/retire une ancre apres l'avoir nettoyee
// pour l'ancre on translitere, vire les non alphanum du debut,
// et on remplace ceux a l'interieur ou au bout par -
function ancre_url($url, $ancre) {
// lever l'#ancre
if (preg_match(',^([^#]*)(#.*)$,', $url, $r)) {
$url = $r[1];
}
if (preg_match('/[^-_a-zA-Z0-9]+/S',$ancre)){
if (!function_exists('translitteration'))
include_spip('inc/charsets');
$ancre = preg_replace(array('/^[^-_a-zA-Z0-9]+/', '/[^-_a-zA-Z0-9]/'), array('', '-'),
translitteration($ancre));
}
return $url . (strlen($ancre) ? '#'. $ancre : '');
}
//
// pour le nom du cache, les types_urls et self
//
// http://doc.spip.org/@nettoyer_uri
function nettoyer_uri()
{
static $done = false;
static $propre = '';
if ($done) return $propre;
$done = true;
$uri1 = $GLOBALS['REQUEST_URI'];
do {
$uri = $uri1;
$uri1 = preg_replace
(',([?&])(PHPSESSID|(var_[^=&]*))=[^&]*(&|$),i',
'\1', $uri);
} while ($uri<>$uri1);
return $propre = (preg_replace(',[?&]$,', '', $uri1));
}
//
// donner l'URL de base d'un lien vers "soi-meme", modulo
// les trucs inutiles
//
function self($amp = '&', $root = false) {
$url = nettoyer_uri();
cerdic
a validé
if (!$root AND (!defined('_SET_HTML_BASE') OR !_SET_HTML_BASE OR !$GLOBALS['profondeur_url']))
$url = preg_replace(',^[^?]*/,', '', $url);
// ajouter le cas echeant les variables _POST['id_...']
foreach ($_POST as $v => $c)
if (substr($v,0,3) == 'id_')
$url = parametre_url($url, $v, $c, '&');
// supprimer les variables sans interet
if (test_espace_prive()) {
$url = preg_replace (',([?&])('
.'lang|show_docs|'
.'changer_lang|var_lang|action)=[^&]*,i', '\1', $url);
$url = preg_replace(',([?&])[&]+,', '\1', $url);
$url = preg_replace(',[&]$,', '\1', $url);
}
// eviter les hacks
$url = htmlspecialchars($url);
// & ?
if ($amp != '&')
$url = str_replace('&', $amp, $url);
// Si ca demarre par ? ou vide, donner './'
$url = preg_replace(',^([?].*)?$,', './\1', $url);
return $url;
}
// Indique si on est dans l'espace prive
function test_espace_prive() {
return defined('_ESPACE_PRIVE') ? _ESPACE_PRIVE : false;
}
cerdic
a validé
/**
* Verifie la presence d'un plugin active, identifie par son prefix
cerdic
a validé
*
* @param string $plugin
* @return bool
*/
function test_plugin_actif($plugin){
return ($plugin AND defined('_DIR_PLUGIN_'.strtoupper($plugin)))? true:false;
}
cerdic
a validé
/**
* Traduction des textes de SPIP
* http://doc.spip.org/@_T
*
* @param string $texte
* @param array $args
* @param array $options
* string class : nom d'une classe a ajouter sur un span pour encapsuler la chaine
* bool force : forcer un retour meme si la chaine n'a pas de traduction
* @return mixed|string
*/
function _T($texte, $args=array(), $options=array()) {
static $traduire=false ;
$o = array('class'=>'', 'force'=>true);
cerdic
a validé
if ($options){
// support de l'ancien argument $class
if (is_string($options))
$options = array('class'=>$options);
$o = array_merge($o,$options);
}
if (!$traduire) {
$traduire = charger_fonction('traduire', 'inc');
include_spip('inc/lang');
}
RastaPopoulos
a validé
// On peut passer explicitement la langue dans le tableau
// On utilise le même nom de variable que la globale
if ($args['spip_lang']){
$lang = $args['spip_lang'];
// On l'enleve pour ne pas le passer au remplacement
unset($args['spip_lang']);
}
// Sinon on prend la langue du contexte
else{
$lang = $GLOBALS['spip_lang'];
}
$text = $traduire($texte, $lang);
if (!strlen($text)){
cerdic
a validé
if (!$o['force'])
return '';
$text = $texte;
// pour les chaines non traduites, assurer un service minimum
if (!$GLOBALS['test_i18n'])
$text = str_replace('_', ' ',
(($n = strpos($text,':')) === false ? $texte :
substr($texte, $n+1)));
$o['class'] = null;
}
cerdic
a validé
return _L($text, $args, $o['class']);
// Remplacer les variables @....@ par leur valeur dans une chaine de langue.
// Aussi appelee quand une chaine n'est pas encore dans les fichiers de langue
function _L($text, $args=array(), $class=null) {
$f = $text;
if (is_array($args)) {
foreach ($args as $name => $value) {
if ($class)
$value = "<span class='$class'>$value</span>";
$t = str_replace ("@$name@", $value, $text);
if ($text !== $t) {unset($args[$name]); $text = $t;}
// Si des variables n'ont pas ete inserees, le signaler
// (chaines de langues pas a jour)
if ($args) spip_log("$f: variables inutilisees " . join(', ', array_keys($args)),_LOG_DEBUG);
if ($GLOBALS['test_i18n'] AND $class===null)
return "<blink style='color:red;'>$text</blink>";
return $text;
// Afficher "ecrire/data/" au lieu de "data/" dans les messages
// ou tmp/ au lieu de ../tmp/
// http://doc.spip.org/@joli_repertoire
function joli_repertoire($rep) {
$a = substr($rep,0,1);
if ($a<>'.' AND $a<>'/')
$rep = (_DIR_RESTREINT?'':_DIR_RESTREINT_ABS).$rep;
$rep = preg_replace(',(^\.\.\/),', '', $rep);
return $rep;
}
//
// spip_timer : on l'appelle deux fois et on a la difference, affichable
//
// http://doc.spip.org/@spip_timer
function spip_timer($t='rien', $raw = false) {
static $time;
$a=time(); $b=microtime();
// microtime peut contenir les microsecondes et le temps
$b=explode(' ',$b);
if (count($b)==2) $a = end($b); // plus precis !
$b = reset($b);
if (!isset($time[$t])) {
} else {
$p = ($a + $b - $time[$t]) * 1000;
unset($time[$t]);
# echo "'$p'";exit;
$s = '';
else {
$s = sprintf("%d ", $x = floor($p/1000));
$p -= ($x*1000);
}
return $s . sprintf($s?"%07.3f ms":"%.3f ms", $p);
// Renvoie False si un fichier n'est pas plus vieux que $duree secondes,
// sinon renvoie True et le date sauf si ca n'est pas souhaite
// http://doc.spip.org/@spip_touch
function spip_touch($fichier, $duree=0, $touch=true) {
if ($duree) {
clearstatcache();
if ((@$f=filemtime($fichier)) AND ($f >= time() - $duree))
return false;
}
if ($touch!==false) {
if (!@touch($fichier)) { spip_unlink($fichier); @touch($fichier); };
@chmod($fichier, _SPIP_CHMOD & ~0111);
return true;
// Ce declencheur de tache de fond, de l'espace prive (cf inc_presentation)
// et de l'espace public (cf #SPIP_CRON dans inc_balise), est appelee
// par un background-image car contrairement a un iframe vide,
// les navigateurs ne diront pas qu'ils n'ont pas fini de charger,
// c'est plus rassurant.
// C'est aussi plus discret qu'un <img> sous un navigateur non graphique.
// http://doc.spip.org/@action_cron
function action_cron() {
include_spip('inc/headers');
http_status(204); // No Content
header("Connection: close");
define('_DIRECT_CRON_FORCE',true);
cron();
/**
* cron() : execution des taches de fond
* On peut lui passer en 1er (ou 2e arg pour compat)
* le tableau de taches attendu par inc_genie()
* Retourne Vrai si un tache a pu etre effectuee
* pas de verrou ici : les verrous sont geres sur chaque tache
* a chaque execution
*
* http://doc.spip.org/@cron
*
* @param array $taches
* taches forcees
* @param array $taches_old
* taches forcees, pour compat avec ancienne syntaxe
* @return bool
*/
function cron ($taches=array(), $taches_old= array()) {
// si pas en mode cron force
// ou si base inaccessible, laisser tomber.
if (!defined('_DIRECT_CRON_FORCE') OR !spip_connect()) return false;
spip_log("cron !",'jq'._LOG_DEBUG);
if (!is_array($taches)) $taches = $taches_old; // compat anciens appels
if ($genie = charger_fonction('genie', 'inc', true)) {
$genie($taches);
return true;
return false;
/**
* Ajout d'une tache dans la file d'attente
*
* @param $function
* The function name to call.
* @param $description
* A human-readable description of the queued job.
* @param $arguments
* Optional array of arguments to pass to the function.
* @param $file
* Optional file path which needs to be included for $function.
* if ends with '/', will do charger_fonction($function,$file);
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
* @param $no_duplicate
* If TRUE, do not add the job to the queue if one with the same function and
* arguments already exists.
* @param $time
* time for starting the job. If 0, job will start as soon as possible
* @param $priority
* -10 (low priority) to +10 (high priority), 0 is the default
* @return int
* id of job
*/
function job_queue_add($function, $description, $arguments = array(), $file = '', $no_duplicate = FALSE, $time=0, $priority=0) {
include_spip('inc/queue');
return queue_add_job($function, $description, $arguments, $file, $no_duplicate, $time, $priority);
}
/**
* Supprimer une tache de la file d'attente
* @param int $id_job
* id of jonb to delete
* @return bool
*/
function job_queue_remove($id_job){
include_spip('inc/queue');
return queue_remove_job($id_job);
}
/**
* Associer une tache a un/des objets de SPIP
* @param int $id_job
* id of job to link
* @param array $objets
* can be a simple array('objet'=>'article','id_objet'=>23)
* or an array of simple array to link multiples objet in one time
*/
function job_queue_link($id_job,$objets){
include_spip('inc/queue');
return queue_link_job($id_job,$objets);
}
/**
* Renvoyer le temps de repos restant jusqu'au prochain job
* 0 si un job est a traiter
* null si la queue n'est pas encore initialise
* $force est utilisee par queue_set_next_job_time() pour maj la valeur
* - si true, force la relecture depuis le fichier
* - si int, affecte la static directement avec la valeur
*
* @staticvar int $queue_next_job_time
* @param int/bool $force_next
* @return int
*/
function queue_sleep_time_to_next_job($force=null) {
static $queue_next_job_time = -1;
if ($force===true)
$queue_next_job_time = -1;
elseif ($force)
$queue_next_job_time = $force;
if ($queue_next_job_time==-1) {
define('_JQ_NEXT_JOB_TIME_FILENAME',_DIR_TMP . "job_queue_next.txt");
// utiliser un cache memoire si dispo
if (include_spip('inc/memoization') AND defined('_MEMOIZE_MEMORY') AND _MEMOIZE_MEMORY) {
$queue_next_job_time = cache_get(_JQ_NEXT_JOB_TIME_FILENAME);
}
else {
$queue_next_job_time = null;
if (lire_fichier(_JQ_NEXT_JOB_TIME_FILENAME, $contenu))
$queue_next_job_time = intval($contenu);
}
}
if (is_null($queue_next_job_time))
return null;
if (!$_SERVER['REQUEST_TIME'])
$_SERVER['REQUEST_TIME'] = time();
return max(0,$queue_next_job_time-$_SERVER['REQUEST_TIME']);
}
// transformation XML des "&" en "&"
// http://doc.spip.org/@quote_amp
function quote_amp($u) {
return preg_replace(
"/&(?![a-z]{0,4}\w{2,3};|#x?[0-9a-f]{2,5};)/i",
"&",$u);
}
// Production d'une balise Script valide
// http://doc.spip.org/@http_script
function http_script($script, $src='', $noscript='') {
if ($src && !isset($done[$src])){
$done[$src] = true;
$src = find_in_path($src, _JAVASCRIPT);
$src = " src='$src'";
if ($script)
preg_replace(',</([^>]*)>,','<\/\1>', $script) .
if ($noscript)
$noscript = "<noscript>\n\t$noscript\n</noscript>\n";
return ($src OR $script OR $noscript)
? "<script type='text/javascript'$src>$script</script>$noscript"
: '';
}
// Transforme n'importe quel champ en une chaine utilisable
// en PHP ou Javascript en toute securite
// < ? php $x = '[(#TEXTE|texte_script)]'; ? >
// http://doc.spip.org/@texte_script
function texte_script($texte) {
return str_replace('\'', '\\\'', str_replace('\\', '\\\\', $texte));
}
davux
a validé
// Chaque appel a cette fonction ajoute un repertoire en tete du chemin courant (path)
// si un repertoire lui est passe en parametre
// retourne le chemin courant sinon, sous forme de array.
// Si l'argument est de la forme dir1:dir2:dir3, ces 3 chemins sont places en tete
// du path, dans cet ordre.
// Exception: si un $dossier_squelette est defini, il reste en tete, pour raison historique
function _chemin($dir_path=NULL){
static $path_base = NULL;
static $path_full = NULL;
if ($path_base==NULL){
$path = defined('_SPIP_PATH') ? _SPIP_PATH :
_DIR_RACINE.'prive/:'.
_DIR_RESTREINT;
if (@is_dir(_DIR_RACINE.'squelettes'))
$path = _DIR_RACINE.'squelettes/:' . $path;
foreach (explode(':', $path) as $dir) {
if (strlen($dir) AND substr($dir,-1) != '/')
$dir .= "/";
$path_base[] = $dir;
}
$path_full = $path_base;
// Et le(s) dossier(s) des squelettes nommes
if (strlen($GLOBALS['dossier_squelettes']))
foreach (array_reverse(explode(':', $GLOBALS['dossier_squelettes'])) as $d)
array_unshift($path_full, ($d[0] == '/' ? '' : _DIR_RACINE) . $d . '/');
$GLOBALS['path_sig'] = md5(serialize($path_full));
if (strlen($dir_path)){
cerdic
a validé
$tete = "";
if (reset($path_base)==_DIR_RACINE.'squelettes/')
$tete = array_shift($path_base);
$dirs = array_reverse(explode(':',$dir_path));
foreach($dirs as $dir_path){
#if ($dir_path{0}!='/')
# $dir_path = $dir_path;
if (substr($dir_path,-1) != '/')
$dir_path .= "/";
if (!in_array($dir_path,$path_base))
array_unshift($path_base,$dir_path);
cerdic
a validé
if (strlen($tete))
array_unshift($path_base,$tete);
$path_full = $path_base;
// Et le(s) dossier(s) des squelettes nommes
if (strlen($GLOBALS['dossier_squelettes']))
foreach (array_reverse(explode(':', $GLOBALS['dossier_squelettes'])) as $d)
array_unshift($path_full, ($d[0] == '/' ? '' : _DIR_RACINE) . $d . '/');
$GLOBALS['path_sig'] = md5(serialize($path_full));
return $path_full;
}
// http://doc.spip.org/@creer_chemin
function creer_chemin() {
$path_a = _chemin();
static $c = '';
// on calcule le chemin si le dossier skel a change
if ($c != $GLOBALS['dossier_squelettes']) {
// assurer le non plantage lors de la montee de version :
$c = $GLOBALS['dossier_squelettes'];
$path_a = _chemin(''); // forcer un recalcul du chemin
}
return $path_a;
}
function lister_themes_prives(){
static $themes = null;
if (is_null($themes)){
$prefs = $GLOBALS['visiteur_session']['prefs'];
if (is_string($prefs))
$prefs = unserialize($GLOBALS['visiteur_session']['prefs']);
if (
((isset($prefs['theme']) AND $theme = $prefs['theme'])
OR (isset($GLOBALS['theme_prive_defaut']) AND $theme = $GLOBALS['theme_prive_defaut']))
AND $theme != _SPIP_THEME_PRIVE)
array_unshift($themes,$theme); // placer le theme choisi en tete
function find_in_theme($file, $subdir='', $include=false){
static $themefiles=array();
if (isset($themefiles["$subdir$file"])) return $themefiles["$subdir$file"];
$themes = lister_themes_prives();
foreach($themes as $theme){
if ($f = find_in_path($file,"prive/themes/$theme/$subdir",$include))
return $themefiles["$subdir$file"] = $f;
spip_log("$file introuvable dans le theme prive ".reset($themes),'theme');
return $themefiles["$subdir$file"] = "";
// Cherche une image dans les dossiers images
// gere le renommage des icones de facon temporaire (le temps de la migration)
// definis par _NOM_IMG_PACK et _DIR_IMG_PACK
// peut se trouver dans un dossier plugin, donc on passe par un find_in_path si elle n'est pas
// dans _DIR_IMG_PACK
// gerer le cas d'un double appel en evitant de refaire le travail inutilement
if (strpos($icone,"/")!==false AND file_exists($icone)) return $icone;
// si c'est un nom d'image complet (article-24.png) essayer de le renvoyer direct
if (preg_match(',[.](png|gif|jpg)$,',$icone) AND $f = find_in_theme("images/$icone"))
cerdic
a validé
return $f;
// sinon passer par le module de renommage
if (is_null($icone_renommer))
$icone_renommer = charger_fonction('icone_renommer','inc',true);
if ($icone_renommer){
list($icone,$fonction) = $icone_renommer($icone,"");
if (file_exists($icone))
return $icone;
}
return find_in_path ($icone, _NOM_IMG_PACK);
}
//
// chercher un fichier $file dans le SPIP_PATH
// si on donne un sous-repertoire en 2e arg optionnel, il FAUT le / final
// si 3e arg vrai, on inclut si ce n'est fait.
// http://doc.spip.org/@find_in_path
function find_in_path ($file, $dirname='', $include=false) {
static $inc = array(); # cf http://trac.rezo.net/trac/spip/changeset/14743
static $c = '';
// on calcule le chemin si le dossier skel a change
if ($c != $GLOBALS['dossier_squelettes']){
// assurer le non plantage lors de la montee de version :
$c = $GLOBALS['dossier_squelettes'];
creer_chemin(); // forcer un recalcul du chemin et la mise a jour de path_sig
}
if (isset($GLOBALS['path_files'][$GLOBALS['path_sig']][$dirname][$file])) {
if (!$GLOBALS['path_files'][$GLOBALS['path_sig']][$dirname][$file])
if ($include AND !isset($inc[$dirname][$file])) {
include_once _ROOT_CWD . $GLOBALS['path_files'][$GLOBALS['path_sig']][$dirname][$file];
$inc[$dirname][$file] = $inc[''][$dirname . $file] = true;
}
return $GLOBALS['path_files'][$GLOBALS['path_sig']][$dirname][$file];
$dirname .= substr($file, 0, ++$a);
$file = substr($file, $a);
foreach(creer_chemin() as $dir) {
if (!isset($dirs[$a = $dir . $dirname]))
$dirs[$a] = (is_dir(_ROOT_CWD . $a) || !$a) ;
if ($dirs[$a]) {
if (file_exists(_ROOT_CWD . ($a .= $file))) {
if ($include AND !isset($inc[$dirname][$file])) {
include_once _ROOT_CWD . $a;
$inc[$dirname][$file] = $inc[''][$dirname . $file] = true;
}
if (!defined('_SAUVER_CHEMIN'))
define('_SAUVER_CHEMIN',true);
return $GLOBALS['path_files'][$GLOBALS['path_sig']][$dirname][$file] = $GLOBALS['path_files'][$GLOBALS['path_sig']][''][$dirname . $file] = $a;
}
if ($include){
spip_log("include_spip $dirname$file non trouve");
if ($include==='required'){
echo '<pre>',
"<strong>Erreur Fatale</strong><br />";
if (function_exists('debug_print_backtrace'))
echo debug_print_backtrace();
echo '</pre>';
die("Erreur interne: ne peut inclure $dirname$file");
}
}
if (!defined('_SAUVER_CHEMIN'))
define('_SAUVER_CHEMIN',true);
return $GLOBALS['path_files'][$GLOBALS['path_sig']][$dirname][$file] = $GLOBALS['path_files'][$GLOBALS['path_sig']][''][$dirname . $file] = false;
function clear_path_cache(){
$GLOBALS['path_files'] = array();
spip_unlink(_CACHE_CHEMIN);
}
// charger le path des plugins
if (@is_readable(_CACHE_PLUGINS_PATH)){
include_once(_CACHE_PLUGINS_PATH);
}
$GLOBALS['path_files'] = array();
// si le visiteur est admin,
// on ne recharge pas le cache pour forcer sa mise a jour
if (
// la session n'est pas encore chargee a ce moment, on ne peut donc pas s'y fier
//AND (!isset($GLOBALS['visiteur_session']['statut']) OR $GLOBALS['visiteur_session']['statut']!='0minirezo')
// utiliser le cookie est un pis aller qui marche 'en general'
// on blinde par un second test au moment de la lecture de la session
// !isset($_COOKIE[$GLOBALS['cookie_prefix'].'_admin'])
!_request('var_mode')
cerdic
a validé
// on essaye de lire directement sans verrou pour aller plus vite