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. *
\***************************************************************************/
/**
* Utilitaires indispensables autour du serveur Http.
*
* @package SPIP\Core\Utilitaires
**/
if (!defined('_ECRIRE_INC_VERSION')) return;
* Cherche une fonction surchargeable et en retourne le nom exact,
* après avoir chargé le fichier la contenant si nécessaire.
*
* Charge un fichier (suivant les chemins connus) et retourne si elle existe
* le nom de la fonction homonyme `$dir_$nom`, ou suffixé `$dir_$nom_dist`
*
* Peut être appelé plusieurs fois, donc optimisé.
* @api
* @uses include_spip() Pour charger le fichier
* @example
* ```
* $envoyer_mail = charger_fonction('envoyer_mail', 'inc');
* $envoyer_mail($email, $sujet, $texte);
* ```
*
* Nom de la fonction (et du fichier)
* Nom du dossier conteneur
* true pour ne pas râler si la fonction n'est pas trouvée
* Nom de la fonction, ou false.
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)){
if ($continue) return false; //appel interne, on passe
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é
/**
* Inclut un fichier PHP (en le cherchant dans les chemins)
*
* @api
* @uses find_in_path()
* @example
* ```
* include_spip('inc/texte');
* ```
*
* @param string $f
* Nom du fichier (sans l'extension)
* @param bool $include
* - true pour inclure le fichier,
* - false ne fait que le chercher
* @return string|bool
* - false : fichier introuvable
* - string : chemin du fichier trouvé
**/
function include_spip($f, $include = true) {
return find_in_path($f . '.php', '', $include);
}
/**
* Requiert un fichier PHP (en le cherchant dans les chemins)
*
* @uses find_in_path()
* @see include_spip()
* @example
* ```
* require_spip('inc/texte');
* ```
*
* @param string $f
* Nom du fichier (sans l'extension)
* @return string|bool
* - false : fichier introuvable
* - string : chemin du fichier trouvé
**/
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 événements
*
* Signature : `spip_log(message[,niveau|type|type.niveau])`
*
* Le niveau de log par défaut est la valeur de la constante `_LOG_INFO`
*
* @example
* ```
* spip_log($message)
* spip_log($message,'recherche')
* spip_log($message,_LOG_DEBUG)
* spip_log($message,'recherche.'._LOG_DEBUG)
* ```
*
* @api
* @uses inc_log_dist()
*
* @param string $message
* @param string|int $name
*
* - int indique le niveau de log, tel que `_LOG_DEBUG`
* - string indique le type de log
* - `string.int` indique les 2 éléments.
* Cette dernière notation est controversée mais le 3ème
* paramètre est planté pour cause de compat ascendante.
function spip_log($message=NULL, $name=NULL) {
static $pre = array();
preg_match('/^([a-z_]*)\.?(\d)?$/iS', (string) $name, $regs);
$logname = null;
$niveau = _LOG_INFO;
if ($niveau <= (defined('_LOG_FILTRE_GRAVITE') ? _LOG_FILTRE_GRAVITE : _LOG_INFO_IMPORTANTE)) {
_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);
/**
* Enregistrement des journaux
*
* @uses inc_journal_dist()
* @param string $phrase Texte du journal
* @param array $opt Tableau d'options
**/
marcimat
a validé
function journal($phrase, $opt = array()) {
$journal = charger_fonction('journal', 'inc');
$journal($phrase, $opt);
}
/**
* Renvoie le `$_GET` ou le `$_POST` émis par l'utilisateur
* ou pioché dans un tableau transmis
*
* @api
* @param string $var
* Clé souhaitée
* @param bool|array $c
* Tableau transmis (sinon cherche dans GET ou POST)
* @return mixed|null
* - null si la clé n'a pas été trouvée
* - la valeur de la clé sinon.
**/
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)
// check rapide mais pas fiable
AND preg_match(',[\x80-\xFF],', $a)
// check fiable
AND include_spip('inc/charsets')
AND is_utf8($a)
) {
return importer_charset($a, 'utf-8');
}
return $a;
}
/**
* Affecte une valeur à une clé (pour usage avec `_request()`)
*
* @see _request() Pour obtenir la valeur
* @note Attention au cas ou l'on fait `set_request('truc', NULL);`
*
* @param string $var Nom de la clé
* @param string $val Valeur à affecter
* @param bool|array $c Tableu de données (sinon utilise `$_GET` et `$_POST`)
* @return array|bool
* - array $c complété si un $c est transmis,
* - false sinon
**/
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 string $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 paramètre
* @filtre parametre_url
* @link http://www.spip.net/4255
* @example
* ```
* [(#SELF|parametre_url{suite,18})] (ajout)
* [(#SELF|parametre_url{suite,''})] (supprime)
* [(#SELF|parametre_url{suite[],1})] (tableaux valeurs multiples)
* ```
* @param string $url URL
* @param string $c Nom du paramètre
* @param string|array|null $v Valeur du paramètre
* @param string $sep Séparateur entre les paramètres
* @return string URL
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
*
* @param string|null $reset
* @return string
*/
function nettoyer_uri($reset = null)
{
static $done = false;
static $propre = '';
if (!is_null($reset)) return $propre=$reset;
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();
if (!$root
AND (
// si pas de profondeur on peut tronquer
$GLOBALS['profondeur_url']<(_DIR_RESTREINT?1:2)
// sinon c'est OK si _SET_HTML_BASE a ete force a false
OR (defined('_SET_HTML_BASE') AND !_SET_HTML_BASE))
)
$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
*
* @return bool
* true si c'est le cas, false sinon.
*/
function test_espace_prive() {
return defined('_ESPACE_PRIVE') ? _ESPACE_PRIVE : false;
}
cerdic
a validé
/**
* Vérifie la présence d'un plugin actif, identifié par son préfixe
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
*
* Traduit une clé de traduction en l'obtenant dans les fichiers de langues.
*
* @api
* @uses inc_traduire_dist()
* @uses _L()
* @example
* ```
* _T('bouton_enregistrer')
* _T('medias:image_tourner_droite')
* _T('medias:erreurs', array('nb'=>3)
* ```
*
cerdic
a validé
* @param string $texte
* Clé de traduction
cerdic
a validé
* @param array $args
* Couples (variable => valeur) pour passer des variables à la chaîne traduite
cerdic
a validé
* @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 string
* Texte
cerdic
a validé
*/
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
RastaPopoulos
a validé
$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
RastaPopoulos
a validé
$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'] AND (_request('var_mode') != 'traduction'))
$text = str_replace('_', ' ',
(($n = strpos($text,':')) === false ? $texte :
substr($texte, $n+1)));
$o['class'] = null;
}
cerdic
a validé
return _L($text, $args, $o['class']);
/**
* Remplace les variables `@...@` par leur valeur dans une chaîne de langue.
*
* Cette fonction est également appelée dans le code source de SPIP quand une
* chaîne n'est pas encore dans les fichiers de langue.
*
* @see _T()
* @example
* ```
* _L('Texte avec @nb@ ...', array('nb'=>3)
* ```
*
* @param string $text
* Texte
* @param array $args
* Couples (variable => valeur) à transformer dans le texte
* @param string|null $class
* Encapsule les valeurs dans un span avec cette classe si transmis.
* @return string
* Texte
*/
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'] OR (_request('var_mode') == 'traduction')) AND $class===null)
return "<span class=debug-traduction-erreur>$text</span>";
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);
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
* @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
* @staticvar int $queue_next_job_time
* @see queue_set_next_job_time()
* @param int|bool $force
* Utilisée par `queue_set_next_job_time()` pour mettre à jour la valeur :
*
* - si `true`, force la relecture depuis le fichier
* - si int, affecte la static directement avec la valeur
* @return int
*
* - `0` si un job est à traiter
* - `null` si la queue n'est pas encore initialisée
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
*/
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);
}
/**
* Produit une balise `<script>` valide
*
* @example
* ```
* echo http_script('alert("ok");');
* echo http_script('','js/jquery.js');
* ```
*
* @param string $script
* Code source du script
* @param string $src
* Permet de faire appel à un fichier javascript distant
* @param string $noscript
* Contenu de la balise `<noscript>`
* @return string
* Balise HTML `<script>` et son contenu
**/
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));
}
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
/**
* Gestion des chemins (ou path) de recherche de fichiers par SPIP
*
* Empile de nouveaux chemins (à la suite de ceux déjà présent, mais avant
* le répertoire squelettes ou les dossiers squelettes), si un reéertoire
* (ou liste de répertoires séparés par `:`) lui est passé en paramètre.
*
* Ainsi, si l'argument est de la forme `dir1:dir2:dir3`, ces 3 chemins sont placés
* en tete du path, dans cet ordre (hormis squelettes & la globale
* $dossier_squelette si definie qui resteront devant)
*
* Retourne dans tous les cas la liste des chemins.
*
* @note
* Cette fonction est appelée à plusieurs endroits et crée une liste
* de chemins finale à peu près de la sorte :
*
* - dossiers squelettes (si globale précisée)
* - squelettes/
* - plugins (en fonction de leurs dépendances) : ceux qui dépendent
* d'un plugin sont devant eux (ils peuvent surcharger leurs fichiers)
* - racine du site
* - squelettes-dist/
* - prive/
* - ecrire/
*
* @param string $dir_path
* - Répertoire(s) à empiler au path
* - '' provoque un recalcul des chemins.
* @return array
* Liste des chemins, par ordre de priorité.
**/
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);