Newer
Older
cerdic
a validé
$rep = (_DIR_RESTREINT ? '' : _DIR_RESTREINT_ABS) . $rep;
}
$rep = preg_replace(',(^\.\.\/),', '', $rep);
cerdic
a validé
return $rep;
}
/**
* Débute ou arrête un chronomètre et retourne sa valeur
*
* On exécute 2 fois la fonction, la première fois pour démarrer le chrono,
* la seconde fois pour l’arrêter et récupérer la valeur
*
* @example
* ```
* spip_timer('papoter');
* // actions
* $duree = spip_timer('papoter');
* ```
*
* @param string $t
* Nom du chronomètre
* @param bool $raw
* - false : retour en texte humainement lisible
* - true : retour en millisecondes
* @return float|int|string|void
*/
gilles.vincent
a validé
function spip_timer($t = 'rien', $raw = false) {
cerdic
a validé
$a = time();
$b = microtime();
// microtime peut contenir les microsecondes et le temps
cerdic
a validé
$b = explode(' ', $b);
if (count($b) == 2) {
$a = end($b);
} // plus precis !
if (!isset($time[$t])) {
$time[$t] = $a + $b;
} else {
$p = ($a + $b - $time[$t]) * 1000;
unset($time[$t]);
# echo "'$p'";exit;
cerdic
a validé
if ($raw) {
return $p;
}
if ($p < 1000) {
$s = '';
cerdic
a validé
} else {
$p -= ($x * 1000);
cerdic
a validé
// Renvoie False si un fichier n'est pas plus vieux que $duree secondes,
// sinon renvoie True et le date sauf si ca n'est pas souhaite
gilles.vincent
a validé
function spip_touch($fichier, $duree = 0, $touch = true) {
if ($duree) {
clearstatcache();
if (($f = @filemtime($fichier)) && $f >= time() - $duree) {
return false;
cerdic
a validé
}
cerdic
a validé
if ($touch !== false) {
if (!@touch($fichier)) {
spip_unlink($fichier);
@touch($fichier);
};
@chmod($fichier, _SPIP_CHMOD & ~0111);
cerdic
a validé
return true;
/**
* Action qui déclenche une tache de fond
*
cerdic
a validé
* @see queue_affichage_cron()
* @uses cron()
cerdic
a validé
**/
function action_cron() {
include_spip('inc/headers');
http_response_code(204); // No Content
define('_DIRECT_CRON_FORCE', true);
cron();
* Exécution des tâches de fond
cerdic
a validé
*
* @uses inc_genie_dist()
cerdic
a validé
*
* @param array $taches
* Tâches forcées
* @param array $taches_old
* Tâches forcées, pour compat avec ancienne syntaxe
* @return bool
* True si la tache a pu être effectuée
// si pas en mode cron force, laisser tomber.
cerdic
a validé
if (!defined('_DIRECT_CRON_FORCE')) {
return false;
}
if (!is_array($taches)) {
$taches = $taches_old;
} // compat anciens appels
// si taches a inserer en base et base inaccessible, laisser tomber
// sinon on ne verifie pas la connexion tout de suite, car si ca se trouve
// queue_sleep_time_to_next_job() dira qu'il n'y a rien a faire
// et on evite d'ouvrir une connexion pour rien (utilisation de _DIRECT_CRON_FORCE dans mes_options.php)
if ($taches && count($taches) && !spip_connect()) {
cerdic
a validé
return false;
}
if ($genie = charger_fonction('genie', 'inc', true)) {
return $genie($taches);
cerdic
a validé
return false;
/**
* Ajout d'une tache dans la file d'attente
*
* @param string $function
* @param string $description
* Une description humainement compréhensible de ce que fait la tâche
* (essentiellement pour l’affichage dans la page de suivi de l’espace privé)
* @param array $arguments
* Facultatif, vide par défaut : les arguments qui seront passés à la fonction, sous forme de tableau PHP
* @param string $file
* Facultatif, vide par défaut : nom du fichier à inclure, via `include_spip($file)`
* exemple : `'inc/mail'` : il ne faut pas indiquer .php
* Si le nom finit par un '/' alors on considère que c’est un répertoire et SPIP fera un `charger_fonction($function, $file)`
* @param bool $no_duplicate
* Facultatif, `false` par défaut
*
* - si `true` la tâche ne sera pas ajoutée si elle existe déjà en file d’attente avec la même fonction et les mêmes arguments.
* - si `function_only` la tâche ne sera pas ajoutée si elle existe déjà en file d’attente avec la même fonction indépendamment de ses arguments
* @param int $time
* Facultatif, `0` par défaut : indique la date sous forme de timestamp à laquelle la tâche doit être programmée.
* Si `0` ou une date passée, la tâche sera exécutée aussitôt que possible (en général en fin hit, en asynchrone).
* @param int $priority
* Facultatif, `0` par défaut : indique un niveau de priorité entre -10 et +10.
* Les tâches sont exécutées par ordre de priorité décroissante, une fois leur date d’exécution passée. La priorité est surtout utilisée quand une tâche cron indique qu’elle n’a pas fini et doit être relancée : dans ce cas SPIP réduit sa priorité pour être sûr que celle tâche ne monopolise pas la file d’attente.
* @return int
* Le numéro de travail ajouté ou `0` si aucun travail n’a été ajouté.
cerdic
a validé
function job_queue_add(
$function,
$description,
cerdic
a validé
$file = '',
$no_duplicate = false,
$time = 0,
$priority = 0
) {
include_spip('inc/queue');
cerdic
a validé
return queue_add_job($function, $description, $arguments, $file, $no_duplicate, $time, $priority);
}
/**
* Supprimer une tache de la file d'attente
cerdic
a validé
*
* @param int $id_job
* id of jonb to delete
* @return bool
*/
cerdic
a validé
function job_queue_remove($id_job) {
include_spip('inc/queue');
cerdic
a validé
return queue_remove_job($id_job);
}
/**
* Associer une tache a un/des objets de SPIP
cerdic
a validé
*
* @param int $id_job
* id of job to link
* @param array $objets
* can be a simple array('objet'=>'article', 'id_objet'=>23)
* or an array of simple array to link multiples objet in one time
cerdic
a validé
function job_queue_link($id_job, $objets) {
include_spip('inc/queue');
cerdic
a validé
return queue_link_job($id_job, $objets);
}
/**
* Renvoyer le temps de repos restant jusqu'au prochain job
*
* @staticvar int $queue_next_job_time
* @see queue_set_next_job_time()
* @param int|bool $force
* Utilisée par `queue_set_next_job_time()` pour mettre à jour la valeur :
*
* - si `true`, force la relecture depuis le fichier
* - si int, affecte la static directement avec la valeur
* - `0` si un job est à traiter
* - `null` si la queue n'est pas encore initialisée
gilles.vincent
a validé
function queue_sleep_time_to_next_job($force = null) {
cerdic
a validé
if ($force === true) {
$queue_next_job_time = -1;
cerdic
a validé
} elseif ($force) {
$queue_next_job_time = $force;
cerdic
a validé
}
cerdic
a validé
if ($queue_next_job_time == -1) {
if (!defined('_JQ_NEXT_JOB_TIME_FILENAME')) {
define('_JQ_NEXT_JOB_TIME_FILENAME', _DIR_TMP . 'job_queue_next.txt');
// utiliser un cache memoire si dispo
if (function_exists('cache_get') && defined('_MEMOIZE_MEMORY') && _MEMOIZE_MEMORY) {
$queue_next_job_time = cache_get(_JQ_NEXT_JOB_TIME_FILENAME);
cerdic
a validé
} else {
$queue_next_job_time = null;
cerdic
a validé
if (lire_fichier(_JQ_NEXT_JOB_TIME_FILENAME, $contenu)) {
$queue_next_job_time = intval($contenu);
cerdic
a validé
}
}
}
cerdic
a validé
if (is_null($queue_next_job_time)) {
return null;
cerdic
a validé
}
if (!$_SERVER['REQUEST_TIME']) {
$_SERVER['REQUEST_TIME'] = time();
cerdic
a validé
}
return $queue_next_job_time - $_SERVER['REQUEST_TIME'];
* @pipeline post_typo
* @param string $u
* @return string
*/
function quote_amp($u) {
return preg_replace(
'/&(?![a-z]{0,4}\w{2,3};|#x?[0-9a-f]{2,6};)/i',
'&',
$u
);
/**
* Produit une balise `<script>` valide
*
* @example
* ```
* echo http_script('alert("ok");');
* echo http_script('','js/jquery.js');
* ```
*
* @param string $script
* Code source du script
* @param string $src
* Permet de faire appel à un fichier javascript distant
* @param string $noscript
* Contenu de la balise `<noscript>`
* @return string
* Balise HTML `<script>` et son contenu
cerdic
a validé
**/
gilles.vincent
a validé
function http_script($script, $src = '', $noscript = '') {
cerdic
a validé
if ($src && !isset($done[$src])) {
$src = find_in_path($src, _JAVASCRIPT);
$src = " src='$src'";
cerdic
a validé
} else {
$src = '';
cerdic
a validé
if ($script) {
cerdic
a validé
preg_replace(',</([^>]*)>,', '<\/\1>', $script) .
cerdic
a validé
}
if ($noscript) {
$noscript = "<noscript>\n\t$noscript\n</noscript>\n";
cerdic
a validé
}
return ($src || $script || $noscript)
cerdic
a validé
? "<script type='text/javascript'$src>$script</script>$noscript"
: '';
}
/**
* Sécurise du texte à écrire dans du PHP ou du Javascript.
cerdic
a validé
*
* Transforme n'importe quel texte en une chaîne utilisable
* en PHP ou Javascript en toute sécurité, à l'intérieur d'apostrophes
* simples (`'` uniquement ; pas `"`)
*
* Utile particulièrement en filtre dans un squelettes
* pour écrire un contenu dans une variable JS ou PHP.
*
* Échappe les apostrophes (') du contenu transmis.
*
* @link https://www.spip.net/4281
* @example
* PHP dans un squelette
* ```
* $x = '[(#TEXTE|texte_script)]';
* ```
*
* JS dans un squelette (transmettre une chaîne de langue)
* ```
* $x = '<:afficher_calendrier|texte_script:>';
* ```
*
* @filtre
* @param string|null $texte
* texte à échapper
* texte échappé
cerdic
a validé
**/
function texte_script(?string $texte): string {
if ($texte === null || $texte === '') {
return '';
}
return str_replace('\'', '\\\'', str_replace('\\', '\\\\', $texte));
}
/**
* Gestion des chemins (ou path) de recherche de fichiers par SPIP
*
* Empile de nouveaux chemins (à la suite de ceux déjà présents, mais avant
* le répertoire `squelettes` ou les dossiers squelettes), si un répertoire
* (ou liste de répertoires séparés par `:`) lui est passé en paramètre.
*
* Ainsi, si l'argument est de la forme `dir1:dir2:dir3`, ces 3 chemins sont placés
* en tête du path, dans cet ordre (hormis `squelettes` & la globale
* `$dossier_squelette` si définie qui resteront devant)
*
* Retourne dans tous les cas la liste des chemins.
*
* @note
* Cette fonction est appelée à plusieurs endroits et crée une liste
* de chemins finale à peu près de la sorte :
*
* - dossiers squelettes (si globale précisée)
* - squelettes/
* - plugins (en fonction de leurs dépendances) : ceux qui dépendent
* d'un plugin sont devant eux (ils peuvent surcharger leurs fichiers)
* - racine du site
* - squelettes-dist/
* - prive/
* - ecrire/
*
* @param string|array $dir_path
* - Répertoire(s) à empiler au path
* - '' provoque un recalcul des chemins.
* @return array
* Liste des chemins, par ordre de priorité.
cerdic
a validé
**/
function _chemin($dir_path = null) {
static $path_base = null;
static $path_full = null;
if ($path_base == null) {
$path = defined('_SPIP_PATH') ? _SPIP_PATH :
cerdic
a validé
_DIR_RACINE . ':' .
_DIR_RACINE . 'squelettes-dist/:' .
_DIR_RACINE . 'prive/:' .
_DIR_RESTREINT;
cerdic
a validé
if (@is_dir(_DIR_RACINE . 'squelettes')) {
$path = _DIR_RACINE . 'squelettes/:' . $path;
}
if (strlen($dir) && !str_ends_with($dir, '/')) {
cerdic
a validé
}
$path_base[] = $dir;
}
$path_full = $path_base;
// Et le(s) dossier(s) des squelettes nommes
cerdic
a validé
if (strlen($GLOBALS['dossier_squelettes'])) {
foreach (array_reverse(explode(':', $GLOBALS['dossier_squelettes'])) as $d) {
array_unshift($path_full, ($d[0] == '/' ? '' : _DIR_RACINE) . $d . '/');
cerdic
a validé
}
}
$GLOBALS['path_sig'] = md5(serialize($path_full));
cerdic
a validé
if ($dir_path === null) {
return $path_full;
}
if (is_array($dir_path) || strlen($dir_path)) {
cerdic
a validé
if (reset($path_base) == _DIR_RACINE . 'squelettes/') {
cerdic
a validé
$tete = array_shift($path_base);
cerdic
a validé
}
$dirs = (is_array($dir_path) ? $dir_path : explode(':', $dir_path));
$dirs = array_reverse($dirs);
cerdic
a validé
foreach ($dirs as $dir_path) {
if (!str_ends_with($dir_path, '/')) {
cerdic
a validé
}
if (!in_array($dir_path, $path_base)) {
array_unshift($path_base, $dir_path);
}
}
if (strlen($tete)) {
array_unshift($path_base, $tete);
}
$path_full = $path_base;
// Et le(s) dossier(s) des squelettes nommes
cerdic
a validé
if (strlen($GLOBALS['dossier_squelettes'])) {
foreach (array_reverse(explode(':', $GLOBALS['dossier_squelettes'])) as $d) {
array_unshift($path_full, ((isset($d[0]) && $d[0] == '/') ? '' : _DIR_RACINE) . $d . '/');
cerdic
a validé
}
}
$GLOBALS['path_sig'] = md5(serialize($path_full));
cerdic
a validé
return $path_full;
}
/**
* Retourne la liste des chemins connus de SPIP, dans l'ordre de priorité
*
* Recalcule la liste si le nom ou liste de dossier squelettes a changé.
*
* @uses _chemin()
*
* @return array Liste de chemins
cerdic
a validé
**/
function creer_chemin() {
$path_a = _chemin();
static $c = '';
// on calcule le chemin si le dossier skel a change
if ($c != $GLOBALS['dossier_squelettes']) {
// assurer le non plantage lors de la montee de version :
$c = $GLOBALS['dossier_squelettes'];
$path_a = _chemin(''); // forcer un recalcul du chemin
}
cerdic
a validé
return $path_a;
}
/**
* Retourne la liste des thèmes du privé utilisables pour cette session
*
* @see inscription_nouveau() pour une particularité historique du champ 'prefs'
*
* @return string[] Nom des thèmes.
*/
function lister_themes_prives(): array {
cerdic
a validé
if (is_null($themes)) {
cerdic
a validé
if (!defined('_SPIP_THEME_PRIVE')) {
cerdic
a validé
}
// Lors d'une installation neuve, prefs n'est pas definie ; sinon, c'est un tableau sérialisé
// FIXME: Aussitôt après une demande d'inscription, $prefs vaut une chaine statut_tmp;
$prefs = $GLOBALS['visiteur_session']['prefs'] ?? [];
if (is_string($prefs) && stripos($prefs, 'a:') === 0) {
$prefs = unserialize($prefs);
} else {
$theme = $prefs['theme'] ?? $GLOBALS['theme_prive_defaut'] ?? null;
if ($theme && $theme !== _SPIP_THEME_PRIVE) {
// placer le theme choisi en tete
cerdic
a validé
array_unshift($themes, $theme);
cerdic
a validé
cerdic
a validé
function find_in_theme($file, $subdir = '', $include = false) {
cerdic
a validé
if (isset($themefiles["$subdir$file"])) {
return $themefiles["$subdir$file"];
}
// on peut fournir une icone generique -xx.svg qui fera le job dans toutes les tailles, et qui est prioritaire sur le png
// si il y a un .svg a la bonne taille (-16.svg) a cote, on l'utilise en remplacement du -16.png
if (
preg_match(',-(\d+)[.](png|gif|svg)$,', $file, $m)
&& ($file_svg_generique = substr($file, 0, -strlen($m[0])) . '-xx.svg')
&& ($f = find_in_theme("$file_svg_generique"))
if (($fsize = substr($f, 0, -6) . $m[1] . '.svg') && file_exists($fsize)) {
return $themefiles["$subdir$file"] = $fsize;
}
else {
return $themefiles["$subdir$file"] = "$f?" . $m[1] . 'px';
}
cerdic
a validé
}
cerdic
a validé
foreach ($themes as $theme) {
if ($f = find_in_path($file, "prive/themes/$theme/$subdir", $include)) {
return $themefiles["$subdir$file"] = $f;
cerdic
a validé
}
cerdic
a validé
spip_log("$file introuvable dans le theme prive " . reset($themes), 'theme');
/**
* Cherche une image dans les dossiers d'images
*
* Cherche en priorité dans les thèmes d'image (prive/themes/X/images)
* et si la fonction n'en trouve pas, gère le renommage des icones (ex: 'supprimer' => 'del')
* de facon temporaire le temps de la migration, et cherche de nouveau.
*
* Si l'image n'est toujours pas trouvée, on la cherche dans les chemins,
* dans le répertoire défini par la constante `_NOM_IMG_PACK`
*
* @see find_in_theme()
* @see inc_icone_renommer_dist()
*
* @param string $icone
* Nom de l'icone cherchée
* @return string
* Chemin complet de l'icone depuis la racine si l'icone est trouée,
* sinon chaîne vide.
cerdic
a validé
**/
function chemin_image($icone) {
if ($p = strpos($icone, '?')) {
// gerer le cas d'un double appel en evitant de refaire le travail inutilement
if (str_contains($icone, '/') && file_exists($icone)) {
cerdic
a validé
return $icone;
}
// si c'est un nom d'image complet (article-24.png) essayer de le renvoyer direct
if (preg_match(',[.](png|gif|jpg|webp|svg)$,', $icone) && ($f = find_in_theme("images/$icone"))) {
cerdic
a validé
return $f;
cerdic
a validé
}
// sinon passer par le module de renommage
cerdic
a validé
if (is_null($icone_renommer)) {
$icone_renommer = charger_fonction('icone_renommer', 'inc', true);
}
if ($icone_renommer) {
[$icone, $fonction] = $icone_renommer($icone, '');
cerdic
a validé
if (file_exists($icone)) {
cerdic
a validé
}
cerdic
a validé
return find_in_path($icone, _NOM_IMG_PACK);
}
//
// chercher un fichier $file dans le SPIP_PATH
// si on donne un sous-repertoire en 2e arg optionnel, il FAUT le / final
// si 3e arg vrai, on inclut si ce n'est fait.
/**
* Recherche un fichier dans les chemins de SPIP (squelettes, plugins, core)
*
* Retournera le premier fichier trouvé (ayant la plus haute priorité donc),
* suivant l'ordre des chemins connus de SPIP.
*
* @api
cerdic
a validé
* @see charger_fonction()
* @uses creer_chemin() Pour la liste des chemins.
* @example
* ```
* $f = find_in_path('css/perso.css');
* $f = find_in_path('perso.css', 'css');
* ```
*
* @param string $file
* Fichier recherché
* @param string $dirname
* Répertoire éventuel de recherche (est aussi extrait automatiquement de $file)
* @param bool|string $include
* - false : ne fait rien de plus
* - true : inclut le fichier (include_once)
* - 'require' : idem, mais tue le script avec une erreur si le fichier n'est pas trouvé.
* @return string|bool
* - string : chemin du fichier trouvé
* - false : fichier introuvable
cerdic
a validé
**/
function find_in_path($file, $dirname = '', $include = false) {
static $dirs = [];
static $inc = []; # cf https://git.spip.net/spip/spip/commit/42e4e028e38c839121efaee84308d08aee307eec
if (!$file && !strlen($file)) {
return false;
}
// on calcule le chemin si le dossier skel a change
cerdic
a validé
if ($c != $GLOBALS['dossier_squelettes']) {
// assurer le non plantage lors de la montee de version :
$c = $GLOBALS['dossier_squelettes'];
creer_chemin(); // forcer un recalcul du chemin et la mise a jour de path_sig
}
if (isset($GLOBALS['path_files'][$GLOBALS['path_sig']][$dirname][$file])) {
cerdic
a validé
if (!$GLOBALS['path_files'][$GLOBALS['path_sig']][$dirname][$file]) {
cerdic
a validé
}
if ($include && !isset($inc[$dirname][$file])) {
include_once _ROOT_CWD . $GLOBALS['path_files'][$GLOBALS['path_sig']][$dirname][$file];
$inc[$dirname][$file] = $inc[''][$dirname . $file] = true;
}
cerdic
a validé
return $GLOBALS['path_files'][$GLOBALS['path_sig']][$dirname][$file];
cerdic
a validé
$a = strrpos($file, '/');
$dirname .= substr($file, 0, ++$a);
$file = substr($file, $a);
cerdic
a validé
foreach (creer_chemin() as $dir) {
if (!isset($dirs[$a = $dir . $dirname])) {
$dirs[$a] = (is_dir(_ROOT_CWD . $a) || !$a);
}
if ($dirs[$a]) {
if (file_exists(_ROOT_CWD . ($a .= $file))) {
if ($include && !isset($inc[$dirname][$file])) {
include_once _ROOT_CWD . $a;
$inc[$dirname][$file] = $inc[''][$dirname . $file] = true;
}
cerdic
a validé
if (!defined('_SAUVER_CHEMIN')) {
// si le chemin n'a pas encore ete charge, ne pas lever le flag, ne pas cacher
cerdic
a validé
if (is_null($GLOBALS['path_files'])) {
return $a;
}
define('_SAUVER_CHEMIN', true);
}
cerdic
a validé
return $GLOBALS['path_files'][$GLOBALS['path_sig']][$dirname][$file] = $GLOBALS['path_files'][$GLOBALS['path_sig']][''][$dirname . $file] = $a;
}
cerdic
a validé
if ($include) {
spip_log("include_spip $dirname$file non trouve");
cerdic
a validé
if ($include === 'required') {
cerdic
a validé
if (function_exists('debug_print_backtrace')) {
debug_print_backtrace();
cerdic
a validé
}
echo '</pre>';
die("Erreur interne: ne peut inclure $dirname$file");
}
}
cerdic
a validé
if (!defined('_SAUVER_CHEMIN')) {
// si le chemin n'a pas encore ete charge, ne pas lever le flag, ne pas cacher
cerdic
a validé
if (is_null($GLOBALS['path_files'])) {
return false;
}
define('_SAUVER_CHEMIN', true);
}
cerdic
a validé
return $GLOBALS['path_files'][$GLOBALS['path_sig']][$dirname][$file] = $GLOBALS['path_files'][$GLOBALS['path_sig']][''][$dirname . $file] = false;
cerdic
a validé
function clear_path_cache() {
cerdic
a validé
function load_path_cache() {
// charger le path des plugins
cerdic
a validé
if (@is_readable(_CACHE_PLUGINS_PATH)) {
include_once(_CACHE_PLUGINS_PATH);
}
// si le visiteur est admin,
// on ne recharge pas le cache pour forcer sa mise a jour
if (
// la session n'est pas encore chargee a ce moment, on ne peut donc pas s'y fier
//AND (!isset($GLOBALS['visiteur_session']['statut']) OR $GLOBALS['visiteur_session']['statut']!='0minirezo')
// utiliser le cookie est un pis aller qui marche 'en general'
// on blinde par un second test au moment de la lecture de la session
// !isset($_COOKIE[$GLOBALS['cookie_prefix'].'_admin'])
cerdic
a validé
) {
cerdic
a validé
// on essaye de lire directement sans verrou pour aller plus vite
cerdic
a validé
if ($contenu = spip_file_get_contents(_CACHE_CHEMIN)) {
cerdic
a validé
// mais si semble corrompu on relit avec un verrou
cerdic
a validé
if (!$GLOBALS['path_files'] = unserialize($contenu)) {
lire_fichier(_CACHE_CHEMIN, $contenu);
if (!$GLOBALS['path_files'] = unserialize($contenu)) {
cerdic
a validé
}
cerdic
a validé
}
}
cerdic
a validé
function save_path_cache() {
&& _SAUVER_CHEMIN
cerdic
a validé
) {
ecrire_fichier(_CACHE_CHEMIN, serialize($GLOBALS['path_files']));
}
* Trouve tous les fichiers du path correspondants à un pattern
*
* Pour un nom de fichier donné, ne retourne que le premier qui sera trouvé
* par un `find_in_path()`
*
* @param string $dir
* @param string $pattern
* @param bool $recurs
* @return array
*/
cerdic
a validé
function find_all_in_path($dir, $pattern, $recurs = false) {
$maxfiles = 10000;
// cas borderline si dans mes_options on appelle redirige_par_entete qui utilise _T et charge un fichier de langue
// on a pas encore inclus flock.php
if (!function_exists('preg_files')) {
include_once _ROOT_RESTREINT . 'inc/flock.php';
}
// Parcourir le chemin
foreach (creer_chemin() as $d) {
cerdic
a validé
$f = $d . $dir;
if (@is_dir($f)) {
$liste = preg_files($f, $pattern, $maxfiles - count($liste_fichiers), $recurs === true ? [] : $recurs);
cerdic
a validé
foreach ($liste as $chemin) {
$nom = basename($chemin);
// ne prendre que les fichiers pas deja trouves
// car find_in_path prend le premier qu'il trouve,
// les autres sont donc masques
cerdic
a validé
if (!isset($liste_fichiers[$nom])) {
$liste_fichiers[$nom] = $chemin;
cerdic
a validé
}
}
}
cerdic
a validé
return $liste_fichiers;
}
/**
* Prédicat sur les scripts de ecrire qui n'authentifient pas par cookie
* et beneficient d'une exception
*
* @param bool $strict
function autoriser_sans_cookie($nom, $strict = false) {
cerdic
a validé
if (in_array($nom, $autsanscookie)) {
include_spip('base/connect_sql');
if (!$strict || !spip_connect()) {
return true;
}
}
}
return false;
}
/**
* Charger la fonction de gestion des urls si elle existe
* @param string $quoi
* 'page' 'objet' 'decoder' ou objet spip pour lequel on cherche la fonction url par defaut (si type==='defaut')
* @param string $type
* type des urls (par defaut la meta type_urls) ou 'defaut' pour trouver la fonction par defaut d'un type d'objet
* @return string
*/
function charger_fonction_url(string $quoi, string $type = '') {
if ($type === 'defaut') {
$objet = objet_type($quoi);
($f = charger_fonction('generer_' . $objet . '_url', 'urls', true))
|| ($f = charger_fonction('generer_url_' . $objet, 'urls', true)) // deprecated
) {
return $f;
}
return '';
}
$url_type = $type;
if (!$url_type) {
$url_type = $GLOBALS['type_urls'] ?? $GLOBALS['meta']['type_urls'] ?? 'page'; // sinon type "page" par défaut
}
// inclure le module d'url
include_spip('urls/' . $url_type);
switch ($quoi) {
case 'page':
if (
function_exists($f = "urls_{$url_type}_generer_url_page")
|| function_exists($f .= '_dist')
// ou une fonction custom utilisateur independante du type d'url
|| function_exists($f = 'generer_url_page')
|| function_exists($f .= '_dist')
) {
return $f;
}
// pas de compat ancienne version ici, c'est une nouvelle feature
return '';
case 'objet':
case 'decoder':
default:
$fquoi = ($quoi === 'objet' ? 'generer_url_objet' : 'decoder_url');
function_exists($f = "urls_{$url_type}_{$fquoi}")
|| function_exists($f .= '_dist')
return $f;
}
// est-ce qu'on a une ancienne fonction urls_xxx_dist() ?
// c'est un ancien module d'url, on appelle l'ancienne fonction qui fait tout
if ($f = charger_fonction($url_type, 'urls', true)) {
return $f;
}
// sinon on se rabat sur les urls page si ce n'est pas un type demande explicitement
if (!$type && $url_type !== 'page') {
return charger_fonction_url($quoi, 'page');
}
return '';
}
}
* Fonction codant les URLs des objets SQL mis en page par SPIP
* @param int|string|null $id
* numero de la cle primaire si nombre
* @param string $entite
* surnom de la table SQL (donne acces au nom de cle primaire)
* @param string $args
* query_string a placer apres cle=$id&....
* @param string $ancre
* ancre a mettre a la fin de l'URL a produire
* @param ?bool $public
* produire l'URL publique ou privee (par defaut: selon espace)
* @param string $type
* fichier dans le repertoire ecrire/urls determinant l'apparence
* @param string $connect
* @return string
* url codee ou fonction de decodage
*/
function generer_objet_url($id, string $entite, string $args = '', string $ancre = '', ?bool $public = null, string $type = '', string $connect = ''): string {
cerdic
a validé
if ($public === null) {
$public = !test_espace_prive();
}
$id = intval($id);
$entite = objet_type($entite); // cas particulier d'appels sur objet/id_objet...
if (!$public) {
cerdic
a validé
if (!$entite) {
return '';
}
if (!function_exists('generer_objet_url_ecrire')) {
include_spip('inc/urls');
cerdic
a validé
}
$res = generer_objet_url_ecrire($id, $entite, $args, $ancre, false, $connect);
$f = charger_fonction_url('objet', $type ?? '');
// @deprecated si $entite='', on veut la fonction de passage URL ==> id
// @see charger_fonction_url
cerdic
a validé
if (!$entite) {
return $f;
}
// mais d'abord il faut tester le cas des urls sur une
// base distante
&& ($g = charger_fonction('connect', 'urls', true))
cerdic
a validé
) {
$f = $g;
cerdic
a validé
}
$res = $f(intval($id), $entite, $args ?: '', $ancre ?: '', $connect);
cerdic
a validé
if ($res) {
return $res;
}
// On a ete gentil mais la ....
spip_log("generer_objet_url: entite $entite " . ($public ? "($f)" : '') . " inconnue $type $public $connect", _LOG_ERREUR);
cerdic
a validé
* @deprecated 4.1
function generer_url_entite($id = 0, $entite = '', $args = '', $ancre = '', $public = null, $type = null) {
trigger_deprecation('spip', '4.1', 'Using "%s" is deprecated, use "%s" instead', __FUNCTION__, 'generer_objet_url');
if ($public && is_string($public)) {
return generer_objet_url(intval($id), $entite, $args ?: '', $ancre ?: '', true, $type ?? '', $public);
return generer_objet_url(intval($id), $entite, $args ?: '', $ancre ?: '', $public, $type ?? '');
/**
* Generer l'url vers la page d'edition dans ecrire/
* @param int|string|null $id
function generer_objet_url_ecrire_edit($id, string $entite, string $args = '', string $ancre = ''): string {
$id = intval($id);
cerdic
a validé
$exec = objet_info($entite, 'url_edit');
$url = generer_url_ecrire($exec, $args);
if (intval($id)) {
$url = parametre_url($url, id_table_objet($entite), $id);
} else {
$url = parametre_url($url, 'new', 'oui');
}
if ($ancre) {
$url = ancre_url($url, $ancre);
}
return $url;
}
* @deprecated 4.1
* @see generer_objet_url_ecrire_edit
*/
function generer_url_ecrire_entite_edit($id, $entite, $args = '', $ancre = '') {
trigger_deprecation('spip', '4.1', 'Using "%s" is deprecated, use "%s" instead', __FUNCTION__, 'generer_objet_url_ecrire_edit');
return generer_objet_url_ecrire_edit(intval($id), $entite, $args, $ancre);
gilles.vincent
a validé
function urls_connect_dist($i, &$entite, $args = '', $ancre = '', $public = null) {
include_spip('base/connect_sql');
cerdic
a validé
$id_type = id_table_objet($entite, $public);
return _DIR_RACINE . get_spip_script('./')
. '?' . _SPIP_PAGE . "=$entite&$id_type=$i&connect=$public"
cerdic
a validé
. (!$args ? '' : "&$args")
. (!$ancre ? '' : "#$ancre");
}
/**
* Transformer les caractères utf8 d'une URL (farsi par exemple) selon la RFC 1738
*
* @param string $url
* @return string
*/
function urlencode_1738($url) {
cerdic
a validé
if (preg_match(',[^\x00-\x7E],sS', $url)) {