/***************************************************************************\
* SPIP, Systeme de publication pour l'internet *
* *
- * Copyright (c) 2001-2014 *
+ * Copyright (c) 2001-2019 *
* 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;
+/**
+ * Déclaration de filtres pour les squelettes
+ *
+ * @package SPIP\Core\Filtres
+ **/
+if (!defined('_ECRIRE_INC_VERSION')) {
+ return;
+}
include_spip('inc/charsets');
include_spip('inc/filtres_mini');
+include_spip('inc/filtres_dates');
+include_spip('inc/filtres_selecteur_generique');
include_spip('base/objets');
include_spip('public/parametrer'); // charger les fichiers fonctions
/**
- * Charger un filtre depuis le php :
+ * Charger un filtre depuis le php
+ *
* - on inclue tous les fichiers fonctions des plugins et du skel
* - on appelle chercher_filtre
*
- * @param string $fonc
- * @param string $default
- * @return string
+ * Pour éviter de perdre le texte si le filtre demandé est introuvable,
+ * on transmet `filtre_identite_dist` en filtre par défaut.
+ *
+ * @uses filtre_identite_dist() Comme fonction par défaut
+ *
+ * @param string $fonc Nom du filtre
+ * @param string $default Filtre par défaut
+ * @return string Fonction PHP correspondante du filtre
*/
-function charger_filtre($fonc, $default='filtre_identite_dist') {
+function charger_filtre($fonc, $default = 'filtre_identite_dist') {
include_spip('public/parametrer'); // inclure les fichiers fonctions
return chercher_filtre($fonc, $default);
}
-function filtre_identite_dist($texte){return $texte;}
+/**
+ * Retourne le texte tel quel
+ *
+ * @param string $texte Texte
+ * @return string Texte
+ **/
+function filtre_identite_dist($texte) { return $texte; }
/**
- * http://doc.spip.org/@chercher_filtre
+ * Cherche un filtre
+ *
+ * Pour une filtre `F` retourne la première fonction trouvée parmis :
+ *
+ * - filtre_F
+ * - filtre_F_dist
+ * - F
+ *
+ * Peut gérer des appels par des fonctions statiques de classes tel que `Foo::Bar`
+ *
+ * En absence de fonction trouvée, retourne la fonction par défaut indiquée.
*
* @param string $fonc
+ * Nom du filtre
* @param null $default
+ * Nom du filtre appliqué par défaut si celui demandé n'est pas trouvé
* @return string
+ * Fonction PHP correspondante du filtre demandé
*/
-function chercher_filtre($fonc, $default=NULL) {
- if (!$fonc) return $default;
+function chercher_filtre($fonc, $default = null) {
+ if (!$fonc) {
+ return $default;
+ }
// Cas des types mime, sans confondre avec les appels de fonction de classe
// Foo::Bar
// qui peuvent etre avec un namespace : space\Foo::Bar
- if (preg_match(',^[\w]+/,',$fonc)){
- $nom = preg_replace(',\W,','_', $fonc);
+ if (preg_match(',^[\w]+/,', $fonc)) {
+ $nom = preg_replace(',\W,', '_', $fonc);
$f = chercher_filtre($nom);
// cas du sous-type MIME sans filtre associe, passer au type:
// si filtre_text_plain pas defini, passe a filtre_text
- if (!$f AND $nom!==$fonc)
- $f = chercher_filtre(preg_replace(',\W.*$,','', $fonc));
+ if (!$f and $nom !== $fonc) {
+ $f = chercher_filtre(preg_replace(',\W.*$,', '', $fonc));
+ }
+
return $f;
}
- foreach (
- array('filtre_'.$fonc, 'filtre_'.$fonc.'_dist', $fonc) as $f){
- if (isset( $GLOBALS['spip_matrice'][$f]) AND is_string($g = $GLOBALS['spip_matrice'][$f]))
- find_in_path($g,'', true);
- if (function_exists($f)
- OR (preg_match("/^(\w*)::(\w*)$/", $f, $regs)
- AND is_callable(array($regs[1], $regs[2]))
- )) {
+ foreach (array('filtre_' . $fonc, 'filtre_' . $fonc . '_dist', $fonc) as $f) {
+ trouver_filtre_matrice($f); // charge des fichiers spécifiques éventuels
+ // fonction ou name\space\fonction
+ if (is_callable($f)) {
+ return $f;
+ }
+ // méthode statique d'une classe Classe::methode ou name\space\Classe::methode
+ elseif (false === strpos($f, '::') and is_callable(array($f))) {
return $f;
}
}
+
return $default;
}
/**
* Applique un filtre
- *
+ *
* Fonction générique qui prend en argument l’objet (texte, etc) à modifier
* et le nom du filtre. Retrouve les arguments du filtre demandé dans les arguments
* transmis à cette fonction, via func_get_args().
*
* @see filtrer() Assez proche
- *
- * @param string $arg
- * Texte sur lequel appliquer le filtre
+ *
+ * @param mixed $arg
+ * Texte (le plus souvent) sur lequel appliquer le filtre
* @param string $filtre
- * Nom du filtre a appliquer
- * @param string $force
- * La fonction doit-elle retourner le texte ou rien ?
- * @return string
- * Texte avec le filtre appliqué s'il a été trouvé,
- * Texte sans le filtre appliqué s'il n'a pas été trouvé et que $force n'a
- * pas été fourni,
- * Chaîne vide si le filtre n'a pas été trouvé et que $force a été fourni.
-**/
-function appliquer_filtre($arg, $filtre, $force=NULL) {
+ * Nom du filtre à appliquer
+ * @param bool $force
+ * La fonction doit-elle retourner le texte ou rien si le filtre est absent ?
+ * @return string
+ * Texte traité par le filtre si le filtre existe,
+ * Texte d'origine si le filtre est introuvable et si $force à `true`
+ * Chaîne vide sinon (filtre introuvable).
+ **/
+function appliquer_filtre($arg, $filtre, $force = null) {
$f = chercher_filtre($filtre);
if (!$f) {
- if (!$force) return '';
- else return $arg;
+ if (!$force) {
+ return '';
+ } else {
+ return $arg;
+ }
}
$args = func_get_args();
array_shift($args); // enlever $arg
array_shift($args); // enlever $filtre
array_unshift($args, $arg); // remettre $arg
- return call_user_func_array($f,$args);
+ return call_user_func_array($f, $args);
}
-// http://doc.spip.org/@spip_version
+/**
+ * Retourne la version de SPIP
+ *
+ * Si l'on retrouve un numéro de révision SVN, il est ajouté entre crochets.
+ * Si effectivement le SPIP est installé par SVN, 'SVN' est ajouté avant sa révision.
+ *
+ * @global spip_version_affichee Contient la version de SPIP
+ * @uses version_svn_courante() Pour trouver le numéro de révision SVN
+ *
+ * @return string
+ * Version de SPIP
+ **/
function spip_version() {
$version = $GLOBALS['spip_version_affichee'];
- if ($svn_revision = version_svn_courante(_DIR_RACINE))
- $version .= ($svn_revision<0 ? ' SVN':'').' ['.abs($svn_revision).']';
+ if ($svn_revision = version_svn_courante(_DIR_RACINE)) {
+ $version .= ($svn_revision < 0 ? ' SVN' : '') . ' [' . abs($svn_revision) . ']';
+ }
+
return $version;
}
-//
-// Mention de la revision SVN courante de l'espace restreint standard
-// (numero non garanti pour l'espace public et en cas de mutualisation)
-// on est negatif si on est sur .svn, et positif si on utilise svn.revision
-// http://doc.spip.org/@version_svn_courante
+/**
+ * Retrouve un numéro de révision SVN d'un répertoire
+ *
+ * Mention de la révision SVN courante d'un répertoire
+ * Retourne un nombre négatif si on est sur .svn, et positif si on utilise svn.revision
+ *
+ * @param string $dir Chemin du répertoire
+ * @return int
+ *
+ * - 0 si aucune info trouvée
+ * - NN (entier) si info trouvée par svn.revision (créé par le générateur de paquet Zip)
+ * - -NN (entier) si info trouvée par .svn/entries
+ *
+ **/
function version_svn_courante($dir) {
- if (!$dir) $dir = '.';
+ if (!$dir) {
+ $dir = '.';
+ }
// version installee par paquet ZIP
- if (lire_fichier($dir.'/svn.revision', $c)
- AND preg_match(',Revision: (\d+),', $c, $d))
+ if (lire_fichier($dir . '/svn.revision', $c)
+ and preg_match(',Revision: (\d+),', $c, $d)
+ ) {
return intval($d[1]);
+ }
// version installee par SVN
- if (lire_fichier($dir . '/.svn/entries', $c)
- AND (
- (preg_match_all(
- ',committed-rev="([0-9]+)",', $c, $r1, PREG_PATTERN_ORDER)
- AND $v = max($r1[1])
- )
- OR
- (preg_match(',^\d.*dir[\r\n]+(\d+),ms', $c, $r1) # svn >= 1.4
- AND $v = $r1[1]
- )))
+ if (file_exists($dir . '/.svn/wc.db') && class_exists('SQLite3')) {
+ $db = new SQLite3($dir . '/.svn/wc.db');
+ $result = $db->query('SELECT changed_revision FROM nodes WHERE local_relpath = "" LIMIT 1');
+ if ($result) {
+ $row = $result->fetchArray();
+ if ($row['changed_revision'] != "") {
+ return -$row['changed_revision'];
+ }
+ }
+ } else if (lire_fichier($dir . '/.svn/entries', $c)
+ and (
+ (preg_match_all(
+ ',committed-rev="([0-9]+)",', $c, $r1, PREG_PATTERN_ORDER)
+ and $v = max($r1[1])
+ )
+ or
+ (preg_match(',^\d.*dir[\r\n]+(\d+),ms', $c, $r1) # svn >= 1.4
+ and $v = $r1[1]
+ ))
+ ) {
return -$v;
+ }
// Bug ou paquet fait main
return 0;
$GLOBALS['spip_matrice']['filtre_audio_x_pn_realaudio'] = 'inc/filtres_mime.php';
-// charge les fonctions graphiques et applique celle demandee
-// http://doc.spip.org/@filtrer
+/**
+ * Charge et exécute un filtre (graphique ou non)
+ *
+ * Recherche la fonction prévue pour un filtre (qui peut être un filtre graphique `image_*`)
+ * et l'exécute avec les arguments transmis à la fonction, obtenus avec `func_get_args()`
+ *
+ * @api
+ * @uses image_filtrer() Pour un filtre image
+ * @uses chercher_filtre() Pour un autre filtre
+ *
+ * @param string $filtre
+ * Nom du filtre à appliquer
+ * @return string
+ * Code HTML retourné par le filtre
+ **/
function filtrer($filtre) {
- if (isset($GLOBALS['spip_matrice'][$filtre]) and is_string($f = $GLOBALS['spip_matrice'][$filtre])){
- find_in_path($f,'', true);
- $GLOBALS['spip_matrice'][$filtre] = true;
- }
$tous = func_get_args();
- if (substr($filtre,0,6)=='image_' && $GLOBALS['spip_matrice'][$filtre])
+ if (trouver_filtre_matrice($filtre) and substr($filtre, 0, 6) == 'image_') {
return image_filtrer($tous);
- elseif($f = chercher_filtre($filtre)) {
+ } elseif ($f = chercher_filtre($filtre)) {
array_shift($tous);
return call_user_func_array($f, $tous);
- }
- else {
+ } else {
// le filtre n'existe pas, on provoque une erreur
- $msg = array('zbug_erreur_filtre', array('filtre'=>texte_script($filtre)));
+ $msg = array('zbug_erreur_filtre', array('filtre' => texte_script($filtre)));
erreur_squelette($msg);
return '';
}
}
-// fonction generique d'entree des filtres images
-// accepte en entree un texte complet, un img-log (produit par #LOGO_XX),
-// un tag <img ...> complet, ou encore un nom de fichier *local* (passer
-// le filtre |copie_locale si on veut l'appliquer a un document)
-// applique le filtre demande a chacune des occurrences
+/**
+ * Cherche un filtre spécial indiqué dans la globale `spip_matrice`
+ * et charge le fichier éventuellement associé contenant le filtre.
+ *
+ * Les filtres d'images par exemple sont déclarés de la sorte, tel que :
+ * ```
+ * $GLOBALS['spip_matrice']['image_reduire'] = true;
+ * $GLOBALS['spip_matrice']['image_monochrome'] = 'filtres/images_complements.php';
+ * ```
+ *
+ * @param string $filtre
+ * @return bool true si on trouve le filtre dans la matrice, false sinon.
+ */
+function trouver_filtre_matrice($filtre) {
+ if (isset($GLOBALS['spip_matrice'][$filtre]) and is_string($f = $GLOBALS['spip_matrice'][$filtre])) {
+ find_in_path($f, '', true);
+ $GLOBALS['spip_matrice'][$filtre] = true;
+ }
+ return !empty($GLOBALS['spip_matrice'][$filtre]);
+}
+
+
+/**
+ * Filtre `set` qui sauve la valeur en entrée dans une variable
+ *
+ * La valeur pourra être retrouvée avec `#GET{variable}`.
+ *
+ * @example
+ * `[(#CALCUL|set{toto})]` enregistre le résultat de `#CALCUL`
+ * dans la variable `toto` et renvoie vide.
+ * C'est équivalent à `[(#SET{toto, #CALCUL})]` dans ce cas.
+ * `#GET{toto}` retourne la valeur sauvegardée.
+ *
+ * @example
+ * `[(#CALCUL|set{toto,1})]` enregistre le résultat de `#CALCUL`
+ * dans la variable toto et renvoie la valeur. Cela permet d'utiliser
+ * d'autres filtres ensuite. `#GET{toto}` retourne la valeur.
+ *
+ * @filtre
+ * @param array $Pile Pile de données
+ * @param mixed $val Valeur à sauver
+ * @param string $key Clé d'enregistrement
+ * @param bool $continue True pour retourner la valeur
+ * @return mixed
+ */
+function filtre_set(&$Pile, $val, $key, $continue = null) {
+ $Pile['vars'][$key] = $val;
+ return $continue ? $val : '';
+}
+
+/**
+ * Filtre `setenv` qui enregistre une valeur dans l'environnement du squelette
+ *
+ * La valeur pourra être retrouvée avec `#ENV{variable}`.
+ *
+ * @example
+ * `[(#CALCUL|setenv{toto})]` enregistre le résultat de `#CALCUL`
+ * dans l'environnement toto et renvoie vide.
+ * `#ENV{toto}` retourne la valeur.
+ *
+ * `[(#CALCUL|setenv{toto,1})]` enregistre le résultat de `#CALCUL`
+ * dans l'environnement toto et renvoie la valeur.
+ * `#ENV{toto}` retourne la valeur.
+ *
+ * @filtre
+ *
+ * @param array $Pile
+ * @param mixed $val Valeur à enregistrer
+ * @param mixed $key Nom de la variable
+ * @param null|mixed $continue Si présent, retourne la valeur en sortie
+ * @return string|mixed Retourne `$val` si `$continue` présent, sinon ''.
+ */
+function filtre_setenv(&$Pile, $val, $key, $continue = null) {
+ $Pile[0][$key] = $val;
+ return $continue ? $val : '';
+}
-// http://doc.spip.org/@image_filtrer
-function image_filtrer($args){
+/**
+ * Filtre `debug` qui affiche un debug de la valeur en entrée
+ *
+ * Log la valeur dans `debug.log` et l'affiche si on est webmestre.
+ *
+ * @example
+ * `[(#TRUC|debug)]` affiche et log la valeur de `#TRUC`
+ * @example
+ * `[(#TRUC|debug{avant}|calcul|debug{apres}|etc)]`
+ * affiche la valeur de `#TRUC` avant et après le calcul,
+ * en précisant "avant" et "apres".
+ *
+ * @filtre
+ * @link http://www.spip.net/5695
+ * @param mixed $val La valeur à debugguer
+ * @param mixed|null $key Clé pour s'y retrouver
+ * @return mixed Retourne la valeur (sans la modifier).
+ */
+function filtre_debug($val, $key = null) {
+ $debug = (
+ is_null($key) ? '' : (var_export($key, true) . " = ")
+ ) . var_export($val, true);
+
+ include_spip('inc/autoriser');
+ if (autoriser('webmestre')) {
+ echo "<div class='spip_debug'>\n", $debug, "</div>\n";
+ }
+
+ spip_log($debug, 'debug');
+
+ return $val;
+}
+
+
+/**
+ * Exécute un filtre image
+ *
+ * Fonction générique d'entrée des filtres images.
+ * Accepte en entrée :
+ *
+ * - un texte complet,
+ * - un img-log (produit par #LOGO_XX),
+ * - un tag `<img ...>` complet,
+ * - un nom de fichier *local* (passer le filtre `|copie_locale` si on veut
+ * l'appliquer à un document distant).
+ *
+ * Applique le filtre demande à chacune des occurrences
+ *
+ * @param array $args
+ * Liste des arguments :
+ *
+ * - le premier est le nom du filtre image à appliquer
+ * - le second est le texte sur lequel on applique le filtre
+ * - les suivants sont les arguments du filtre image souhaité.
+ * @return string
+ * Texte qui a reçu les filtres
+ **/
+function image_filtrer($args) {
$filtre = array_shift($args); # enlever $filtre
$texte = array_shift($args);
- if (!strlen($texte)) return;
- find_in_path('filtres_images_mini.php','inc/', true);
+ if (!strlen($texte)) {
+ return;
+ }
+ find_in_path('filtres_images_mini.php', 'inc/', true);
statut_effacer_images_temporaires(true); // activer la suppression des images temporaires car le compilo finit la chaine par un image_graver
// Cas du nom de fichier local
- if ( strpos(substr($texte,strlen(_DIR_RACINE)),'..')===FALSE
- AND !preg_match(',^/|[<>]|\s,S', $texte)
- AND (
- file_exists(preg_replace(',[?].*$,','',$texte))
- OR preg_match(';^(\w{3,7}://);', $texte)
- )) {
- array_unshift($args,"<img src='$texte' />");
+ if (strpos(substr($texte, strlen(_DIR_RACINE)), '..') === false
+ and !preg_match(',^/|[<>]|\s,S', $texte)
+ and (
+ file_exists(preg_replace(',[?].*$,', '', $texte))
+ or tester_url_absolue($texte)
+ )
+ ) {
+ array_unshift($args, "<img src='$texte' />");
$res = call_user_func_array($filtre, $args);
statut_effacer_images_temporaires(false); // desactiver pour les appels hors compilo
return $res;
',(<([a-z]+) [^<>]*spip_documents[^<>]*>)?\s*(<img\s.*>),UimsS',
$texte, $tags, PREG_SET_ORDER)) {
foreach ($tags as $tag) {
- $class = extraire_attribut($tag[3],'class');
- if (!$class || (strpos($class,'no_image_filtrer')===FALSE)){
- array_unshift($args,$tag[3]);
+ $class = extraire_attribut($tag[3], 'class');
+ if (!$class or
+ (strpos($class, 'filtre_inactif') == false
+ // compat historique a virer en 3.2
+ and strpos($class, 'no_image_filtrer') === false)
+ ) {
+ array_unshift($args, $tag[3]);
if ($reduit = call_user_func_array($filtre, $args)) {
// En cas de span spip_documents, modifier le style=...width:
- if($tag[1]){
+ if ($tag[1]) {
$w = extraire_attribut($reduit, 'width');
- if (!$w AND preg_match(",width:\s*(\d+)px,S",extraire_attribut($reduit,'style'),$regs))
+ if (!$w and preg_match(",width:\s*(\d+)px,S", extraire_attribut($reduit, 'style'), $regs)) {
$w = $regs[1];
- if ($w AND ($style = extraire_attribut($tag[1], 'style'))){
+ }
+ if ($w and ($style = extraire_attribut($tag[1], 'style'))) {
$style = preg_replace(",width:\s*\d+px,S", "width:${w}px", $style);
$replace = inserer_attribut($tag[1], 'style', $style);
$texte = str_replace($tag[1], $replace, $texte);
}
}
// traiter aussi un eventuel mouseover
- if ($mouseover = extraire_attribut($reduit,'onmouseover')){
- if (preg_match(",this[.]src=['\"]([^'\"]+)['\"],ims", $mouseover, $match)){
+ if ($mouseover = extraire_attribut($reduit, 'onmouseover')) {
+ if (preg_match(",this[.]src=['\"]([^'\"]+)['\"],ims", $mouseover, $match)) {
$srcover = $match[1];
array_shift($args);
- array_unshift($args,"<img src='".$match[1]."' />");
+ array_unshift($args, "<img src='" . $match[1] . "' />");
$srcover_filter = call_user_func_array($filtre, $args);
- $srcover_filter = extraire_attribut($srcover_filter,'src');
- $reduit = str_replace($srcover,$srcover_filter,$reduit);
+ $srcover_filter = extraire_attribut($srcover_filter, 'src');
+ $reduit = str_replace($srcover, $srcover_filter, $reduit);
}
}
$texte = str_replace($tag[3], $reduit, $texte);
return $texte;
}
-//
-// Retourner taille d'une image
-// pour les filtres |largeur et |hauteur
-//
-// http://doc.spip.org/@taille_image
+
+/**
+ * Retourne les tailles d'une image
+ *
+ * Pour les filtres `largeur` et `hauteur`
+ *
+ * @param string $img
+ * Balise HTML `<img ... />` ou chemin de l'image (qui peut être une URL distante).
+ * @return array
+ * Liste (hauteur, largeur) en pixels
+ **/
function taille_image($img) {
- static $largeur_img =array(), $hauteur_img= array();
+ static $largeur_img = array(), $hauteur_img = array();
$srcWidth = 0;
$srcHeight = 0;
- $logo = extraire_attribut($img,'src');
+ $logo = extraire_attribut($img, 'src');
- if (!$logo) $logo = $img;
- else {
- $srcWidth = extraire_attribut($img,'width');
- $srcHeight = extraire_attribut($img,'height');
+ if (!$logo) {
+ $logo = $img;
+ } else {
+ $srcWidth = extraire_attribut($img, 'width');
+ $srcHeight = extraire_attribut($img, 'height');
}
// ne jamais operer directement sur une image distante pour des raisons de perfo
// la copie locale a toutes les chances d'etre la ou de resservir
- if (preg_match(';^(\w{3,7}://);', $logo)){
+ if (tester_url_absolue($logo)) {
include_spip('inc/distant');
$fichier = copie_locale($logo);
$logo = $fichier ? _DIR_RACINE . $fichier : $logo;
}
- if (($p=strpos($logo,'?'))!==FALSE)
- $logo=substr($logo,0,$p);
+ if (($p = strpos($logo, '?')) !== false) {
+ $logo = substr($logo, 0, $p);
+ }
$srcsize = false;
- if (isset($largeur_img[$logo]))
+ if (isset($largeur_img[$logo])) {
$srcWidth = $largeur_img[$logo];
- if (isset($hauteur_img[$logo]))
+ }
+ if (isset($hauteur_img[$logo])) {
$srcHeight = $hauteur_img[$logo];
- if (!$srcWidth OR !$srcHeight){
+ }
+ if (!$srcWidth or !$srcHeight) {
if (file_exists($logo)
- AND $srcsize = @getimagesize($logo)){
- if (!$srcWidth) $largeur_img[$logo] = $srcWidth = $srcsize[0];
- if (!$srcHeight) $hauteur_img[$logo] = $srcHeight = $srcsize[1];
+ and $srcsize = @getimagesize($logo)
+ ) {
+ if (!$srcWidth) {
+ $largeur_img[$logo] = $srcWidth = $srcsize[0];
+ }
+ if (!$srcHeight) {
+ $hauteur_img[$logo] = $srcHeight = $srcsize[1];
+ }
}
// $logo peut etre une reference a une image temporaire dont a n'a que le log .src
// on s'y refere, l'image sera reconstruite en temps utile si necessaire
- elseif(@file_exists($f = "$logo.src")
- AND lire_fichier($f,$valeurs)
- AND $valeurs=unserialize($valeurs)) {
- if (!$srcWidth) $largeur_img[$logo] = $srcWidth = $valeurs["largeur_dest"];
- if (!$srcHeight) $hauteur_img[$logo] = $srcHeight = $valeurs["hauteur_dest"];
- }
+ elseif (@file_exists($f = "$logo.src")
+ and lire_fichier($f, $valeurs)
+ and $valeurs = unserialize($valeurs)
+ ) {
+ if (!$srcWidth) {
+ $largeur_img[$logo] = $srcWidth = $valeurs["largeur_dest"];
+ }
+ if (!$srcHeight) {
+ $hauteur_img[$logo] = $srcHeight = $valeurs["hauteur_dest"];
+ }
+ }
}
+
return array($srcHeight, $srcWidth);
}
-// http://doc.spip.org/@largeur
+
+
+/**
+ * Retourne la largeur d'une image
+ *
+ * @filtre
+ * @link http://www.spip.net/4296
+ * @uses taille_image()
+ * @see hauteur()
+ *
+ * @param string $img
+ * Balise HTML `<img ... />` ou chemin de l'image (qui peut être une URL distante).
+ * @return int|null
+ * Largeur en pixels, NULL ou 0 si aucune image.
+ **/
function largeur($img) {
- if (!$img) return;
- list ($h,$l) = taille_image($img);
+ if (!$img) {
+ return;
+ }
+ list($h, $l) = taille_image($img);
+
return $l;
}
-// http://doc.spip.org/@hauteur
+
+/**
+ * Retourne la hauteur d'une image
+ *
+ * @filtre
+ * @link http://www.spip.net/4291
+ * @uses taille_image()
+ * @see largeur()
+ *
+ * @param string $img
+ * Balise HTML `<img ... />` ou chemin de l'image (qui peut être une URL distante).
+ * @return int|null
+ * Hauteur en pixels, NULL ou 0 si aucune image.
+ **/
function hauteur($img) {
- if (!$img) return;
- list ($h,$l) = taille_image($img);
+ if (!$img) {
+ return;
+ }
+ list($h, $l) = taille_image($img);
+
return $h;
}
-// Echappement des entites HTML avec correction des entites "brutes"
-// (generees par les butineurs lorsqu'on rentre des caracteres n'appartenant
-// pas au charset de la page [iso-8859-1 par defaut])
-//
-// Attention on limite cette correction aux caracteres "hauts" (en fait > 99
-// pour aller plus vite que le > 127 qui serait logique), de maniere a
-// preserver des echappements de caracteres "bas" (par exemple [ ou ")
-// et au cas particulier de & qui devient &amp; dans les url
-// http://doc.spip.org/@corriger_entites_html
+/**
+ * Échappement des entités HTML avec correction des entités « brutes »
+ *
+ * Ces entités peuvent être générées par les butineurs lorsqu'on rentre des
+ * caractères n'appartenant pas au charset de la page [iso-8859-1 par défaut]
+ *
+ * Attention on limite cette correction aux caracteres « hauts » (en fait > 99
+ * pour aller plus vite que le > 127 qui serait logique), de manière à
+ * préserver des eéhappements de caractères « bas » (par exemple `[` ou `"`)
+ * et au cas particulier de `&` qui devient `&amp;` dans les URL
+ *
+ * @see corriger_toutes_entites_html()
+ * @param string $texte
+ * @return string
+ **/
function corriger_entites_html($texte) {
- if (strpos($texte,'&') === false) return $texte;
+ if (strpos($texte, '&') === false) {
+ return $texte;
+ }
+
return preg_replace(',&(#[0-9][0-9][0-9]+;|amp;),iS', '&\1', $texte);
}
-// idem mais corriger aussi les &eacute; en é
-// http://doc.spip.org/@corriger_toutes_entites_html
+
+/**
+ * Échappement des entités HTML avec correction des entités « brutes » ainsi
+ * que les `&eacute;` en `é`
+ *
+ * Identique à `corriger_entites_html()` en corrigeant aussi les
+ * `&eacute;` en `é`
+ *
+ * @see corriger_entites_html()
+ * @param string $texte
+ * @return string
+ **/
function corriger_toutes_entites_html($texte) {
- if (strpos($texte,'&') === false) return $texte;
+ if (strpos($texte, '&') === false) {
+ return $texte;
+ }
+
return preg_replace(',&(#?[a-z0-9]+;),iS', '&\1', $texte);
}
-// http://doc.spip.org/@proteger_amp
-function proteger_amp($texte){
- return str_replace('&','&',$texte);
+/**
+ * Échappe les `&` en `&`
+ *
+ * @param string $texte
+ * @return string
+ **/
+function proteger_amp($texte) {
+ return str_replace('&', '&', $texte);
}
-//
+
/**
- * http://doc.spip.org/@entites_html
+ * Échappe en entités HTML certains caractères d'un texte
+ *
+ * Traduira un code HTML en transformant en entités HTML les caractères
+ * en dehors du charset de la page ainsi que les `"`, `<` et `>`.
+ *
+ * Ceci permet d’insérer le texte d’une balise dans un `<textarea> </textarea>`
+ * sans dommages.
+ *
+ * @filtre
+ * @link http://www.spip.net/4280
+ *
+ * @uses echappe_html()
+ * @uses echappe_retour()
+ * @uses proteger_amp()
+ * @uses corriger_entites_html()
+ * @uses corriger_toutes_entites_html()
*
* @param string $texte
* chaine a echapper
* @param bool $tout
- * corriger toutes les &xx; en &xx;
+ * corriger toutes les `&xx;` en `&xx;`
* @param bool $quote
- * echapper aussi les simples quotes en '
+ * Échapper aussi les simples quotes en `'`
* @return mixed|string
*/
-function entites_html($texte, $tout=false, $quote=true) {
- if (!is_string($texte) OR !$texte
- OR strpbrk($texte, "&\"'<>")==false
- ) return $texte;
+function entites_html($texte, $tout = false, $quote = true) {
+ if (!is_string($texte) or !$texte
+ or strpbrk($texte, "&\"'<>") == false
+ ) {
+ return $texte;
+ }
include_spip('inc/texte');
- $flags = !defined('PHP_VERSION_ID') OR PHP_VERSION_ID < 50400 ? ENT_COMPAT : ENT_COMPAT|ENT_HTML401;
- $texte = spip_htmlspecialchars(echappe_retour(echappe_html($texte, '', true), '', 'proteger_amp'), $quote?ENT_QUOTES:$flags);
- if ($tout)
+ $flags = ($quote ? ENT_QUOTES : ENT_NOQUOTES);
+ if (defined('ENT_HTML401')) {
+ $flags |= ENT_HTML401;
+ }
+ $texte = spip_htmlspecialchars(echappe_retour(echappe_html($texte, '', true), '', 'proteger_amp'), $flags);
+ if ($tout) {
return corriger_toutes_entites_html($texte);
- else
+ } else {
return corriger_entites_html($texte);
+ }
}
-// Transformer les é dans le charset local
-// http://doc.spip.org/@filtrer_entites
+/**
+ * Convertit les caractères spéciaux HTML dans le charset du site.
+ *
+ * @exemple
+ * Si le charset de votre site est `utf-8`, `é` ou `é`
+ * sera transformé en `é`
+ *
+ * @filtre
+ * @link http://www.spip.net/5513
+ *
+ * @param string $texte
+ * Texte à convertir
+ * @return string
+ * Texte converti
+ **/
function filtrer_entites($texte) {
- if (strpos($texte,'&') === false) return $texte;
+ if (strpos($texte, '&') === false) {
+ return $texte;
+ }
// filtrer
$texte = html2unicode($texte);
// remettre le tout dans le charset cible
- return unicode2charset($texte);
+ $texte = unicode2charset($texte);
+ // cas particulier des " et ' qu'il faut filtrer aussi
+ // (on le faisait deja avec un ")
+ if (strpos($texte, "&#") !== false) {
+ $texte = str_replace(array("'", "'", """, """), array("'", "'", '"', '"'), $texte);
+ }
+
+ return $texte;
}
-// caracteres de controle - http://www.w3.org/TR/REC-xml/#charsets
-// http://doc.spip.org/@supprimer_caracteres_illegaux
+
+if (!function_exists('filtre_filtrer_entites_dist')) {
+ /**
+ * Version sécurisée de filtrer_entites
+ *
+ * @uses interdire_scripts()
+ * @uses filtrer_entites()
+ *
+ * @param string $t
+ * @return string
+ */
+ function filtre_filtrer_entites_dist($t) {
+ include_spip('inc/texte');
+ return interdire_scripts(filtrer_entites($t));
+ }
+}
+
+
+/**
+ * Supprime des caractères illégaux
+ *
+ * Remplace les caractères de controle par le caractère `-`
+ *
+ * @link http://www.w3.org/TR/REC-xml/#charsets
+ *
+ * @param string|array $texte
+ * @return string|array
+ **/
function supprimer_caracteres_illegaux($texte) {
static $from = "\x0\x1\x2\x3\x4\x5\x6\x7\x8\xB\xC\xE\xF\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F";
static $to = null;
-
+
if (is_array($texte)) {
- return array_map('corriger_caracteres_windows', $texte);
+ return array_map('supprimer_caracteres_illegaux', $texte);
}
-
- if (!$to) $to = str_repeat('-', strlen($from));
+
+ if (!$to) {
+ $to = str_repeat('-', strlen($from));
+ }
+
return strtr($texte, $from, $to);
}
-// Supprimer caracteres windows et les caracteres de controle ILLEGAUX
-// http://doc.spip.org/@corriger_caracteres
-function corriger_caracteres ($texte) {
+/**
+ * Correction de caractères
+ *
+ * Supprimer les caracteres windows non conformes et les caracteres de controle illégaux
+ *
+ * @param string|array $texte
+ * @return string|array
+ **/
+function corriger_caracteres($texte) {
$texte = corriger_caracteres_windows($texte);
$texte = supprimer_caracteres_illegaux($texte);
+
return $texte;
}
/**
- * Encode du HTML pour transmission XML
- * notamment dans les flux RSS
+ * Encode du HTML pour transmission XML notamment dans les flux RSS
*
- * http://doc.spip.org/@texte_backend
+ * Ce filtre transforme les liens en liens absolus, importe les entitées html et échappe les tags html.
*
- * @param $texte
- * @return mixed
+ * @filtre
+ * @link http://www.spip.net/4287
+ *
+ * @param string $texte
+ * Texte à transformer
+ * @return string
+ * Texte encodé pour XML
*/
function texte_backend($texte) {
// " -> " et tout ce genre de choses
$u = $GLOBALS['meta']['pcre_u'];
$texte = str_replace(" ", " ", $texte);
- $texte = preg_replace('/\s{2,}/S'.$u, " ", $texte);
+ $texte = preg_replace('/\s{2,}/S' . $u, " ", $texte);
// ne pas echapper les sinqle quotes car certains outils de syndication gerent mal
$texte = entites_html($texte, false, false);
+ // mais bien echapper les double quotes !
+ $texte = str_replace('"', '"', $texte);
// verifier le charset
$texte = charset2unicode($texte);
// Caracteres problematiques en iso-latin 1
- if ($GLOBALS['meta']['charset'] == 'iso-8859-1') {
+ if (isset($GLOBALS['meta']['charset']) and $GLOBALS['meta']['charset'] == 'iso-8859-1') {
$texte = str_replace(chr(156), 'œ', $texte);
$texte = str_replace(chr(140), 'Œ', $texte);
$texte = str_replace(chr(159), 'Ÿ', $texte);
return str_replace($apostrophe, "'", $texte);
}
-// Comme ci-dessus, mais avec addslashes final pour squelettes avec PHP (rss)
-
+/**
+ * Encode et quote du HTML pour transmission XML notamment dans les flux RSS
+ *
+ * Comme texte_backend(), mais avec addslashes final pour squelettes avec PHP (rss)
+ *
+ * @uses texte_backend()
+ * @filtre
+ *
+ * @param string $texte
+ * Texte à transformer
+ * @return string
+ * Texte encodé et quote pour XML
+ */
function texte_backendq($texte) {
return addslashes(texte_backend($texte));
}
-// Enleve le numero des titres numerotes ("1. Titre" -> "Titre")
-// http://doc.spip.org/@supprimer_numero
+
+/**
+ * Enlève un numéro préfixant un texte
+ *
+ * Supprime `10. ` dans la chaine `10. Titre`
+ *
+ * @filtre
+ * @link http://www.spip.net/4314
+ * @see recuperer_numero() Pour obtenir le numéro
+ * @example
+ * ```
+ * [<h1>(#TITRE|supprimer_numero)</h1>]
+ * ```
+ *
+ * @param string $texte
+ * Texte
+ * @return int|string
+ * Numéro de titre, sinon chaîne vide
+ **/
function supprimer_numero($texte) {
return preg_replace(
- ",^[[:space:]]*([0-9]+)([.)]|".chr(194).'?'.chr(176).")[[:space:]]+,S",
- "", $texte);
+ ",^[[:space:]]*([0-9]+)([.)]|" . chr(194) . '?' . chr(176) . ")[[:space:]]+,S",
+ "", $texte);
}
-// et la fonction inverse
-// http://doc.spip.org/@recuperer_numero
+/**
+ * Récupère un numéro préfixant un texte
+ *
+ * Récupère le numéro `10` dans la chaine `10. Titre`
+ *
+ * @filtre
+ * @link http://www.spip.net/5514
+ * @see supprimer_numero() Pour supprimer le numéro
+ * @see balise_RANG_dist() Pour obtenir un numéro de titre
+ * @example
+ * ```
+ * [(#TITRE|recuperer_numero)]
+ * ```
+ *
+ * @param string $texte
+ * Texte
+ * @return int|string
+ * Numéro de titre, sinon chaîne vide
+ **/
function recuperer_numero($texte) {
if (preg_match(
- ",^[[:space:]]*([0-9]+)([.)]|".chr(194).'?'.chr(176).")[[:space:]]+,S",
- $texte, $regs))
- return intval($regs[1]);
- else
+ ",^[[:space:]]*([0-9]+)([.)]|" . chr(194) . '?' . chr(176) . ")[[:space:]]+,S",
+ $texte, $regs)) {
+ return strval($regs[1]);
+ } else {
return '';
+ }
}
-// Suppression basique et brutale de tous les <...>
-// http://doc.spip.org/@supprimer_tags
+/**
+ * Suppression basique et brutale de tous les tags
+ *
+ * Supprime tous les tags `<...>`.
+ * Utilisé fréquemment pour écrire des RSS.
+ *
+ * @filtre
+ * @link http://www.spip.net/4315
+ * @example
+ * ```
+ * <title>[(#TITRE|supprimer_tags|texte_backend)]</title>
+ * ```
+ *
+ * @note
+ * Ce filtre supprime aussi les signes inférieurs `<` rencontrés.
+ *
+ * @param string $texte
+ * Texte à échapper
+ * @param string $rempl
+ * Inutilisé.
+ * @return string
+ * Texte converti
+ **/
function supprimer_tags($texte, $rempl = "") {
- $texte = preg_replace(",<[^>]*>,US", $rempl, $texte);
- // ne pas oublier un < final non ferme
+ $texte = preg_replace(",<(!--|\w|/)[^>]*>,US", $rempl, $texte);
+ // ne pas oublier un < final non ferme car coupe
+ $texte = preg_replace(",<(!--|\w|/).*$,US", $rempl, $texte);
// mais qui peut aussi etre un simple signe plus petit que
- $texte = str_replace('<', ' ', $texte);
+ $texte = str_replace('<', '<', $texte);
+
return $texte;
}
-// Convertit les <...> en la version lisible en HTML
-// http://doc.spip.org/@echapper_tags
+/**
+ * Convertit les chevrons de tag en version lisible en HTML
+ *
+ * Transforme les chevrons de tag `<...>` en entité HTML.
+ *
+ * @filtre
+ * @link http://www.spip.net/5515
+ * @example
+ * ```
+ * <pre>[(#TEXTE|echapper_tags)]</pre>
+ * ```
+ *
+ * @param string $texte
+ * Texte à échapper
+ * @param string $rempl
+ * Inutilisé.
+ * @return string
+ * Texte converti
+ **/
function echapper_tags($texte, $rempl = "") {
$texte = preg_replace("/<([^>]*)>/", "<\\1>", $texte);
+
return $texte;
}
-// Convertit un texte HTML en texte brut
-// http://doc.spip.org/@textebrut
+/**
+ * Convertit un texte HTML en texte brut
+ *
+ * Enlève les tags d'un code HTML, élimine les doubles espaces.
+ *
+ * @filtre
+ * @link http://www.spip.net/4317
+ * @example
+ * ```
+ * <title>[(#TITRE|textebrut) - ][(#NOM_SITE_SPIP|textebrut)]</title>
+ * ```
+ *
+ * @param string $texte
+ * Texte à convertir
+ * @return string
+ * Texte converti
+ **/
function textebrut($texte) {
$u = $GLOBALS['meta']['pcre_u'];
- $texte = preg_replace('/\s+/S'.$u, " ", $texte);
- $texte = preg_replace("/<(p|br)( [^>]*)?".">/iS", "\n\n", $texte);
+ $texte = preg_replace('/\s+/S' . $u, " ", $texte);
+ $texte = preg_replace("/<(p|br)( [^>]*)?" . ">/iS", "\n\n", $texte);
$texte = preg_replace("/^\n+/", "", $texte);
$texte = preg_replace("/\n+$/", "", $texte);
$texte = preg_replace("/\n +/", "\n", $texte);
$texte = supprimer_tags($texte);
$texte = preg_replace("/( | )+/S", " ", $texte);
// nettoyer l'apostrophe curly qui pose probleme a certains rss-readers, lecteurs de mail...
- $texte = str_replace("’","'",$texte);
+ $texte = str_replace("’", "'", $texte);
+
return $texte;
}
-// Remplace les liens SPIP en liens ouvrant dans une nouvelle fenetre (target=blank)
-// http://doc.spip.org/@liens_ouvrants
-function liens_ouvrants ($texte) {
- return preg_replace(",<a\s+([^>]*https?://[^>]*class=[\"']spip_(out|url)\b[^>]+)>,",
- "<a \\1 target=\"_blank\">", $texte);
+
+/**
+ * Remplace les liens SPIP en liens ouvrant dans une nouvelle fenetre (target=blank)
+ *
+ * @filtre
+ * @link http://www.spip.net/4297
+ *
+ * @param string $texte
+ * Texte avec des liens
+ * @return string
+ * Texte avec liens ouvrants
+ **/
+function liens_ouvrants($texte) {
+ if (preg_match_all(",(<a\s+[^>]*https?://[^>]*class=[\"']spip_(out|url)\b[^>]+>),imsS",
+ $texte, $liens, PREG_PATTERN_ORDER)) {
+ foreach ($liens[0] as $a) {
+ $rel = 'noopener noreferrer ' . extraire_attribut($a, 'rel');
+ $ablank = inserer_attribut($a, 'rel', $rel);
+ $ablank = inserer_attribut($ablank, 'target', '_blank');
+ $texte = str_replace($a, $ablank, $texte);
+ }
+ }
+
+ return $texte;
}
/**
* Ajouter un attribut rel="nofollow" sur tous les liens d'un texte
+ *
* @param string $texte
* @return string
*/
function liens_nofollow($texte) {
- if (stripos($texte,"<a")===false)
+ if (stripos($texte, "<a") === false) {
return $texte;
+ }
- if (preg_match_all(",<a\b[^>]*>,UimsS",$texte, $regs, PREG_PATTERN_ORDER)){
- foreach($regs[0] as $a){
- $rel = extraire_attribut($a,"rel");
- if (strpos($rel,"nofollow")===false){
- $rel = "nofollow" . ($rel?" $rel":"");
- $anofollow = inserer_attribut($a,"rel",$rel);
- $texte = str_replace($a,$anofollow,$texte);
+ if (preg_match_all(",<a\b[^>]*>,UimsS", $texte, $regs, PREG_PATTERN_ORDER)) {
+ foreach ($regs[0] as $a) {
+ $rel = extraire_attribut($a, "rel");
+ if (strpos($rel, "nofollow") === false) {
+ $rel = "nofollow" . ($rel ? " $rel" : "");
+ $anofollow = inserer_attribut($a, "rel", $rel);
+ $texte = str_replace($a, $anofollow, $texte);
}
}
}
return $texte;
}
-// Transformer les sauts de paragraphe en simples passages a la ligne
-// http://doc.spip.org/@PtoBR
-function PtoBR($texte){
+/**
+ * Transforme les sauts de paragraphe HTML `p` en simples passages à la ligne `br`
+ *
+ * @filtre
+ * @link http://www.spip.net/4308
+ * @example
+ * ```
+ * [<div>(#DESCRIPTIF|PtoBR)[(#NOTES|PtoBR)]</div>]
+ * ```
+ *
+ * @param string $texte
+ * Texte à transformer
+ * @return string
+ * Texte sans paraghaphes
+ **/
+function PtoBR($texte) {
$u = $GLOBALS['meta']['pcre_u'];
$texte = preg_replace("@</p>@iS", "\n", $texte);
$texte = preg_replace("@<p\b.*>@UiS", "<br />", $texte);
- $texte = preg_replace("@^\s*<br />@S".$u, "", $texte);
+ $texte = preg_replace("@^\s*<br />@S" . $u, "", $texte);
+
return $texte;
}
/**
- * lignes_longues assure qu'un texte ne vas pas deborder d'un bloc
+ * Assure qu'un texte ne vas pas déborder d'un bloc
* par la faute d'un mot trop long (souvent des URLs)
- * Ne devrait plus etre utilise et fait directement en CSS par un style
- * word-wrap:break-word;
- * cf http://www.alsacreations.com/tuto/lire/1038-gerer-debordement-contenu-css.html
*
- * Pour assurer la compatibilite du filtre, on encapsule le contenu par
- * un div ou span portant ce style inline.
+ * Ne devrait plus être utilisé et fait directement en CSS par un style
+ * `word-wrap:break-word;`
*
- * http://doc.spip.org/@lignes_longues
+ * @note
+ * Pour assurer la compatibilité du filtre, on encapsule le contenu par
+ * un `div` ou `span` portant ce style CSS inline.
*
- * @param string $texte
- * @return string
+ * @filtre
+ * @link http://www.spip.net/4298
+ * @link http://www.alsacreations.com/tuto/lire/1038-gerer-debordement-contenu-css.html
+ * @deprecated Utiliser le style CSS `word-wrap:break-word;`
+ *
+ * @param string $texte Texte
+ * @return string Texte encadré du style CSS
*/
function lignes_longues($texte) {
- if (!strlen(trim($texte))) return $texte;
+ if (!strlen(trim($texte))) {
+ return $texte;
+ }
include_spip('inc/texte');
- $tag = preg_match(',</?('._BALISES_BLOCS.')[>[:space:]],iS', $texte) ?
+ $tag = preg_match(',</?(' . _BALISES_BLOCS . ')[>[:space:]],iS', $texte) ?
'div' : 'span';
return "<$tag style='word-wrap:break-word;'>$texte</$tag>";
}
-// Majuscules y compris accents, en HTML
-// http://doc.spip.org/@majuscules
+/**
+ * Passe un texte en majuscules, y compris les accents, en HTML
+ *
+ * Encadre le texte du style CSS `text-transform: uppercase;`.
+ * Le cas spécifique du i turc est géré.
+ *
+ * @filtre
+ * @example
+ * ```
+ * [(#EXTENSION|majuscules)]
+ * ```
+ *
+ * @param string $texte Texte
+ * @return string Texte en majuscule
+ */
function majuscules($texte) {
- if (!strlen($texte)) return '';
+ if (!strlen($texte)) {
+ return '';
+ }
// Cas du turc
if ($GLOBALS['spip_lang'] == 'tr') {
# remplacer hors des tags et des entites
- if (preg_match_all(',<[^<>]+>|&[^;]+;,S', $texte, $regs, PREG_SET_ORDER))
- foreach ($regs as $n => $match)
+ if (preg_match_all(',<[^<>]+>|&[^;]+;,S', $texte, $regs, PREG_SET_ORDER)) {
+ foreach ($regs as $n => $match) {
$texte = str_replace($match[0], "@@SPIP_TURC$n@@", $texte);
+ }
+ }
$texte = str_replace('i', 'İ', $texte);
- if ($regs)
- foreach ($regs as $n => $match)
+ if ($regs) {
+ foreach ($regs as $n => $match) {
$texte = str_replace("@@SPIP_TURC$n@@", $match[0], $texte);
+ }
+ }
}
// Cas general
return "<span style='text-transform: uppercase;'>$texte</span>";
}
-// "127.4 ko" ou "3.1 Mo"
-// http://doc.spip.org/@taille_en_octets
-function taille_en_octets ($taille) {
- if ($taille < 1) return '';
- if ($taille < 1024) {$taille = _T('taille_octets', array('taille' => $taille));}
- else if ($taille < 1024*1024) {
- $taille = _T('taille_ko', array('taille' => round($taille/1024, 1)));
- } else if ($taille < 1024*1024*1024) {
- $taille = _T('taille_mo', array('taille' => round($taille/1024/1024, 1)));
+/**
+ * Retourne une taille en octets humainement lisible
+ *
+ * Tel que "127.4 ko" ou "3.1 Mo"
+ *
+ * @example
+ * - `[(#TAILLE|taille_en_octets)]`
+ * - `[(#VAL{123456789}|taille_en_octets)]` affiche `117.7 Mo`
+ *
+ * @filtre
+ * @link http://www.spip.net/4316
+ * @param int $taille
+ * @return string
+ **/
+function taille_en_octets($taille) {
+ if (!defined('_KILOBYTE')) {
+ /**
+ * Définit le nombre d'octets dans un Kilobyte
+ *
+ * @var int
+ **/
+ define('_KILOBYTE', 1024);
+ }
+
+ if ($taille < 1) {
+ return '';
+ }
+ if ($taille < _KILOBYTE) {
+ $taille = _T('taille_octets', array('taille' => $taille));
+ } elseif ($taille < _KILOBYTE * _KILOBYTE) {
+ $taille = _T('taille_ko', array('taille' => round($taille / _KILOBYTE, 1)));
+ } elseif ($taille < _KILOBYTE * _KILOBYTE * _KILOBYTE) {
+ $taille = _T('taille_mo', array('taille' => round($taille / _KILOBYTE / _KILOBYTE, 1)));
} else {
- $taille = _T('taille_go', array('taille' => round($taille/1024/1024/1024, 2)));
+ $taille = _T('taille_go', array('taille' => round($taille / _KILOBYTE / _KILOBYTE / _KILOBYTE, 2)));
}
+
return $taille;
}
-// Rend une chaine utilisable sans dommage comme attribut HTML
-// http://doc.spip.org/@attribut_html
-function attribut_html($texte,$textebrut = true) {
+/**
+ * Rend une chaine utilisable sans dommage comme attribut HTML
+ *
+ * @example `<a href="#URL_ARTICLE" title="[(#TITRE|attribut_html)]">#TITRE</a>`
+ *
+ * @filtre
+ * @link http://www.spip.net/4282
+ * @uses textebrut()
+ * @uses texte_backend()
+ *
+ * @param string $texte
+ * Texte à mettre en attribut
+ * @param bool $textebrut
+ * Passe le texte en texte brut (enlève les balises html) ?
+ * @return string
+ * Texte prêt pour être utilisé en attribut HTML
+ **/
+function attribut_html($texte, $textebrut = true) {
$u = $GLOBALS['meta']['pcre_u'];
- if ($textebrut)
- $texte = preg_replace(array(",\n,",",\s(?=\s),msS".$u),array(" ",""),textebrut($texte));
+ if ($textebrut) {
+ $texte = preg_replace(array(",\n,", ",\s(?=\s),msS" . $u), array(" ", ""), textebrut($texte));
+ }
$texte = texte_backend($texte);
- $texte = str_replace(array("'",'"'),array(''', '"'), $texte);
-
- return preg_replace(array("/&(amp;|#38;)/","/&(?![A-Za-z]{0,4}\w{2,3};|#[0-9]{2,5};)/"),array("&","&") , $texte);
+ $texte = str_replace(array("'", '"'), array(''', '"'), $texte);
+
+ return preg_replace(array("/&(amp;|#38;)/", "/&(?![A-Za-z]{0,4}\w{2,3};|#[0-9]{2,5};)/"), array("&", "&"),
+ $texte);
}
-// Vider les url nulles comme 'http://' ou 'mailto:'
-// et leur appliquer un htmlspecialchars() + gerer les &
-// http://doc.spip.org/@vider_url
+
+/**
+ * Vider les URL nulles
+ *
+ * - Vide les URL vides comme `http://` ou `mailto:` (sans rien d'autre)
+ * - échappe les entités et gère les `&`
+ *
+ * @uses entites_html()
+ *
+ * @param string $url
+ * URL à vérifier et échapper
+ * @param bool $entites
+ * `true` pour échapper les entités HTML.
+ * @return string
+ * URL ou chaîne vide
+ **/
function vider_url($url, $entites = true) {
# un message pour abs_url
$GLOBALS['mode_abs_url'] = 'url';
$url = trim($url);
$r = ",^(?:" . _PROTOCOLES_STD . '):?/?/?$,iS';
- return preg_match($r, $url) ? '': ($entites ? entites_html($url) : $url);
-}
-// Extraire une date de n'importe quel champ (a completer...)
-// http://doc.spip.org/@extraire_date
-function extraire_date($texte) {
- // format = 2001-08
- if (preg_match(",([1-2][0-9]{3})[^0-9]*(1[0-2]|0?[1-9]),",$texte,$regs))
- return $regs[1]."-".sprintf("%02d", $regs[2])."-01";
+ return preg_match($r, $url) ? '' : ($entites ? entites_html($url) : $url);
}
-// Maquiller une adresse e-mail
-// http://doc.spip.org/@antispam
+
+/**
+ * Maquiller une adresse e-mail
+ *
+ * Remplace `@` par 3 caractères aléatoires.
+ *
+ * @uses creer_pass_aleatoire()
+ *
+ * @param string $texte Adresse email
+ * @return string Adresse email maquillée
+ **/
function antispam($texte) {
include_spip('inc/acces');
$masque = creer_pass_aleatoire(3);
+
return preg_replace("/@/", " $masque ", $texte);
}
-// http://doc.spip.org/@securiser_acces
-function securiser_acces($id_auteur, $cle, $dir, $op='', $args='')
-{
+/**
+ * Vérifie un accès à faible sécurité
+ *
+ * Vérifie qu'un visiteur peut accéder à la page demandée,
+ * qui est protégée par une clé, calculée à partir du low_sec de l'auteur,
+ * et des paramètres le composant l'appel (op, args)
+ *
+ * @example
+ * `[(#ID_AUTEUR|securiser_acces{#ENV{cle}, rss, #ENV{op}, #ENV{args}}|sinon_interdire_acces)]`
+ *
+ * @see bouton_spip_rss() pour générer un lien de faible sécurité pour les RSS privés
+ * @see afficher_low_sec() pour calculer une clé valide
+ * @uses verifier_low_sec()
+ *
+ * @filtre
+ * @param int $id_auteur
+ * L'auteur qui demande la page
+ * @param string $cle
+ * La clé à tester
+ * @param string $dir
+ * Un type d'accès (nom du répertoire dans lequel sont rangés les squelettes demandés, tel que 'rss')
+ * @param string $op
+ * Nom de l'opération éventuelle
+ * @param string $args
+ * Nom de l'argument calculé
+ * @return bool
+ * True si on a le droit d'accès, false sinon.
+ **/
+function securiser_acces($id_auteur, $cle, $dir, $op = '', $args = '') {
include_spip('inc/acces');
- if ($op) $dir .= " $op $args";
+ if ($op) {
+ $dir .= " $op $args";
+ }
+
return verifier_low_sec($id_auteur, $cle, $dir);
}
/**
- * La fonction sinon retourne le second parametre lorsque
- * le premier est considere vide, sinon retourne le premier parametre.
+ * Retourne le second paramètre lorsque
+ * le premier est considere vide, sinon retourne le premier paramètre.
*
- * En php sinon($a, 'rien') retourne $a ou 'rien' si $a est vide.
- * En filtre spip |sinon{#TEXTE, rien} : affiche #TEXTE ou "rien" si #TEXTE est vide,
+ * En php `sinon($a, 'rien')` retourne `$a`, ou `'rien'` si `$a` est vide.
+ * En filtre SPIP `|sinon{#TEXTE, rien}` : affiche `#TEXTE` ou `rien` si `#TEXTE` est vide,
+ *
+ * @filtre
+ * @see filtre_logique() pour la compilation du filtre dans un squelette
+ * @link http://www.spip.net/4313
+ * @note
+ * L'utilisation de `|sinon` en tant que filtre de squelette
+ * est directement compilé dans `public/references` par la fonction `filtre_logique()`
*
- * Note : l'utilisation de |sinon en tant que filtre de squelette
- * est directement compile dans public/references par la fonction filtre_logique()
- *
* @param mixed $texte
- * Contenu de reference a tester
+ * Contenu de reference a tester
* @param mixed $sinon
- * Contenu a retourner si le contenu de reference est vide
+ * Contenu a retourner si le contenu de reference est vide
* @return mixed
- * Retourne $texte, sinon $sinon.
-**/
-function sinon ($texte, $sinon='') {
- if ($texte OR (!is_array($texte) AND strlen($texte)))
+ * Retourne $texte, sinon $sinon.
+ **/
+function sinon($texte, $sinon = '') {
+ if ($texte or (!is_array($texte) and strlen($texte))) {
return $texte;
- else
+ } else {
return $sinon;
+ }
}
-// |choixsivide{vide,pasvide} affiche pasvide si la chaine n'est pas vide...
-// http://doc.spip.org/@choixsivide
+/**
+ * Filtre `|choixsivide{vide, pas vide}` alias de `|?{si oui, si non}` avec les arguments inversés
+ *
+ * @example
+ * `[(#TEXTE|choixsivide{vide, plein})]` affiche vide si le `#TEXTE`
+ * est considéré vide par PHP (chaîne vide, false, 0, tableau vide, etc…).
+ * C'est l'équivalent de `[(#TEXTE|?{plein, vide})]`
+ *
+ * @filtre
+ * @see choixsiegal()
+ * @link http://www.spip.net/4189
+ *
+ * @param mixed $a
+ * La valeur à tester
+ * @param mixed $vide
+ * Ce qui est retourné si `$a` est considéré vide
+ * @param mixed $pasvide
+ * Ce qui est retourné sinon
+ * @return mixed
+ **/
function choixsivide($a, $vide, $pasvide) {
return $a ? $pasvide : $vide;
}
-// |choixsiegal{aquoi,oui,non} affiche oui si la chaine est egal a aquoi ...
-// http://doc.spip.org/@choixsiegal
-function choixsiegal($a1,$a2,$v,$f) {
+/**
+ * Filtre `|choixsiegal{valeur, sioui, sinon}`
+ *
+ * @example
+ * `#LANG_DIR|choixsiegal{ltr,left,right}` retourne `left` si
+ * `#LANG_DIR` vaut `ltr` et `right` sinon.
+ *
+ * @filtre
+ * @link http://www.spip.net/4148
+ *
+ * @param mixed $a1
+ * La valeur à tester
+ * @param mixed $a2
+ * La valeur de comparaison
+ * @param mixed $v
+ * Ce qui est retourné si la comparaison est vraie
+ * @param mixed $f
+ * Ce qui est retourné sinon
+ * @return mixed
+ **/
+function choixsiegal($a1, $a2, $v, $f) {
return ($a1 == $a2) ? $v : $f;
}
-
-//
-// Date, heure, saisons
-//
-
-// on normalise la date, si elle vient du contexte (public/parametrer.php), on force le jour
-// http://doc.spip.org/@normaliser_date
-function normaliser_date($date, $forcer_jour = false) {
- $date = vider_date($date);
- if ($date) {
- if (preg_match("/^[0-9]{8,10}$/", $date))
- $date = date("Y-m-d H:i:s", $date);
- if (preg_match("#^([12][0-9]{3})([-/]00)?( [-0-9:]+)?$#", $date, $regs))
- $date = $regs[1]."-00-00".$regs[3];
- else if (preg_match("#^([12][0-9]{3}[-/][01]?[0-9])([-/]00)?( [-0-9:]+)?$#", $date, $regs))
- $date = preg_replace("@/@","-",$regs[1])."-00".$regs[3];
- else
- $date = date("Y-m-d H:i:s", strtotime($date));
-
- if ($forcer_jour)
- $date = str_replace('-00', '-01', $date);
- }
- return $date;
-}
-
-// http://doc.spip.org/@vider_date
-function vider_date($letexte) {
- if (strncmp("0000-00-00", $letexte,10)==0) return '';
- if (strncmp("0001-01-01", $letexte,10)==0) return '';
- if (strncmp("1970-01-01", $letexte,10)==0) return ''; // eviter le bug GMT-1
- return $letexte;
-}
-
-// http://doc.spip.org/@recup_heure
-function recup_heure($date){
-
- static $d = array(0,0,0);
- if (!preg_match('#([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})#', $date, $r))
- return $d;
-
- array_shift($r);
- return $r;
-}
-
-// http://doc.spip.org/@heures
-function heures($numdate) {
- $date_array = recup_heure($numdate);
- if ($date_array)
- list($heures, $minutes, $secondes) = $date_array;
- return $heures;
-}
-
-// http://doc.spip.org/@minutes
-function minutes($numdate) {
- $date_array = recup_heure($numdate);
- if ($date_array)
- list($heures, $minutes, $secondes) = $date_array;
- return $minutes;
-}
-
-// http://doc.spip.org/@secondes
-function secondes($numdate) {
- $date_array = recup_heure($numdate);
- if ($date_array)
- list($heures,$minutes,$secondes) = $date_array;
- return $secondes;
-}
-
-// http://doc.spip.org/@heures_minutes
-function heures_minutes($numdate) {
- return _T('date_fmt_heures_minutes', array('h'=> heures($numdate), 'm'=> minutes($numdate)));
-}
-
-// http://doc.spip.org/@recup_date
-function recup_date($numdate, $forcer_jour = true){
- if (!$numdate) return '';
- $heures = $minutes = $secondes = 0;
- if (preg_match('#([0-9]{1,2})/([0-9]{1,2})/([0-9]{4}|[0-9]{1,2})#', $numdate, $regs)) {
- $jour = $regs[1];
- $mois = $regs[2];
- $annee = $regs[3];
- if ($annee < 90){
- $annee = 2000 + $annee;
- } elseif ($annee<100) {
- $annee = 1900 + $annee ;
- }
- list($heures, $minutes, $secondes) = recup_heure($numdate);
-
- }
- elseif (preg_match('#([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})#',$numdate, $regs)) {
- $annee = $regs[1];
- $mois = $regs[2];
- $jour = $regs[3];
- list($heures, $minutes, $secondes) = recup_heure($numdate);
- }
- elseif (preg_match('#([0-9]{4})-([0-9]{2})#', $numdate, $regs)){
- $annee = $regs[1];
- $mois = $regs[2];
- $jour ='';
- list($heures, $minutes, $secondes) = recup_heure($numdate);
- }
- elseif (preg_match('#^([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})$#', $numdate, $regs)){
- $annee = $regs[1];
- $mois = $regs[2];
- $jour = $regs[3];
- $heures = $regs[4];
- $minutes = $regs[5];
- $secondes = $regs[6];
- } else $annee = $mois = $jour ='';
- if ($annee > 4000) $annee -= 9000;
- if (substr($jour, 0, 1) == '0') $jour = substr($jour, 1);
-
- if ($forcer_jour AND $jour == '0') $jour = '1';
- if ($forcer_jour AND $mois == '0') $mois = '1';
- if ($annee OR $mois OR $jour OR $heures OR $minutes OR $secondes)
- return array($annee, $mois, $jour, $heures, $minutes, $secondes);
-}
-
-// une date pour l'interface : utilise date_relative si le decalage
-// avec time() est de moins de douze heures, sinon la date complete
-// http://doc.spip.org/@date_interface
-function date_interface($date, $decalage_maxi = 43200/* 12*3600 */) {
- return sinon(
- date_relative($date, $decalage_maxi),
- affdate_heure($date)
- );
-}
-
-// http://doc.spip.org/@date_relative
-function date_relative($date, $decalage_maxi=0,$ref_date=null) {
-
- if (is_null($ref_date))
- $ref_time = time();
- else
- $ref_time = strtotime($ref_date);
-
- if (!$date) return;
- $decal = date("U",$ref_time) - date("U", strtotime($date));
-
- if ($decalage_maxi AND ($decal > $decalage_maxi OR $decal < 0))
- return '';
-
- if ($decal < 0) {
- $il_y_a = "date_dans";
- $decal = -1 * $decal;
- } else {
- $il_y_a = "date_il_y_a";
- }
-
- if ($decal > 3600 * 24 * 30 * 6)
- return affdate_court($date);
-
- if ($decal > 3600 * 24 * 30) {
- $mois = floor ($decal / (3600 * 24 * 30));
- if ($mois < 2)
- $delai = "$mois "._T("date_un_mois");
- else
- $delai = "$mois "._T("date_mois");
- }
- else if ($decal > 3600 * 24 * 7) {
- $semaines = floor ($decal / (3600 * 24 * 7));
- if ($semaines < 2)
- $delai = "$semaines "._T("date_une_semaine");
- else
- $delai = "$semaines "._T("date_semaines");
- }
- else if ($decal > 3600 * 24) {
- $jours = floor ($decal / (3600 * 24));
- if ($jours < 2)
- return $il_y_a=="date_dans"?_T("date_demain"):_T("date_hier");
- else
- $delai = "$jours "._T("date_jours");
- }
- else if ($decal >= 3600) {
- $heures = floor ($decal / 3600);
- if ($heures < 2)
- $delai = "$heures "._T("date_une_heure");
- else
- $delai = "$heures "._T("date_heures");
- }
- else if ($decal >= 60) {
- $minutes = floor($decal / 60);
- if ($minutes < 2)
- $delai = "$minutes "._T("date_une_minute");
- else
- $delai = "$minutes "._T("date_minutes");
- } else {
- $secondes = ceil($decal);
- if ($secondes < 2)
- $delai = "$secondes "._T("date_une_seconde");
- else
- $delai = "$secondes "._T("date_secondes");
- }
-
- return _T($il_y_a, array("delai"=> $delai));
-}
-
-
-// http://doc.spip.org/@date_relativecourt
-function date_relativecourt($date, $decalage_maxi=0) {
-
- if (!$date) return;
- $decal = date("U",strtotime(date('Y-m-d'))-strtotime(date('Y-m-d',strtotime($date))));
-
- if ($decalage_maxi AND ($decal > $decalage_maxi OR $decal < 0))
+/**
+ * Alignements en HTML (Old-style, préférer CSS)
+ *
+ * Cette fonction ne crée pas de paragraphe
+ *
+ * @deprecated Utiliser CSS
+ * @param string $letexte
+ * @param string $justif
+ * @return string
+ */
+function aligner($letexte, $justif = '') {
+ $letexte = trim($letexte);
+ if (!strlen($letexte)) {
return '';
-
- if ($decal < -24*3600) {
- $retour = date_relative($date, $decalage_maxi);
}
- elseif ($decal < 0) {
- $retour = _T("date_demain");
- }
- else if ($decal < (3600 * 24) ) {
- $retour = _T("date_aujourdhui");
- }
- else if ($decal < (3600 * 24 *2) ) {
- $retour = _T("date_hier");
- }
- else {
- $retour = date_relative($date, $decalage_maxi);
- }
-
+ // Paragrapher rapidement
+ $letexte = "<div style='text-align:$justif'>"
+ . $letexte
+ . "</div>";
- return $retour;
+ return $letexte;
}
/**
- * Formatage humain de la date $numdate selon le format $vue
- * http://doc.spip.org/@affdate_base
+ * Justifie en HTML (Old-style, préférer CSS)
*
- * @param $numdate
- * @param $vue
- * @param array $options
- * param : 'abbr' ou 'initiale' permet d'afficher les jours au format court ou initiale
- * annee_courante : permet de definir l'annee de reference pour l'affichage des dates courtes
- * @return mixed|string
+ * @deprecated Utiliser CSS
+ * @uses aligner()
+ * @param string $letexte
+ * @return string
*/
-function affdate_base($numdate, $vue, $options = array()) {
- if (is_string($options))
- $options = array('param'=>$options);
- $date_array = recup_date($numdate, false);
- if (!$date_array) return;
- list($annee, $mois, $jour, $heures, $minutes, $secondes)= $date_array;
-
- // 1er, 21st, etc.
- $journum = $jour;
-
- if ($jour == 0) {
- $jour = '';
- } else {
- $njour = intval($jour);
- if ($jourth = _T('date_jnum'.$jour))
- $jour = $jourth;
- }
-
- $mois = intval($mois);
- if ($mois > 0 AND $mois < 13) {
- $nommois = _T('date_mois_'.$mois);
- if ($jour)
- $jourmois = _T('date_de_mois_'.$mois, array('j'=>$jour, 'nommois'=>$nommois));
- else
- $jourmois = $nommois;
- } else $nommois = '';
-
- if ($annee < 0) {
- $annee = -$annee." "._T('date_avant_jc');
- $avjc = true;
- }
- else $avjc = false;
-
- switch ($vue) {
- case 'saison':
- case 'saison_annee':
- $saison = '';
- if ($mois > 0){
- $saison = 1;
- if (($mois == 3 AND $jour >= 21) OR $mois > 3) $saison = 2;
- if (($mois == 6 AND $jour >= 21) OR $mois > 6) $saison = 3;
- if (($mois == 9 AND $jour >= 21) OR $mois > 9) $saison = 4;
- if (($mois == 12 AND $jour >= 21) OR $mois > 12) $saison = 1;
- }
- if($vue == 'saison')
- return $saison?_T('date_saison_'.$saison):'';
- else
- return $saison?trim(_T('date_fmt_saison_annee', array('saison'=>_T('date_saison_'.$saison), 'annee'=>$annee))) :'';
-
- case 'court':
- if ($avjc) return $annee;
- $a = ((isset($options['annee_courante']) AND $options['annee_courante'])?$options['annee_courante']:date('Y'));
- if ($annee < ($a - 100) OR $annee > ($a + 100)) return $annee;
- if ($annee != $a) return _T('date_fmt_mois_annee', array ('mois'=>$mois, 'nommois'=>spip_ucfirst($nommois), 'annee'=>$annee));
- return _T('date_fmt_jour_mois', array ('jourmois'=>$jourmois, 'jour'=>$jour, 'mois'=>$mois, 'nommois'=>$nommois, 'annee'=>$annee));
-
- case 'jourcourt':
- if ($avjc) return $annee;
- $a = ((isset($options['annee_courante']) AND $options['annee_courante'])?$options['annee_courante']:date('Y'));
- if ($annee < ($a - 100) OR $annee > ($a + 100)) return $annee;
- if ($annee != $a) return _T('date_fmt_jour_mois_annee', array ('jourmois'=>$jourmois, 'jour'=>$jour, 'mois'=>$mois, 'nommois'=>$nommois, 'annee'=>$annee));
- return _T('date_fmt_jour_mois', array ('jourmois'=>$jourmois, 'jour'=>$jour, 'mois'=>$mois, 'nommois'=>$nommois, 'annee'=>$annee));
-
- case 'entier':
- if ($avjc) return $annee;
- if ($jour)
- return _T('date_fmt_jour_mois_annee', array ('jourmois'=>$jourmois, 'jour'=>$jour, 'mois'=>$mois, 'nommois'=>$nommois, 'annee'=>$annee));
- elseif ($mois)
- return trim(_T('date_fmt_mois_annee', array ('mois'=>$mois, 'nommois'=>$nommois, 'annee'=>$annee)));
- else
- return $annee;
-
- case 'nom_mois':
- $param = ((isset($options['param']) AND $options['param']) ? '_'.$options['param'] : '');
- if ($param and $mois) {
- return _T('date_mois_'.$mois.$param);
- }
- return $nommois;
-
- case 'mois':
- return sprintf("%02s",$mois);
-
- case 'jour':
- return $jour;
-
- case 'journum':
- return $journum;
-
- case 'nom_jour':
- if (!$mois OR !$njour)
- return '';
- $nom = mktime(1,1,1,$mois,$njour,$annee);
- $nom = 1+date('w',$nom);
- $param = ((isset($options['param']) AND $options['param']) ? '_'.$options['param'] : '');
- return _T('date_jour_'.$nom.$param);
-
- case 'mois_annee':
- if ($avjc) return $annee;
- return trim(_T('date_fmt_mois_annee', array('mois'=>$mois, 'nommois'=>$nommois, 'annee'=>$annee)));
-
- case 'annee':
- return $annee;
-
- // Cas d'une vue non definie : retomber sur le format
- // de date propose par http://www.php.net/date
- default:
- return date($vue, strtotime($numdate));
- }
-}
-
-// http://doc.spip.org/@nom_jour
-function nom_jour($numdate, $forme = '') {
- if(!($forme == 'abbr' OR $forme == 'initiale')) $forme = '';
- return affdate_base($numdate, 'nom_jour', $forme);
-}
-
-// http://doc.spip.org/@jour
-function jour($numdate) {
- return affdate_base($numdate, 'jour');
-}
-
-// http://doc.spip.org/@journum
-function journum($numdate) {
- return affdate_base($numdate, 'journum');
-}
-
-// http://doc.spip.org/@mois
-function mois($numdate) {
- return affdate_base($numdate, 'mois');
-}
-
-// http://doc.spip.org/@nom_mois
-function nom_mois($numdate, $forme='') {
- if(!($forme == 'abbr')) $forme = '';
- return affdate_base($numdate, 'nom_mois', $forme);
-}
-
-// http://doc.spip.org/@annee
-function annee($numdate) {
- return affdate_base($numdate, 'annee');
-}
-
-// http://doc.spip.org/@saison
-function saison($numdate) {
- return affdate_base($numdate, 'saison');
-}
-
-// http://doc.spip.org/@saison_annee
-function saison_annee($numdate) {
- return affdate_base($numdate, 'saison_annee');
-}
-
-// http://doc.spip.org/@affdate
-function affdate($numdate, $format='entier') {
- return affdate_base($numdate, $format);
-}
-
-// http://doc.spip.org/@affdate_court
-function affdate_court($numdate, $annee_courante=null) {
- return affdate_base($numdate, 'court', array('annee_courante'=>$annee_courante));
-}
-
-// http://doc.spip.org/@affdate_jourcourt
-function affdate_jourcourt($numdate, $annee_courante=null) {
- return affdate_base($numdate, 'jourcourt', array('annee_courante'=>$annee_courante));
-}
-
-// http://doc.spip.org/@affdate_mois_annee
-function affdate_mois_annee($numdate) {
- return affdate_base($numdate, 'mois_annee');
-}
-
-// http://doc.spip.org/@affdate_heure
-function affdate_heure($numdate) {
- $date_array = recup_date($numdate);
- if (!$date_array) return;
- list($annee, $mois, $jour, $heures, $minutes, $sec)= $date_array;
- return _T('date_fmt_jour_heure', array('jour' => affdate($numdate), 'heure' => _T('date_fmt_heures_minutes', array('h'=> $heures, 'm'=> $minutes))));
-}
+function justifier($letexte) { return aligner($letexte, 'justify'); }
/**
- * Afficher de facon textuelle les dates de debut et fin en fonction des cas
- * - Lundi 20 fevrier a 18h
- * - Le 20 fevrier de 18h a 20h
- * - Du 20 au 23 fevrier
- * - Du 20 fevrier au 30 mars
- * - Du 20 fevrier 2007 au 30 mars 2008
- * $horaire='oui' ou true permet d'afficher l'horaire, toute autre valeur n'indique que le jour
- * $forme peut contenir une ou plusieurs valeurs parmi
- * - abbr (afficher le nom des jours en abbrege)
- * - hcal (generer une date au format hcal)
- * - jour (forcer l'affichage des jours)
- * - annee (forcer l'affichage de l'annee)
+ * Aligne à droite en HTML (Old-style, préférer CSS)
*
- * @param string $date_debut
- * @param string $date_fin
- * @param string $horaire
- * @param string $forme
+ * @deprecated Utiliser CSS
+ * @uses aligner()
+ * @param string $letexte
* @return string
*/
-function affdate_debut_fin($date_debut, $date_fin, $horaire = 'oui', $forme=''){
- $abbr = $jour = '';
- $affdate = "affdate_jourcourt";
- if (strpos($forme,'abbr') !==false) $abbr = 'abbr';
- if (strpos($forme,'annee')!==false) $affdate = 'affdate';
- if (strpos($forme,'jour') !==false) $jour = 'jour';
-
- $dtstart = $dtend = $dtabbr = "";
- if (strpos($forme,'hcal')!==false) {
- $dtstart = "<abbr class='dtstart' title='".date_iso($date_debut)."'>";
- $dtend = "<abbr class='dtend' title='".date_iso($date_fin)."'>";
- $dtabbr = "</abbr>";
- }
-
- $date_debut = strtotime($date_debut);
- $date_fin = strtotime($date_fin);
- $d = date("Y-m-d", $date_debut);
- $f = date("Y-m-d", $date_fin);
- $h = ($horaire==='oui' OR $horaire===true);
- $hd = _T('date_fmt_heures_minutes_court', array('h'=> date("H",$date_debut), 'm'=> date("i",$date_debut)));
- $hf = _T('date_fmt_heures_minutes_court', array('h'=> date("H",$date_fin), 'm'=> date("i",$date_fin)));
-
- if ($d==$f)
- { // meme jour
- $nomjour = nom_jour($d,$abbr);
- $s = $affdate($d);
- $s = _T('date_fmt_jour',array('nomjour'=>$nomjour,'jour' => $s));
- if ($h){
- if ($hd==$hf){
- // Lundi 20 fevrier a 18h25
- $s = spip_ucfirst(_T('date_fmt_jour_heure',array('jour'=>$s,'heure'=>$hd)));
- $s = "$dtstart$s$dtabbr";
- }else{
- // Le <abbr...>lundi 20 fevrier de 18h00</abbr> a <abbr...>20h00</abbr>
- if($dtabbr && $dtstart && $dtend)
- $s = spip_ucfirst(_T('date_fmt_jour_heure_debut_fin_abbr',array('jour'=>$s,'heure_debut'=>$hd,'heure_fin'=>$hf,'dtstart'=>$dtstart,'dtend'=>$dtend,'dtabbr'=>$dtabbr)));
- // Le lundi 20 fevrier de 18h00 a 20h00
- else
- $s = spip_ucfirst(_T('date_fmt_jour_heure_debut_fin',array('jour'=>$s,'heure_debut'=>$hd,'heure_fin'=>$hf)));
- }
- }else{
- if($dtabbr && $dtstart)
- $s = $dtstart.spip_ucfirst($s).$dabbr;
- else
- $s = spip_ucfirst($s);
- }
- }
- else if ((date("Y-m",$date_debut))==date("Y-m",$date_fin))
- { // meme annee et mois, jours differents
- if(!$h)
- $date_debut = jour($d);
- else
- $date_debut = $affdate($d);
- $date_fin = $affdate($f);
- if($jour){
- $nomjour_debut = nom_jour($d,$abbr);
- $date_debut = _T('date_fmt_jour',array('nomjour'=>$nomjour_debut,'jour' => $date_debut));
- $nomjour_fin = nom_jour($f,$abbr);
- $date_fin = _T('date_fmt_jour',array('nomjour'=>$nomjour_fin,'jour' => $date_fin));
- }
- if ($h){
- $date_debut = _T('date_fmt_jour_heure',array('jour'=>$date_debut,'heure'=>$hd));
- $date_fin = _T('date_fmt_jour_heure',array('jour'=>$date_fin,'heure'=>$hf));
- }
- $date_debut = $dtstart.$date_debut.$dtabbr;
- $date_fin = $dtend.$date_fin.$dtabbr;
-
- $s = _T('date_fmt_periode',array('date_debut' => $date_debut,'date_fin'=>$date_fin));
- }
- else {
- $date_debut = affdate($d);
- $date_fin = affdate($f);
- if($jour){
- $nomjour_debut = nom_jour($d,$abbr);
- $date_debut = _T('date_fmt_jour_periode',array('nomjour'=>$nomjour_debut,'jour' => $date_debut));
- $nomjour_fin = nom_jour($f,$abbr);
- $date_fin = _T('date_fmt_jour_periode',array('nomjour'=>$nomjour_fin,'jour' => $date_fin));
- }
- if ($h){
- $date_debut = _T('date_fmt_jour_heure',array('jour'=>$date_debut,'heure'=>$hd));
- $date_fin = _T('date_fmt_jour_heure',array('jour'=>$date_fin,'heure'=>$hf));
- }
-
- $date_debut = $dtstart.$date_debut.$dtabbr;
- $date_fin=$dtend.$date_fin.$dtabbr;
- $s = _T('date_fmt_periode',array('date_debut' => $date_debut,'date_fin'=>$date_fin));
-
- }
- return $s;
-}
+function aligner_droite($letexte) { return aligner($letexte, 'right'); }
/**
- * Alignements en HTML (Old-style, preferer CSS)
- * Cette fonction ne cree pas de paragraphe
- *
- * http://doc.spip.org/@aligner
+ * Aligne à gauche en HTML (Old-style, préférer CSS)
*
- * @param $letexte
- * @param string $justif
+ * @deprecated Utiliser CSS
+ * @uses aligner()
+ * @param string $letexte
* @return string
*/
-function aligner($letexte, $justif='') {
- $letexte = trim($letexte);
- if (!strlen($letexte)) return '';
-
- // Paragrapher rapidement
- $letexte = "<div style='text-align:$justif'>"
- . $letexte
- ."</div>";
+function aligner_gauche($letexte) { return aligner($letexte, 'left'); }
- return $letexte;
-}
-// http://doc.spip.org/@justifier
-function justifier($letexte) { return aligner($letexte,'justify');}
-// http://doc.spip.org/@aligner_droite
-function aligner_droite($letexte) { return aligner($letexte,'right');}
-// http://doc.spip.org/@aligner_gauche
-function aligner_gauche($letexte) {return aligner($letexte,'left');}
-// http://doc.spip.org/@centrer
-function centrer($letexte) {return aligner($letexte,'center');}
+/**
+ * Centre en HTML (Old-style, préférer CSS)
+ *
+ * @deprecated Utiliser CSS
+ * @uses aligner()
+ * @param string $letexte
+ * @return string
+ */
+function centrer($letexte) { return aligner($letexte, 'center'); }
-// http://doc.spip.org/@style_align
+/**
+ * Retourne un texte de style CSS aligné sur la langue en cours
+ *
+ * @deprecated
+ * @param mixed $bof Inutilisé
+ * @return string Style CSS
+ **/
function style_align($bof) {
- global $spip_lang_left;
- return "text-align: $spip_lang_left";
+
+ return "text-align: " . $GLOBALS['spip_lang_left'];
}
//
// Export iCal
//
-// http://doc.spip.org/@filtrer_ical
-function filtrer_ical($texte) {
- #include_spip('inc/charsets');
- $texte = html2unicode($texte);
- $texte = unicode2charset(charset2unicode($texte, $GLOBALS['meta']['charset'], 1), 'utf-8');
- $texte = preg_replace("/\n/", " ", $texte);
- $texte = preg_replace("/,/", "\,", $texte);
-
- return $texte;
-}
-
-// http://doc.spip.org/@date_ical
-function date_ical($date, $addminutes = 0) {
- list($heures, $minutes, $secondes) = recup_heure($date);
- list($annee, $mois, $jour) = recup_date($date);
- return date("Ymd\THis",
- mktime($heures, $minutes+$addminutes,$secondes,$mois,$jour,$annee));
-}
-
-// date_iso retourne la date au format "RFC 3339" / "ISO 8601"
-// voir http://www.php.net/manual/fr/ref.datetime.php#datetime.constants
-// http://doc.spip.org/@date_iso
-function date_iso($date_heure) {
- list($annee, $mois, $jour) = recup_date($date_heure);
- list($heures, $minutes, $secondes) = recup_heure($date_heure);
- $time = @mktime($heures, $minutes, $secondes, $mois, $jour, $annee);
- return gmdate('Y-m-d\TH:i:s\Z', $time);
-}
-
-// date_822 retourne la date au format "RFC 822"
-// utilise pour <pubdate> dans certains feeds RSS
-// http://doc.spip.org/@date_822
-function date_822($date_heure) {
- list($annee, $mois, $jour) = recup_date($date_heure);
- list($heures, $minutes, $secondes) = recup_heure($date_heure);
- $time = mktime($heures, $minutes, $secondes, $mois, $jour, $annee);
- return date('r', $time);
-}
-
-// http://doc.spip.org/@date_anneemoisjour
-function date_anneemoisjour($d) {
- if (!$d) $d = date("Y-m-d");
- return substr($d, 0, 4) . substr($d, 5, 2) .substr($d, 8, 2);
-}
-
-// http://doc.spip.org/@date_anneemois
-function date_anneemois($d) {
- if (!$d) $d = date("Y-m-d");
- return substr($d, 0, 4) . substr($d, 5, 2);
-}
-
-// http://doc.spip.org/@date_debut_semaine
-function date_debut_semaine($annee, $mois, $jour) {
- $w_day = date("w", mktime(0,0,0,$mois, $jour, $annee));
- if ($w_day == 0) $w_day = 7; // Gaffe: le dimanche est zero
- $debut = $jour-$w_day+1;
- return date("Ymd", mktime(0,0,0,$mois,$debut,$annee));
-}
-
-// http://doc.spip.org/@date_fin_semaine
-function date_fin_semaine($annee, $mois, $jour) {
- $w_day = date("w", mktime(0,0,0,$mois, $jour, $annee));
- if ($w_day == 0) $w_day = 7; // Gaffe: le dimanche est zero
- $debut = $jour-$w_day+1;
- return date("Ymd", mktime(0,0,0,$mois,$debut+6,$annee));
-}
-
+/**
+ * Adapte un texte pour être inséré dans une valeur d'un export ICAL
+ *
+ * Passe le texte en utf8, enlève les sauts de lignes et échappe les virgules.
+ *
+ * @example `SUMMARY:[(#TITRE|filtrer_ical)]`
+ * @filtre
+ *
+ * @param string $texte
+ * @return string
+ **/
+function filtrer_ical($texte) {
+ #include_spip('inc/charsets');
+ $texte = html2unicode($texte);
+ $texte = unicode2charset(charset2unicode($texte, $GLOBALS['meta']['charset'], 1), 'utf-8');
+ $texte = preg_replace("/\n/", " ", $texte);
+ $texte = preg_replace("/,/", "\,", $texte);
-//
-// Recuperation de donnees dans le champ extra
-// Ce filtre n'a de sens qu'avec la balise #EXTRA
-//
-// http://doc.spip.org/@extra
-function extra($letexte, $champ) {
- $champs = unserialize($letexte);
- return $champs[$champ];
+ return $texte;
}
-// postautobr : transforme les sauts de ligne en _
-// http://doc.spip.org/@post_autobr
-function post_autobr($texte, $delim="\n_ ") {
- if (!function_exists('echappe_html'))
+
+/**
+ * Transforme les sauts de ligne simples en sauts forcés avec `_ `
+ *
+ * Ne modifie pas les sauts de paragraphe (2 sauts consécutifs au moins),
+ * ou les retours à l'intérieur de modèles ou de certaines balises html.
+ *
+ * @note
+ * Cette fonction pouvait être utilisée pour forcer les alinéas,
+ * (retours à la ligne sans saut de paragraphe), mais ce traitement
+ * est maintenant automatique.
+ * Cf. plugin Textwheel et la constante _AUTOBR
+ *
+ * @uses echappe_html()
+ * @uses echappe_retour()
+ *
+ * @param string $texte
+ * @param string $delim
+ * Ce par quoi sont remplacés les sauts
+ * @return string
+ **/
+function post_autobr($texte, $delim = "\n_ ") {
+ if (!function_exists('echappe_html')) {
include_spip('inc/texte_mini');
+ }
$texte = str_replace("\r\n", "\r", $texte);
$texte = str_replace("\r", "\n", $texte);
- if (preg_match(",\n+$,", $texte, $fin))
+ if (preg_match(",\n+$,", $texte, $fin)) {
$texte = substr($texte, 0, -strlen($fin = $fin[0]));
- else
+ } else {
$fin = '';
+ }
$texte = echappe_html($texte, '', true);
// echapper les modeles
- if (strpos($texte,"<")!==false){
+ if (strpos($texte, "<") !== false) {
include_spip('inc/lien');
- if (defined('_PREG_MODELE')){
- $preg_modeles = "@"._PREG_MODELE."@imsS";
+ if (defined('_PREG_MODELE')) {
+ $preg_modeles = "@" . _PREG_MODELE . "@imsS";
$texte = echappe_html($texte, '', true, $preg_modeles);
}
}
$debut = '';
$suite = $texte;
- while ($t = strpos('-'.$suite, "\n", 1)) {
- $debut .= substr($suite, 0, $t-1);
+ while ($t = strpos('-' . $suite, "\n", 1)) {
+ $debut .= substr($suite, 0, $t - 1);
$suite = substr($suite, $t);
$car = substr($suite, 0, 1);
- if (($car<>'-') AND ($car<>'_') AND ($car<>"\n") AND ($car<>"|") AND ($car<>"}")
- AND !preg_match(',^\s*(\n|</?(quote|div|dl|dt|dd)|$),S',($suite))
- AND !preg_match(',</?(quote|div|dl|dt|dd)> *$,iS', $debut)) {
+ if (($car <> '-') and ($car <> '_') and ($car <> "\n") and ($car <> "|") and ($car <> "}")
+ and !preg_match(',^\s*(\n|</?(quote|div|dl|dt|dd)|$),S', ($suite))
+ and !preg_match(',</?(quote|div|dl|dt|dd)> *$,iS', $debut)
+ ) {
$debut .= $delim;
- } else
+ } else {
$debut .= "\n";
+ }
if (preg_match(",^\n+,", $suite, $regs)) {
- $debut.=$regs[0];
+ $debut .= $regs[0];
$suite = substr($suite, strlen($regs[0]));
}
}
- $texte = $debut.$suite;
+ $texte = $debut . $suite;
$texte = echappe_retour($texte);
- return $texte.$fin;
+
+ return $texte . $fin;
}
+/**
+ * Expression régulière pour obtenir le contenu des extraits idiomes `<:module:cle:>`
+ *
+ * @var string
+ */
+define('_EXTRAIRE_IDIOME', '@<:(?:([a-z0-9_]+):)?([a-z0-9_]+):>@isS');
+
+/**
+ * Extrait une langue des extraits idiomes (`<:module:cle_de_langue:>`)
+ *
+ * Retrouve les balises `<:cle_de_langue:>` d'un texte et remplace son contenu
+ * par l'extrait correspondant à la langue demandée (si possible), sinon dans la
+ * langue par défaut du site.
+ *
+ * Ne pas mettre de span@lang=fr si on est déjà en fr.
+ *
+ * @filtre
+ * @uses inc_traduire_dist()
+ * @uses code_echappement()
+ * @uses echappe_retour()
+ *
+ * @param string $letexte
+ * @param string $lang
+ * Langue à retrouver (si vide, utilise la langue en cours).
+ * @param array $options Options {
+ * @type bool $echappe_span
+ * True pour échapper les balises span (false par défaut)
+ * @type string $lang_defaut
+ * Code de langue : permet de définir la langue utilisée par défaut,
+ * en cas d'absence de traduction dans la langue demandée.
+ * Par défaut la langue du site.
+ * Indiquer 'aucune' pour ne pas retourner de texte si la langue
+ * exacte n'a pas été trouvée.
+ * }
+ * @return string
+ **/
+function extraire_idiome($letexte, $lang = null, $options = array()) {
+ static $traduire = false;
+ if ($letexte
+ and preg_match_all(_EXTRAIRE_IDIOME, $letexte, $regs, PREG_SET_ORDER)
+ ) {
+ if (!$traduire) {
+ $traduire = charger_fonction('traduire', 'inc');
+ include_spip('inc/lang');
+ }
+ if (!$lang) {
+ $lang = $GLOBALS['spip_lang'];
+ }
+ // Compatibilité avec le prototype de fonction précédente qui utilisait un boolean
+ if (is_bool($options)) {
+ $options = array('echappe_span' => $options);
+ }
+ if (!isset($options['echappe_span'])) {
+ $options = array_merge($options, array('echappe_span' => false));
+ }
+
+ foreach ($regs as $reg) {
+ $cle = ($reg[1] ? $reg[1] . ':' : '') . $reg[2];
+ $desc = $traduire($cle, $lang, true);
+ $l = $desc->langue;
+ // si pas de traduction, on laissera l'écriture de l'idiome entier dans le texte.
+ if (strlen($desc->texte)) {
+ $trad = code_echappement($desc->texte, 'idiome', false);
+ if ($l !== $lang) {
+ $trad = str_replace("'", '"', inserer_attribut($trad, 'lang', $l));
+ }
+ if (lang_dir($l) !== lang_dir($lang)) {
+ $trad = str_replace("'", '"', inserer_attribut($trad, 'dir', lang_dir($l)));
+ }
+ if (!$options['echappe_span']) {
+ $trad = echappe_retour($trad, 'idiome');
+ }
+ $letexte = str_replace($reg[0], $trad, $letexte);
+ }
+ }
+ }
+ return $letexte;
+}
+
+/**
+ * Expression régulière pour obtenir le contenu des extraits polyglottes `<multi>`
+ *
+ * @var string
+ */
define('_EXTRAIRE_MULTI', "@<multi>(.*?)</multi>@sS");
-// Extraire et transformer les blocs multi ; on indique la langue courante
-// pour ne pas mettre de span@lang=fr si on est deja en fr
-// http://doc.spip.org/@extraire_multi
-function extraire_multi($letexte, $lang=null, $echappe_span=false) {
- if (preg_match_all(_EXTRAIRE_MULTI, $letexte, $regs, PREG_SET_ORDER)) {
- if (!$lang) $lang = $GLOBALS['spip_lang'];
+/**
+ * Extrait une langue des extraits polyglottes (`<multi>`)
+ *
+ * Retrouve les balises `<multi>` d'un texte et remplace son contenu
+ * par l'extrait correspondant à la langue demandée.
+ *
+ * Si la langue demandée n'est pas trouvée dans le multi, ni une langue
+ * approchante (exemple `fr` si on demande `fr_TU`), on retourne l'extrait
+ * correspondant à la langue par défaut (option 'lang_defaut'), qui est
+ * par défaut la langue du site. Et si l'extrait n'existe toujours pas
+ * dans cette langue, ça utilisera la première langue utilisée
+ * dans la balise `<multi>`.
+ *
+ * Ne pas mettre de span@lang=fr si on est déjà en fr.
+ *
+ * @filtre
+ * @link http://www.spip.net/5332
+ *
+ * @uses extraire_trads()
+ * @uses approcher_langue()
+ * @uses lang_typo()
+ * @uses code_echappement()
+ * @uses echappe_retour()
+ *
+ * @param string $letexte
+ * @param string $lang
+ * Langue à retrouver (si vide, utilise la langue en cours).
+ * @param array $options Options {
+ * @type bool $echappe_span
+ * True pour échapper les balises span (false par défaut)
+ * @type string $lang_defaut
+ * Code de langue : permet de définir la langue utilisée par défaut,
+ * en cas d'absence de traduction dans la langue demandée.
+ * Par défaut la langue du site.
+ * Indiquer 'aucune' pour ne pas retourner de texte si la langue
+ * exacte n'a pas été trouvée.
+ * }
+ * @return string
+ **/
+function extraire_multi($letexte, $lang = null, $options = array()) {
+
+ if ($letexte
+ and preg_match_all(_EXTRAIRE_MULTI, $letexte, $regs, PREG_SET_ORDER)
+ ) {
+ if (!$lang) {
+ $lang = $GLOBALS['spip_lang'];
+ }
+
+ // Compatibilité avec le prototype de fonction précédente qui utilisait un boolean
+ if (is_bool($options)) {
+ $options = array('echappe_span' => $options, 'lang_defaut' => _LANGUE_PAR_DEFAUT);
+ }
+ if (!isset($options['echappe_span'])) {
+ $options = array_merge($options, array('echappe_span' => false));
+ }
+ if (!isset($options['lang_defaut'])) {
+ $options = array_merge($options, array('lang_defaut' => _LANGUE_PAR_DEFAUT));
+ }
+
+ include_spip('inc/lang');
foreach ($regs as $reg) {
// chercher la version de la langue courante
$trads = extraire_trads($reg[1]);
if ($l = approcher_langue($trads, $lang)) {
$trad = $trads[$l];
} else {
- include_spip('inc/texte');
- // langue absente, prendre la premiere dispo
- // mais typographier le texte selon les regles de celle-ci
- // Attention aux blocs multi sur plusieurs lignes
- $l = key($trads);
- $trad = $trads[$l];
- $typographie = charger_fonction(lang_typo($l), 'typographie');
- $trad = $typographie($trad);
- include_spip('inc/texte');
- // Tester si on echappe en span ou en div
- // il ne faut pas echapper en div si propre produit un seul paragraphe
- $trad_propre = preg_replace(",(^<p[^>]*>|</p>$),Uims","",propre($trad));
- $mode = preg_match(',</?('._BALISES_BLOCS.')[>[:space:]],iS', $trad_propre) ? 'div' : 'span';
- $trad = code_echappement($trad, 'multi', false, $mode);
- $trad = str_replace("'", '"', inserer_attribut($trad, 'lang', $l));
- if (lang_dir($l) !== lang_dir($lang))
- $trad = str_replace("'", '"', inserer_attribut($trad, 'dir', lang_dir($l)));
- if (!$echappe_span)
- $trad = echappe_retour($trad, 'multi');
+ if ($options['lang_defaut'] == 'aucune') {
+ $trad = '';
+ } else {
+ // langue absente, prendre le fr ou une langue précisée (meme comportement que inc/traduire.php)
+ // ou la premiere dispo
+ // mais typographier le texte selon les regles de celle-ci
+ // Attention aux blocs multi sur plusieurs lignes
+ if (!$l = approcher_langue($trads, $options['lang_defaut'])) {
+ $l = key($trads);
+ }
+ $trad = $trads[$l];
+ $typographie = charger_fonction(lang_typo($l), 'typographie');
+ $trad = $typographie($trad);
+ // Tester si on echappe en span ou en div
+ // il ne faut pas echapper en div si propre produit un seul paragraphe
+ include_spip('inc/texte');
+ $trad_propre = preg_replace(",(^<p[^>]*>|</p>$),Uims", "", propre($trad));
+ $mode = preg_match(',</?(' . _BALISES_BLOCS . ')[>[:space:]],iS', $trad_propre) ? 'div' : 'span';
+ $trad = code_echappement($trad, 'multi', false, $mode);
+ $trad = str_replace("'", '"', inserer_attribut($trad, 'lang', $l));
+ if (lang_dir($l) !== lang_dir($lang)) {
+ $trad = str_replace("'", '"', inserer_attribut($trad, 'dir', lang_dir($l)));
+ }
+ if (!$options['echappe_span']) {
+ $trad = echappe_retour($trad, 'multi');
+ }
+ }
}
$letexte = str_replace($reg[0], $trad, $letexte);
}
return $letexte;
}
-// convertit le contenu d'une balise multi en un tableau
-// http://doc.spip.org/@extraire_trad
+/**
+ * Convertit le contenu d'une balise `<multi>` en un tableau
+ *
+ * Exemple de blocs.
+ * - `texte par défaut [fr] en français [en] en anglais`
+ * - `[fr] en français [en] en anglais`
+ *
+ * @param string $bloc
+ * Le contenu intérieur d'un bloc multi
+ * @return array [code de langue => texte]
+ * Peut retourner un code de langue vide, lorsqu'un texte par défaut est indiqué.
+ **/
function extraire_trads($bloc) {
$lang = '';
// ce reg fait planter l'analyse multi s'il y a de l'{italique} dans le champ
// while (preg_match("/^(.*?)[{\[]([a-z_]+)[}\]]/siS", $bloc, $regs)) {
while (preg_match("/^(.*?)[\[]([a-z_]+)[\]]/siS", $bloc, $regs)) {
$texte = trim($regs[1]);
- if ($texte OR $lang)
+ if ($texte or $lang) {
$trads[$lang] = $texte;
+ }
$bloc = substr($bloc, strlen($regs[0]));
$lang = $regs[2];
}
return $trads;
}
-// Calculer l'initiale d'un nom
-function initiale($nom){
- return spip_substr(trim(strtoupper(extraire_multi($nom))),0,1);
+
+/**
+ * Calculer l'initiale d'un nom
+ *
+ * @param string $nom
+ * @return string L'initiale en majuscule
+ */
+function filtre_initiale($nom) {
+ return spip_substr(trim(strtoupper(extraire_multi($nom))), 0, 1);
}
-//
-// Ce filtre retourne la donnee si c'est la premiere fois qu'il la voit ;
-// possibilite de gerer differentes "familles" de donnees |unique{famille}
-# |unique{famille,1} affiche le nombre d'elements affiches (preferer toutefois #TOTAL_UNIQUE)
-# ameliorations possibles :
-# 1) si la donnee est grosse, mettre son md5 comme cle
-# 2) purger $mem quand on change de squelette (sinon bug inclusions)
-//
-// http://www.spip.net/@unique
-// http://doc.spip.org/@unique
-function unique($donnee, $famille='', $cpt = false) {
+
+/**
+ * Retourne la donnée si c'est la première fois qu'il la voit
+ *
+ * Il est possible de gérer différentes "familles" de données avec
+ * le second paramètre.
+ *
+ * @filtre
+ * @link http://www.spip.net/4320
+ * @example
+ * ```
+ * [(#ID_SECTEUR|unique)]
+ * [(#ID_SECTEUR|unique{tete})] n'a pas d'incidence sur
+ * [(#ID_SECTEUR|unique{pied})]
+ * [(#ID_SECTEUR|unique{pied,1})] affiche le nombre d'éléments.
+ * Préférer totefois #TOTAL_UNIQUE{pied}
+ * ```
+ *
+ * @todo
+ * Ameliorations possibles :
+ *
+ * 1) si la donnée est grosse, mettre son md5 comme clé
+ * 2) purger $mem quand on change de squelette (sinon bug inclusions)
+ *
+ * @param string $donnee
+ * Donnée que l'on souhaite unique
+ * @param string $famille
+ * Famille de stockage (1 unique donnée par famille)
+ *
+ * - _spip_raz_ : (interne) Vide la pile de mémoire et la retourne
+ * - _spip_set_ : (interne) Affecte la pile de mémoire avec la donnée
+ * @param bool $cpt
+ * True pour obtenir le nombre d'éléments différents stockés
+ * @return string|int|array|null|void
+ *
+ * - string : Donnée si c'est la première fois qu'elle est vue
+ * - void : si la donnée a déjà été vue
+ * - int : si l'on demande le nombre d'éléments
+ * - array (interne) : si on dépile
+ * - null (interne) : si on empile
+ **/
+function unique($donnee, $famille = '', $cpt = false) {
static $mem = array();
// permettre de vider la pile et de la restaurer
// pour le calcul de introduction...
- if ($famille=='_spip_raz_'){
+ if ($famille == '_spip_raz_') {
$tmp = $mem;
$mem = array();
+
return $tmp;
- } elseif ($famille=='_spip_set_'){
+ } elseif ($famille == '_spip_set_') {
$mem = $donnee;
+
return;
}
// eviter une notice
}
}
-//
-// Filtre |alterner
-//
-// Exemple [(#COMPTEUR_BOUCLE|alterner{'bleu','vert','rouge'})]
-//
-// http://doc.spip.org/@alterner
+
+/**
+ * Filtre qui alterne des valeurs en fonction d'un compteur
+ *
+ * Affiche à tour de rôle et dans l'ordre, un des arguments transmis
+ * à chaque incrément du compteur.
+ *
+ * S'il n'y a qu'un seul argument, et que c'est un tableau,
+ * l'alternance se fait sur les valeurs du tableau.
+ *
+ * Souvent appliqué à l'intérieur d'une boucle, avec le compteur `#COMPTEUR_BOUCLE`
+ *
+ * @example
+ * - `[(#COMPTEUR_BOUCLE|alterner{bleu,vert,rouge})]`
+ * - `[(#COMPTEUR_BOUCLE|alterner{#LISTE{bleu,vert,rouge}})]`
+ *
+ * @filtre
+ * @link http://www.spip.net/4145
+ *
+ * @param int $i
+ * Le compteur
+ * @return mixed
+ * Une des valeurs en fonction du compteur.
+ **/
function alterner($i) {
// recuperer les arguments (attention fonctions un peu space)
$num = func_num_args();
$args = func_get_args();
- if($num == 2 && is_array($args[1])) {
- $args = $args[1];
- array_unshift($args,'');
- $num = count($args);
- }
+ if ($num == 2 && is_array($args[1])) {
+ $args = $args[1];
+ array_unshift($args, '');
+ $num = count($args);
+ }
// renvoyer le i-ieme argument, modulo le nombre d'arguments
- return $args[(intval($i)-1)%($num-1)+1];
+ return $args[(intval($i) - 1) % ($num - 1) + 1];
}
-// recuperer un attribut d'une balise html
-// ($complet demande de retourner $r)
-// la regexp est mortelle : cf. tests/filtres/extraire_attribut.php
-// Si on a passe un tableau de balises, renvoyer un tableau de resultats
-// (dans ce cas l'option $complet n'est pas disponible)
-// http://doc.spip.org/@extraire_attribut
+
+/**
+ * Récupérer un attribut d'une balise HTML
+ *
+ * la regexp est mortelle : cf. `tests/unit/filtres/extraire_attribut.php`
+ * Si on a passé un tableau de balises, renvoyer un tableau de résultats
+ * (dans ce cas l'option `$complet` n'est pas disponible)
+ *
+ * @param string|array $balise
+ * Texte ou liste de textes dont on veut extraire des balises
+ * @param string $attribut
+ * Nom de l'attribut désiré
+ * @param bool $complet
+ * True pour retourner un tableau avec
+ * - le texte de la balise
+ * - l'ensemble des résultats de la regexp ($r)
+ * @return string|array
+ * - Texte de l'attribut retourné, ou tableau des texte d'attributs
+ * (si 1er argument tableau)
+ * - Tableau complet (si 2e argument)
+ **/
function extraire_attribut($balise, $attribut, $complet = false) {
if (is_array($balise)) {
array_walk($balise,
'$a = extraire_attribut($a,$t);'
),
$attribut);
+
return $balise;
}
if (preg_match(
- ',(^.*?<(?:(?>\s*)(?>[\w:.-]+)(?>(?:=(?:"[^"]*"|\'[^\']*\'|[^\'"]\S*))?))*?)(\s+'
- .$attribut
- .'(?:=\s*("[^"]*"|\'[^\']*\'|[^\'"]\S*))?)()([^>]*>.*),isS',
+ ',(^.*?<(?:(?>\s*)(?>[\w:.-]+)(?>(?:=(?:"[^"]*"|\'[^\']*\'|[^\'"]\S*))?))*?)(\s+'
+ . $attribut
+ . '(?:=\s*("[^"]*"|\'[^\']*\'|[^\'"]\S*))?)()((?:[\s/][^>]*)?>.*),isS',
- $balise, $r)) {
- if ($r[3][0] == '"' || $r[3][0] == "'") {
+ $balise, $r)) {
+ if (isset($r[3][0]) and ($r[3][0] == '"' || $r[3][0] == "'")) {
$r[4] = substr($r[3], 1, -1);
$r[3] = $r[3][0];
- } elseif ($r[3]!=='') {
- $r[4] = $r[3];
+ } elseif ($r[3] !== '') {
+ $r[4] = $r[3];
$r[3] = '';
} else {
- $r[4] = trim($r[2]);
+ $r[4] = trim($r[2]);
+ }
+ $att = $r[4];
+ if (strpos($att, "&#") !== false) {
+ $att = str_replace(array("'", "'", """, """), array("'", "'", '"', '"'), $att);
}
- $att = filtrer_entites(str_replace("'", "'", $r[4]));
+ $att = filtrer_entites($att);
+ } else {
+ $att = null;
}
- else
- $att = NULL;
- if ($complet)
+ if ($complet) {
return array($att, $r);
- else
+ } else {
return $att;
+ }
}
/**
- * modifier (ou inserer) un attribut html dans une balise
+ * Insérer (ou modifier) un attribut html dans une balise
+ *
+ * @example
+ * - `[(#LOGO_ARTICLE|inserer_attribut{class, logo article})]`
+ * - `[(#LOGO_ARTICLE|inserer_attribut{alt, #TTTRE|attribut_html|couper{60}})]`
+ * - `[(#FICHIER|image_reduire{40}|inserer_attribut{data-description, #DESCRIPTIF})]`
+ * Laissera les balises HTML de la valeur (ici `#DESCRIPTIF`) si on n'applique pas le
+ * filtre `attribut_html` dessus.
*
- * http://doc.spip.org/@inserer_attribut
+ * @filtre
+ * @link http://www.spip.net/4294
+ * @uses attribut_html()
+ * @uses extraire_attribut()
*
* @param string $balise
+ * Code html de la balise (ou contenant une balise)
* @param string $attribut
+ * Nom de l'attribut html à modifier
* @param string $val
+ * Valeur de l'attribut à appliquer
* @param bool $proteger
+ * Prépare la valeur en tant qu'attribut de balise (mais conserve les balises html).
* @param bool $vider
+ * True pour vider l'attribut. Une chaîne vide pour `$val` fera pareil.
* @return string
- */
-function inserer_attribut($balise, $attribut, $val, $proteger=true, $vider=false) {
+ * Code html modifié
+ **/
+function inserer_attribut($balise, $attribut, $val, $proteger = true, $vider = false) {
// preparer l'attribut
// supprimer les etc mais pas les balises html
// qui ont un sens dans un attribut value d'un input
- if ($proteger) $val = attribut_html($val,false);
+ if ($proteger) {
+ $val = attribut_html($val, false);
+ }
// echapper les ' pour eviter tout bug
$val = str_replace("'", "'", $val);
- if ($vider AND strlen($val)==0)
+ if ($vider and strlen($val) == 0) {
$insert = '';
- else
+ } else {
$insert = " $attribut='$val'";
+ }
list($old, $r) = extraire_attribut($balise, $attribut, true);
- if ($old !== NULL) {
+ if ($old !== null) {
// Remplacer l'ancien attribut du meme nom
- $balise = $r[1].$insert.$r[5];
- }
- else {
+ $balise = $r[1] . $insert . $r[5];
+ } else {
// preferer une balise " />" (comme <img />)
- if (preg_match(',/>,', $balise))
- $balise = preg_replace(",\s?/>,S", $insert." />", $balise, 1);
- // sinon une balise <a ...> ... </a>
- else
- $balise = preg_replace(",\s?>,S", $insert.">", $balise, 1);
+ if (preg_match(',/>,', $balise)) {
+ $balise = preg_replace(",\s?/>,S", $insert . " />", $balise, 1);
+ } // sinon une balise <a ...> ... </a>
+ else {
+ $balise = preg_replace(",\s?>,S", $insert . ">", $balise, 1);
+ }
}
return $balise;
}
-// http://doc.spip.org/@vider_attribut
-function vider_attribut ($balise, $attribut) {
+/**
+ * Supprime un attribut HTML
+ *
+ * @example `[(#LOGO_ARTICLE|vider_attribut{class})]`
+ *
+ * @filtre
+ * @link http://www.spip.net/4142
+ * @uses inserer_attribut()
+ * @see extraire_attribut()
+ *
+ * @param string $balise Code HTML de l'élément
+ * @param string $attribut Nom de l'attribut à enlever
+ * @return string Code HTML sans l'attribut
+ **/
+function vider_attribut($balise, $attribut) {
return inserer_attribut($balise, $attribut, '', false, true);
}
/**
- * Un filtre pour determiner le nom du satut des inscrits
+ * Un filtre pour déterminer le nom du statut des inscrits
*
* @param void|int $id
* @param string $mode
* @return string
*/
-function tester_config($id, $mode='') {
+function tester_config($id, $mode = '') {
include_spip('action/inscrire_auteur');
+
return tester_statut_inscription($mode, $id);
}
//
// Quelques fonctions de calcul arithmetique
//
-// http://doc.spip.org/@plus
-function plus($a,$b) {
- return $a+$b;
-}
-// http://doc.spip.org/@moins
-function moins($a,$b) {
- return $a-$b;
+function floatstr($a) { return str_replace(',','.',(string)floatval($a)); }
+function strize($f, $a, $b) { return floatstr($f(floatstr($a),floatstr($b))); }
+
+/**
+ * Additionne 2 nombres
+ *
+ * @filtre
+ * @link http://www.spip.net/4307
+ * @see moins()
+ * @example
+ * ```
+ * [(#VAL{28}|plus{14})]
+ * ```
+ *
+ * @param int $a
+ * @param int $b
+ * @return int $a+$b
+ **/
+function plus($a, $b) {
+ return $a + $b;
+}
+function strplus($a, $b) {return strize('plus', $a, $b);}
+/**
+ * Soustrait 2 nombres
+ *
+ * @filtre
+ * @link http://www.spip.net/4302
+ * @see plus()
+ * @example
+ * ```
+ * [(#VAL{28}|moins{14})]
+ * ```
+ *
+ * @param int $a
+ * @param int $b
+ * @return int $a-$b
+ **/
+function moins($a, $b) {
+ return $a - $b;
}
-// http://doc.spip.org/@mult
-function mult($a,$b) {
- return $a*$b;
+function strmoins($a, $b) {return strize('moins', $a, $b);}
+
+/**
+ * Multiplie 2 nombres
+ *
+ * @filtre
+ * @link http://www.spip.net/4304
+ * @see div()
+ * @see modulo()
+ * @example
+ * ```
+ * [(#VAL{28}|mult{14})]
+ * ```
+ *
+ * @param int $a
+ * @param int $b
+ * @return int $a*$b
+ **/
+function mult($a, $b) {
+ return $a * $b;
}
-// http://doc.spip.org/@div
-function div($a,$b) {
- return $b?$a/$b:0;
+function strmult($a, $b) {return strize('mult', $a, $b);}
+
+/**
+ * Divise 2 nombres
+ *
+ * @filtre
+ * @link http://www.spip.net/4279
+ * @see mult()
+ * @see modulo()
+ * @example
+ * ```
+ * [(#VAL{28}|div{14})]
+ * ```
+ *
+ * @param int $a
+ * @param int $b
+ * @return int $a/$b (ou 0 si $b est nul)
+ **/
+function div($a, $b) {
+ return $b ? $a / $b : 0;
}
-// http://doc.spip.org/@modulo
-function modulo($nb, $mod, $add=0) {
- return ($mod?$nb%$mod:0)+$add;
+function strdiv($a, $b) {return strize('div', $a, $b);}
+
+/**
+ * Retourne le modulo 2 nombres
+ *
+ * @filtre
+ * @link http://www.spip.net/4301
+ * @see mult()
+ * @see div()
+ * @example
+ * ```
+ * [(#VAL{28}|modulo{14})]
+ * ```
+ *
+ * @param int $nb
+ * @param int $mod
+ * @param int $add
+ * @return int ($nb % $mod) + $add
+ **/
+function modulo($nb, $mod, $add = 0) {
+ return ($mod ? $nb % $mod : 0) + $add;
}
* @return bool
* - false si pas conforme,
* - true sinon
-**/
+ **/
function nom_acceptable($nom) {
if (!is_string($nom)) {
return false;
}
- if (!defined('_TAGS_NOM_AUTEUR')) define('_TAGS_NOM_AUTEUR','');
+ if (!defined('_TAGS_NOM_AUTEUR')) {
+ define('_TAGS_NOM_AUTEUR', '');
+ }
$tags_acceptes = array_unique(explode(',', 'multi,' . _TAGS_NOM_AUTEUR));
- foreach($tags_acceptes as $tag) {
+ foreach ($tags_acceptes as $tag) {
if (strlen($tag)) {
- $remp1[] = '<'.trim($tag).'>';
- $remp1[] = '</'.trim($tag).'>';
- $remp2[] = '\x60'.trim($tag).'\x61';
- $remp2[] = '\x60/'.trim($tag).'\x61';
+ $remp1[] = '<' . trim($tag) . '>';
+ $remp1[] = '</' . trim($tag) . '>';
+ $remp2[] = '\x60' . trim($tag) . '\x61';
+ $remp2[] = '\x60/' . trim($tag) . '\x61';
}
- }
+ }
$v_nom = str_replace($remp2, $remp1, supprimer_tags(str_replace($remp1, $remp2, $nom)));
+
return str_replace('<', '<', $v_nom) == $nom;
}
-// Verifier la conformite d'une ou plusieurs adresses email
-// retourne false ou la normalisation de la derniere adresse donnee
-// http://doc.spip.org/@email_valide
+
+/**
+ * Vérifier la conformité d'une ou plusieurs adresses email (suivant RFC 822)
+ *
+ * @param string $adresses
+ * Adresse ou liste d'adresse
+ * @return bool|string
+ * - false si pas conforme,
+ * - la normalisation de la dernière adresse donnée sinon
+ **/
function email_valide($adresses) {
// eviter d'injecter n'importe quoi dans preg_match
- if (!is_string($adresses))
+ if (!is_string($adresses)) {
return false;
+ }
// Si c'est un spammeur autant arreter tout de suite
if (preg_match(",[\n\r].*(MIME|multipart|Content-),i", $adresses)) {
spip_log("Tentative d'injection de mail : $adresses");
+
return false;
}
// "Marie Toto <Marie@toto.com>"
$adresse = trim(preg_replace(",^[^<>\"]*<([^<>\"]+)>$,i", "\\1", $v));
// RFC 822
- if (!preg_match('#^[^()<>@,;:\\"/[:space:]]+(@([-_0-9a-z]+\.)*[-_0-9a-z]+)$#i', $adresse))
+ if (!preg_match('#^[^()<>@,;:\\"/[:space:]]+(@([-_0-9a-z]+\.)*[-_0-9a-z]+)$#i', $adresse)) {
return false;
+ }
}
+
return $adresse;
}
-// http://doc.spip.org/@afficher_enclosures
+/**
+ * Permet d'afficher un symbole à côté des liens pointant vers les
+ * documents attachés d'un article (liens ayant `rel=enclosure`).
+ *
+ * @filtre
+ * @link http://www.spip.net/4134
+ *
+ * @param string $tags Texte
+ * @return string Texte
+ **/
function afficher_enclosures($tags) {
$s = array();
foreach (extraire_balises($tags, 'a') as $tag) {
if (extraire_attribut($tag, 'rel') == 'enclosure'
- AND $t = extraire_attribut($tag, 'href')) {
- $s[] = preg_replace(',>[^<]+</a>,S',
+ and $t = extraire_attribut($tag, 'href')
+ ) {
+ $s[] = preg_replace(',>[^<]+</a>,S',
'>'
- .http_img_pack('attachment-16.png', $t,
- 'title="'.attribut_html($t).'"')
- .'</a>', $tag);
+ . http_img_pack('attachment-16.png', $t,
+ 'title="' . attribut_html($t) . '"')
+ . '</a>', $tag);
}
}
+
return join(' ', $s);
}
-// http://doc.spip.org/@afficher_tags
-function afficher_tags($tags, $rels='tag,directory') {
+
+/**
+ * Filtre des liens HTML `<a>` selon la valeur de leur attribut `rel`
+ * et ne retourne que ceux là.
+ *
+ * @filtre
+ * @link http://www.spip.net/4187
+ *
+ * @param string $tags Texte
+ * @param string $rels Attribut `rel` à capturer (ou plusieurs séparés par des virgules)
+ * @return string Liens trouvés
+ **/
+function afficher_tags($tags, $rels = 'tag,directory') {
$s = array();
foreach (extraire_balises($tags, 'a') as $tag) {
$rel = extraire_attribut($tag, 'rel');
- if (strstr(",$rels,", ",$rel,"))
+ if (strstr(",$rels,", ",$rel,")) {
$s[] = $tag;
+ }
}
+
return join(', ', $s);
}
-// Passe un <enclosure url="fichier" length="5588242" type="audio/mpeg"/>
-// au format microformat <a rel="enclosure" href="fichier" ...>fichier</a>
-// attention length="zz" devient title="zz", pour rester conforme
-// http://doc.spip.org/@enclosure2microformat
+
+/**
+ * Convertir les médias fournis par un flux RSS (podcasts)
+ * en liens conformes aux microformats
+ *
+ * Passe un `<enclosure url="fichier" length="5588242" type="audio/mpeg"/>`
+ * au format microformat `<a rel="enclosure" href="fichier" ...>fichier</a>`.
+ *
+ * Peut recevoir un `<link` ou un `<media:content` parfois.
+ *
+ * Attention : `length="zz"` devient `title="zz"`, pour rester conforme.
+ *
+ * @filtre
+ * @see microformat2enclosure() Pour l'inverse
+ *
+ * @param string $e Tag RSS `<enclosure>`
+ * @return string Tag HTML `<a>` avec microformat.
+ **/
function enclosure2microformat($e) {
- if (!$url = filtrer_entites(extraire_attribut($e, 'url')))
+ if (!$url = filtrer_entites(extraire_attribut($e, 'url'))) {
$url = filtrer_entites(extraire_attribut($e, 'href'));
+ }
$type = extraire_attribut($e, 'type');
if (!$length = extraire_attribut($e, 'length')) {
# <media:content : longeur dans fileSize. On tente.
$length = extraire_attribut($e, 'fileSize');
}
$fichier = basename($url);
+
return '<a rel="enclosure"'
- . ($url? ' href="'.spip_htmlspecialchars($url).'"' : '')
- . ($type? ' type="'.spip_htmlspecialchars($type).'"' : '')
- . ($length? ' title="'.spip_htmlspecialchars($length).'"' : '')
- . '>'.$fichier.'</a>';
+ . ($url ? ' href="' . spip_htmlspecialchars($url) . '"' : '')
+ . ($type ? ' type="' . spip_htmlspecialchars($type) . '"' : '')
+ . ($length ? ' title="' . spip_htmlspecialchars($length) . '"' : '')
+ . '>' . $fichier . '</a>';
}
-// La fonction inverse
-// http://doc.spip.org/@microformat2enclosure
+
+/**
+ * Convertir les liens conformes aux microformats en médias pour flux RSS,
+ * par exemple pour les podcasts
+ *
+ * Passe un texte ayant des liens avec microformat
+ * `<a rel="enclosure" href="fichier" ...>fichier</a>`
+ * au format RSS `<enclosure url="fichier" ... />`.
+ *
+ * @filtre
+ * @see enclosure2microformat() Pour l'inverse
+ *
+ * @param string $tags Texte HTML ayant des tag `<a>` avec microformat
+ * @return string Tags RSS `<enclosure>`.
+ **/
function microformat2enclosure($tags) {
$enclosures = array();
- foreach (extraire_balises($tags, 'a') as $e)
- if (extraire_attribut($e, 'rel') == 'enclosure') {
- $url = filtrer_entites(extraire_attribut($e, 'href'));
- $type = extraire_attribut($e, 'type');
- if (!$length = intval(extraire_attribut($e, 'title')))
- $length = intval(extraire_attribut($e, 'length')); # vieux data
- $fichier = basename($url);
- $enclosures[] = '<enclosure'
- . ($url? ' url="'.spip_htmlspecialchars($url).'"' : '')
- . ($type? ' type="'.spip_htmlspecialchars($type).'"' : '')
- . ($length? ' length="'.$length.'"' : '')
- . ' />';
+ foreach (extraire_balises($tags, 'a') as $e) {
+ if (extraire_attribut($e, 'rel') == 'enclosure') {
+ $url = filtrer_entites(extraire_attribut($e, 'href'));
+ $type = extraire_attribut($e, 'type');
+ if (!$length = intval(extraire_attribut($e, 'title'))) {
+ $length = intval(extraire_attribut($e, 'length'));
+ } # vieux data
+ $fichier = basename($url);
+ $enclosures[] = '<enclosure'
+ . ($url ? ' url="' . spip_htmlspecialchars($url) . '"' : '')
+ . ($type ? ' type="' . spip_htmlspecialchars($type) . '"' : '')
+ . ($length ? ' length="' . $length . '"' : '')
+ . ' />';
+ }
}
+
return join("\n", $enclosures);
}
-// Creer les elements ATOM <dc:subject> a partir des tags
-// http://doc.spip.org/@tags2dcsubject
+
+
+/**
+ * Créer les éléments ATOM `<dc:subject>` à partir des tags
+ *
+ * Convertit les liens avec attribut `rel="tag"`
+ * en balise `<dc:subject></dc:subject>` pour les flux RSS au format Atom.
+ *
+ * @filtre
+ *
+ * @param string $tags Texte
+ * @return string Tags RSS Atom `<dc:subject>`.
+ **/
function tags2dcsubject($tags) {
$subjects = '';
foreach (extraire_balises($tags, 'a') as $e) {
if (extraire_attribut($e, rel) == 'tag') {
$subjects .= '<dc:subject>'
. texte_backend(textebrut($e))
- . '</dc:subject>'."\n";
+ . '</dc:subject>' . "\n";
}
}
+
return $subjects;
}
-// retourne la premiere balise du type demande
-// ex: [(#DESCRIPTIF|extraire_balise{img})]
-// Si on a passe un tableau de textes, renvoyer un tableau de resultats
-// http://doc.spip.org/@extraire_balise
-function extraire_balise($texte, $tag='a') {
+/**
+ * Retourne la premiere balise html du type demandé
+ *
+ * Retourne le contenu d'une balise jusqu'à la première fermeture rencontrée
+ * du même type.
+ * Si on a passe un tableau de textes, retourne un tableau de resultats.
+ *
+ * @example `[(#DESCRIPTIF|extraire_balise{img})]`
+ *
+ * @filtre
+ * @link http://www.spip.net/4289
+ * @see extraire_balises()
+ * @note
+ * Attention : les résultats peuvent être incohérents sur des balises imbricables,
+ * tel que demander à extraire `div` dans le texte `<div> un <div> mot </div> absent </div>`,
+ * ce qui retournerait `<div> un <div> mot </div>` donc.
+ *
+ * @param string|array $texte
+ * Texte(s) dont on souhaite extraire une balise html
+ * @param string $tag
+ * Nom de la balise html à extraire
+ * @return void|string|array
+ * - Code html de la balise, sinon rien
+ * - Tableau de résultats, si tableau en entrée.
+ **/
+function extraire_balise($texte, $tag = 'a') {
if (is_array($texte)) {
- array_walk($texte,
+ array_walk(
+ $texte,
create_function('&$a,$key,$t', '$a = extraire_balise($a,$t);'),
- $tag);
+ $tag
+ );
+
return $texte;
}
if (preg_match(
- ",<$tag\b[^>]*(/>|>.*</$tag\b[^>]*>|>),UimsS",
- $texte, $regs))
+ ",<$tag\b[^>]*(/>|>.*</$tag\b[^>]*>|>),UimsS",
+ $texte, $regs)) {
return $regs[0];
+ }
}
-// extraire toutes les balises du type demande, sous forme de tableau
-// Si on a passe un tableau de textes, renvoyer un tableau de resultats
-// http://doc.spip.org/@extraire_balises
-function extraire_balises($texte, $tag='a') {
+/**
+ * Extrait toutes les balises html du type demandé
+ *
+ * Retourne dans un tableau le contenu de chaque balise jusqu'à la première
+ * fermeture rencontrée du même type.
+ * Si on a passe un tableau de textes, retourne un tableau de resultats.
+ *
+ * @example `[(#TEXTE|extraire_balises{img}|implode{" - "})]`
+ *
+ * @filtre
+ * @link http://www.spip.net/5618
+ * @see extraire_balise()
+ * @note
+ * Attention : les résultats peuvent être incohérents sur des balises imbricables,
+ * tel que demander à extraire `div` dans un texte.
+ *
+ * @param string|array $texte
+ * Texte(s) dont on souhaite extraire une balise html
+ * @param string $tag
+ * Nom de la balise html à extraire
+ * @return array
+ * - Liste des codes html des occurrences de la balise, sinon tableau vide
+ * - Tableau de résultats, si tableau en entrée.
+ **/
+function extraire_balises($texte, $tag = 'a') {
if (is_array($texte)) {
- array_walk($texte,
+ array_walk(
+ $texte,
create_function('&$a,$key,$t', '$a = extraire_balises($a,$t);'),
- $tag);
+ $tag
+ );
+
return $texte;
}
if (preg_match_all(
- ",<${tag}\b[^>]*(/>|>.*</${tag}\b[^>]*>|>),UimsS",
- $texte, $regs, PREG_PATTERN_ORDER))
+ ",<${tag}\b[^>]*(/>|>.*</${tag}\b[^>]*>|>),UimsS",
+ $texte, $regs, PREG_PATTERN_ORDER)) {
return $regs[0];
- else
+ } else {
return array();
+ }
}
-// comme in_array mais renvoie son 3e arg si le 2er arg n'est pas un tableau
-// prend ' ' comme representant de vrai et '' de faux
+/**
+ * Indique si le premier argument est contenu dans le second
+ *
+ * Cette fonction est proche de `in_array()` en PHP avec comme principale
+ * différence qu'elle ne crée pas d'erreur si le second argument n'est pas
+ * un tableau (dans ce cas elle tentera de le désérialiser, et sinon retournera
+ * la valeur par défaut transmise).
+ *
+ * @example `[(#VAL{deux}|in_any{#LISTE{un,deux,trois}}|oui) ... ]`
+ *
+ * @filtre
+ * @see filtre_find() Assez proche, avec les arguments valeur et tableau inversés.
+ *
+ * @param string $val
+ * Valeur à chercher dans le tableau
+ * @param array|string $vals
+ * Tableau des valeurs. S'il ce n'est pas un tableau qui est transmis,
+ * la fonction tente de la désérialiser.
+ * @param string $def
+ * Valeur par défaut retournée si `$vals` n'est pas un tableau.
+ * @return string
+ * - ' ' si la valeur cherchée est dans le tableau
+ * - '' si la valeur n'est pas dans le tableau
+ * - `$def` si on n'a pas transmis de tableau
+ **/
+function in_any($val, $vals, $def = '') {
+ if (!is_array($vals) and $v = unserialize($vals)) {
+ $vals = $v;
+ }
-// http://doc.spip.org/@in_any
-function in_any($val, $vals, $def='') {
- if (!is_array($vals) AND $v=unserialize($vals)) $vals = $v;
- return (!is_array($vals) ? $def : (in_array($val, $vals) ? ' ' : ''));
+ return (!is_array($vals) ? $def : (in_array($val, $vals) ? ' ' : ''));
}
-// valeur_numerique("3*2") => 6
-// n'accepte que les *, + et - (a ameliorer si on l'utilise vraiment)
-// http://doc.spip.org/@valeur_numerique
+
+/**
+ * Retourne le résultat d'une expression mathématique simple
+ *
+ * N'accepte que les *, + et - (à ameliorer si on l'utilise vraiment).
+ *
+ * @filtre
+ * @example
+ * ```
+ * valeur_numerique("3*2") retourne 6
+ * ```
+ *
+ * @param string $expr
+ * Expression mathématique `nombre operateur nombre` comme `3*2`
+ * @return int
+ * Résultat du calcul
+ **/
function valeur_numerique($expr) {
$a = 0;
- if (preg_match(',^[0-9]+(\s*[+*-]\s*[0-9]+)*$,S', trim($expr)))
+ if (preg_match(',^[0-9]+(\s*[+*-]\s*[0-9]+)*$,S', trim($expr))) {
eval("\$a = $expr;");
+ }
+
return intval($a);
}
-// http://doc.spip.org/@regledetrois
-function regledetrois($a,$b,$c)
-{
- return round($a*$b/$c);
+/**
+ * Retourne un calcul de règle de trois
+ *
+ * @filtre
+ * @example
+ * ```
+ * [(#VAL{6}|regledetrois{4,3})] retourne 8
+ * ```
+ *
+ * @param int $a
+ * @param int $b
+ * @param int $c
+ * @return int
+ * Retourne `$a*$b/$c`
+ **/
+function regledetrois($a, $b, $c) {
+ return round($a * $b / $c);
}
-// Fournit la suite de Input-Hidden correspondant aux parametres de
-// l'URL donnee en argument, compatible avec les types_urls depuis [14447].
-// cf. tests/filtres/form_hidden.html
-// http://doc.spip.org/@form_hidden
+
+/**
+ * Crée des tags HTML input hidden pour chaque paramètre et valeur d'une URL
+ *
+ * Fournit la suite de Input-Hidden correspondant aux paramètres de
+ * l'URL donnée en argument, compatible avec les types_urls
+ *
+ * @filtre
+ * @link http://www.spip.net/4286
+ * @see balise_ACTION_FORMULAIRE()
+ * Également pour transmettre les actions à un formulaire
+ * @example
+ * ```
+ * [(#ENV{action}|form_hidden)] dans un formulaire
+ * ```
+ *
+ * @param string $action URL
+ * @return string Suite de champs input hidden
+ **/
function form_hidden($action) {
$contexte = array();
include_spip('inc/urls');
if ($p = urls_decoder_url($action, '')
- AND reset($p)) {
+ and reset($p)
+ ) {
$fond = array_shift($p);
- if ($fond!='404'){
+ if ($fond != '404') {
$contexte = array_shift($p);
$contexte['page'] = $fond;
- $action = preg_replace('/([?]'.preg_quote($fond).'[^&=]*[0-9]+)(&|$)/', '?&', $action);
+ $action = preg_replace('/([?]' . preg_quote($fond) . '[^&=]*[0-9]+)(&|$)/', '?&', $action);
}
}
// defaire ce qu'a injecte urls_decoder_url : a revoir en modifiant la signature de urls_decoder_url
- if (defined('_DEFINIR_CONTEXTE_TYPE') AND _DEFINIR_CONTEXTE_TYPE)
+ if (defined('_DEFINIR_CONTEXTE_TYPE') and _DEFINIR_CONTEXTE_TYPE) {
unset($contexte['type']);
- if (defined('_DEFINIR_CONTEXTE_TYPE_PAGE') AND _DEFINIR_CONTEXTE_TYPE_PAGE)
+ }
+ if (defined('_DEFINIR_CONTEXTE_TYPE_PAGE') and _DEFINIR_CONTEXTE_TYPE_PAGE) {
unset($contexte['type-page']);
+ }
// on va remplir un tableau de valeurs en prenant bien soin de ne pas
// ecraser les elements de la forme mots[]=1&mots[]=2
// d'abord avec celles de l'url
if (false !== ($p = strpos($action, '?'))) {
- foreach(preg_split('/&(amp;)?/S',substr($action,$p+1)) as $c){
- list($var,$val) = explode('=', $c, 2);
+ foreach (preg_split('/&(amp;)?/S', substr($action, $p + 1)) as $c) {
+ $c = explode('=', $c, 2);
+ $var = array_shift($c);
+ $val = array_shift($c);
if ($var) {
- $val = rawurldecode($val);
- $var = rawurldecode($var); // decoder les [] eventuels
- if (preg_match(',\[\]$,S', $var))
+ $val = rawurldecode($val);
+ $var = rawurldecode($var); // decoder les [] eventuels
+ if (preg_match(',\[\]$,S', $var)) {
$values[] = array($var, $val);
- else if (!isset($values[$var]))
- $values[$var] = array($var, $val);
+ } else {
+ if (!isset($values[$var])) {
+ $values[$var] = array($var, $val);
+ }
+ }
}
}
}
// ensuite avec celles du contexte, sans doublonner !
- foreach($contexte as $var=>$val)
- if (preg_match(',\[\]$,S', $var))
+ foreach ($contexte as $var => $val) {
+ if (preg_match(',\[\]$,S', $var)) {
$values[] = array($var, $val);
- else if (!isset($values[$var]))
- $values[$var] = array($var, $val);
+ } else {
+ if (!isset($values[$var])) {
+ $values[$var] = array($var, $val);
+ }
+ }
+ }
// puis on rassemble le tout
$hidden = array();
- foreach($values as $value) {
- list($var,$val) = $value;
+ foreach ($values as $value) {
+ list($var, $val) = $value;
$hidden[] = '<input name="'
. entites_html($var)
- .'"'
+ . '"'
. (is_null($val)
? ''
- : ' value="'.entites_html($val).'"'
- )
- . ' type="hidden"'."\n/>";
+ : ' value="' . entites_html($val) . '"'
+ )
+ . ' type="hidden"' . "\n/>";
}
+
return join("", $hidden);
}
-// http://doc.spip.org/@filtre_bornes_pagination_dist
+/**
+ * Calcule les bornes d'une pagination
+ *
+ * @filtre
+ *
+ * @param int $courante
+ * Page courante
+ * @param int $nombre
+ * Nombre de pages
+ * @param int $max
+ * Nombre d'éléments par page
+ * @return int[]
+ * Liste (première page, dernière page).
+ **/
function filtre_bornes_pagination_dist($courante, $nombre, $max = 10) {
- if($max<=0 OR $max>=$nombre)
+ if ($max <= 0 or $max >= $nombre) {
return array(1, $nombre);
+ }
+
+ $premiere = max(1, $courante - floor(($max - 1) / 2));
+ $derniere = min($nombre, $premiere + $max - 2);
+ $premiere = $derniere == $nombre ? $derniere - $max + 1 : $premiere;
- $premiere = max(1, $courante-floor(($max-1)/2));
- $derniere = min($nombre, $premiere+$max-2);
- $premiere = $derniere == $nombre ? $derniere-$max+1 : $premiere;
return array($premiere, $derniere);
}
-// Ces trois fonctions permettent de simuler les filtres |reset et |end
-// pour extraire la premiere ou la derniere valeur d'un tableau ; utile
-// pour la pagination (mais peut-etre a refaire plus simplement)
-// http://doc.spip.org/@filtre_valeur_tableau
-function filtre_valeur_tableau($array, $index) {
- if (!is_array($array)
- OR !isset($array[$index]))
- return null;
- return $array[$index];
-}
-// http://doc.spip.org/@filtre_reset
+/**
+ * Retourne la première valeur d'un tableau
+ *
+ * Plus précisément déplace le pointeur du tableau sur la première valeur et la retourne.
+ *
+ * @example `[(#LISTE{un,deux,trois}|reset)]` retourne 'un'
+ *
+ * @filtre
+ * @link http://php.net/manual/fr/function.reset.php
+ * @see filtre_end()
+ *
+ * @param array $array
+ * @return mixed|null|false
+ * - null si $array n'est pas un tableau,
+ * - false si le tableau est vide
+ * - la première valeur du tableau sinon.
+ **/
function filtre_reset($array) {
return !is_array($array) ? null : reset($array);
}
-// http://doc.spip.org/@filtre_end
+
+/**
+ * Retourne la dernière valeur d'un tableau
+ *
+ * Plus précisément déplace le pointeur du tableau sur la dernière valeur et la retourne.
+ *
+ * @example `[(#LISTE{un,deux,trois}|end)]` retourne 'trois'
+ *
+ * @filtre
+ * @link http://php.net/manual/fr/function.end.php
+ * @see filtre_reset()
+ *
+ * @param array $array
+ * @return mixed|null|false
+ * - null si $array n'est pas un tableau,
+ * - false si le tableau est vide
+ * - la dernière valeur du tableau sinon.
+ **/
function filtre_end($array) {
return !is_array($array) ? null : end($array);
}
-// http://doc.spip.org/@filtre_push
+/**
+ * Empile une valeur à la fin d'un tableau
+ *
+ * @example `[(#LISTE{un,deux,trois}|push{quatre}|print)]`
+ *
+ * @filtre
+ * @link http://www.spip.net/4571
+ * @link http://php.net/manual/fr/function.array-push.php
+ *
+ * @param array $array
+ * @param mixed $val
+ * @return array|string
+ * - '' si $array n'est pas un tableau ou si echec.
+ * - le tableau complété de la valeur sinon.
+ *
+ **/
function filtre_push($array, $val) {
- if($array == '' OR !array_push($array, $val)) return '';
+ if (!is_array($array) or !array_push($array, $val)) {
+ return '';
+ }
+
return $array;
}
-// http://doc.spip.org/@filtre_find
+/**
+ * Indique si une valeur est contenue dans un tableau
+ *
+ * @example `[(#LISTE{un,deux,trois}|find{quatre}|oui) ... ]`
+ *
+ * @filtre
+ * @link http://www.spip.net/4575
+ * @see in_any() Assez proche, avec les paramètres tableau et valeur inversés.
+ *
+ * @param array $array
+ * @param mixed $val
+ * @return bool
+ * - `false` si `$array` n'est pas un tableau
+ * - `true` si la valeur existe dans le tableau, `false` sinon.
+ **/
function filtre_find($array, $val) {
- return (is_array($array) AND in_array($val, $array));
+ return (is_array($array) and in_array($val, $array));
}
-//
-// fonction standard de calcul de la balise #PAGINATION
-// on peut la surcharger en definissant filtre_pagination dans mes_fonctions
-//
-
-// http://doc.spip.org/@filtre_pagination_dist
-function filtre_pagination_dist($total, $nom, $position, $pas, $liste = true, $modele='', $connect='', $env=array()) {
+/**
+ * Filtre calculant une pagination, utilisé par la balise `#PAGINATION`
+ *
+ * Le filtre cherche le modèle `pagination.html` par défaut, mais peut
+ * chercher un modèle de pagination particulier avec l'argument `$modele`.
+ * S'il `$modele='prive'`, le filtre cherchera le modèle `pagination_prive.html`.
+ *
+ * @filtre
+ * @see balise_PAGINATION_dist()
+ *
+ * @param int $total
+ * Nombre total d'éléments
+ * @param string $nom
+ * Nom identifiant la pagination
+ * @param int $position
+ * Page à afficher (tel que la 3è page)
+ * @param int $pas
+ * Nombre d'éléments par page
+ * @param bool $liste
+ * - True pour afficher toute la liste des éléments,
+ * - False pour n'afficher que l'ancre
+ * @param string $modele
+ * Nom spécifique du modèle de pagination
+ * @param string $connect
+ * Nom du connecteur à la base de données
+ * @param array $env
+ * Environnement à transmettre au modèle
+ * @return string
+ * Code HTML de la pagination
+ **/
+function filtre_pagination_dist(
+ $total,
+ $nom,
+ $position,
+ $pas,
+ $liste = true,
+ $modele = '',
+ $connect = '',
+ $env = array()
+) {
static $ancres = array();
- if ($pas<1) return '';
- $ancre = 'pagination'.$nom; // #pagination_articles
- $debut = 'debut'.$nom; // 'debut_articles'
+ if ($pas < 1) {
+ return '';
+ }
+ $ancre = 'pagination' . $nom; // #pagination_articles
+ $debut = 'debut' . $nom; // 'debut_articles'
// n'afficher l'ancre qu'une fois
- if (!isset($ancres[$ancre]))
- $bloc_ancre = $ancres[$ancre] = "<a name='".$ancre."' id='".$ancre."'></a>";
- else $bloc_ancre = '';
+ if (!isset($ancres[$ancre])) {
+ $bloc_ancre = $ancres[$ancre] = "<a name='" . $ancre . "' id='" . $ancre . "'></a>";
+ } else {
+ $bloc_ancre = '';
+ }
// liste = false : on ne veut que l'ancre
- if (!$liste)
+ if (!$liste) {
return $ancres[$ancre];
+ }
$pagination = array(
'debut' => $debut,
- 'url' => parametre_url(self(),'fragment',''), // nettoyer l'id ahah eventuel
+ 'url' => parametre_url(self(), 'fragment', ''), // nettoyer l'id ahah eventuel
'total' => $total,
'position' => intval($position),
'pas' => $pas,
- 'nombre_pages' => floor(($total-1)/$pas)+1,
- 'page_courante' => floor(intval($position)/$pas)+1,
+ 'nombre_pages' => floor(($total - 1) / $pas) + 1,
+ 'page_courante' => floor(intval($position) / $pas) + 1,
'ancre' => $ancre,
'bloc_ancre' => $bloc_ancre
);
- if (is_array($env))
- $pagination = array_merge($env,$pagination);
+ if (is_array($env)) {
+ $pagination = array_merge($env, $pagination);
+ }
// Pas de pagination
- if ($pagination['nombre_pages']<=1)
+ if ($pagination['nombre_pages'] <= 1) {
return '';
+ }
- if ($modele) $modele = '_'.$modele;
+ if ($modele) {
+ $modele = '_' . $modele;
+ }
- return recuperer_fond("modeles/pagination$modele", $pagination, array('trim'=>true), $connect);
+ return recuperer_fond("modeles/pagination$modele", $pagination, array('trim' => true), $connect);
}
-// passer les url relatives a la css d'origine en url absolues
-// http://doc.spip.org/@urls_absolues_css
+
+/**
+ * Passer les url relatives à la css d'origine en url absolues
+ *
+ * @uses suivre_lien()
+ *
+ * @param string $contenu
+ * Contenu du fichier CSS
+ * @param string $source
+ * Chemin du fichier CSS
+ * @return string
+ * Contenu avec urls en absolus
+ **/
function urls_absolues_css($contenu, $source) {
- $path = suivre_lien(url_absolue($source),'./');
+ $path = suivre_lien(url_absolue($source), './');
return preg_replace_callback(
- ",url\s*\(\s*['\"]?([^'\"/][^:]*)['\"]?\s*\),Uims",
+ ",url\s*\(\s*['\"]?([^'\"/#\s][^:]*)['\"]?\s*\),Uims",
create_function('$x',
- 'return "url(\"".suivre_lien("'.$path.'",$x[1])."\")";'
+ 'return "url(\'".suivre_lien(\'' . $path . '\',$x[1])."\')";'
), $contenu);
}
-// recuperere le chemin d'une css existante et :
-// 1. regarde si une css inversee droite-gauche existe dans le meme repertoire
-// 2. sinon la cree (ou la recree) dans _DIR_VAR/cache_css/
-// SI on lui donne a manger une feuille nommee _rtl.css il va faire l'inverse
-// http://doc.spip.org/@direction_css
-function direction_css ($css, $voulue='') {
- if (!preg_match(',(_rtl)?\.css$,i', $css, $r)) return $css;
+
+/**
+ * Inverse le code CSS (left <--> right) d'une feuille de style CSS
+ *
+ * Récupère le chemin d'une CSS existante et :
+ *
+ * 1. regarde si une CSS inversée droite-gauche existe dans le meme répertoire
+ * 2. sinon la crée (ou la recrée) dans `_DIR_VAR/cache_css/`
+ *
+ * Si on lui donne à manger une feuille nommée `*_rtl.css` il va faire l'inverse.
+ *
+ * @filtre
+ * @example
+ * ```
+ * [<link rel="stylesheet" href="(#CHEMIN{css/perso.css}|direction_css)" type="text/css" />]
+ * ```
+ * @param string $css
+ * Chemin vers le fichier CSS
+ * @param string $voulue
+ * Permet de forcer le sens voulu (en indiquant `ltr`, `rtl` ou un
+ * code de langue). En absence, prend le sens de la langue en cours.
+ *
+ * @return string
+ * Chemin du fichier CSS inversé
+ **/
+function direction_css($css, $voulue = '') {
+ if (!preg_match(',(_rtl)?\.css$,i', $css, $r)) {
+ return $css;
+ }
// si on a precise le sens voulu en argument, le prendre en compte
if ($voulue = strtolower($voulue)) {
- if ($voulue != 'rtl' AND $voulue != 'ltr')
+ if ($voulue != 'rtl' and $voulue != 'ltr') {
$voulue = lang_dir($voulue);
+ }
+ } else {
+ $voulue = lang_dir();
}
- else
- $voulue = lang_dir();
$r = count($r) > 1;
$right = $r ? 'left' : 'right'; // 'right' de la css lue en entree
$dir = $r ? 'rtl' : 'ltr';
$ndir = $r ? 'ltr' : 'rtl';
- if ($voulue == $dir)
+ if ($voulue == $dir) {
return $css;
+ }
if (
// url absolue
- preg_match(",^http:,i",$css)
+ preg_match(",^http:,i", $css)
// ou qui contient un ?
- OR (($p=strpos($css,'?'))!==FALSE)) {
+ or (($p = strpos($css, '?')) !== false)
+ ) {
$distant = true;
$cssf = parse_url($css);
- $cssf = $cssf['path'].($cssf['query']?"?".$cssf['query']:"");
+ $cssf = $cssf['path'] . ($cssf['query'] ? "?" . $cssf['query'] : "");
$cssf = preg_replace(',[?:&=],', "_", $cssf);
- }
- else {
+ } else {
$distant = false;
$cssf = $css;
// 1. regarder d'abord si un fichier avec la bonne direction n'est pas aussi
//propose (rien a faire dans ce cas)
- $f = preg_replace(',(_rtl)?\.css$,i', '_'.$ndir.'.css', $css);
- if (@file_exists($f))
+ $f = preg_replace(',(_rtl)?\.css$,i', '_' . $ndir . '.css', $css);
+ if (@file_exists($f)) {
return $f;
+ }
}
// 2.
- $dir_var = sous_repertoire (_DIR_VAR, 'cache-css');
+ $dir_var = sous_repertoire(_DIR_VAR, 'cache-css');
$f = $dir_var
. preg_replace(',.*/(.*?)(_rtl)?\.css,', '\1', $cssf)
- . '.' . substr(md5($cssf), 0,4) . '_' . $ndir . '.css';
+ . '.' . substr(md5($cssf), 0, 4) . '_' . $ndir . '.css';
// la css peut etre distante (url absolue !)
- if ($distant){
+ if ($distant) {
include_spip('inc/distant');
$contenu = recuperer_page($css);
- if (!$contenu) return $css;
- }
- else {
+ if (!$contenu) {
+ return $css;
+ }
+ } else {
if ((@filemtime($f) > @filemtime($css))
- AND (_VAR_MODE != 'recalcul'))
+ and (_VAR_MODE != 'recalcul')
+ ) {
return $f;
- if (!lire_fichier($css, $contenu))
+ }
+ if (!lire_fichier($css, $contenu)) {
return $css;
+ }
}
$contenu = str_replace(
array('right', 'left', '@@@@L E F T@@@@'),
array('@@@@L E F T@@@@', 'right', 'left'),
$contenu);
-
+
// reperer les @import auxquels il faut propager le direction_css
- preg_match_all(",\@import\s*url\s*\(\s*['\"]?([^'\"/][^:]*)['\"]?\s*\),Uims",$contenu,$regs);
- $src = array();$src_direction_css = array();$src_faux_abs=array();
+ preg_match_all(",\@import\s*url\s*\(\s*['\"]?([^'\"/][^:]*)['\"]?\s*\),Uims", $contenu, $regs);
+ $src = array();
+ $src_direction_css = array();
+ $src_faux_abs = array();
$d = dirname($css);
- foreach($regs[1] as $k=>$import_css){
- $css_direction = direction_css("$d/$import_css",$voulue);
+ foreach ($regs[1] as $k => $import_css) {
+ $css_direction = direction_css("$d/$import_css", $voulue);
// si la css_direction est dans le meme path que la css d'origine, on tronque le path, elle sera passee en absolue
- if (substr($css_direction,0,strlen($d)+1)=="$d/") $css_direction = substr($css_direction,strlen($d)+1);
- // si la css_direction commence par $dir_var on la fait passer pour une absolue
- elseif (substr($css_direction,0,strlen($dir_var))==$dir_var) {
- $css_direction = substr($css_direction,strlen($dir_var));
- $src_faux_abs["/@@@@@@/".$css_direction] = $css_direction;
- $css_direction = "/@@@@@@/".$css_direction;
+ if (substr($css_direction, 0, strlen($d) + 1) == "$d/") {
+ $css_direction = substr($css_direction, strlen($d) + 1);
+ } // si la css_direction commence par $dir_var on la fait passer pour une absolue
+ elseif (substr($css_direction, 0, strlen($dir_var)) == $dir_var) {
+ $css_direction = substr($css_direction, strlen($dir_var));
+ $src_faux_abs["/@@@@@@/" . $css_direction] = $css_direction;
+ $css_direction = "/@@@@@@/" . $css_direction;
}
$src[] = $regs[0][$k];
- $src_direction_css[] = str_replace($import_css,$css_direction,$regs[0][$k]);
+ $src_direction_css[] = str_replace($import_css, $css_direction, $regs[0][$k]);
}
- $contenu = str_replace($src,$src_direction_css,$contenu);
+ $contenu = str_replace($src, $src_direction_css, $contenu);
$contenu = urls_absolues_css($contenu, $css);
// virer les fausses url absolues que l'on a mis dans les import
- if (count($src_faux_abs))
- $contenu = str_replace(array_keys($src_faux_abs),$src_faux_abs,$contenu);
+ if (count($src_faux_abs)) {
+ $contenu = str_replace(array_keys($src_faux_abs), $src_faux_abs, $contenu);
+ }
- if (!ecrire_fichier($f, $contenu))
+ if (!ecrire_fichier($f, $contenu)) {
return $css;
+ }
return $f;
}
-// recuperere le chemin d'une css existante et :
-// cree (ou recree) dans _DIR_VAR/cache_css/ une css dont les url relatives sont passees en url absolues
-// http://doc.spip.org/@url_absolue_css
-function url_absolue_css ($css) {
- if (!preg_match(',\.css$,i', $css, $r)) return $css;
+
+/**
+ * Transforme les urls relatives d'un fichier CSS en absolues
+ *
+ * Récupère le chemin d'une css existante et crée (ou recrée) dans `_DIR_VAR/cache_css/`
+ * une css dont les url relatives sont passées en url absolues
+ *
+ * Le calcul n'est pas refait si le fichier cache existe déjà et que
+ * la source n'a pas été modifiée depuis.
+ *
+ * @uses recuperer_page() si l'URL source n'est pas sur le même site
+ * @uses urls_absolues_css()
+ *
+ * @param string $css
+ * Chemin ou URL du fichier CSS source
+ * @return string
+ * - Chemin du fichier CSS transformé (si source lisible et mise en cache réussie)
+ * - Chemin ou URL du fichier CSS source sinon.
+ **/
+function url_absolue_css($css) {
+ if (!preg_match(',\.css$,i', $css, $r)) {
+ return $css;
+ }
$url_absolue_css = url_absolue($css);
- $f = basename($css,'.css');
- $f = sous_repertoire (_DIR_VAR, 'cache-css')
- . preg_replace(",(.*?)(_rtl|_ltr)?$,","\\1-urlabs-" . substr(md5("$css-urlabs"), 0,4) . "\\2",$f)
+ $f = basename($css, '.css');
+ $f = sous_repertoire(_DIR_VAR, 'cache-css')
+ . preg_replace(",(.*?)(_rtl|_ltr)?$,", "\\1-urlabs-" . substr(md5("$css-urlabs"), 0, 4) . "\\2", $f)
. '.css';
- if ((@filemtime($f) > @filemtime($css))
- AND (_VAR_MODE != 'recalcul'))
+ if ((@filemtime($f) > @filemtime($css)) and (_VAR_MODE != 'recalcul')) {
return $f;
+ }
- if ($url_absolue_css==$css){
- if (strncmp($GLOBALS['meta']['adresse_site'],$css,$l=strlen($GLOBALS['meta']['adresse_site']))!=0
- OR !lire_fichier(_DIR_RACINE . substr($css,$l), $contenu)){
- include_spip('inc/distant');
- if (!$contenu = recuperer_page($css))
- return $css;
+ if ($url_absolue_css == $css) {
+ if (strncmp($GLOBALS['meta']['adresse_site'], $css, $l = strlen($GLOBALS['meta']['adresse_site'])) != 0
+ or !lire_fichier(_DIR_RACINE . substr($css, $l), $contenu)
+ ) {
+ include_spip('inc/distant');
+ if (!$contenu = recuperer_page($css)) {
+ return $css;
+ }
}
- }
- elseif (!lire_fichier($css, $contenu))
+ } elseif (!lire_fichier($css, $contenu)) {
return $css;
+ }
// passer les url relatives a la css d'origine en url absolues
$contenu = urls_absolues_css($contenu, $css);
// ecrire la css
- if (!ecrire_fichier($f, $contenu))
+ if (!ecrire_fichier($f, $contenu)) {
return $css;
+ }
return $f;
}
-
/**
- * Le filtre table_valeur
- * permet de recuperer la valeur d'une cle donnee
+ * Récupère la valeur d'une clé donnée
* dans un tableau (ou un objet).
- *
+ *
+ * @filtre
+ * @link http://www.spip.net/4572
+ * @example
+ * ```
+ * [(#VALEUR|table_valeur{cle/sous/element})]
+ * ```
+ *
* @param mixed $table
- * Tableau ou objet
- * (ou chaine serialisee de tableau, ce qui permet d'enchainer le filtre)
- *
+ * Tableau ou objet PHP
+ * (ou chaîne serialisée de tableau, ce qui permet d'enchaîner le filtre)
* @param string $cle
- * Cle du tableau (ou parametre public de l'objet)
- * Cette cle peut contenir des caracteres / pour selectionner
- * des sous elements dans le tableau, tel que "sous/element/ici"
- * pour obtenir la valeur de $tableau['sous']['element']['ici']
- *
+ * Clé du tableau (ou paramètre public de l'objet)
+ * Cette clé peut contenir des caractères / pour sélectionner
+ * des sous éléments dans le tableau, tel que `sous/element/ici`
+ * pour obtenir la valeur de `$tableau['sous']['element']['ici']`
* @param mixed $defaut
- * Valeur par defaut retournee si la cle demandee n'existe pas
+ * Valeur par defaut retournée si la clé demandée n'existe pas
+ * @param bool $conserver_null
+ * Permet de forcer la fonction à renvoyer la valeur null d'un index
+ * et non pas $defaut comme cela est fait naturellement par la fonction
+ * isset. On utilise alors array_key_exists() à la place de isset().
*
- * @return mixed Valeur trouvee ou valeur par defaut.
-**/
-function table_valeur($table, $cle, $defaut='') {
+ * @return mixed
+ * Valeur trouvée ou valeur par défaut.
+ **/
+function table_valeur($table, $cle, $defaut = '', $conserver_null = false) {
foreach (explode('/', $cle) as $k) {
$table = is_string($table) ? @unserialize($table) : $table;
if (is_object($table)) {
- $table = (($k !== "") and isset($table->$k)) ? $table->$k : $defaut;
+ $table = (($k !== "") and isset($table->$k)) ? $table->$k : $defaut;
} elseif (is_array($table)) {
- $table = isset($table[$k]) ? $table[$k] : $defaut;
+ if ($conserver_null) {
+ $table = array_key_exists($k, $table) ? $table[$k] : $defaut;
+ } else {
+ $table = isset($table[$k]) ? $table[$k] : $defaut;
+ }
} else {
$table = $defaut;
}
}
+
return $table;
}
-// filtre match pour faire des tests avec expression reguliere
-// [(#TEXTE|match{^ceci$,Uims})]
-// retourne le fragment de chaine qui "matche"
-// il est possible de passer en 3eme argument optionnel le numero de parenthese capturante
-// accepte egalement la syntaxe #TRUC|match{truc(...)$,1} ou le modificateur n'est pas passe en second argument
-// http://doc.spip.org/@match
-function match($texte, $expression, $modif="UimsS",$capte=0) {
- if (intval($modif) AND $capte==0){
+/**
+ * Retrouve un motif dans un texte à partir d'une expression régulière
+ *
+ * S'appuie sur la fonction `preg_match()` en PHP
+ *
+ * @example
+ * - `[(#TITRE|match{toto})]`
+ * - `[(#TEXTE|match{^ceci$,Uims})]`
+ * - `[(#TEXTE|match{truc(...)$, UimsS, 1})]` Capture de la parenthèse indiquée
+ * - `[(#TEXTE|match{truc(...)$, 1})]` Équivalent, sans indiquer les modificateurs
+ *
+ * @filtre
+ * @link http://www.spip.net/4299
+ * @link http://php.net/manual/fr/function.preg-match.php Pour des infos sur `preg_match()`
+ *
+ * @param string $texte
+ * Texte dans lequel chercher
+ * @param string|int $expression
+ * Expression régulière de recherche, sans le délimiteur
+ * @param string $modif
+ * - string : Modificateurs de l'expression régulière
+ * - int : Numéro de parenthèse capturante
+ * @param int $capte
+ * Numéro de parenthèse capturante
+ * @return bool|string
+ * - false : l'expression n'a pas été trouvée
+ * - true : expression trouvée, mais pas la parenthèse capturante
+ * - string : expression trouvée.
+ **/
+function match($texte, $expression, $modif = "UimsS", $capte = 0) {
+ if (intval($modif) and $capte == 0) {
$capte = $modif;
$modif = "UimsS";
}
- $expression=str_replace("\/","/",$expression);
- $expression=str_replace("/","\/",$expression);
+ $expression = str_replace("\/", "/", $expression);
+ $expression = str_replace("/", "\/", $expression);
- if (preg_match('/' . $expression . '/' . $modif,$texte, $r)) {
- if (isset($r[$capte]))
+ if (preg_match('/' . $expression . '/' . $modif, $texte, $r)) {
+ if (isset($r[$capte])) {
return $r[$capte];
- else
+ } else {
return true;
+ }
}
+
return false;
}
-// filtre replace pour faire des operations avec expression reguliere
-// [(#TEXTE|replace{^ceci$,cela,UimsS})]
-// http://doc.spip.org/@replace
-function replace($texte, $expression, $replace='', $modif="UimsS") {
- $expression=str_replace("\/","/", $expression);
- $expression=str_replace("/","\/",$expression);
+
+/**
+ * Remplacement de texte à base d'expression régulière
+ *
+ * @filtre
+ * @link http://www.spip.net/4309
+ * @see match()
+ * @example
+ * ```
+ * [(#TEXTE|replace{^ceci$,cela,UimsS})]
+ * ```
+ *
+ * @param string $texte
+ * Texte
+ * @param string $expression
+ * Expression régulière
+ * @param string $replace
+ * Texte de substitution des éléments trouvés
+ * @param string $modif
+ * Modificateurs pour l'expression régulière.
+ * @return string
+ * Texte
+ **/
+function replace($texte, $expression, $replace = '', $modif = "UimsS") {
+ $expression = str_replace("\/", "/", $expression);
+ $expression = str_replace("/", "\/", $expression);
+
return preg_replace('/' . $expression . '/' . $modif, $replace, $texte);
}
-// cherche les documents numerotes dans un texte traite par propre()
-// et affecte les doublons['documents']
-// http://doc.spip.org/@traiter_doublons_documents
-// http://doc.spip.org/@traiter_doublons_documents
+/**
+ * Cherche les documents numerotés dans un texte traite par `propre()`
+ *
+ * Affecte la liste des doublons['documents']
+ *
+ * @param array $doublons
+ * Liste des doublons
+ * @param string $letexte
+ * Le texte
+ * @return string
+ * Le texte
+ **/
function traiter_doublons_documents(&$doublons, $letexte) {
// Verifier dans le texte & les notes (pas beau, helas)
- $t = $letexte.$GLOBALS['les_notes'];
+ $t = $letexte . $GLOBALS['les_notes'];
if (strstr($t, 'spip_document_') // evite le preg_match_all si inutile
- AND preg_match_all(
- ',<[^>]+\sclass=["\']spip_document_([0-9]+)[\s"\'],imsS',
- $t, $matches, PREG_PATTERN_ORDER))
+ and preg_match_all(
+ ',<[^>]+\sclass=["\']spip_document_([0-9]+)[\s"\'],imsS',
+ $t, $matches, PREG_PATTERN_ORDER)
+ ) {
+ if (!isset($doublons['documents'])) {
+ $doublons['documents'] = "";
+ }
$doublons['documents'] .= "," . join(',', $matches[1]);
+ }
return $letexte;
}
-// filtre vide qui ne renvoie rien
-// http://doc.spip.org/@vide
-function vide($texte){
+/**
+ * Filtre vide qui ne renvoie rien
+ *
+ * @example
+ * `[(#CALCUL|vide)]` n'affichera pas le résultat du calcul
+ * @filtre
+ *
+ * @param mixed $texte
+ * @return string Chaîne vide
+ **/
+function vide($texte) {
return "";
}
// Filtres pour le modele/emb (embed document)
//
-// A partir d'un #ENV, retourne des <param ...>
-// http://doc.spip.org/@env_to_params
-function env_to_params ($texte, $ignore_params=array()) {
- $ignore_params = array_merge (
+/**
+ * Écrit des balises HTML `<param...>` à partir d'un tableau de données tel que `#ENV`
+ *
+ * Permet d'écrire les balises `<param>` à indiquer dans un `<object>`
+ * en prenant toutes les valeurs du tableau transmis.
+ *
+ * Certaines clés spécifiques à SPIP et aux modèles embed sont omises :
+ * id, lang, id_document, date, date_redac, align, fond, recurs, emb, dir_racine
+ *
+ * @example `[(#ENV*|env_to_params)]`
+ *
+ * @filtre
+ * @link http://www.spip.net/4005
+ *
+ * @param array|string $env
+ * Tableau cle => valeur des paramètres à écrire, ou chaine sérialisée de ce tableau
+ * @param array $ignore_params
+ * Permet de compléter les clés ignorées du tableau.
+ * @return string
+ * Code HTML résultant
+ **/
+function env_to_params($env, $ignore_params = array()) {
+ $ignore_params = array_merge(
array('id', 'lang', 'id_document', 'date', 'date_redac', 'align', 'fond', '', 'recurs', 'emb', 'dir_racine'),
- $ignore_params);
- $tableau = unserialize($texte);
+ $ignore_params
+ );
+ if (!is_array($env)) {
+ $env = unserialize($env);
+ }
$texte = "";
- foreach ($tableau as $i => $j)
- if (is_string($j) AND !in_array($i,$ignore_params))
- $texte .= "<param name='".$i."'\n\tvalue='".$j."' />";
+ if ($env) {
+ foreach ($env as $i => $j) {
+ if (is_string($j) and !in_array($i, $ignore_params)) {
+ $texte .= "<param name='" . $i . "'\n\tvalue='" . $j . "' />";
+ }
+ }
+ }
+
return $texte;
}
-// A partir d'un #ENV, retourne des attributs
-// http://doc.spip.org/@env_to_attributs
-function env_to_attributs ($texte, $ignore_params=array()) {
- $ignore_params = array_merge (
+
+/**
+ * Écrit des attributs HTML à partir d'un tableau de données tel que `#ENV`
+ *
+ * Permet d'écrire des attributs d'une balise HTML en utilisant les données du tableau transmis.
+ * Chaque clé deviendra le nom de l'attribut (et la valeur, sa valeur)
+ *
+ * Certaines clés spécifiques à SPIP et aux modèles embed sont omises :
+ * id, lang, id_document, date, date_redac, align, fond, recurs, emb, dir_racine
+ *
+ * @example `<embed src='#URL_DOCUMENT' [(#ENV*|env_to_attributs)] width='#GET{largeur}' height='#GET{hauteur}'></embed>`
+ * @filtre
+ *
+ * @param array|string $env
+ * Tableau cle => valeur des attributs à écrire, ou chaine sérialisée de ce tableau
+ * @param array $ignore_params
+ * Permet de compléter les clés ignorées du tableau.
+ * @return string
+ * Code HTML résultant
+ **/
+function env_to_attributs($env, $ignore_params = array()) {
+ $ignore_params = array_merge(
array('id', 'lang', 'id_document', 'date', 'date_redac', 'align', 'fond', '', 'recurs', 'emb', 'dir_racine'),
- $ignore_params);
- $tableau = unserialize($texte);
+ $ignore_params
+ );
+ if (!is_array($env)) {
+ $env = unserialize($env);
+ }
$texte = "";
- foreach ($tableau as $i => $j)
- if (is_string($j) AND !in_array($i,$ignore_params))
- $texte .= $i."='".$j."' ";
+ if ($env) {
+ foreach ($env as $i => $j) {
+ if (is_string($j) and !in_array($i, $ignore_params)) {
+ $texte .= $i . "='" . $j . "' ";
+ }
+ }
+ }
+
return $texte;
}
-// Concatener des chaines
-// #TEXTE|concat{texte1,texte2,...}
-// http://doc.spip.org/@concat
-function concat(){
+
+/**
+ * Concatène des chaînes
+ *
+ * @filtre
+ * @link http://www.spip.net/4150
+ * @example
+ * ```
+ * #TEXTE|concat{texte1,texte2,...}
+ * ```
+ *
+ * @return string Chaînes concaténés
+ **/
+function concat() {
$args = func_get_args();
+
return join('', $args);
}
-// http://doc.spip.org/@charge_scripts
-function charge_scripts($scripts) {
- $flux = "";
- $args = is_array($scripts)?$scripts:explode("|",$scripts);
- foreach($args as $script) {
- if(preg_match(",^\w+$,",$script)) {
- $path = find_in_path("javascript/$script.js");
- if($path) $flux .= spip_file_get_contents($path);
- }
- }
- return $flux;
-}
+/**
+ * Retourne le contenu d'un ou plusieurs fichiers
+ *
+ * Les chemins sont cherchés dans le path de SPIP
+ *
+ * @see balise_INCLURE_dist() La balise `#INCLURE` peut appeler cette fonction
+ *
+ * @param array|string $files
+ * - array : Liste de fichiers
+ * - string : fichier ou fichiers séparés par `|`
+ * @param bool $script
+ * - si true, considère que c'est un fichier js à chercher `javascript/`
+ * @return string
+ * Contenu du ou des fichiers, concaténé
+ **/
+function charge_scripts($files, $script = true) {
+ $flux = "";
+ foreach (is_array($files) ? $files : explode("|", $files) as $file) {
+ if (!is_string($file)) {
+ continue;
+ }
+ if ($script) {
+ $file = preg_match(",^\w+$,", $file) ? "javascript/$file.js" : '';
+ }
+ if ($file) {
+ $path = find_in_path($file);
+ if ($path) {
+ $flux .= spip_file_get_contents($path);
+ }
+ }
+ }
+ return $flux;
+}
/**
- * produit une balise img avec un champ alt d'office si vide
- * attention le htmlentities et la traduction doivent etre appliques avant.
+ * Produit une balise img avec un champ alt d'office si vide
*
- * http://doc.spip.org/@http_img_pack
+ * Attention le htmlentities et la traduction doivent être appliqués avant.
*
- * @param $img
- * @param $alt
+ * @param string $img
+ * @param string $alt
* @param string $atts
* @param string $title
* @param array $options
* sous forme -xx.png (pour les icones essentiellement) (oui par defaut)
* @return string
*/
-function http_img_pack($img, $alt, $atts='', $title='', $options = array()) {
- if (!isset($options['chemin_image']) OR $options['chemin_image']==true)
+function http_img_pack($img, $alt, $atts = '', $title = '', $options = array()) {
+ if (!isset($options['chemin_image']) or $options['chemin_image'] == true) {
$img = chemin_image($img);
- if (stripos($atts, 'width')===false){
+ }
+ if (stripos($atts, 'width') === false) {
// utiliser directement l'info de taille presente dans le nom
- if ((!isset($options['utiliser_suffixe_size']) OR $options['utiliser_suffixe_size']==true)
- AND preg_match(',-([0-9]+)[.](png|gif)$,',$img,$regs)){
+ if ((!isset($options['utiliser_suffixe_size']) or $options['utiliser_suffixe_size'] == true)
+ and preg_match(',-([0-9]+)[.](png|gif)$,', $img, $regs)
+ ) {
$largeur = $hauteur = intval($regs[1]);
- }
- else{
+ } else {
$taille = taille_image($img);
- list($hauteur,$largeur) = $taille;
- if (!$hauteur OR !$largeur)
+ list($hauteur, $largeur) = $taille;
+ if (!$hauteur or !$largeur) {
return "";
+ }
}
- $atts.=" width='".$largeur."' height='".$hauteur."'";
+ $atts .= " width='" . $largeur . "' height='" . $hauteur . "'";
}
- return "<img src='$img' alt='" . attribut_html($alt ? $alt : $title) . "'"
- . ($title ? ' title="'.attribut_html($title).'"' : '')
- . " ".ltrim($atts)
- . " />";
+
+ return "<img src='$img' alt='" . attribut_html($alt ? $alt : $title) . "'"
+ . ($title ? ' title="' . attribut_html($title) . '"' : '')
+ . " " . ltrim($atts)
+ . " />";
}
/**
- * generer une directive style='background:url()' a partir d'un fichier image
- *
- * http://doc.spip.org/@http_style_background
+ * Générer une directive `style='background:url()'` à partir d'un fichier image
*
* @param string $img
* @param string $att
* @return string
*/
-function http_style_background($img, $att=''){
- return " style='background".($att?"":"-image").": url(\"".chemin_image($img)."\")" . ($att ? (' ' . $att) : '') . ";'";
+function http_style_background($img, $att = '') {
+ return " style='background" . ($att ? "" : "-image") . ": url(\"" . chemin_image($img) . "\")" . ($att ? (' ' . $att) : '') . ";'";
}
/**
- * une fonction pour generer une balise img a partir d'un nom de fichier
+ * Générer une balise HTML `img` à partir d'un nom de fichier
+ *
+ * @uses http_img_pack()
*
* @param string $img
* @param string $alt
* @param string $class
* @return string
+ * Code HTML de la balise IMG
*/
-function filtre_balise_img_dist($img,$alt="",$class=""){
- return http_img_pack($img, $alt, $class?" class='".attribut_html($class)."'":'', '', array('chemin_image'=>false,'utiliser_suffixe_size'=>false));
+function filtre_balise_img_dist($img, $alt = "", $class = "") {
+ return http_img_pack($img, $alt, $class ? " class='" . attribut_html($class) . "'" : '', '',
+ array('chemin_image' => false, 'utiliser_suffixe_size' => false));
}
-//[(#ENV*|unserialize|foreach)]
-// http://doc.spip.org/@filtre_foreach_dist
-function filtre_foreach_dist($balise_deserializee, $modele = 'foreach') {
+/**
+ * Affiche chaque valeur d'un tableau associatif en utilisant un modèle
+ *
+ * @example
+ * - `[(#ENV*|unserialize|foreach)]`
+ * - `[(#ARRAY{a,un,b,deux}|foreach)]`
+ *
+ * @filtre
+ * @link http://www.spip.net/4248
+ *
+ * @param array $tableau
+ * Tableau de données à afficher
+ * @param string $modele
+ * Nom du modèle à utiliser
+ * @return string
+ * Code HTML résultant
+ **/
+function filtre_foreach_dist($tableau, $modele = 'foreach') {
$texte = '';
- if(is_array($balise_deserializee))
- foreach($balise_deserializee as $k => $v) {
- $res = recuperer_fond('modeles/'.$modele,
+ if (is_array($tableau)) {
+ foreach ($tableau as $k => $v) {
+ $res = recuperer_fond('modeles/' . $modele,
array_merge(array('cle' => $k), (is_array($v) ? $v : array('valeur' => $v)))
);
$texte .= $res;
}
+ }
+
return $texte;
}
-// renvoie la liste des plugins actifs du site
-// si le premier parametre est un prefix de cette liste, renvoie vrai, faux sinon
-// la valeur du second parametre si celui-ci renvoie a une information connue
-// cf liste_plugin_actifs() pour connaitre les informations affichables
-// appelee par la balise #PLUGIN
-// http://doc.spip.org/@filtre_info_plugin_dist
-function filtre_info_plugin_dist($plugin, $type_info) {
+
+/**
+ * Obtient des informations sur les plugins actifs
+ *
+ * @filtre
+ * @uses liste_plugin_actifs() pour connaître les informations affichables
+ *
+ * @param string $plugin
+ * Préfixe du plugin ou chaîne vide
+ * @param string $type_info
+ * Type d'info demandée
+ * @param bool $reload
+ * true (à éviter) pour forcer le recalcul du cache des informations des plugins.
+ * @return array|string|bool
+ *
+ * - Liste sérialisée des préfixes de plugins actifs (si $plugin = '')
+ * - Suivant $type_info, avec $plugin un préfixe
+ * - est_actif : renvoie true s'il est actif, false sinon
+ * - x : retourne l'information x du plugin si présente (et plugin actif)
+ * - tout : retourne toutes les informations du plugin actif
+ **/
+function filtre_info_plugin_dist($plugin, $type_info, $reload = false) {
include_spip('inc/plugin');
$plugin = strtoupper($plugin);
$plugins_actifs = liste_plugin_actifs();
- if (!$plugin)
+ if (!$plugin) {
return serialize(array_keys($plugins_actifs));
- elseif (empty($plugins_actifs[$plugin]))
+ } elseif (empty($plugins_actifs[$plugin]) and !$reload) {
return '';
- elseif ($type_info == 'est_actif')
+ } elseif (($type_info == 'est_actif') and !$reload) {
return $plugins_actifs[$plugin] ? 1 : 0;
- elseif (isset($plugins_actifs[$plugin][$type_info]))
+ } elseif (isset($plugins_actifs[$plugin][$type_info]) and !$reload) {
return $plugins_actifs[$plugin][$type_info];
- else {
- $get_infos = charger_fonction('get_infos','plugins');
+ } else {
+ $get_infos = charger_fonction('get_infos', 'plugins');
// On prend en compte les extensions
- if (!is_dir($plugins_actifs[$plugin]['dir_type']))
+ if (!is_dir($plugins_actifs[$plugin]['dir_type'])) {
$dir_plugins = constant($plugins_actifs[$plugin]['dir_type']);
- else
+ } else {
$dir_plugins = $plugins_actifs[$plugin]['dir_type'];
- if (!$infos = $get_infos($plugins_actifs[$plugin]['dir'], false, $dir_plugins))
+ }
+ if (!$infos = $get_infos($plugins_actifs[$plugin]['dir'], $reload, $dir_plugins)) {
return '';
- if ($type_info == 'tout')
+ }
+ if ($type_info == 'tout') {
return $infos;
- else
+ } elseif ($type_info == 'est_actif') {
+ return $infos ? 1 : 0;
+ } else {
return strval($infos[$type_info]);
+ }
}
}
-// http://doc.spip.org/@puce_changement_statut
-function puce_changement_statut($id_objet, $statut, $id_rubrique, $type, $ajax=false){
- $puce_statut = charger_fonction('puce_statut','inc');
+/**
+ * Affiche la puce statut d'un objet, avec un menu rapide pour changer
+ * de statut si possibilité de l'avoir
+ *
+ * @see inc_puce_statut_dist()
+ *
+ * @filtre
+ *
+ * @param int $id_objet
+ * Identifiant de l'objet
+ * @param string $statut
+ * Statut actuel de l'objet
+ * @param int $id_rubrique
+ * Identifiant du parent
+ * @param string $type
+ * Type d'objet
+ * @param bool $ajax
+ * Indique s'il ne faut renvoyer que le coeur du menu car on est
+ * dans une requete ajax suite à un post de changement rapide
+ * @return string
+ * Code HTML de l'image de puce de statut à insérer (et du menu de changement si présent)
+ */
+function puce_changement_statut($id_objet, $statut, $id_rubrique, $type, $ajax = false) {
+ $puce_statut = charger_fonction('puce_statut', 'inc');
+
return $puce_statut($id_objet, $statut, $id_rubrique, $type, $ajax);
}
+
/**
- * [(#STATUT|puce_statut{article})] affiche une puce passive
- * [(#STATUT|puce_statut{article,#ID_ARTICLE,#ID_RUBRIQUE})] affiche une puce avec changement rapide
+ * Affiche la puce statut d'un objet, avec un menu rapide pour changer
+ * de statut si possibilité de l'avoir
+ *
+ * Utilisable sur tout objet qui a declaré ses statuts
+ *
+ * @example
+ * [(#STATUT|puce_statut{article})] affiche une puce passive
+ * [(#STATUT|puce_statut{article,#ID_ARTICLE,#ID_RUBRIQUE})] affiche une puce avec changement rapide
+ *
+ * @see inc_puce_statut_dist()
+ *
+ * @filtre
*
- * utilisable sur tout objet qui a declare
* @param string $statut
+ * Statut actuel de l'objet
* @param string $objet
+ * Type d'objet
* @param int $id_objet
+ * Identifiant de l'objet
* @param int $id_parent
+ * Identifiant du parent
* @return string
+ * Code HTML de l'image de puce de statut à insérer (et du menu de changement si présent)
*/
-function filtre_puce_statut_dist($statut,$objet,$id_objet=0,$id_parent=0){
+function filtre_puce_statut_dist($statut, $objet, $id_objet = 0, $id_parent = 0) {
static $puce_statut = null;
- if (!$puce_statut)
- $puce_statut = charger_fonction('puce_statut','inc');
- return $puce_statut($id_objet, $statut, $id_parent, $objet, false, objet_info($objet,'editable')?_ACTIVER_PUCE_RAPIDE:false);
+ if (!$puce_statut) {
+ $puce_statut = charger_fonction('puce_statut', 'inc');
+ }
+
+ return $puce_statut($id_objet, $statut, $id_parent, $objet, false,
+ objet_info($objet, 'editable') ? _ACTIVER_PUCE_RAPIDE : false);
}
/**
- * Encoder un contexte pour l'ajax, le signer avec une cle, le crypter
- * avec le secret du site, le gziper si possible...
- * l'entree peut etre serialisee (le #ENV** des fonds ajax et ajax_stat)
+ * Encoder un contexte pour l'ajax
+ *
+ * Encoder le contexte, le signer avec une clé, le crypter
+ * avec le secret du site, le gziper si possible.
*
- * http://doc.spip.org/@encoder_contexte_ajax
+ * L'entrée peut-être sérialisée (le `#ENV**` des fonds ajax et ajax_stat)
+ *
+ * @see decoder_contexte_ajax()
+ * @uses calculer_cle_action()
*
* @param string|array $c
* contexte, peut etre un tableau serialize
* @param string $ajaxid
* ajaxid pour cibler le bloc et forcer sa mise a jour
* @return string
+ * hash du contexte
*/
-function encoder_contexte_ajax($c,$form='', $emboite=NULL, $ajaxid='') {
+function encoder_contexte_ajax($c, $form = '', $emboite = null, $ajaxid = '') {
if (is_string($c)
- AND !is_null(@unserialize($c))) {
+ and @unserialize($c) !== false
+ ) {
$c = unserialize($c);
}
// pour que la pagination ajax ne soit pas plantee
// si on charge la page &debut_x=1 : car alors en cliquant sur l'item 0,
// le debut_x=0 n'existe pas, et on resterait sur 1
- foreach ($c as $k => $v) {
- if (strpos($k,'debut_') === 0) {
- unset($c[$k]);
+ if (is_array($c)) {
+ foreach ($c as $k => $v) {
+ if (strpos($k, 'debut_') === 0) {
+ unset($c[$k]);
+ }
}
}
-
- if (!function_exists('calculer_cle_action'))
+
+ if (!function_exists('calculer_cle_action')) {
include_spip("inc/securiser_action");
- $cle = calculer_cle_action($form.(is_array($c)?serialize($c):$c));
- $c = serialize(array($c,$cle));
+ }
+
+ $c = serialize($c);
+ $cle = calculer_cle_action($form . $c);
+ $c = "$cle:$c";
// on ne stocke pas les contextes dans des fichiers caches
// par defaut, sauf si cette configuration a ete forcee
// OU que la longueur de l''argument generee est plus long
// que ce que telere Suhosin.
- $cache_contextes_ajax = (defined('_CACHE_CONTEXTES_AJAX') AND _CACHE_CONTEXTES_AJAX);
+ $cache_contextes_ajax = (defined('_CACHE_CONTEXTES_AJAX') and _CACHE_CONTEXTES_AJAX);
if (!$cache_contextes_ajax) {
$env = $c;
if (function_exists('gzdeflate') && function_exists('gzinflate')) {
$env = gzdeflate($env);
- // http://core.spip.org/issues/2667 | https://bugs.php.net/bug.php?id=61287
- if (substr(phpversion(),0,5) == '5.4.0' AND !@gzinflate($env)) {
+ // http://core.spip.net/issues/2667 | https://bugs.php.net/bug.php?id=61287
+ if ((PHP_VERSION_ID == 50400) and !@gzinflate($env)) {
$cache_contextes_ajax = true;
spip_log("Contextes AJAX forces en fichiers ! Erreur PHP 5.4.0", _LOG_AVERTISSEMENT);
}
$env = base64_encode($env);
// tester Suhosin et la valeur maximale des variables en GET...
if ($max_len = @ini_get('suhosin.get.max_value_length')
- and $max_len < ($len = strlen($env))) {
+ and $max_len < ($len = strlen($env))
+ ) {
$cache_contextes_ajax = true;
spip_log("Contextes AJAX forces en fichiers !"
. " Cela arrive lorsque la valeur du contexte"
. " pour accepter au moins 1024 caracteres.", _LOG_AVERTISSEMENT);
}
}
-
+
if ($cache_contextes_ajax) {
$dir = sous_repertoire(_DIR_CACHE, 'contextes');
// stocker les contextes sur disque et ne passer qu'un hash dans l'url
$md5 = md5($c);
- ecrire_fichier("$dir/c$md5",$c);
+ ecrire_fichier("$dir/c$md5", $c);
$env = $md5;
- }
-
- if ($emboite === NULL) return $env;
- if (!trim($emboite)) return "";
+ }
+
+ if ($emboite === null) {
+ return $env;
+ }
+ if (!trim($emboite)) {
+ return "";
+ }
// toujours encoder l'url source dans le bloc ajax
$r = self();
- $r = ' data-origin="'.$r.'"';
+ $r = ' data-origin="' . $r . '"';
$class = 'ajaxbloc';
- if ($ajaxid AND is_string($ajaxid)){
- $class .= ' ajax-id-'.$ajaxid;
+ if ($ajaxid and is_string($ajaxid)) {
+ // ajaxid est normalement conforme a un nom de classe css
+ // on ne verifie pas la conformite, mais on passe entites_html par dessus par precaution
+ $class .= ' ajax-id-' . entites_html($ajaxid);
}
- $compl = "aria-live='polite' aria-atomic='true' ";
- return "<div class='$class' ".$compl."data-ajax-env='$env'$r>\n$emboite</div><!--ajaxbloc-->\n";
+
+ return "<div class='$class' " . "data-ajax-env='$env'$r>\n$emboite</div><!--ajaxbloc-->\n";
}
-// la procedure inverse de encoder_contexte_ajax()
-// http://doc.spip.org/@decoder_contexte_ajax
-function decoder_contexte_ajax($c,$form='') {
- if (!function_exists('calculer_cle_action'))
+/**
+ * Décoder un hash de contexte pour l'ajax
+ *
+ * Précude inverse de `encoder_contexte_ajax()`
+ *
+ * @see encoder_contexte_ajax()
+ * @uses calculer_cle_action()
+ *
+ * @param string $c
+ * hash du contexte
+ * @param string $form
+ * nom du formulaire eventuel
+ * @return array|string|bool
+ * - array|string : contexte d'environnement, possiblement sérialisé
+ * - false : erreur de décodage
+ */
+function decoder_contexte_ajax($c, $form = '') {
+ if (!function_exists('calculer_cle_action')) {
include_spip("inc/securiser_action");
- if (( (defined('_CACHE_CONTEXTES_AJAX') AND _CACHE_CONTEXTES_AJAX) OR strlen($c)==32)
- AND $dir = sous_repertoire(_DIR_CACHE, 'contextes')
- AND lire_fichier("$dir/c$c",$contexte)) {
- $c = $contexte;
+ }
+ if (((defined('_CACHE_CONTEXTES_AJAX') and _CACHE_CONTEXTES_AJAX) or strlen($c) == 32)
+ and $dir = sous_repertoire(_DIR_CACHE, 'contextes')
+ and lire_fichier("$dir/c$c", $contexte)
+ ) {
+ $c = $contexte;
} else {
$c = @base64_decode($c);
$c = _xor($c);
- if (function_exists('gzdeflate') && function_exists('gzinflate'))
+ if (function_exists('gzdeflate') && function_exists('gzinflate')) {
$c = @gzinflate($c);
+ }
+ }
+
+ // extraire la signature en debut de contexte
+ // et la verifier avant de deserializer
+ // format : signature:donneesserializees
+ if ($p = strpos($c,":")){
+ $cle = substr($c,0,$p);
+ $c = substr($c,$p+1);
+
+ if ($cle == calculer_cle_action($form . $c)) {
+ $env = @unserialize($c);
+ return $env;
+ }
}
- list($env, $cle) = @unserialize($c);
- if ($cle == calculer_cle_action($form.(is_array($env)?serialize($env):$env)))
- return $env;
return false;
}
-// encrypter/decrypter un message
-// http://www.php.net/manual/fr/language.operators.bitwise.php#81358
-// http://doc.spip.org/@_xor
-function _xor($message, $key=null){
+
+/**
+ * Encrypte ou décrypte un message
+ *
+ * @link http://www.php.net/manual/fr/language.operators.bitwise.php#81358
+ *
+ * @param string $message
+ * Message à encrypter ou décrypter
+ * @param null|string $key
+ * Clé de cryptage / décryptage.
+ * Une clé sera calculée si non transmise
+ * @return string
+ * Message décrypté ou encrypté
+ **/
+function _xor($message, $key = null) {
if (is_null($key)) {
- if (!function_exists('calculer_cle_action'))
+ if (!function_exists('calculer_cle_action')) {
include_spip("inc/securiser_action");
+ }
$key = pack("H*", calculer_cle_action('_xor'));
}
$keylen = strlen($key);
$messagelen = strlen($message);
- for($i=0; $i<$messagelen; $i++)
- $message[$i] = ~($message[$i]^$key[$i%$keylen]);
+ for ($i = 0; $i < $messagelen; $i++) {
+ $message[$i] = ~($message[$i] ^ $key[$i % $keylen]);
+ }
return $message;
}
-// Les vrai fonctions sont dans le plugin forum, mais on evite ici une erreur du compilateur
-// en absence du plugin
-function url_reponse_forum($texte){return $texte;}
-function url_rss_forum($texte){return $texte;}
+/**
+ * Retourne une URL de réponse de forum (aucune action ici)
+ *
+ * @see filtre_url_reponse_forum() du plugin forum (prioritaire)
+ * @note
+ * La vraie fonction est dans le plugin forum,
+ * mais on évite ici une erreur du compilateur en absence du plugin
+ * @param string $texte
+ * @return string
+ */
+function url_reponse_forum($texte) { return $texte; }
+
+/**
+ * retourne une URL de suivi rss d'un forum (aucune action ici)
+ *
+ * @see filtre_url_rss_forum() du plugin forum (prioritaire)
+ * @note
+ * La vraie fonction est dans le plugin forum,
+ * mais on évite ici une erreur du compilateur en absence du plugin
+ * @param string $texte
+ * @return string
+ */
+function url_rss_forum($texte) { return $texte; }
/**
- * une fonction pour generer des menus avec liens
- * ou un <strong class='on'> non clicable lorsque l'item est selectionne
+ * Génère des menus avec liens ou `<strong class='on'>` non clicable lorsque
+ * l'item est sélectionné
+ *
+ * @filtre
+ * @link http://www.spip.net/4004
+ * @example
+ * ```
+ * [(#URL_RUBRIQUE|lien_ou_expose{#TITRE, #ENV{test}|=={en_cours}})]
+ * ```
*
* @param string $url
+ * URL du lien
* @param string $libelle
- * le texte du lien
+ * Texte du lien
* @param bool $on
- * etat expose (genere un strong) ou non (genere un lien)
+ * État exposé (génère un strong) ou non (génère un lien)
* @param string $class
+ * Classes CSS ajoutées au lien
* @param string $title
+ * Title ajouté au lien
* @param string $rel
+ * Attribut `rel` ajouté au lien
* @param string $evt
- * complement a la balise a pour gerer un evenement javascript, de la forme " onclick='...'"
+ * Complement à la balise `a` pour gérer un événement javascript,
+ * de la forme ` onclick='...'`
* @return string
+ * Code HTML
*/
-function lien_ou_expose($url,$libelle=NULL,$on=false,$class="",$title="",$rel="", $evt=''){
+function lien_ou_expose($url, $libelle = null, $on = false, $class = "", $title = "", $rel = "", $evt = '') {
if ($on) {
$bal = "strong";
$att = "class='on'";
} else {
$bal = 'a';
$att = "href='$url'"
- .($title?" title='".attribut_html($title)."'":'')
- .($class?" class='".attribut_html($class)."'":'')
- .($rel?" rel='".attribut_html($rel)."'":'')
- .$evt;
+ . ($title ? " title='" . attribut_html($title) . "'" : '')
+ . ($class ? " class='" . attribut_html($class) . "'" : '')
+ . ($rel ? " rel='" . attribut_html($rel) . "'" : '')
+ . $evt;
}
- if ($libelle === NULL)
+ if ($libelle === null) {
$libelle = $url;
+ }
+
return "<$bal $att>$libelle</$bal>";
}
* "module:chaine"
*
* @param int $nb : le nombre
- * @param string $chaine_un : l'item de langue si $nb vaut un
- * @param string $chaine_plusieurs : l'item de lanque si $nb > 1
+ * @param string $chaine_un : l'item de langue si $nb vaut un
+ * @param string $chaine_plusieurs : l'item de lanque si $nb > 1
* @param string $var : La variable à remplacer par $nb dans l'item de langue (facultatif, défaut "nb")
* @param array $vars : Les autres variables nécessaires aux chaines de langues (facultatif)
* @return string : la chaine de langue finale en utilisant la fonction _T()
*/
-function singulier_ou_pluriel($nb,$chaine_un,$chaine_plusieurs,$var='nb',$vars=array()){
- if (!$nb=intval($nb)) return "";
- if (!is_array($vars)) return "";
+function singulier_ou_pluriel($nb, $chaine_un, $chaine_plusieurs, $var = 'nb', $vars = array()) {
+ if (!$nb = intval($nb)) {
+ return "";
+ }
+ if (!is_array($vars)) {
+ return "";
+ }
$vars[$var] = $nb;
- if ($nb>1) return _T($chaine_plusieurs, $vars);
- else return _T($chaine_un,$vars);
+ if ($nb > 1) {
+ return _T($chaine_plusieurs, $vars);
+ } else {
+ return _T($chaine_un, $vars);
+ }
}
/**
* Fonction de base pour une icone dans un squelette
- * structure html : <span><a><img><b>texte</b></span>
+ * structure html : `<span><a><img><b>texte</b></span>`
*
* @param string $type
* 'lien' ou 'bouton'
* classe supplementaire (horizontale, verticale, ajax ...)
* @param string $javascript
* "onclick='...'" par exemple
- * @return string
+ * @return string
*/
-function prepare_icone_base($type, $lien, $texte, $fond, $fonction="", $class="",$javascript=""){
- if (in_array($fonction,array("del","supprimer.gif")))
+function prepare_icone_base($type, $lien, $texte, $fond, $fonction = "", $class = "", $javascript = "") {
+ if (in_array($fonction, array("del", "supprimer.gif"))) {
$class .= ' danger';
- elseif ($fonction == "rien.gif")
+ } elseif ($fonction == "rien.gif") {
$fonction = "";
- elseif ($fonction == "delsafe")
+ } elseif ($fonction == "delsafe") {
$fonction = "del";
+ }
// remappage des icone : article-24.png+new => article-new-24.png
- if ($icone_renommer = charger_fonction('icone_renommer','inc',true))
- list($fond,$fonction) = $icone_renommer($fond,$fonction);
+ if ($icone_renommer = charger_fonction('icone_renommer', 'inc', true)) {
+ list($fond, $fonction) = $icone_renommer($fond, $fonction);
+ }
// ajouter le type d'objet dans la class de l'icone
- $class .= " " . substr(basename($fond),0,-4);
+ $class .= " " . substr(basename($fond), 0, -4);
$alt = attribut_html($texte);
$title = " title=\"$alt\""; // est-ce pertinent de doubler le alt par un title ?
$ajax = "";
- if (strpos($class,"ajax")!==false) {
- $ajax="ajax";
- if (strpos($class,"preload")!==false)
- $ajax.=" preload";
- if (strpos($class,"nocache")!==false)
- $ajax.=" nocache";
- $ajax=" class='$ajax'";
+ if (strpos($class, "ajax") !== false) {
+ $ajax = "ajax";
+ if (strpos($class, "preload") !== false) {
+ $ajax .= " preload";
+ }
+ if (strpos($class, "nocache") !== false) {
+ $ajax .= " nocache";
+ }
+ $ajax = " class='$ajax'";
}
$size = 24;
- if (preg_match("/-([0-9]{1,3})[.](gif|png)$/i",$fond,$match))
+ if (preg_match("/-([0-9]{1,3})[.](gif|png)$/i", $fond, $match)) {
$size = $match[1];
+ }
- if ($fonction){
+ if ($fonction) {
// 2 images pour composer l'icone : le fond (article) en background,
// la fonction (new) en image
$icone = http_img_pack($fonction, $alt, "width='$size' height='$size'\n" .
- http_style_background($fond));
- }
- else {
+ http_style_background($fond));
+ } else {
$icone = http_img_pack($fond, $alt, "width='$size' height='$size'");
}
- if ($type=='lien')
+ if ($type == 'lien') {
return "<span class='icone s$size $class'>"
. "<a href='$lien'$title$ajax$javascript>"
. $icone
. "<b>$texte</b>"
. "</a></span>\n";
-
- else
- return bouton_action("$icone<b>$texte</b>",$lien,"icone s$size $class",$javascript,$alt);
+ } else {
+ return bouton_action("$icone<b>$texte</b>", $lien, "icone s$size $class", $javascript, $alt);
+ }
}
-function icone_base($lien, $texte, $fond, $fonction="", $class="",$javascript=""){
+/**
+ * Crée un lien ayant une icone
+ *
+ * @uses prepare_icone_base()
+ *
+ * @param string $lien
+ * URL du lien
+ * @param string $texte
+ * Texte du lien
+ * @param string $fond
+ * Objet avec ou sans son extension et sa taille (article, article-24, article-24.png)
+ * @param string $fonction
+ * Fonction du lien (`edit`, `new`, `del`)
+ * @param string $class
+ * Classe CSS, tel que `left`, `right` pour définir un alignement
+ * @param string $javascript
+ * Javascript ajouté sur le lien
+ * @return string
+ * Code HTML du lien
+ **/
+function icone_base($lien, $texte, $fond, $fonction = "", $class = "", $javascript = "") {
return prepare_icone_base('lien', $lien, $texte, $fond, $fonction, $class, $javascript);
}
-function filtre_icone_verticale_dist($lien, $texte, $fond, $fonction="", $class="",$javascript=""){
- return icone_base($lien,$texte,$fond,$fonction,"verticale $class",$javascript);
+
+/**
+ * Crée un lien précédé d'une icone au dessus du texte
+ *
+ * @uses icone_base()
+ * @see icone_verticale() Pour un usage dans un code PHP.
+ *
+ * @filtre
+ * @example
+ * ```
+ * [(#AUTORISER{voir,groupemots,#ID_GROUPE})
+ * [(#URL_ECRIRE{groupe_mots,id_groupe=#ID_GROUPE}
+ * |icone_verticale{<:mots:icone_voir_groupe_mots:>,groupe_mots-24.png,'',left})]
+ * ]
+ * ```
+ *
+ * @param string $lien
+ * URL du lien
+ * @param string $texte
+ * Texte du lien
+ * @param string $fond
+ * Objet avec ou sans son extension et sa taille (article, article-24, article-24.png)
+ * @param string $fonction
+ * Fonction du lien (`edit`, `new`, `del`)
+ * @param string $class
+ * Classe CSS à ajouter, tel que `left`, `right`, `center` pour définir un alignement.
+ * Il peut y en avoir plusieurs : `left ajax`
+ * @param string $javascript
+ * Javascript ajouté sur le lien
+ * @return string
+ * Code HTML du lien
+ **/
+function filtre_icone_verticale_dist($lien, $texte, $fond, $fonction = "", $class = "", $javascript = "") {
+ return icone_base($lien, $texte, $fond, $fonction, "verticale $class", $javascript);
}
-function filtre_icone_horizontale_dist($lien, $texte, $fond, $fonction="", $class="",$javascript=""){
- return icone_base($lien,$texte,$fond,$fonction,"horizontale $class",$javascript);
+
+/**
+ * Crée un lien précédé d'une icone horizontale
+ *
+ * @uses icone_base()
+ * @see icone_horizontale() Pour un usage dans un code PHP.
+ *
+ * @filtre
+ * @example
+ * En tant que filtre dans un squelettes :
+ * ```
+ * [(#URL_ECRIRE{sites}|icone_horizontale{<:sites:icone_voir_sites_references:>,site-24.png})]
+ *
+ * [(#AUTORISER{supprimer,groupemots,#ID_GROUPE}|oui)
+ * [(#URL_ACTION_AUTEUR{supprimer_groupe_mots,#ID_GROUPE,#URL_ECRIRE{mots}}
+ * |icone_horizontale{<:mots:icone_supprimer_groupe_mots:>,groupe_mots,del})]
+ * ]
+ * ```
+ *
+ * En tant que filtre dans un code php :
+ * ```
+ * $icone_horizontale=chercher_filtre('icone_horizontale');
+ * $icone = $icone_horizontale(generer_url_ecrire("stats_visites","id_article=$id_article"),
+ * _T('statistiques:icone_evolution_visites', array('visites' => $visites)),
+ * "statistique-24.png");
+ * ```
+ *
+ * @param string $lien
+ * URL du lien
+ * @param string $texte
+ * Texte du lien
+ * @param string $fond
+ * Objet avec ou sans son extension et sa taille (article, article-24, article-24.png)
+ * @param string $fonction
+ * Fonction du lien (`edit`, `new`, `del`)
+ * @param string $class
+ * Classe CSS à ajouter
+ * @param string $javascript
+ * Javascript ajouté sur le lien
+ * @return string
+ * Code HTML du lien
+ **/
+function filtre_icone_horizontale_dist($lien, $texte, $fond, $fonction = "", $class = "", $javascript = "") {
+ return icone_base($lien, $texte, $fond, $fonction, "horizontale $class", $javascript);
}
-function filtre_bouton_action_horizontal_dist($lien, $texte, $fond, $fonction="", $class="",$confirm=""){
+/**
+ * Crée un bouton d'action intégrant une icone horizontale
+ *
+ * @uses prepare_icone_base()
+ *
+ * @filtre
+ * @example
+ * ```
+ * [(#URL_ACTION_AUTEUR{supprimer_mot, #ID_MOT, #URL_ECRIRE{groupe_mots,id_groupe=#ID_GROUPE}}
+ * |bouton_action_horizontal{<:mots:info_supprimer_mot:>,mot-24.png,del})]
+ * ```
+ *
+ * @param string $lien
+ * URL de l'action
+ * @param string $texte
+ * Texte du bouton
+ * @param string $fond
+ * Objet avec ou sans son extension et sa taille (article, article-24, article-24.png)
+ * @param string $fonction
+ * Fonction du bouton (`edit`, `new`, `del`)
+ * @param string $class
+ * Classe CSS à ajouter
+ * @param string $confirm
+ * Message de confirmation à ajouter en javascript sur le bouton
+ * @return string
+ * Code HTML du lien
+ **/
+function filtre_bouton_action_horizontal_dist($lien, $texte, $fond, $fonction = "", $class = "", $confirm = "") {
return prepare_icone_base('bouton', $lien, $texte, $fond, $fonction, "horizontale $class", $confirm);
}
-/*
- * Filtre icone pour compatibilite
- * mappe sur icone_base
+
+/**
+ * Filtre `icone` pour compatibilité mappé sur `icone_base`
+ *
+ * @uses icone_base()
+ * @see filtre_icone_verticale_dist()
+ *
+ * @filtre
+ * @deprecated Utiliser le filtre `icone_verticale`
+ *
+ * @param string $lien
+ * URL du lien
+ * @param string $texte
+ * Texte du lien
+ * @param string $fond
+ * Nom de l'image utilisée
+ * @param string $align
+ * Classe CSS d'alignement (`left`, `right`, `center`)
+ * @param string $fonction
+ * Fonction du lien (`edit`, `new`, `del`)
+ * @param string $class
+ * Classe CSS à ajouter
+ * @param string $javascript
+ * Javascript ajouté sur le lien
+ * @return string
+ * Code HTML du lien
*/
-function filtre_icone_dist($lien, $texte, $fond, $align="", $fonction="", $class="",$javascript=""){
- return icone_base($lien,$texte,$fond,$fonction,"verticale $align $class",$javascript);
+function filtre_icone_dist($lien, $texte, $fond, $align = "", $fonction = "", $class = "", $javascript = "") {
+ return icone_base($lien, $texte, $fond, $fonction, "verticale $align $class", $javascript);
}
/**
- * filtre explode pour les squelettes permettant d'ecrire
- * #GET{truc}|explode{-}
+ * Explose un texte en tableau suivant un séparateur
*
- * @param strong $a
- * @param string $b
- * @return array
+ * @note
+ * Inverse l'écriture de la fonction PHP de même nom
+ * pour que le filtre soit plus pratique dans les squelettes
+ *
+ * @filtre
+ * @example
+ * ```
+ * [(#GET{truc}|explode{-})]
+ * ```
+ *
+ * @param string $a Texte
+ * @param string $b Séparateur
+ * @return array Liste des éléments
*/
-function filtre_explode_dist($a,$b){return explode($b,$a);}
+function filtre_explode_dist($a, $b) { return explode($b, $a); }
/**
- * filtre implode pour les squelettes permettant d'ecrire
- * #GET{truc}|implode{-}
+ * Implose un tableau en chaine en liant avec un séparateur
*
- * @param array $a
- * @param string $b
- * @return string
+ * @note
+ * Inverse l'écriture de la fonction PHP de même nom
+ * pour que le filtre soit plus pratique dans les squelettes
+ *
+ * @filtre
+ * @example
+ * ```
+ * [(#GET{truc}|implode{-})]
+ * ```
+ *
+ * @param array $a Tableau
+ * @param string $b Séparateur
+ * @return string Texte
*/
-function filtre_implode_dist($a,$b){return is_array($a)?implode($b,$a):$a;}
+function filtre_implode_dist($a, $b) { return is_array($a) ? implode($b, $a) : $a; }
/**
- * Produire les styles prives qui associent item de menu avec icone en background
- * @return string
+ * Produire les styles privés qui associent item de menu avec icone en background
+ *
+ * @return string Code CSS
*/
-function bando_images_background(){
+function bando_images_background() {
include_spip('inc/bandeau');
// recuperer tous les boutons et leurs images
- $boutons = definir_barre_boutons(definir_barre_contexte(),true,false);
+ $boutons = definir_barre_boutons(definir_barre_contexte(), true, false);
$res = "";
- foreach($boutons as $page => $detail){
- if ($detail->icone AND strlen(trim($detail->icone)))
- $res .="\n.navigation_avec_icones #bando1_$page {background-image:url(".$detail->icone.");}";
- $selecteur = (in_array($page,array('outils_rapides','outils_collaboratifs'))?"":".navigation_avec_icones ");
- if (is_array($detail->sousmenu))
- foreach($detail->sousmenu as $souspage=>$sousdetail)
- if ($sousdetail->icone AND strlen(trim($sousdetail->icone)))
- $res .="\n$selecteur.bando2_$souspage {background-image:url(".$sousdetail->icone.");}";
+ foreach ($boutons as $page => $detail) {
+ if ($detail->icone and strlen(trim($detail->icone))) {
+ $res .= "\n.navigation_avec_icones #bando1_$page {background-image:url(" . $detail->icone . ");}";
+ }
+ $selecteur = (in_array($page, array('outils_rapides', 'outils_collaboratifs')) ? "" : ".navigation_avec_icones ");
+ if (is_array($detail->sousmenu)) {
+ foreach ($detail->sousmenu as $souspage => $sousdetail) {
+ if ($sousdetail->icone and strlen(trim($sousdetail->icone))) {
+ $res .= "\n$selecteur.bando2_$souspage {background-image:url(" . $sousdetail->icone . ");}";
+ }
+ }
+ }
}
+
return $res;
}
* et avant execution de l'action. Si la callback renvoie false, elle annule le declenchement de l'action
* @return string
*/
-function bouton_action($libelle, $url, $class="", $confirm="", $title="", $callback=""){
+function bouton_action($libelle, $url, $class = "", $confirm = "", $title = "", $callback = "") {
if ($confirm) {
$confirm = "confirm(\"" . attribut_html($confirm) . "\")";
- if ($callback)
- $callback = "$confirm?($callback):false";
- else
- $callback = $confirm;
+ if ($callback) {
+ $callback = "$confirm?($callback):false";
+ } else {
+ $callback = $confirm;
+ }
}
- $onclick = $callback?" onclick='return ".addcslashes($callback,"'")."'":"";
+ $onclick = $callback ? " onclick='return " . addcslashes($callback, "'") . "'" : "";
$title = $title ? " title='$title'" : "";
- return "<form class='bouton_action_post $class' method='post' action='$url'><div>".form_hidden($url)
- ."<button type='submit' class='submit'$title$onclick>$libelle</button></div></form>";
+
+ return "<form class='bouton_action_post $class' method='post' action='$url'><div>" . form_hidden($url)
+ . "<button type='submit' class='submit'$title$onclick>$libelle</button></div></form>";
}
/**
* Proteger les champs passes dans l'url et utiliser dans {tri ...}
* preserver l'espace pour interpreter ensuite num xxx et multi xxx
+ *
* @param string $t
* @return string
*/
-function tri_protege_champ($t){
- return preg_replace(',[^\s\w.+],','',$t);
+function tri_protege_champ($t) {
+ return preg_replace(',[^\s\w.+],', '', $t);
}
/**
* Interpreter les multi xxx et num xxx utilise comme tri
* pour la clause order
* 'multi xxx' devient simplement 'multi' qui est calcule dans le select
+ *
* @param string $t
* @param array $from
* @return string
*/
-function tri_champ_order($t, $from=null){
- if(strncmp($t,'multi ',6)==0){
+function tri_champ_order($t, $from = null) {
+ if (strncmp($t, 'multi ', 6) == 0) {
return "multi";
}
$champ = $t;
- if (strncmp($t,'num ',4)==0)
- $champ = substr($t,4);
+ if (strncmp($t, 'num ', 4) == 0) {
+ $champ = substr($t, 4);
+ }
// enlever les autres espaces non evacues par tri_protege_champ
- $champ = preg_replace(',\s,','',$champ);
+ $champ = preg_replace(',\s,', '', $champ);
- if (is_array($from)){
- $trouver_table = charger_fonction('trouver_table','base');
- foreach($from as $idt=>$table_sql){
+ if (is_array($from)) {
+ $trouver_table = charger_fonction('trouver_table', 'base');
+ foreach ($from as $idt => $table_sql) {
if ($desc = $trouver_table($table_sql)
- AND isset($desc['field'][$champ])){
+ and isset($desc['field'][$champ])
+ ) {
$champ = "$idt.$champ";
break;
}
}
}
- if (strncmp($t,'num ',4)==0)
+ if (strncmp($t, 'num ', 4) == 0) {
return "0+$champ";
- else
+ } else {
return $champ;
+ }
}
/**
* @param string $t
* @return string
*/
-function tri_champ_select($t){
- if(strncmp($t,'multi ',6)==0){
- $t = substr($t,6);
- $t = preg_replace(',\s,','',$t);
- $t = sql_multi($t,$GLOBALS['spip_lang']);
+function tri_champ_select($t) {
+ if (strncmp($t, 'multi ', 6) == 0) {
+ $t = substr($t, 6);
+ $t = preg_replace(',\s,', '', $t);
+ $t = sql_multi($t, $GLOBALS['spip_lang']);
+
return $t;
}
- if(trim($t)=='hasard'){
+ if (trim($t) == 'hasard') {
return 'rand() AS hasard';
}
+
return "''";
}
* @param string $etoile
* @return string
*/
-function generer_info_entite($id_objet, $type_objet, $info, $etoile=""){
- global $table_des_traitements;
- static $trouver_table=null;
+function generer_info_entite($id_objet, $type_objet, $info, $etoile = "") {
+ static $trouver_table = null;
static $objets;
// On verifie qu'on a tout ce qu'il faut
$id_objet = intval($id_objet);
- if (!($id_objet and $type_objet and $info))
+ if (!($id_objet and $type_objet and $info)) {
return '';
+ }
// si on a deja note que l'objet n'existe pas, ne pas aller plus loin
- if (isset($objets[$type_objet]) AND $objets[$type_objet]===false)
+ if (isset($objets[$type_objet]) and $objets[$type_objet] === false) {
return '';
+ }
// Si on demande l'url, on retourne direct la fonction
- if ($info == 'url')
+ if ($info == 'url') {
return generer_url_entite($id_objet, $type_objet);
+ }
// Sinon on va tout chercher dans la table et on garde en memoire
$demande_titre = ($info == 'titre');
// On ne fait la requete que si on a pas deja l'objet ou si on demande le titre mais qu'on ne l'a pas encore
if (!isset($objets[$type_objet][$id_objet])
- OR
- ($demande_titre AND !isset($objets[$type_objet][$id_objet]['titre']))
- ){
- if (!$trouver_table)
- $trouver_table = charger_fonction('trouver_table','base');
+ or
+ ($demande_titre and !isset($objets[$type_objet][$id_objet]['titre']))
+ ) {
+ if (!$trouver_table) {
+ $trouver_table = charger_fonction('trouver_table', 'base');
+ }
$desc = $trouver_table(table_objet_sql($type_objet));
- if (!$desc)
+ if (!$desc) {
return $objets[$type_objet] = false;
+ }
// Si on demande le titre, on le gere en interne
$champ_titre = "";
- if ($demande_titre){
+ if ($demande_titre) {
// si pas de titre declare mais champ titre, il sera peuple par le select *
- $champ_titre = (!empty($desc['titre'])) ? ', ' . $desc['titre']:'';
+ $champ_titre = (!empty($desc['titre'])) ? ', ' . $desc['titre'] : '';
}
include_spip('base/abstract_sql');
include_spip('base/connect_sql');
$objets[$type_objet][$id_objet] = sql_fetsel(
- '*'.$champ_titre,
+ '*' . $champ_titre,
$desc['table_sql'],
- id_table_objet($type_objet).' = '.intval($id_objet)
+ id_table_objet($type_objet) . ' = ' . intval($id_objet)
);
}
// Si la fonction generer_TRUC_TYPE existe, on l'utilise pour formater $info_generee
- if ($generer = charger_fonction("generer_${info}_${type_objet}", '', true))
+ if ($generer = charger_fonction("generer_${info}_${type_objet}", '', true)) {
$info_generee = $generer($id_objet, $objets[$type_objet][$id_objet]);
- // Si la fonction generer_TRUC_entite existe, on l'utilise pour formater $info_generee
- else if ($generer = charger_fonction("generer_${info}_entite", '', true))
- $info_generee = $generer($id_objet, $type_objet, $objets[$type_objet][$id_objet]);
- // Sinon on prend directement le champ SQL tel quel
- else
- $info_generee = (isset($objets[$type_objet][$id_objet][$info])?$objets[$type_objet][$id_objet][$info]:'');
-
- // On va ensuite chercher les traitements automatiques a faire
- $champ = strtoupper($info);
- $traitement = isset($table_des_traitements[$champ]) ? $table_des_traitements[$champ] : false;
- $table_sql = table_objet_sql($type_objet);
-
- if (!$etoile
- AND is_array($traitement)
- AND (isset($traitement[$table_sql]) OR isset($traitement[0]))){
- $traitement = $traitement[isset($traitement[$table_sql]) ? $table_sql : 0];
- $traitement = str_replace('%s', "'".texte_script($info_generee)."'", $traitement);
- // FIXME: $connect et $Pile[0] font souvent partie des traitements.
- // on les definit pour eviter des notices, mais ce fonctionnement est a ameliorer !
- $connect = ""; $Pile = array(0 => array('id_objet'=>$id_objet,'objet'=>$type_objet));
- eval("\$info_generee = $traitement;");
+ } // Si la fonction generer_TRUC_entite existe, on l'utilise pour formater $info_generee
+ else {
+ if ($generer = charger_fonction("generer_${info}_entite", '', true)) {
+ $info_generee = $generer($id_objet, $type_objet, $objets[$type_objet][$id_objet]);
+ } // Sinon on prend directement le champ SQL tel quel
+ else {
+ $info_generee = (isset($objets[$type_objet][$id_objet][$info]) ? $objets[$type_objet][$id_objet][$info] : '');
+ }
+ }
+
+ // On va ensuite appliquer les traitements automatiques si besoin
+ if (!$etoile) {
+ // FIXME: on fournit un ENV minimum avec id et type et connect=''
+ // mais ce fonctionnement est a ameliorer !
+ $info_generee = appliquer_traitement_champ($info_generee, $info, table_objet($type_objet),
+ array('id_objet' => $id_objet, 'objet' => $type_objet, ''));
}
return $info_generee;
}
/**
- * Wrap un texte avec des balises
- * wrap('mot','<b>') => '<b>mot</b>'
+ * Appliquer a un champ SQL le traitement qui est configure pour la balise homonyme dans les squelettes
+ *
+ * @param string $texte
+ * @param string $champ
+ * @param string $table_objet
+ * @param array $env
+ * @param string $connect
+ * @return string
+ */
+function appliquer_traitement_champ($texte, $champ, $table_objet = '', $env = array(), $connect = '') {
+ if (!$champ) {
+ return $texte;
+ }
+
+ // On charge toujours les filtres de texte car la majorité des traitements les utilisent
+ // et il ne faut pas partir du principe que c'est déjà chargé (form ajax, etc)
+ include_spip('inc/texte');
+
+ $champ = strtoupper($champ);
+ $traitements = isset($GLOBALS['table_des_traitements'][$champ]) ? $GLOBALS['table_des_traitements'][$champ] : false;
+ if (!$traitements or !is_array($traitements)) {
+ return $texte;
+ }
+
+ $traitement = '';
+ if ($table_objet and (!isset($traitements[0]) or count($traitements) > 1)) {
+ // necessaire pour prendre en charge les vieux appels avec un table_objet_sql en 3e arg
+ $table_objet = table_objet($table_objet);
+ if (isset($traitements[$table_objet])) {
+ $traitement = $traitements[$table_objet];
+ }
+ }
+ if (!$traitement and isset($traitements[0])) {
+ $traitement = $traitements[0];
+ }
+ // (sinon prendre le premier de la liste par defaut ?)
+
+ if (!$traitement) {
+ return $texte;
+ }
+
+ $traitement = str_replace('%s', "'" . texte_script($texte) . "'", $traitement);
+
+ // Fournir $connect et $Pile[0] au traitement si besoin
+ $Pile = array(0 => $env);
+ eval("\$texte = $traitement;");
+
+ return $texte;
+}
+
+
+/**
+ * Generer un lien (titre clicable vers url) vers un objet
+ *
+ * @param int $id_objet
+ * @param $objet
+ * @param int $longueur
+ * @param null|string $connect
+ * @return string
+ */
+function generer_lien_entite($id_objet, $objet, $longueur = 80, $connect = null) {
+ include_spip('inc/liens');
+ $titre = traiter_raccourci_titre($id_objet, $objet, $connect);
+ // lorsque l'objet n'est plus declare (plugin desactive par exemple)
+ // le raccourcis n'est plus valide
+ $titre = isset($titre['titre']) ? typo($titre['titre']) : '';
+ // on essaye avec generer_info_entite ?
+ if (!strlen($titre) and !$connect) {
+ $titre = generer_info_entite($id_objet, $objet, 'titre');
+ }
+ if (!strlen($titre)) {
+ $titre = _T('info_sans_titre');
+ }
+ $url = generer_url_entite($id_objet, $objet, '', '', $connect);
+
+ return "<a href='$url' class='$objet'>" . couper($titre, $longueur) . "</a>";
+}
+
+
+/**
+ * Englobe (Wrap) un texte avec des balises
+ *
+ * @example `wrap('mot','<b>')` donne `<b>mot</b>'`
+ *
+ * @filtre
+ * @uses extraire_balises()
+ *
* @param string $texte
* @param string $wrap
* @return string
*/
-function wrap($texte,$wrap) {
+function wrap($texte, $wrap) {
$balises = extraire_balises($wrap);
- if (preg_match_all(",<([a-z]\w*)\b[^>]*>,UimsS",$wrap, $regs, PREG_PATTERN_ORDER)) {
+ if (preg_match_all(",<([a-z]\w*)\b[^>]*>,UimsS", $wrap, $regs, PREG_PATTERN_ORDER)) {
$texte = $wrap . $texte;
$regs = array_reverse($regs[1]);
- $wrap = "</".implode("></",$regs).">";
+ $wrap = "</" . implode("></", $regs) . ">";
$texte = $texte . $wrap;
}
+
return $texte;
}
* @param int $indent
* @return array|mixed|string
*/
-function filtre_print_dist($u, $join="<br />", $indent=0) {
- if (is_string($u)){
+function filtre_print_dist($u, $join = "<br />", $indent = 0) {
+ if (is_string($u)) {
$u = typo($u);
+
return $u;
}
// caster $u en array si besoin
- if (is_object($u))
- $u = (array) $u;
+ if (is_object($u)) {
+ $u = (array)$u;
+ }
- if (is_array($u)){
+ if (is_array($u)) {
$out = "";
// toutes les cles sont numeriques ?
// et aucun enfant n'est un tableau
// liste simple separee par des virgules
- $numeric_keys = array_map('is_numeric',array_keys($u));
- $array_values = array_map('is_array',$u);
- $object_values = array_map('is_object',$u);
- if (array_sum($numeric_keys)==count($numeric_keys)
- AND !array_sum($array_values)
- AND !array_sum($object_values)){
+ $numeric_keys = array_map('is_numeric', array_keys($u));
+ $array_values = array_map('is_array', $u);
+ $object_values = array_map('is_object', $u);
+ if (array_sum($numeric_keys) == count($numeric_keys)
+ and !array_sum($array_values)
+ and !array_sum($object_values)
+ ) {
return join(", ", array_map('filtre_print_dist', $u));
}
// sinon on passe a la ligne et on indente
- $i_str = str_pad("",$indent," ");
- foreach($u as $k => $v){
- $out .= $join . $i_str . "$k: " . filtre_print_dist($v,$join,$indent+2);
+ $i_str = str_pad("", $indent, " ");
+ foreach ($u as $k => $v) {
+ $out .= $join . $i_str . "$k: " . filtre_print_dist($v, $join, $indent + 2);
}
+
return $out;
}
* @param string $info
* @return string
*/
-function objet_info($objet,$info){
+function objet_info($objet, $info) {
$table = table_objet_sql($objet);
$infos = lister_tables_objets_sql($table);
- return (isset($infos[$info])?$infos[$info]:'');
+
+ return (isset($infos[$info]) ? $infos[$info] : '');
}
/**
* Filtre pour afficher 'Aucun truc' ou '1 truc' ou 'N trucs'
- * avec la bonne chaine de langue en fonction de l'objet utilise
- * @param $nb
- * @param $objet
+ * avec la bonne chaîne de langue en fonction de l'objet utilisé
+ *
+ * @param int $nb
+ * Nombre d'éléments
+ * @param string $objet
+ * Objet
* @return mixed|string
+ * Texte traduit du comptage, tel que '3 articles'
*/
-function objet_afficher_nb($nb, $objet){
- if (!$nb)
- return _T(objet_info($objet,'info_aucun_objet'));
- else
- return _T(objet_info($objet,$nb==1?'info_1_objet':'info_nb_objets'),array('nb'=>$nb));
+function objet_afficher_nb($nb, $objet) {
+ if (!$nb) {
+ return _T(objet_info($objet, 'info_aucun_objet'));
+ } else {
+ return _T(objet_info($objet, $nb == 1 ? 'info_1_objet' : 'info_nb_objets'), array('nb' => $nb));
+ }
}
/**
* @param int $taille
* @return string
*/
-function objet_icone($objet,$taille=24){
- $icone = objet_info($objet,'icone_objet')."-".$taille.".png";
+function objet_icone($objet, $taille = 24) {
+ $icone = objet_info($objet, 'icone_objet') . "-" . $taille . ".png";
$icone = chemin_image($icone);
$balise_img = charger_filtre('balise_img');
- return $icone?$balise_img($icone,_T(objet_info($objet,'texte_objet'))):'';
+
+ return $icone ? $balise_img($icone, _T(objet_info($objet, 'texte_objet'))) : '';
+}
+
+/**
+ * Renvoyer une traduction d'une chaine de langue contextuelle à un objet si elle existe,
+ * la traduction de la chaine generique
+ *
+ * Ex : [(#ENV{objet}|objet_label{trad_reference})]
+ * va chercher si une chaine objet:trad_reference existe et renvoyer sa trad le cas echeant
+ * sinon renvoie la trad de la chaine trad_reference
+ * Si la chaine fournie contient un prefixe il est remplacé par celui de l'objet pour chercher la chaine contextuelle
+ *
+ * Les arguments $args et $options sont ceux de la fonction _T
+ *
+ * @param string $objet
+ * @param string $chaine
+ * @param array $args
+ * @param array $options
+ * @return string
+ */
+function objet_T($objet, $chaine, $args = array(), $options = array()){
+ $chaine = explode(':',$chaine);
+ if ($t = _T($objet . ':' . end($chaine), $args, array_merge($options, array('force'=>false)))) {
+ return $t;
+ }
+ $chaine = implode(':',$chaine);
+ return _T($chaine, $args, $options);
}
/**
* Fonction de secours pour inserer le head_css de facon conditionnelle
- *
+ *
* Appelée en filtre sur le squelette qui contient #INSERT_HEAD,
* elle vérifie l'absence éventuelle de #INSERT_HEAD_CSS et y suplée si besoin
* pour assurer la compat avec les squelettes qui n'utilisent pas.
- *
+ *
* @param string $flux Code HTML
* @return string Code HTML
*/
-function insert_head_css_conditionnel($flux){
- if (strpos($flux,'<!-- insert_head_css -->')===false
- AND $p=strpos($flux,'<!-- insert_head -->')){
+function insert_head_css_conditionnel($flux) {
+ if (strpos($flux, '<!-- insert_head_css -->') === false
+ and $p = strpos($flux, '<!-- insert_head -->')
+ ) {
// plutot avant le premier js externe (jquery) pour etre non bloquant
- if ($p1 = stripos($flux,'<script src=') AND $p1<$p)
+ if ($p1 = stripos($flux, '<script src=') and $p1 < $p) {
$p = $p1;
- $flux = substr_replace($flux,pipeline('insert_head_css','<!-- insert_head_css -->'),$p,0);
+ }
+ $flux = substr_replace($flux, pipeline('insert_head_css', '<!-- insert_head_css -->'), $p, 0);
}
+
return $flux;
}
/**
- * Produire un fichier statique a partir d'un squelette dynamique
- * Permet ensuite a apache de le servir en statique sans repasser
- * par spip.php a chaque hit sur le fichier
- * si le format (css ou js) est passe dans contexte['format'], on l'utilise
- * sinon on regarde si le fond finit par .css ou .js
- * sinon on utilie "html"
+ * Produire un fichier statique à partir d'un squelette dynamique
+ *
+ * Permet ensuite à Apache de le servir en statique sans repasser
+ * par spip.php à chaque hit sur le fichier.
+ *
+ * Si le format (css ou js) est passe dans `contexte['format']`, on l'utilise
+ * sinon on regarde si le fond finit par .css ou .js, sinon on utilie "html"
+ *
+ * @uses urls_absolues_css()
*
* @param string $fond
* @param array $contexte
* @param string $connect
* @return string
*/
-function produire_fond_statique($fond, $contexte=array(), $options = array(), $connect=''){
- if (isset($contexte['format'])){
+function produire_fond_statique($fond, $contexte = array(), $options = array(), $connect = '') {
+ if (isset($contexte['format'])) {
$extension = $contexte['format'];
unset($contexte['format']);
- }
- else {
+ } else {
$extension = "html";
- if (preg_match(',[.](css|js|json)$,',$fond,$m))
+ if (preg_match(',[.](css|js|json)$,', $fond, $m)) {
$extension = $m[1];
+ }
}
// recuperer le contenu produit par le squelette
$options['raw'] = true;
- $cache = recuperer_fond($fond,$contexte,$options,$connect);
-
+ $cache = recuperer_fond($fond, $contexte, $options, $connect);
+
// calculer le nom de la css
- $dir_var = sous_repertoire (_DIR_VAR, 'cache-'.$extension);
- $nom_safe = preg_replace(",\W,",'_',str_replace('.','_',$fond));
- $filename = $dir_var . $extension."dyn-$nom_safe-".substr(md5($fond.serialize($contexte).$connect),0,8) .".$extension";
+ $dir_var = sous_repertoire(_DIR_VAR, 'cache-' . $extension);
+ $nom_safe = preg_replace(",\W,", '_', str_replace('.', '_', $fond));
+ $contexte_implicite = calculer_contexte_implicite();
+ $filename = $dir_var . $extension . "dyn-$nom_safe-"
+ . substr(md5($fond . serialize($contexte_implicite) . serialize($contexte) . $connect), 0, 8)
+ . ".$extension";
// mettre a jour le fichier si il n'existe pas
// ou trop ancien
// le dernier fichier produit est toujours suffixe par .last
// et recopie sur le fichier cible uniquement si il change
if (!file_exists($filename)
- OR !file_exists($filename.".last")
- OR (isset($cache['lastmodified']) AND $cache['lastmodified'] AND filemtime($filename.".last")<$cache['lastmodified'])
- OR (defined('_VAR_MODE') AND _VAR_MODE=='recalcul')) {
+ or !file_exists($filename . ".last")
+ or (isset($cache['lastmodified']) and $cache['lastmodified'] and filemtime($filename . ".last") < $cache['lastmodified'])
+ or (defined('_VAR_MODE') and _VAR_MODE == 'recalcul')
+ ) {
$contenu = $cache['texte'];
// passer les urls en absolu si c'est une css
- if ($extension=="css")
- $contenu = urls_absolues_css($contenu, test_espace_prive()?generer_url_ecrire('accueil'):generer_url_public($fond));
-
+ if ($extension == "css") {
+ $contenu = urls_absolues_css($contenu,
+ test_espace_prive() ? generer_url_ecrire('accueil') : generer_url_public($fond));
+ }
+
+ $comment = '';
// ne pas insérer de commentaire si c'est du json
- if ($extension!="json") {
+ if ($extension != "json") {
$comment = "/* #PRODUIRE{fond=$fond";
- foreach($contexte as $k=>$v)
+ foreach ($contexte as $k => $v) {
$comment .= ",$k=$v";
+ }
// pas de date dans le commentaire car sinon ca invalide le md5 et force la maj
// mais on peut mettre un md5 du contenu, ce qui donne un aperu rapide si la feuille a change ou non
- $comment .="}\n md5:".md5($contenu)." */\n";
+ $comment .= "}\n md5:" . md5($contenu) . " */\n";
}
// et ecrire le fichier
- ecrire_fichier($filename.".last",$comment.$contenu);
+ ecrire_fichier($filename . ".last", $comment . $contenu);
// regarder si on recopie
if (!file_exists($filename)
- OR md5_file($filename)!==md5_file($filename.".last")){
- @copy($filename.".last",$filename);
- spip_clearstatcache(true,$filename); // eviter que PHP ne reserve le vieux timestamp
+ or md5_file($filename) !== md5_file($filename . ".last")
+ ) {
+ @copy($filename . ".last", $filename);
+ clearstatcache(true, $filename); // eviter que PHP ne reserve le vieux timestamp
}
}
-
- return $filename;
+
+ return timestamp($filename);
}
/**
* [(#CHEMIN{monfichier}|timestamp)]
*
* @param string $fichier
+ * Le chemin du fichier sur lequel on souhaite ajouter le timestamp
* @return string
+ * $fichier auquel on a ajouté le timestamp
*/
-function timestamp($fichier){
- if (!$fichier OR !file_exists($fichier)) return $fichier;
- $m = filemtime($fichier);
+function timestamp($fichier) {
+ if (!$fichier
+ or !file_exists($fichier)
+ or !$m = filemtime($fichier)
+ ) {
+ return $fichier;
+ }
+
return "$fichier?$m";
}
+/**
+ * Supprimer le timestamp d'une url
+ *
+ * @param string $url
+ * @return string
+ */
+function supprimer_timestamp($url) {
+ if (strpos($url, "?") === false) {
+ return $url;
+ }
+
+ return preg_replace(",\?[[:digit:]]+$,", "", $url);
+}
+
/**
* Nettoyer le titre d'un email
- * eviter une erreur lorsqu'on utilise |nettoyer_titre_email dans un squelette de mail
- * @param $titre
- * @return mixed
+ *
+ * Éviter une erreur lorsqu'on utilise `|nettoyer_titre_email` dans un squelette de mail
+ *
+ * @filtre
+ * @uses nettoyer_titre_email()
+ *
+ * @param string $titre
+ * @return string
*/
-function filtre_nettoyer_titre_email_dist($titre){
+function filtre_nettoyer_titre_email_dist($titre) {
include_spip('inc/envoyer_mail');
+
return nettoyer_titre_email($titre);
}
*
* Il permet de placer un objet dans la hiérarchie des rubriques de SPIP
*
+ * @uses chercher_rubrique()
+ *
* @param string $titre
* @param int $id_objet
* @param int $id_parent
* @param bool $retour_sans_cadre
* @return string
*/
-function filtre_chercher_rubrique_dist($titre,$id_objet, $id_parent, $objet, $id_secteur, $restreint,$actionable = false, $retour_sans_cadre=false){
+function filtre_chercher_rubrique_dist(
+ $titre,
+ $id_objet,
+ $id_parent,
+ $objet,
+ $id_secteur,
+ $restreint,
+ $actionable = false,
+ $retour_sans_cadre = false
+) {
include_spip('inc/filtres_ecrire');
- return chercher_rubrique($titre,$id_objet, $id_parent, $objet, $id_secteur, $restreint,$actionable, $retour_sans_cadre);
+
+ return chercher_rubrique($titre, $id_objet, $id_parent, $objet, $id_secteur, $restreint, $actionable,
+ $retour_sans_cadre);
}
/**
* Rediriger une page suivant une autorisation,
* et ce, n'importe où dans un squelette, même dans les inclusions.
- * Exemple :
- * [(#AUTORISER{non}|sinon_interdire_acces)]
- * [(#AUTORISER{non}|sinon_interdire_acces{#URL_PAGE{login}, 401})]
*
- * @param bool $ok Indique si l'on doit rediriger ou pas
- * @param string $url Adresse vers laquelle rediriger
- * @param int $statut Statut HTML avec lequel on redirigera
- * @return string
+ * En l'absence de redirection indiquée, la fonction redirige par défaut
+ * sur une 403 dans l'espace privé et 404 dans l'espace public.
+ *
+ * @example
+ * ```
+ * [(#AUTORISER{non}|sinon_interdire_acces)]
+ * [(#AUTORISER{non}|sinon_interdire_acces{#URL_PAGE{login}, 401})]
+ * ```
+ *
+ * @filtre
+ * @param bool $ok
+ * Indique si l'on doit rediriger ou pas
+ * @param string $url
+ * Adresse eventuelle vers laquelle rediriger
+ * @param int $statut
+ * Statut HTML avec lequel on redirigera
+ * @param string $message
+ * message d'erreur
+ * @return string|void
+ * Chaîne vide si l'accès est autorisé
*/
-function sinon_interdire_acces($ok=false, $url='', $statut=0){
- if ($ok) return '';
-
+function sinon_interdire_acces($ok = false, $url = '', $statut = 0, $message = null) {
+ if ($ok) {
+ return '';
+ }
+
// Vider tous les tampons
$level = @ob_get_level();
- while ($level--)
+ while ($level--) {
@ob_end_clean();
-
+ }
+
include_spip('inc/headers');
+
+ // S'il y a une URL, on redirige (si pas de statut, la fonction mettra 302 par défaut)
+ if ($url) {
+ redirige_par_entete($url, '', $statut);
+ }
+
+ // ecriture simplifiee avec message en 3eme argument (= statut 403)
+ if (!is_numeric($statut) and is_null($message)) {
+ $message = $statut;
+ $statut = 0;
+ }
+ if (!$message) {
+ $message = '';
+ }
$statut = intval($statut);
-
- // Si aucun argument on essaye de deviner quoi faire par défaut
- if (!$url and !$statut){
- // Si on est dans l'espace privé, on génère du 403 Forbidden
- if (test_espace_prive()){
- http_status(403);
- $echec = charger_fonction('403','exec');
- $echec();
+
+ // Si on est dans l'espace privé, on génère du 403 Forbidden par defaut ou du 404
+ if (test_espace_prive()) {
+ if (!$statut or !in_array($statut, array(404, 403))) {
+ $statut = 403;
}
+ http_status(403);
+ $echec = charger_fonction('403', 'exec');
+ $echec($message);
+ } else {
// Sinon dans l'espace public on redirige vers une 404 par défaut, car elle toujours présente normalement
- else{
+ if (!$statut) {
$statut = 404;
}
- }
-
- // On suit les directives indiquées dans les deux arguments
-
- // S'il y a un statut
- if ($statut){
// Dans tous les cas on modifie l'entité avec ce qui est demandé
http_status($statut);
// Si le statut est une erreur et qu'il n'y a pas de redirection on va chercher le squelette du même nom
- if ($statut >= 400 and !$url)
- echo recuperer_fond("$statut");
+ if ($statut >= 400) {
+ echo recuperer_fond("$statut", array('erreur' => $message));
+ }
}
-
- // S'il y a une URL, on redirige (si pas de statut, la fonction mettra 302 par défaut)
- if ($url) redirige_par_entete($url, '', $statut);
-
+
+
exit;
}
/**
* Assurer le fonctionnement de |compacte meme sans l'extension compresseur
+ *
* @param string $source
* @param null|string $format
* @return string
*/
-function filtre_compacte_dist($source, $format = null){
- if (function_exists('compacte'))
+function filtre_compacte_dist($source, $format = null) {
+ if (function_exists('compacte')) {
return compacte($source, $format);
+ }
+
return $source;
}
-
-?>