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
cerdic
a validé
**/
cerdic
a validé
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.
gilles.vincent
a validé
function charger_fonction($nom, $dossier = 'exec', $continue = false) {
static $echecs = array();
marcimat
a validé
if (strlen($dossier) and substr($dossier, -1) != '/') {
cerdic
a validé
$dossier .= '/';
}
$f = str_replace('/', '_', $dossier) . $nom;
cerdic
a validé
if (function_exists($f)) {
return $f;
cerdic
a validé
}
if (function_exists($g = $f . '_dist')) {
return $g;
cerdic
a validé
}
cerdic
a validé
if (isset($echecs[$f])) {
return $echecs[$f];
}
// Sinon charger le fichier de declaration si plausible
cerdic
a validé
if (!preg_match(',^\w+$,', $f)) {
if ($continue) {
return false;
} //appel interne, on passe
include_spip('inc/minipres');
echo minipres();
exit;
}
// passer en minuscules (cf les balises de formulaires)
// et inclure le fichier
cerdic
a validé
if (!$inc = include_spip($dossier . ($d = strtolower($nom)))
// si le fichier truc/machin/nom.php n'existe pas,
// la fonction peut etre definie dans truc/machin.php qui regroupe plusieurs petites fonctions
marcimat
a validé
and strlen(dirname($dossier)) and dirname($dossier) != '.'
cerdic
a validé
) {
include_spip(substr($dossier, 0, -1));
}
if (function_exists($f)) {
return $f;
}
if (function_exists($g)) {
return $g;
}
cerdic
a validé
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>' . spip_htmlentities($d) . '</b>')),
array('all_inline'=>true,'status'=>404));
/**
* Inclusion unique avec verification d'existence du fichier + log en crash sinon
cerdic
a validé
*
* @param string $file
* @return bool
*/
cerdic
a validé
function include_once_check($file) {
if (file_exists($file)) {
include_once $file;
return true;
}
$crash = (isset($GLOBALS['meta']['message_crash_plugins']) ? unserialize($GLOBALS['meta']['message_crash_plugins']) : '');
cerdic
a validé
$crash = ($crash ? $crash : array());
$crash[$file] = true;
cerdic
a validé
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é
cerdic
a validé
**/
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()
cerdic
a validé
* @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é
cerdic
a validé
**/
function require_spip($f) {
return find_in_path($f . '.php', '', 'required');
}
kent1
a validé
/**
* Exécute une fonction (appellée par un pipeline) avec la donnée transmise.
kent1
a validé
* 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
kent1
a validé
* Cf. compose_filtres dans references.php, qui est la
* version compilee de cette fonctionnalite
* appel unitaire d'une fonction du pipeline
* utilisee dans le script pipeline precompile
kent1
a validé
* on passe $val par reference pour limiter les allocations memoire
* @param string $fonc
* Nom de la fonction appelée par le pipeline
kent1
a validé
* @param string|array $val
kent1
a validé
* @return string|array $val
cerdic
a validé
**/
function minipipe($fonc, &$val) {
Fil
a validé
// fonction
cerdic
a validé
if (function_exists($fonc)) {
Fil
a validé
$val = call_user_func($fonc, $val);
cerdic
a validé
} // Class::Methode
else {
if (preg_match("/^(\w*)::(\w*)$/S", $fonc, $regs)
marcimat
a validé
and $methode = array($regs[1], $regs[2])
and is_callable($methode)
cerdic
a validé
) {
$val = call_user_func($methode, $val);
} else {
spip_log("Erreur - '$fonc' non definie !");
}
}
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
/**
* Appel d’un pipeline
*
* Exécute le pipeline souhaité, éventuellement avec des données initiales.
* Chaque plugin qui a demandé à voir ce pipeline vera sa fonction spécifique appelée.
* Les fonctions (des plugins) appelées peuvent modifier à leur guise le contenu.
*
* Deux types de retours. Si `$val` est un tableau de 2 éléments, avec une clé `data`
* on retourne uniquement ce contenu (`$val['data']`) sinon on retourne tout `$val`.
*
*
* @example
* Appel du pipeline `pre_insertion`
* ```
* $champs = pipeline('pre_insertion', array(
* 'args' => array('table' => 'spip_articles'),
* 'data' => $champs
* ));
* ```
*
* @param string $action
* Nom du pipeline
* @param null|string|array $val
* Données à l’entrée du pipeline
* @return mixed|null
* Résultat
*/
gilles.vincent
a validé
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
cerdic
a validé
if (!($ok = @is_readable($charger))) {
cerdic
a validé
}
}
// appliquer notre fonction si elle existe
cerdic
a validé
$fonc = 'execute_pipeline_' . strtolower($action);
if (function_exists($fonc)) {
$val = $fonc($val);
cerdic
a validé
} // plantage ?
else {
cerdic
a validé
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)
marcimat
a validé
and count($val) == 2
and (array_key_exists('data', $val))
cerdic
a validé
) {
cerdic
a validé
}
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`
* Les différents niveaux possibles sont :
*
* - `_LOG_HS` : écrira 'HS' au début de la ligne logguée
* - `_LOG_ALERTE_ROUGE` : 'ALERTE'
* - `_LOG_CRITIQUE` : 'CRITIQUE'
* - `_LOG_ERREUR` : 'ERREUR'
* - `_LOG_AVERTISSEMENT` : 'WARNING'
* - `_LOG_INFO_IMPORTANTE` : '!INFO'
* - `_LOG_INFO` : 'info'
* - `_LOG_DEBUG` : 'debug'
*
* 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 compatibilité ascendante.
cerdic
a validé
function spip_log($message = null, $name = null) {
static $pre = array();
cerdic
a validé
preg_match('/^([a-z_]*)\.?(\d)?$/iS', (string)$name, $regs);
marcimat
a validé
if (!isset($regs[1]) or !$logname = $regs[1]) {
$logname = null;
cerdic
a validé
}
marcimat
a validé
if (!isset($regs[2]) or !$niveau = $regs[2]) {
$niveau = _LOG_INFO;
cerdic
a validé
}
if ($niveau <= (defined('_LOG_FILTRE_GRAVITE') ? _LOG_FILTRE_GRAVITE : _LOG_INFO_IMPORTANTE)) {
cerdic
a validé
if (!$pre) {
cerdic
a validé
_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');
}
cerdic
a validé
if (!is_string($message)) {
$message = print_r($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
cerdic
a validé
**/
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.
cerdic
a validé
**/
gilles.vincent
a validé
function _request($var, $c = false) {
cerdic
a validé
if (is_array($c)) {
return isset($c[$var]) ? $c[$var] : null;
}
cerdic
a validé
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')
marcimat
a validé
and _AJAX
and isset($GLOBALS['meta']['charset'])
and $GLOBALS['meta']['charset'] != 'utf-8'
and is_string($a)
cerdic
a validé
// check rapide mais pas fiable
marcimat
a validé
and preg_match(',[\x80-\xFF],', $a)
cerdic
a validé
// check fiable
marcimat
a validé
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 Tableau de données (sinon utilise `$_GET` et `$_POST`)
* @return array|bool
* - array $c complété si un $c est transmis,
* - false sinon
cerdic
a validé
**/
function set_request($var, $val = null, $c = false) {
if (is_array($c)) {
unset($c[$var]);
cerdic
a validé
if ($val !== null) {
$c[$var] = $val;
cerdic
a validé
}
return $c;
}
unset($_GET[$var]);
cerdic
a validé
if ($val !== null) {
cerdic
a validé
}
return false; # n'affecte pas $c
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
/**
* Sanitizer une valeur *SI* elle provient du GET ou POST
* Utile dans les squelettes pour les valeurs qu'on attrape dans le env,
* dont on veut permettre à un squelette de confiance appelant de fournir une valeur complexe
* mais qui doit etre nettoyee si elle provient de l'URL
*
* On peut sanitizer
* - une valeur simple : `$where = spip_sanitize_from_request($value, 'where')`
* - un tableau en partie : `$env = spip_sanitize_from_request($env, ['key1','key2'])`
* - un tableau complet : `$env = spip_sanitize_from_request($env, '*')`
*
* @param string|array $value
* @param string|array $key
* @param string $sanitize_function
* @return array|mixed|string
*/
function spip_sanitize_from_request($value, $key, $sanitize_function='entites_html') {
if (is_array($value)) {
if ($key=='*') {
$key = array_keys($value);
}
if (!is_array($key)) {
$key = [$key];
}
foreach ($key as $k) {
if (!empty($value[$k])) {
$value[$k] = spip_sanitize_from_request($value[$k], $k, $sanitize_function);
}
}
return $value;
}
// si la valeur vient des GET ou POST on la sanitize
if (!empty($value) and $value == _request($key)) {
$value = $sanitize_function($value);
}
return $value;
}
* Tester si une URL est absolue
*
* On est sur le web, on exclut certains protocoles,
* notamment 'file://', 'php://' et d'autres…
* @param string $url
cerdic
a validé
function tester_url_absolue($url) {
$url = trim($url);
if (preg_match(";^([a-z]{3,7}:)?//;Uims", $url, $m)) {
if (
isset($m[1])
and $p = strtolower(rtrim($m[1], ':'))
and in_array($p, array('file', 'php', 'zlib', 'glob', 'phar', 'ssh2', 'rar', 'ogg', 'expect', 'zip'))
) {
return false;
}
return true;
}
return false;
* Prend une URL et lui ajoute/retire un paramètre
* @filtre
* @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
cerdic
a validé
function parametre_url($url, $c, $v = null, $sep = '&') {
// requete erronnee : plusieurs variable dans $c et aucun $v
marcimat
a validé
if (strpos($c, "|") !== false and is_null($v)) {
return null;
cerdic
a validé
}
// lever l'#ancre
if (preg_match(',^([^#]*)(#.*)$,', $url, $r)) {
$url = $r[1];
$ancre = $r[2];
cerdic
a validé
} else {
$ancre = '';
cerdic
a validé
}
// eclater
$url = preg_split(',[?]|&|&,', $url);
// recuperer la base
$a = array_shift($url);
cerdic
a validé
if (!$a) {
$a = './';
}
cerdic
a validé
$regexp = ',^(' . str_replace('[]', '\[\]', $c) . '[[]?[]]?)(=.*)?$,';
$ajouts = array_flip(explode('|', $c));
$u = is_array($v) ? $v : rawurlencode($v);
cerdic
a validé
$testv = (is_array($v) ? count($v) : strlen($v));
$v_read = null;
// lire les variables et agir
foreach ($url as $n => $val) {
if (preg_match($regexp, urldecode($val), $r)) {
cerdic
a validé
if ($v === null) {
// c'est un tableau, on memorise les valeurs
cerdic
a validé
if (substr($r[1], -2) == "[]") {
if (!$v_read) {
$v_read = array();
}
$v_read[] = $r[2] ? substr($r[2], 1) : '';
} // c'est un scalaire, on retourne direct
else {
cerdic
a validé
return $r[2] ? substr($r[2], 1) : '';
cerdic
a validé
} // suppression
elseif (!$testv) {
unset($url[$n]);
// Ajout. Pour une variable, remplacer au meme endroit,
// pour un tableau ce sera fait dans la prochaine boucle
cerdic
a validé
elseif (substr($r[1], -2) != '[]') {
$url[$n] = $r[1] . '=' . $u;
unset($ajouts[$r[1]]);
}
// Pour les tableaux on laisse tomber les valeurs de
// départ, on remplira à l'étape suivante
else {
}
}
// traiter les parametres pas encore trouves
cerdic
a validé
if ($v === null
marcimat
a validé
and $args = func_get_args()
and count($args) == 2
cerdic
a validé
) {
return $v_read; // rien trouve ou un tableau
cerdic
a validé
foreach ($ajouts as $k => $n) {
if (!is_array($v)) {
$url[] = $k . '=' . $u;
} else {
$id = (substr($k, -2) == '[]') ? $k : ($k . "[]");
cerdic
a validé
$url[] = $id . '=' . (is_array($w) ? 'Array' : $w);
// eliminer les vides
$url = array_filter($url);
// recomposer l'adresse
cerdic
a validé
if ($url) {
$a .= '?' . join($sep, $url);
cerdic
a validé
}
return $a . $ancre;
/**
* Ajoute (ou retire) une ancre sur une URL
*
* L’ancre est nettoyée : on translitère, vire les non alphanum du début,
* et on remplace ceux à l'interieur ou au bout par `-`
*
* @example
* - `$url = ancre_url($url, 'navigation'); // => mettra l’ancre #navigation
* - `$url = ancre_url($url, ''); // => enlèvera une éventuelle ancre
* @uses translitteration()
* @param string $url
* @param string $ancre
* @return string
*/
function ancre_url($url, $ancre) {
// lever l'#ancre
if (preg_match(',^([^#]*)(#.*)$,', $url, $r)) {
$url = $r[1];
}
cerdic
a validé
if (preg_match('/[^-_a-zA-Z0-9]+/S', $ancre)) {
if (!function_exists('translitteration')) {
include_spip('inc/charsets');
cerdic
a validé
}
$ancre = preg_replace(
array('/^[^-_a-zA-Z0-9]+/', '/[^-_a-zA-Z0-9]/'),
array('', '-'),
translitteration($ancre)
);
}
cerdic
a validé
return $url . (strlen($ancre) ? '#' . $ancre : '');
}
/**
*
* @param string|null $reset
* @return string
*/
cerdic
a validé
function nettoyer_uri($reset = null) {
static $done = false;
static $propre = '';
cerdic
a validé
if (!is_null($reset)) {
return $propre = $reset;
}
if ($done) {
return $propre;
}
return $propre = nettoyer_uri_var($GLOBALS['REQUEST_URI']);
}
/**
* Nettoie une request_uri des paramètres var_xxx
*
* Attention, la regexp doit suivre _CONTEXTE_IGNORE_VARIABLES défini au début de public/assembler.php
*
* @param $request_uri
* @return string
*/
function nettoyer_uri_var($request_uri) {
$uri1 = $request_uri;
do {
$uri = $uri1;
$uri1 = preg_replace(',([?&])(var_[^=&]*|PHPSESSID|fbclid|utm_[^=&]*)=[^&]*(&|$),i',
'\1', $uri);
cerdic
a validé
} while ($uri <> $uri1);
return preg_replace(',[?&]$,', '', $uri1);
}
/**
* Donner l'URL de base d'un lien vers "soi-meme", modulo les trucs inutiles
*
* @param string $amp
* Style des esperluettes
* @param bool $root
* @return string
* URL vers soi-même
cerdic
a validé
**/
function self($amp = '&', $root = false) {
$url = nettoyer_uri();
if (!$root
marcimat
a validé
and (
// si pas de profondeur on peut tronquer
cerdic
a validé
$GLOBALS['profondeur_url'] < (_DIR_RESTREINT ? 1 : 2)
// sinon c'est OK si _SET_HTML_BASE a ete force a false
marcimat
a validé
or (defined('_SET_HTML_BASE') and !_SET_HTML_BASE))
cerdic
a validé
) {
$url = preg_replace(',^[^?]*/,', '', $url);
cerdic
a validé
}
// ajouter le cas echeant les variables _POST['id_...']
cerdic
a validé
foreach ($_POST as $v => $c) {
if (substr($v, 0, 3) == 'id_') {
$url = parametre_url($url, $v, $c, '&');
cerdic
a validé
}
}
// supprimer les variables sans interet
if (test_espace_prive()) {
cerdic
a validé
$url = preg_replace(',([?&])('
. 'lang|show_docs|'
. 'changer_lang|var_lang|action)=[^&]*,i', '\1', $url);
$url = preg_replace(',([?&])[&]+,', '\1', $url);
$url = preg_replace(',[&]$,', '\1', $url);
}
include_spip('inc/filtres_mini');
$url = spip_htmlspecialchars($url);
b_b
a validé
cerdic
a validé
$url = str_replace(array("'", '"', '<', '[', ']', ':'), array('%27', '%22', '%3C', '%5B', '%5D', '%3A'), $url);
// & ?
cerdic
a validé
if ($amp != '&') {
$url = str_replace('&', $amp, $url);
cerdic
a validé
}
// 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
*/
cerdic
a validé
function test_plugin_actif($plugin) {
marcimat
a validé
return ($plugin and defined('_DIR_PLUGIN_' . strtoupper($plugin))) ? true : false;
cerdic
a validé
}
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))
* _T("email_sujet", array('spip_lang'=>$lang_usager))
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. la variable spip_lang permet de forcer la langue
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
* - bool sanitize : nettoyer le html suspect dans les arguments
* @return string
* Texte
cerdic
a validé
*/
gilles.vincent
a validé
function _T($texte, $args = array(), $options = array()) {
cerdic
a validé
static $traduire = false;
$o = array('class' => '', 'force' => true, 'sanitize' => true);
cerdic
a validé
if ($options) {
cerdic
a validé
// support de l'ancien argument $class
cerdic
a validé
if (is_string($options)) {
$options = array('class' => $options);
}
$o = array_merge($o, $options);
cerdic
a validé
}
cerdic
a validé
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
cerdic
a validé
if (isset($args['spip_lang'])) {
RastaPopoulos
a validé
$lang = $args['spip_lang'];
// On l'enleve pour ne pas le passer au remplacement
unset($args['spip_lang']);
cerdic
a validé
} // Sinon on prend la langue du contexte
RastaPopoulos
a validé
$lang = $GLOBALS['spip_lang'];
}
$text = $traduire($texte, $lang);
cerdic
a validé
if (!strlen($text)) {
if (!$o['force']) {
cerdic
a validé
return '';
cerdic
a validé
}
cerdic
a validé
$text = $texte;
// pour les chaines non traduites, assurer un service minimum
marcimat
a validé
if (!$GLOBALS['test_i18n'] and (_request('var_mode') != 'traduction')) {
$text = str_replace('_', ' ',
cerdic
a validé
(($n = strpos($text, ':')) === false ? $texte :
substr($texte, $n + 1)));
cerdic
a validé
}
$o['class'] = null;
}
return _L($text, $args, $o);
/**
* 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 array $options
* - string class : nom d'une classe a ajouter sur un span pour encapsuler la chaine
* - bool sanitize : nettoyer le html suspect dans les arguments
* @return string
* Texte
*/
function _L($text, $args = array(), $options = array()) {
$f = $text;
$defaut_options = array(
'class' => null,
'sanitize' => true,
);
// support de l'ancien argument $class
if ($options and is_string($options)) {
$options = array('class' => $options);
}
if (is_array($options)) {
$options += $defaut_options;
} else {
$options = $defaut_options;
}
if (is_array($args) and count($args)) {
if (!function_exists('interdire_scripts')) {
include_spip('inc/texte');
}
if (!function_exists('echapper_html_suspect')) {
include_spip('inc/texte_mini');
}
foreach ($args as $name => $value) {
cerdic
a validé
if (strpos($text, "@$name@") !== false) {
if ($options['sanitize']) {
$value = echapper_html_suspect($value);
$value = interdire_scripts($value, -1);
}
if (!empty($options['class'])) {
$value = "<span class='".$options['class']."'>$value</span>";
}
$text = str_replace("@$name@", $value, $text);
cerdic
a validé
unset($args[$name]);
}
// Si des variables n'ont pas ete inserees, le signaler
// (chaines de langues pas a jour)
cerdic
a validé
if ($args) {
spip_log("$f: variables inutilisees " . join(', ', array_keys($args)), _LOG_DEBUG);
}
if (($GLOBALS['test_i18n'] or (_request('var_mode') == 'traduction')) and is_null($options['class'])) {
return "<span class=debug-traduction-erreur>$text</span>";
cerdic
a validé
} else {
return $text;
cerdic
a validé
}
/**
* Retourne un joli chemin de répertoire
*
* Pour afficher `ecrire/action/` au lieu de `action/` dans les messages
* ou `tmp/` au lieu de `../tmp/`
*
* @param stirng $rep Chemin d’un répertoire
* @return string
*/
function joli_repertoire($rep) {
cerdic
a validé
$a = substr($rep, 0, 1);
marcimat
a validé
if ($a <> '.' and $a <> '/') {
cerdic
a validé
$rep = (_DIR_RESTREINT ? '' : _DIR_RESTREINT_ABS) . $rep;
}
$rep = preg_replace(',(^\.\.\/),', '', $rep);
cerdic
a validé
return $rep;
}
/**
* Débute ou arrête un chronomètre et retourne sa valeur
*
* On exécute 2 fois la fonction, la première fois pour démarrer le chrono,
* la seconde fois pour l’arrêter et récupérer la valeur
*
* @example
* ```
* spip_timer('papoter');
* // actions
* $duree = spip_timer('papoter');
* ```
*
* @param string $t
* Nom du chronomètre
* @param bool $raw
* - false : retour en texte humainement lisible
* - true : retour en millisecondes
* @return float|int|string|void
*/
gilles.vincent
a validé
function spip_timer($t = 'rien', $raw = false) {
cerdic
a validé
$a = time();
$b = microtime();
// microtime peut contenir les microsecondes et le temps
cerdic
a validé
$b = explode(' ', $b);
if (count($b) == 2) {
$a = end($b);
} // plus precis !
if (!isset($time[$t])) {
$time[$t] = $a + $b;
} else {
$p = ($a + $b - $time[$t]) * 1000;
unset($time[$t]);
# echo "'$p'";exit;
cerdic
a validé
if ($raw) {
return $p;
}
if ($p < 1000) {
$s = '';
cerdic
a validé
} else {
$s = sprintf("%d ", $x = floor($p / 1000));
$p -= ($x * 1000);
cerdic
a validé
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://code.spip.net/@spip_touch
gilles.vincent
a validé
function spip_touch($fichier, $duree = 0, $touch = true) {
if ($duree) {
clearstatcache();
if ((@$f = filemtime($fichier)) and ($f >= time() - $duree)) {
return false;
cerdic
a validé
}
cerdic
a validé
if ($touch !== false) {
if (!@touch($fichier)) {
spip_unlink($fichier);
@touch($fichier);
};
@chmod($fichier, _SPIP_CHMOD & ~0111);