Skip to content
Extraits de code Groupes Projets
Valider bc1e040c rédigé par marcimat's avatar marcimat
Parcourir les fichiers

refactor: Déplacer une grande partie de inc/utils dans boostrap/inc/

parent a34ad9e6
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
Affichage de
avec 3786 ajouts et 3747 suppressions
...@@ -32,6 +32,8 @@ global ...@@ -32,6 +32,8 @@ global
$mysql_rappel_connexion, $mysql_rappel_connexion,
$mysql_rappel_nom_base, $mysql_rappel_nom_base,
$nombre_de_logs, $nombre_de_logs,
$path_sig,
$path_files,
$plugins, $plugins,
$puce, $puce,
$source_vignettes, $source_vignettes,
...@@ -210,3 +212,9 @@ $meta = $connect_id_rubrique = []; ...@@ -210,3 +212,9 @@ $meta = $connect_id_rubrique = [];
// version de l'interface a la base // version de l'interface a la base
$spip_sql_version = 1; $spip_sql_version = 1;
// 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.
$path_sig = '';
$path_files = null;
...@@ -26,7 +26,7 @@ define('_DIR_RESTREINT', (is_dir(_DIR_RESTREINT_ABS) ? _DIR_RESTREINT_ABS : '')) ...@@ -26,7 +26,7 @@ define('_DIR_RESTREINT', (is_dir(_DIR_RESTREINT_ABS) ? _DIR_RESTREINT_ABS : ''))
define('_DIR_RACINE', _DIR_RESTREINT ? '' : '../'); define('_DIR_RACINE', _DIR_RESTREINT ? '' : '../');
/** chemin absolu vers la racine */ /** chemin absolu vers la racine */
define('_ROOT_RACINE', dirname(__DIR__, 2) . '/'); define('_ROOT_RACINE', dirname(__DIR__, 3) . '/');
/** chemin absolu vers le repertoire de travail */ /** chemin absolu vers le repertoire de travail */
define('_ROOT_CWD', getcwd() . '/'); define('_ROOT_CWD', getcwd() . '/');
/** chemin absolu vers ecrire */ /** chemin absolu vers ecrire */
...@@ -61,7 +61,7 @@ if (!defined('_NOM_IMG_PACK')) { ...@@ -61,7 +61,7 @@ if (!defined('_NOM_IMG_PACK')) {
define('_DIR_IMG_PACK', (_DIR_RACINE . 'prive/' . _NOM_IMG_PACK)); define('_DIR_IMG_PACK', (_DIR_RACINE . 'prive/' . _NOM_IMG_PACK));
/** le chemin php (absolu) vers les images standard (pour hebergement centralise) */ /** le chemin php (absolu) vers les images standard (pour hebergement centralise) */
define('_ROOT_IMG_PACK', dirname(__DIR__, 2) . '/prive/' . _NOM_IMG_PACK); define('_ROOT_IMG_PACK', dirname(__DIR__, 3) . '/prive/' . _NOM_IMG_PACK);
if (!defined('_JAVASCRIPT')) { if (!defined('_JAVASCRIPT')) {
/** Nom du repertoire des bibliotheques JavaScript */ /** Nom du repertoire des bibliotheques JavaScript */
......
<?php
/**
* Différentes fonctions chargées au démarrage de SPIP
*
* Ces fichiers ne peuvent pas être surchargés dans des plugins
*/
include_once __DIR__ . '/inc/auth.php';
include_once __DIR__ . '/inc/form.php';
include_once __DIR__ . '/inc/initialization.php';
include_once __DIR__ . '/inc/i18n.php';
include_once __DIR__ . '/inc/jobs.php';
include_once __DIR__ . '/inc/loading.php';
include_once __DIR__ . '/inc/logging.php';
include_once __DIR__ . '/inc/path.php';
include_once __DIR__ . '/inc/pipeline.php';
include_once __DIR__ . '/inc/request.php';
include_once __DIR__ . '/inc/sanitize.php';
include_once __DIR__ . '/inc/templating.php';
include_once __DIR__ . '/inc/utils.php';
include_once __DIR__ . '/inc/urls.php';
require_once dirname(__DIR__) . '/base/connect_sql.php';
<?php
/**
* Indique si on est dans l'espace prive
*
* @return bool
* true si c'est le cas, false sinon.
*/
function test_espace_prive() {
return defined('_ESPACE_PRIVE') ? _ESPACE_PRIVE : false;
}
/**
* Prédicat sur les scripts de ecrire qui n'authentifient pas par cookie
* et beneficient d'une exception
*
* @param string $nom
* @param bool $strict
* @return bool
*/
function autoriser_sans_cookie($nom, $strict = false) {
static $autsanscookie = ['install', 'base_repair'];
if (in_array($nom, $autsanscookie)) {
if (test_espace_prive()) {
include_spip('base/connect_sql');
if (!$strict || !spip_connect()) {
return true;
}
}
}
return false;
}
/**
* Retourne le statut du visiteur s'il s'annonce.
*
* Pour que cette fonction marche depuis mes_options,
* il faut forcer l'init si ce n'est fait
* mais on risque de perturber des plugins en initialisant trop tot
* certaines constantes.
* @return string|0|false
**/
function verifier_visiteur() {
@spip_initialisation_core(
(_DIR_RACINE . _NOM_PERMANENTS_INACCESSIBLES),
(_DIR_RACINE . _NOM_PERMANENTS_ACCESSIBLES),
(_DIR_RACINE . _NOM_TEMPORAIRES_INACCESSIBLES),
(_DIR_RACINE . _NOM_TEMPORAIRES_ACCESSIBLES)
);
// Demarrer une session NON AUTHENTIFIEE si on donne son nom
// dans un formulaire sans login (ex: #FORMULAIRE_FORUM)
// Attention on separe bien session_nom et nom, pour eviter
// les melanges entre donnees SQL et variables plus aleatoires
$variables_session = ['session_nom', 'session_email'];
foreach ($variables_session as $var) {
if (_request($var) !== null) {
$init = true;
break;
}
}
if (isset($init)) {
#@spip_initialisation_suite();
$session = charger_fonction('session', 'inc');
$session();
include_spip('inc/texte');
foreach ($variables_session as $var) {
if (($a = _request($var)) !== null) {
$GLOBALS['visiteur_session'][$var] = safehtml($a);
}
}
if (!isset($GLOBALS['visiteur_session']['id_auteur'])) {
$GLOBALS['visiteur_session']['id_auteur'] = 0;
}
$session($GLOBALS['visiteur_session']);
return 0;
}
$h = (isset($_SERVER['PHP_AUTH_USER']) && !$GLOBALS['ignore_auth_http']);
if ($h || isset($_COOKIE['spip_session']) || isset($_COOKIE[$GLOBALS['cookie_prefix'] . '_session'])) {
$session = charger_fonction('session', 'inc');
if ($session()) {
return $GLOBALS['visiteur_session']['statut'];
}
if ($h && isset($_SERVER['PHP_AUTH_PW'])) {
include_spip('inc/auth');
$h = lire_php_auth($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']);
}
if ($h) {
$GLOBALS['visiteur_session'] = $h;
return $GLOBALS['visiteur_session']['statut'];
}
}
// au moins son navigateur nous dit la langue preferee de cet inconnu
include_spip('inc/lang');
utiliser_langue_visiteur();
return false;
}
/**
* Renvoie une chaîne qui identifie la session courante
*
* Permet de savoir si on peut utiliser un cache enregistré pour cette session.
* Cette chaîne est courte (8 cars) pour pouvoir être utilisée dans un nom
* de fichier cache.
*
* @pipeline_appel definir_session
*
* @param bool $force
* @return string
* Identifiant de la session
**/
function spip_session($force = false) {
static $session;
if ($force || !isset($session)) {
$s = '';
if (!empty($GLOBALS['visiteur_session'])) {
include_spip('inc/session');
$cookie = lire_cookie_session();
$s = serialize($GLOBALS['visiteur_session']) . '_' . ($cookie ?: '');
}
$s = pipeline('definir_session', $s);
$session = ($s ? substr(md5($s), 0, 8) : '');
}
#spip_log('session: '.$session);
return $session;
}
<?php
// Pour les formulaires en methode POST,
// mettre le nom du script a la fois en input-hidden et dans le champ action:
// 1) on peut ainsi memoriser le signet comme si c'etait un GET
// 2) ca suit http://en.wikipedia.org/wiki/Representational_State_Transfer
/**
* Retourne un formulaire (POST par défaut) vers un script exec
* de l’interface privée
*
* @param string $script
* Nom de la page exec
* @param string $corps
* Contenu du formulaire
* @param string $atts
* Si présent, remplace les arguments par défaut (method=post) par ceux indiqués
* @param string $submit
* Si indiqué, un bouton de soumission est créé avec texte sa valeur.
* @return string
* Code HTML du formulaire
**/
function generer_form_ecrire($script, $corps, $atts = '', $submit = '') {
$script1 = explode('&', $script);
$script1 = reset($script1);
return "<form action='"
. ($script ? generer_url_ecrire($script) : '')
. "' "
. ($atts ?: " method='post'")
. "><div>\n"
. "<input type='hidden' name='exec' value='$script1' />"
. $corps
. (!$submit ? '' :
("<div style='text-align: " . $GLOBALS['spip_lang_right'] . "'><input class='fondo submit btn' type='submit' value=\"" . entites_html($submit) . '" /></div>'))
. "</div></form>\n";
}
/**
* Générer un formulaire pour lancer une action vers $script
*
* Attention, JS/Ajax n'aime pas le melange de param GET/POST
* On n'applique pas la recommandation ci-dessus pour les scripts publics
* qui ne sont pas destines a etre mis en signets
*
* @param string $script
* @param string $corps
* @param string $atts
* @param bool $public
* @return string
*/
function generer_form_action($script, $corps, $atts = '', $public = false) {
// si l'on est dans l'espace prive, on garde dans l'url
// l'exec a l'origine de l'action, qui permet de savoir si il est necessaire
// ou non de proceder a l'authentification (cas typique de l'install par exemple)
$h = (_DIR_RACINE && !$public)
? generer_url_ecrire(_request('exec'))
: generer_url_public();
return "\n<form action='" .
$h .
"'" .
$atts .
">\n" .
'<div>' .
"\n<input type='hidden' name='action' value='$script' />" .
$corps .
'</div></form>';
}
<?php
/**
* Traduction des textes de SPIP
*
* Traduit une clé de traduction en l'obtenant dans les fichiers de langues.
*
* @api
* @uses inc_traduire_dist()
* @uses _L()
* @example
* ```
* _T('bouton_enregistrer')
* _T('medias:image_tourner_droite')
* _T('medias:erreurs', array('nb'=>3))
* _T("email_sujet", array('spip_lang'=>$lang_usager))
* ```
*
* @param string $texte
* Clé de traduction
* @param array $args
* Couples (variable => valeur) pour passer des variables à la chaîne traduite. la variable spip_lang permet de forcer la langue
* @param array $options
* - string class : nom d'une classe a ajouter sur un span pour encapsuler la chaine
* - bool force : forcer un retour meme si la chaine n'a pas de traduction
* - bool sanitize : nettoyer le html suspect dans les arguments
* @return string
* texte
*/
function _T($texte, $args = [], $options = []) {
static $traduire = false;
$o = ['class' => '', 'force' => true, 'sanitize' => true];
if ($options) {
// support de l'ancien argument $class
if (is_string($options)) {
$options = ['class' => $options];
}
$o = array_merge($o, $options);
}
if (!$traduire) {
$traduire = charger_fonction('traduire', 'inc');
include_spip('inc/lang');
}
// On peut passer explicitement la langue dans le tableau
// On utilise le même nom de variable que la globale
if (isset($args['spip_lang'])) {
$lang = $args['spip_lang'];
// On l'enleve pour ne pas le passer au remplacement
unset($args['spip_lang']);
} // Sinon on prend la langue du contexte
else {
$lang = $GLOBALS['spip_lang'];
}
$text = $traduire($texte, $lang);
if ($text === null || !strlen($text)) {
if (!$o['force']) {
return '';
}
$text = $texte;
// pour les chaines non traduites, assurer un service minimum
if (!$GLOBALS['test_i18n'] && _request('var_mode') != 'traduction') {
$n = strpos($text, ':');
if ($n !== false) {
$text = substr($text, $n + 1);
}
$text = str_replace('_', ' ', $text);
}
$o['class'] = null;
}
return _L($text, $args, $o);
}
/**
* Remplace les variables `@...@` par leur valeur dans une chaîne de langue.
*
* Cette fonction est également appelée dans le code source de SPIP quand une
* chaîne n'est pas encore dans les fichiers de langue.
*
* @see _T()
* @example
* ```
* _L('Texte avec @nb@ ...', array('nb'=>3)
* ```
*
* @param string $text
* texte
* @param array $args
* Couples (variable => valeur) à transformer dans le texte
* @param array $options
* - string class : nom d'une classe a ajouter sur un span pour encapsuler la chaine
* - bool sanitize : nettoyer le html suspect dans les arguments
* @return string
* texte
*/
function _L($text, $args = [], $options = []) {
$f = $text;
$defaut_options = [
'class' => null,
'sanitize' => true,
];
// support de l'ancien argument $class
if ($options && is_string($options)) {
$options = ['class' => $options];
}
if (is_array($options)) {
$options += $defaut_options;
} else {
$options = $defaut_options;
}
if (is_array($args) && count($args)) {
if (!function_exists('interdire_scripts')) {
include_spip('inc/texte');
}
if (!function_exists('echapper_html_suspect')) {
include_spip('inc/texte_mini');
}
foreach ($args as $name => $value) {
if (str_contains($text, (string) "@$name@")) {
if ($options['sanitize']) {
$value = echapper_html_suspect($value);
$value = interdire_scripts($value, -1);
}
if (!empty($options['class'])) {
$value = "<span class='" . $options['class'] . "'>$value</span>";
}
$text = str_replace("@$name@", (string) $value, (string) $text);
unset($args[$name]);
}
}
// Si des variables n'ont pas ete inserees, le signaler
// (chaines de langues pas a jour)
if ($args) {
spip_log("$f: variables inutilisees " . join(', ', array_keys($args)), _LOG_DEBUG);
}
}
if (($GLOBALS['test_i18n'] || _request('var_mode') == 'traduction') && is_null($options['class'])) {
return "<span class='debug-traduction-erreur'>$text</span>";
} else {
return $text;
}
}
/**
* Sélectionne la langue donnée en argument et mémorise la courante
*
* Restaure l'ancienne langue si appellée sans argument.
*
* @note
* On pourrait économiser l'empilement en cas de non changemnt
* et lui faire retourner `False` pour prevenir l'appelant
* Le noyau de Spip sait le faire, mais pour assurer la compatibilité
* cette fonction retourne toujours non `False`
*
* @uses changer_langue()
* @param null|string $lang
* - string : Langue à appliquer,
* - null : Pour restituer la dernière langue mémorisée.
* @return string
* - string Langue utilisée.
**/
function lang_select($lang = null) {
static $pile_langues = [];
if (!function_exists('changer_langue')) {
include_spip('inc/lang');
}
if ($lang === null) {
$lang = array_pop($pile_langues);
} else {
array_push($pile_langues, $GLOBALS['spip_lang']);
}
if (isset($GLOBALS['spip_lang']) && $lang == $GLOBALS['spip_lang']) {
return $lang;
}
changer_langue($lang);
return $lang;
}
Ce diff est replié.
<?php
/**
* Action qui déclenche une tache de fond
*
* @see queue_affichage_cron()
* @uses cron()
**/
function action_cron() {
include_spip('inc/headers');
http_response_code(204); // No Content
header('Connection: close');
define('_DIRECT_CRON_FORCE', true);
cron();
}
/**
* Exécution des tâches de fond
*
* @uses inc_genie_dist()
*
* @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
*/
function cron($taches = [], $taches_old = []) {
// si pas en mode cron force, laisser tomber.
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()) {
return false;
}
spip_log('cron !', 'jq' . _LOG_DEBUG);
if ($genie = charger_fonction('genie', 'inc', true)) {
return $genie($taches);
}
return false;
}
/**
* Ajout d'une tache dans la file d'attente
*
* @param string $function
* Le nom de la fonction PHP qui doit être appelée.
* @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é.
*/
function job_queue_add(
$function,
$description,
$arguments = [],
$file = '',
$no_duplicate = false,
$time = 0,
$priority = 0
) {
include_spip('inc/queue');
return queue_add_job($function, $description, $arguments, $file, $no_duplicate, $time, $priority);
}
/**
* Supprimer une tache de la file d'attente
*
* @param int $id_job
* id of jonb to delete
* @return bool
*/
function job_queue_remove($id_job) {
include_spip('inc/queue');
return queue_remove_job($id_job);
}
/**
* Associer une tache a un/des objets de SPIP
*
* @param int $id_job
* id of job to link
* @param array $objets
* can be a simple array('objet'=>'article', 'id_objet'=>23)
* or an array of simple array to link multiples objet in one time
*/
function job_queue_link($id_job, $objets) {
include_spip('inc/queue');
return queue_link_job($id_job, $objets);
}
/**
* Renvoyer le temps de repos restant jusqu'au prochain job
*
* @staticvar int $queue_next_job_time
* @see queue_set_next_job_time()
* @param int|bool $force
* Utilisée par `queue_set_next_job_time()` pour mettre à jour la valeur :
*
* - si `true`, force la relecture depuis le fichier
* - si int, affecte la static directement avec la valeur
* @return int|null
* - `0` si un job est à traiter
* - `null` si la queue n'est pas encore initialisée
*/
function queue_sleep_time_to_next_job($force = null) {
static $queue_next_job_time = -1;
if ($force === true) {
$queue_next_job_time = -1;
} elseif ($force) {
$queue_next_job_time = $force;
}
if ($queue_next_job_time == -1) {
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);
} else {
$queue_next_job_time = null;
$contenu = null;
if (lire_fichier(_JQ_NEXT_JOB_TIME_FILENAME, $contenu)) {
$queue_next_job_time = intval($contenu);
}
}
}
if (is_null($queue_next_job_time)) {
return null;
}
if (!$_SERVER['REQUEST_TIME']) {
$_SERVER['REQUEST_TIME'] = time();
}
return $queue_next_job_time - $_SERVER['REQUEST_TIME'];
}
<?php
/**
* Cherche une fonction surchargeable et en retourne le nom exact,
* après avoir chargé le fichier la contenant si nécessaire.
*
* Charge un fichier (suivant les chemins connus) et retourne si elle existe
* le nom de la fonction homonyme `$dir_$nom`, ou suffixé `$dir_$nom_dist`
*
* Peut être appelé plusieurs fois, donc optimisé.
*
* @api
* @uses include_spip() Pour charger le fichier
* @example
* ```
* $envoyer_mail = charger_fonction('envoyer_mail', 'inc');
* $envoyer_mail($email, $sujet, $texte);
* ```
*
* @param string $nom
* Nom de la fonction (et du fichier)
* @param string $dossier
* Nom du dossier conteneur
* @param bool $continue
* true pour ne pas râler si la fonction n'est pas trouvée
* @return string
* Nom de la fonction, ou false.
*/
function charger_fonction($nom, $dossier = 'exec', $continue = false) {
static $echecs = [];
if (strlen($dossier) && !str_ends_with($dossier, '/')) {
$dossier .= '/';
}
$f = str_replace('/', '_', $dossier) . $nom;
if (function_exists($f)) {
return $f;
}
if (function_exists($g = $f . '_dist')) {
return $g;
}
if (isset($echecs[$f])) {
return $echecs[$f];
}
// Sinon charger le fichier de declaration si plausible
if (!preg_match(',^\w+$,', $f)) {
if ($continue) {
return false;
} //appel interne, on passe
include_spip('inc/minipres');
echo minipres();
exit;
}
// passer en minuscules (cf les balises de formulaires)
// et inclure le fichier
if (
!($inc = include_spip($dossier . ($d = strtolower($nom))))
&& strlen(dirname($dossier))
&& dirname($dossier) != '.'
) {
include_spip(substr($dossier, 0, -1));
}
if (function_exists($f)) {
return $f;
}
if (function_exists($g)) {
return $g;
}
if ($continue) {
return $echecs[$f] = false;
}
// Echec : message d'erreur
spip_log("fonction $nom ($f ou $g) indisponible" .
($inc ? '' : " (fichier $d absent de $dossier)"));
include_spip('inc/minipres');
include_spip('inc/filtres_mini');
echo minipres(
_T('forum_titre_erreur'),
$inc ?
_T('fonction_introuvable', ['fonction' => '<code>' . spip_htmlentities($f) . '</code>'])
. '<br />'
. _T('fonction_introuvable', ['fonction' => '<code>' . spip_htmlentities($g) . '</code>'])
:
_T('fichier_introuvable', ['fichier' => '<code>' . spip_htmlentities($d) . '</code>']),
['all_inline' => true,'status' => 404]
);
exit;
}
/**
* Inclusion unique avec verification d'existence du fichier + log en crash sinon
*
* @param string $file
* @return bool
*/
function include_once_check($file) {
if (file_exists($file)) {
include_once $file;
return true;
}
$crash = (isset($GLOBALS['meta']['message_crash_plugins']) ? unserialize($GLOBALS['meta']['message_crash_plugins']) : '');
$crash = ($crash ?: []);
$crash[$file] = true;
ecrire_meta('message_crash_plugins', serialize($crash));
return false;
}
/**
* Inclut un fichier PHP (en le cherchant dans les chemins)
*
* @api
* @uses find_in_path()
* @example
* ```
* include_spip('inc/texte');
* ```
*
* @param string $f
* Nom du fichier (sans l'extension)
* @param bool $include
* - true pour inclure le fichier,
* - false ne fait que le chercher
* @return string|bool
* - false : fichier introuvable
* - string : chemin du fichier trouvé
**/
function include_spip($f, $include = true) {
return find_in_path($f . '.php', '', $include);
}
/**
* Requiert un fichier PHP (en le cherchant dans les chemins)
*
* @uses find_in_path()
* @see include_spip()
* @example
* ```
* require_spip('inc/texte');
* ```
*
* @param string $f
* Nom du fichier (sans l'extension)
* @return string|bool
* - false : fichier introuvable
* - string : chemin du fichier trouvé
**/
function require_spip($f) {
return find_in_path($f . '.php', '', 'required');
}
/**
* Raccourci pour inclure mes_fonctions.php et tous les fichiers _fonctions.php des plugin
* quand on a besoin dans le PHP de filtres/fonctions qui y sont definis
*/
function include_fichiers_fonctions() {
static $done = false;
if (!$done) {
include_spip('inc/lang');
// NB: mes_fonctions peut initialiser $dossier_squelettes (old-style)
// donc il faut l'inclure "en globals"
if ($f = find_in_path('mes_fonctions.php')) {
global $dossier_squelettes;
include_once(_ROOT_CWD . $f);
}
if (@is_readable(_CACHE_PLUGINS_FCT)) {
// chargement optimise precompile
include_once(_CACHE_PLUGINS_FCT);
}
if (test_espace_prive()) {
include_spip('inc/filtres_ecrire');
}
include_spip('public/fonctions'); // charger les fichiers fonctions associes aux criteres, balises..
$done = true;
}
}
/**
* 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);
if (
($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');
if (
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 '';
}
}
/**
* Trouve un squelette dans le repertoire modeles/
*
* @param $nom
* @return string
*/
function trouve_modele($nom) {
return trouver_fond($nom, 'modeles/');
}
/**
* Trouver un squelette dans le chemin
* on peut specifier un sous-dossier dans $dir
* si $pathinfo est a true, retourne un tableau avec
* les composantes du fichier trouve
* + le chemin complet sans son extension dans fond
*
* @param string $nom
* @param string $dir
* @param bool $pathinfo
* @return array|string
*/
function trouver_fond($nom, $dir = '', $pathinfo = false) {
$f = find_in_path($nom . '.' . _EXTENSION_SQUELETTES, $dir ? rtrim($dir, '/') . '/' : '');
if (!$pathinfo) {
return $f;
}
// renvoyer un tableau detaille si $pathinfo==true
$p = pathinfo($f);
if (!isset($p['extension']) || !$p['extension']) {
$p['extension'] = _EXTENSION_SQUELETTES;
}
if (!isset($p['extension']) || !$p['filename']) {
$p['filename'] = ($p['basename'] ? substr($p['basename'], 0, -strlen($p['extension']) - 1) : '');
}
$p['fond'] = ($f ? substr($f, 0, -strlen($p['extension']) - 1) : '');
return $p;
}
/**
* Retourne un lien vers une aide
*
* Aide, aussi depuis l'espace privé à présent.
* Surchargeable mais pas d'erreur fatale si indisponible.
*
* @param string $aide
* Cle d'identification de l'aide desiree
* @param bool $distante
* Generer une url locale (par defaut)
* ou une url distante [directement sur spip.net]
* @return
* Lien sur une icone d'aide
**/
function aider($aide = '', $distante = false) {
$aider = charger_fonction('aide', 'inc', true);
return $aider ? $aider($aide, '', [], $distante) : '';
}
/**
* Teste, pour un nom de page de l'espace privé, s'il est possible
* de générer son contenu.
*
* Dans ce cas, on retourne la fonction d'exécution correspondante à utiliser
* (du répertoire `ecrire/exec`). Deux cas particuliers et prioritaires :
* `fond` est retourné si des squelettes existent.
*
* - `fond` : pour des squelettes de `prive/squelettes/contenu`
* ou pour des objets éditoriaux dont les squelettes seront échaffaudés
*
* @param string $nom
* Nom de la page
* @return string
* Nom de l'exec, sinon chaîne vide.
**/
function tester_url_ecrire($nom) {
static $exec = [];
if (isset($exec[$nom])) {
return $exec[$nom];
}
// tester si c'est une page en squelette
if (trouver_fond($nom, 'prive/squelettes/contenu/')) {
return $exec[$nom] = 'fond';
} // echafaudage d'un fond !
elseif (include_spip('public/styliser_par_z') && z_echafaudable($nom)) {
return $exec[$nom] = 'fond';
}
// attention, il ne faut pas inclure l'exec ici
// car sinon #URL_ECRIRE provoque des inclusions
// et des define intrusifs potentiels
return $exec[$nom] = ((find_in_path("{$nom}.php", 'exec/') || charger_fonction($nom, 'exec', true)) ? $nom : '');
}
<?php
/**
* Enregistrement des événements
*
* Signature : `spip_log(message[,niveau|type|type.niveau])`
*
* Le niveau de log par défaut est la valeur de la constante `_LOG_INFO`
*
* Les différents niveaux possibles sont :
*
* - `_LOG_HS` : écrira 'HS' au début de la ligne logguée
* - `_LOG_ALERTE_ROUGE` : 'ALERTE'
* - `_LOG_CRITIQUE` : 'CRITIQUE'
* - `_LOG_ERREUR` : 'ERREUR'
* - `_LOG_AVERTISSEMENT` : 'WARNING'
* - `_LOG_INFO_IMPORTANTE` : '!INFO'
* - `_LOG_INFO` : 'info'
* - `_LOG_DEBUG` : 'debug'
*
* @example
* ```
* spip_log($message)
* spip_log($message, 'recherche')
* spip_log($message, _LOG_DEBUG)
* spip_log($message, 'recherche.'._LOG_DEBUG)
* ```
*
* @api
* @link https://programmer.spip.net/spip_log
* @uses inc_log_dist()
*
* @param string $message
* Message à loger
* @param string|int $name
*
* - int indique le niveau de log, tel que `_LOG_DEBUG`
* - string indique le type de log
* - `string.int` indique les 2 éléments.
* Cette dernière notation est controversée mais le 3ème
* paramètre est planté pour cause de compatibilité ascendante.
*/
function spip_log($message = null, $name = null) {
static $pre = [];
static $log;
preg_match('/^([a-z_]*)\.?(\d)?$/iS', (string)$name, $regs);
if (!isset($regs[1]) || !$logname = $regs[1]) {
$logname = null;
}
if (!isset($regs[2])) {
$niveau = _LOG_INFO;
}
else {
$niveau = intval($regs[2]);
}
if ($niveau <= (defined('_LOG_FILTRE_GRAVITE') ? _LOG_FILTRE_GRAVITE : _LOG_INFO_IMPORTANTE)) {
if (!$pre) {
$pre = [
_LOG_HS => 'HS:',
_LOG_ALERTE_ROUGE => 'ALERTE:',
_LOG_CRITIQUE => 'CRITIQUE:',
_LOG_ERREUR => 'ERREUR:',
_LOG_AVERTISSEMENT => 'WARNING:',
_LOG_INFO_IMPORTANTE => '!INFO:',
_LOG_INFO => 'info:',
_LOG_DEBUG => 'debug:'
];
$log = charger_fonction('log', 'inc');
}
if (!is_string($message)) {
$message = print_r($message, true);
}
$log($pre[$niveau] . ' ' . $message, $logname);
}
}
/**
* Enregistrement des journaux
*
* @uses inc_journal_dist()
* @param string $phrase texte du journal
* @param array $opt Tableau d'options
**/
function journal($phrase, $opt = []) {
$journal = charger_fonction('journal', 'inc');
$journal($phrase, $opt);
}
<?php
/**
* 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é.
**/
function _chemin($dir_path = null) {
static $path_base = null;
static $path_full = null;
if ($path_base == null) {
// Chemin standard depuis l'espace public
$path = defined('_SPIP_PATH') ? _SPIP_PATH :
_DIR_RACINE . ':' .
_DIR_RACINE . 'squelettes-dist/:' .
_DIR_RACINE . 'prive/:' .
_DIR_RESTREINT;
// Ajouter squelettes/
if (@is_dir(_DIR_RACINE . 'squelettes')) {
$path = _DIR_RACINE . 'squelettes/:' . $path;
}
foreach (explode(':', $path) as $dir) {
if (strlen($dir) && !str_ends_with($dir, '/')) {
$dir .= '/';
}
$path_base[] = $dir;
}
$path_full = $path_base;
// Et le(s) dossier(s) des squelettes nommes
if (strlen($GLOBALS['dossier_squelettes'])) {
foreach (array_reverse(explode(':', $GLOBALS['dossier_squelettes'])) as $d) {
array_unshift($path_full, ($d[0] == '/' ? '' : _DIR_RACINE) . $d . '/');
}
}
$GLOBALS['path_sig'] = md5(serialize($path_full));
}
if ($dir_path === null) {
return $path_full;
}
if (is_array($dir_path) || strlen($dir_path)) {
$tete = '';
if (reset($path_base) == _DIR_RACINE . 'squelettes/') {
$tete = array_shift($path_base);
}
$dirs = (is_array($dir_path) ? $dir_path : explode(':', $dir_path));
$dirs = array_reverse($dirs);
foreach ($dirs as $dir_path) {
if (!str_ends_with($dir_path, '/')) {
$dir_path .= '/';
}
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
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 . '/');
}
}
$GLOBALS['path_sig'] = md5(serialize($path_full));
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
**/
function creer_chemin() {
$path_a = _chemin();
static $c = '';
// on calcule le chemin si le dossier skel a change
if ($c != $GLOBALS['dossier_squelettes']) {
// assurer le non plantage lors de la montee de version :
$c = $GLOBALS['dossier_squelettes'];
$path_a = _chemin(''); // forcer un recalcul du chemin
}
return $path_a;
}
/**
* 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 {
static $themes = null;
if (is_null($themes)) {
// si pas encore definie
if (!defined('_SPIP_THEME_PRIVE')) {
define('_SPIP_THEME_PRIVE', 'spip');
}
$themes = [_SPIP_THEME_PRIVE];
// 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 {
$prefs = [];
}
$theme = $prefs['theme'] ?? $GLOBALS['theme_prive_defaut'] ?? null;
if ($theme && $theme !== _SPIP_THEME_PRIVE) {
// placer le theme choisi en tete
array_unshift($themes, $theme);
}
}
return $themes;
}
function find_in_theme($file, $subdir = '', $include = false) {
static $themefiles = [];
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';
}
}
$themes = lister_themes_prives();
foreach ($themes as $theme) {
if ($f = find_in_path($file, "prive/themes/$theme/$subdir", $include)) {
return $themefiles["$subdir$file"] = $f;
}
}
spip_log("$file introuvable dans le theme prive " . reset($themes), 'theme');
return $themefiles["$subdir$file"] = '';
}
/**
* Cherche une image dans les dossiers 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.
**/
function chemin_image($icone) {
static $icone_renommer;
if ($p = strpos($icone, '?')) {
$icone = substr($icone, 0, $p);
}
// gerer le cas d'un double appel en evitant de refaire le travail inutilement
if (str_contains($icone, '/') && file_exists($icone)) {
return $icone;
}
// si c'est un nom d'image complet (article-24.png) essayer de le renvoyer direct
if (preg_match(',[.](png|gif|jpg|webp|svg)$,', $icone) && ($f = find_in_theme("images/$icone"))) {
return $f;
}
// sinon passer par le module de renommage
if (is_null($icone_renommer)) {
$icone_renommer = charger_fonction('icone_renommer', 'inc', true);
}
if ($icone_renommer) {
[$icone, $fonction] = $icone_renommer($icone, '');
if (file_exists($icone)) {
return $icone;
}
}
return find_in_path($icone, _NOM_IMG_PACK);
}
/**
* 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
* @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
**/
function find_in_path($file, $dirname = '', $include = false) {
static $dirs = [];
static $inc = []; # cf https://git.spip.net/spip/spip/commit/42e4e028e38c839121efaee84308d08aee307eec
static $c = '';
if (!$file && !strlen($file)) {
return false;
}
// on calcule le chemin si le dossier skel a change
if ($c != $GLOBALS['dossier_squelettes']) {
// assurer le non plantage lors de la montee de version :
$c = $GLOBALS['dossier_squelettes'];
creer_chemin(); // forcer un recalcul du chemin et la mise a jour de path_sig
}
if (isset($GLOBALS['path_files'][$GLOBALS['path_sig']][$dirname][$file])) {
if (!$GLOBALS['path_files'][$GLOBALS['path_sig']][$dirname][$file]) {
return false;
}
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;
}
return $GLOBALS['path_files'][$GLOBALS['path_sig']][$dirname][$file];
}
$a = strrpos($file, '/');
if ($a !== false) {
$dirname .= substr($file, 0, ++$a);
$file = substr($file, $a);
}
foreach (creer_chemin() as $dir) {
if (!isset($dirs[$a = $dir . $dirname])) {
$dirs[$a] = (is_dir(_ROOT_CWD . $a) || !$a);
}
if ($dirs[$a]) {
if (file_exists(_ROOT_CWD . ($a .= $file))) {
if ($include && !isset($inc[$dirname][$file])) {
include_once _ROOT_CWD . $a;
$inc[$dirname][$file] = $inc[''][$dirname . $file] = true;
}
if (!defined('_SAUVER_CHEMIN')) {
// si le chemin n'a pas encore ete charge, ne pas lever le flag, ne pas cacher
if (is_null($GLOBALS['path_files'])) {
return $a;
}
define('_SAUVER_CHEMIN', true);
}
return $GLOBALS['path_files'][$GLOBALS['path_sig']][$dirname][$file] = $GLOBALS['path_files'][$GLOBALS['path_sig']][''][$dirname . $file] = $a;
}
}
}
if ($include) {
spip_log("include_spip $dirname$file non trouve");
if ($include === 'required') {
echo '<pre>',
'<strong>Erreur Fatale</strong><br />';
if (function_exists('debug_print_backtrace')) {
debug_print_backtrace();
}
echo '</pre>';
die("Erreur interne: ne peut inclure $dirname$file");
}
}
if (!defined('_SAUVER_CHEMIN')) {
// si le chemin n'a pas encore ete charge, ne pas lever le flag, ne pas cacher
if (is_null($GLOBALS['path_files'])) {
return false;
}
define('_SAUVER_CHEMIN', true);
}
return $GLOBALS['path_files'][$GLOBALS['path_sig']][$dirname][$file] = $GLOBALS['path_files'][$GLOBALS['path_sig']][''][$dirname . $file] = false;
}
function clear_path_cache() {
$GLOBALS['path_files'] = [];
spip_unlink(_CACHE_CHEMIN);
}
function load_path_cache() {
// charger le path des plugins
if (@is_readable(_CACHE_PLUGINS_PATH)) {
include_once(_CACHE_PLUGINS_PATH);
}
$GLOBALS['path_files'] = [];
// 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'])
// et en ignorant ce cache en cas de recalcul explicite
!_request('var_mode')
) {
// on essaye de lire directement sans verrou pour aller plus vite
if ($contenu = spip_file_get_contents(_CACHE_CHEMIN)) {
// mais si semble corrompu on relit avec un verrou
if (!$GLOBALS['path_files'] = unserialize($contenu)) {
lire_fichier(_CACHE_CHEMIN, $contenu);
if (!$GLOBALS['path_files'] = unserialize($contenu)) {
$GLOBALS['path_files'] = [];
}
}
}
}
}
function save_path_cache() {
if (
defined('_SAUVER_CHEMIN')
&& _SAUVER_CHEMIN
) {
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()`
*
* @api
* @uses creer_chemin()
* @uses preg_files()
*
* @param string $dir
* @param string $pattern
* @param bool $recurs
* @return array
*/
function find_all_in_path($dir, $pattern, $recurs = false) {
$liste_fichiers = [];
$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) {
$f = $d . $dir;
if (@is_dir($f)) {
$liste = preg_files($f, $pattern, $maxfiles - count($liste_fichiers), $recurs === true ? [] : $recurs);
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
if (!isset($liste_fichiers[$nom])) {
$liste_fichiers[$nom] = $chemin;
}
}
}
}
return $liste_fichiers;
}
<?php
/**
* Exécute une fonction (appellée par un pipeline) avec la donnée transmise.
*
* Un pipeline est lie a une action et une valeur
* chaque element du pipeline est autorise a modifier la valeur
* le pipeline execute les elements disponibles pour cette action,
* les uns apres les autres, et retourne la valeur finale
*
* Cf. compose_filtres dans references.php, qui est la
* version compilee de cette fonctionnalite
* appel unitaire d'une fonction du pipeline
* utilisee dans le script pipeline precompile
*
* on passe $val par reference pour limiter les allocations memoire
*
* @param string $fonc
* Nom de la fonction appelée par le pipeline
* @param string|array $val
* Les paramètres du pipeline, son environnement
* @return string|array $val
* Les paramètres du pipeline modifiés
**/
function minipipe($fonc, &$val) {
// fonction
if (function_exists($fonc)) {
$val = $fonc($val);
} // Class::Methode
else {
if (
preg_match('/^(\w*)::(\w*)$/S', $fonc, $regs)
&& ($methode = [$regs[1], $regs[2]])
&& is_callable($methode)
) {
$val = $methode($val);
} else {
spip_log("Erreur - '$fonc' non definie !");
}
}
return $val;
}
/**
* Appel d’un pipeline
*
* Exécute le pipeline souhaité, éventuellement avec des données initiales.
* Chaque plugin qui a demandé à voir ce pipeline vera sa fonction spécifique appelée.
* Les fonctions (des plugins) appelées peuvent modifier à leur guise le contenu.
*
* Deux types de retours. Si `$val` est un tableau de 2 éléments, avec une clé `data`
* on retourne uniquement ce contenu (`$val['data']`) sinon on retourne tout `$val`.
*
*
* @example
* Appel du pipeline `pre_insertion`
* ```
* $champs = pipeline('pre_insertion', array(
* 'args' => array('table' => 'spip_articles'),
* 'data' => $champs
* ));
* ```
*
* @param string $action
* Nom du pipeline
* @param mixed $val
* Données à l’entrée du pipeline
* @return mixed|null
* Résultat
*/
function pipeline($action, $val = null) {
static $charger;
// chargement initial des fonctions mises en cache, ou generation du cache
if (!$charger) {
if (!($ok = @is_readable($charger = _CACHE_PIPELINES))) {
include_spip('inc/plugin');
// generer les fichiers php precompiles
// de chargement des plugins et des pipelines
actualise_plugins_actifs();
if (!($ok = @is_readable($charger))) {
spip_log("fichier $charger pas cree");
}
}
if ($ok) {
include_once $charger;
}
}
// appliquer notre fonction si elle existe
$fonc = 'execute_pipeline_' . strtolower($action);
if (function_exists($fonc)) {
$val = $fonc($val);
} // plantage ?
else {
spip_log("fonction $fonc absente : pipeline desactive", _LOG_ERREUR);
}
// si le flux est une table avec 2 cle args&data
// on ne ressort du pipe que les donnees dans 'data'
// array_key_exists pour php 4.1.0
if (
is_array($val)
&& count($val) == 2
&& array_key_exists('data', $val)
) {
$val = $val['data'];
}
return $val;
}
<?php
/**
* Renvoie le `$_GET` ou le `$_POST` émis par l'utilisateur
* ou pioché dans un tableau transmis
*
* @api
* @param string $var
* Clé souhaitée
* @param bool|array $c
* Tableau transmis (sinon cherche dans GET ou POST)
* @return mixed|null
* - null si la clé n'a pas été trouvée
* - la valeur de la clé sinon.
**/
function _request($var, $c = false) {
if (is_array($c)) {
return $c[$var] ?? null;
}
if (isset($_GET[$var])) {
$a = $_GET[$var];
} elseif (isset($_POST[$var])) {
$a = $_POST[$var];
} else {
return null;
}
// Si on est en ajax et en POST tout a ete encode
// via encodeURIComponent, il faut donc repasser
// dans le charset local...
if (
defined('_AJAX')
&& _AJAX
&& isset($GLOBALS['meta']['charset'])
&& $GLOBALS['meta']['charset'] != 'utf-8'
// check rapide mais pas fiable
&& is_string($a)
&& preg_match(',[\x80-\xFF],', $a)
// check fiable
&& include_spip('inc/charsets')
&& is_utf8($a)
) {
return importer_charset($a, 'utf-8');
}
return $a;
}
/**
* Affecte une valeur à une clé (pour usage avec `_request()`)
*
* @see _request() Pour obtenir la valeur
* @note Attention au cas ou l'on fait `set_request('truc', NULL);`
*
* @param string $var Nom de la clé
* @param string $val Valeur à affecter
* @param bool|array $c Tableau de données (sinon utilise `$_GET` et `$_POST`)
* @return array|bool
* - array $c complété si un $c est transmis,
* - false sinon
**/
function set_request($var, $val = null, $c = false) {
if (is_array($c)) {
unset($c[$var]);
if ($val !== null) {
$c[$var] = $val;
}
return $c;
}
unset($_GET[$var]);
unset($_POST[$var]);
if ($val !== null) {
$_GET[$var] = $val;
}
return false; # n'affecte pas $c
}
/**
* Sanitizer une valeur *SI* elle provient du GET ou POST
* Utile dans les squelettes pour les valeurs qu'on attrape dans le env,
* dont on veut permettre à un squelette de confiance appelant de fournir une valeur complexe
* mais qui doit etre nettoyee si elle provient de l'URL
*
* On peut sanitizer
* - une valeur simple : `$where = spip_sanitize_from_request($value, 'where')`
* - un tableau en partie : `$env = spip_sanitize_from_request($env, ['key1','key2'])`
* - un tableau complet : `$env = spip_sanitize_from_request($env, '*')`
*
* @param string|array $value
* @param string|array $key
* @param string $sanitize_function
* @return array|mixed|string
*/
function spip_sanitize_from_request($value, $key, $sanitize_function = 'entites_html') {
if (is_array($value)) {
if ($key == '*') {
$key = array_keys($value);
}
if (!is_array($key)) {
$key = [$key];
}
foreach ($key as $k) {
if (!empty($value[$k])) {
$value[$k] = spip_sanitize_from_request($value[$k], $k, $sanitize_function);
}
}
return $value;
}
// si la valeur vient des GET ou POST on la sanitize
if (!empty($value) && $value == _request($key)) {
$value = $sanitize_function($value);
}
return $value;
}
<?php
/**
* Supprimer les éventuels caracteres nuls %00, qui peuvent tromper
* la commande is_readable('chemin/vers/fichier/interdit%00truc_normal').
*
* Cette fonction est appliquée par SPIP à son initialisation sur GET/POST/COOKIES/GLOBALS
* @param array $t le tableau ou la chaine à desinfecter (passage par référence)
* @param bool $deep = true : appliquer récursivement
**/
function spip_desinfecte(&$t, $deep = true) {
foreach ($t as $key => $val) {
if (is_string($t[$key])) {
$t[$key] = str_replace(chr(0), '-', $t[$key]);
} // traiter aussi les "texte_plus" de article_edit
else {
if ($deep && is_array($t[$key]) && $key !== 'GLOBALS') {
spip_desinfecte($t[$key], $deep);
}
}
}
}
/**
* Nettoie une chaine pour servir comme classes CSS.
*
* @note
* les classes CSS acceptent théoriquement tous les caractères sauf NUL.
* Ici, on limite (enlève) les caractères autres qu’alphanumérique, espace, - + _ @
*
* @param string|string[] $classes
* @return string|string[]
*/
function spip_sanitize_classname($classes) {
if (is_array($classes)) {
return array_map('spip_sanitize_classname', $classes);
}
return preg_replace('/[^ 0-9a-z_\-+@]/i', '', $classes);
}
<?php
/**
* Génère une erreur de squelette
*
* Génère une erreur de squelette qui sera bien visible par un
* administrateur authentifié lors d'une visite de la page en erreur
*
* @param bool|string|array $message
* - Message d'erreur (string|array)
* - false pour retourner le texte des messages d'erreurs
* - vide pour afficher les messages d'erreurs
* @param string|array|object $lieu
* Lieu d'origine de l'erreur
* @return null|string
* - Rien dans la plupart des cas
* - string si $message à false.
**/
function erreur_squelette($message = '', $lieu = '') {
$debusquer = charger_fonction('debusquer', 'public');
if (is_array($lieu)) {
include_spip('public/compiler');
$lieu = reconstruire_contexte_compil($lieu);
}
return $debusquer($message, $lieu);
}
/**
* Calcule un squelette avec un contexte et retourne son contenu
*
* La fonction de base de SPIP : un squelette + un contexte => une page.
* $fond peut etre un nom de squelette, ou une liste de squelette au format array.
* Dans ce dernier cas, les squelettes sont tous evalues et mis bout a bout
* $options permet de selectionner les options suivantes :
*
* - trim => true (valeur par defaut) permet de ne rien renvoyer si le fond ne produit que des espaces ;
* - raw => true permet de recuperer la strucure $page complete avec entetes et invalideurs
* pour chaque $fond fourni.
*
* @api
* @param string /array $fond
* - Le ou les squelettes à utiliser, sans l'extension, {@example prive/liste/auteurs}
* - Le fichier sera retrouvé dans la liste des chemins connus de SPIP (squelettes, plugins, spip)
* @param array $contexte
* - Informations de contexte envoyées au squelette, {@example array('id_rubrique' => 8)}
* - La langue est transmise automatiquement (sauf option étoile).
* @param array $options
* Options complémentaires :
*
* - trim : applique un trim sur le résultat (true par défaut)
* - raw : retourne un tableau d'information sur le squelette (false par défaut)
* - etoile : ne pas transmettre la langue au contexte automatiquement (false par défaut),
* équivalent de INCLURE*
* - ajax : gere les liens internes du squelette en ajax (équivalent du paramètre {ajax})
* @param string $connect
* Non du connecteur de bdd a utiliser
* @return string|array
* - Contenu du squelette calculé
* - ou tableau d'information sur le squelette.
*/
function recuperer_fond($fond, $contexte = [], $options = [], string $connect = '') {
if (!function_exists('evaluer_fond')) {
include_spip('public/assembler');
}
// assurer la compat avec l'ancienne syntaxe
// (trim etait le 3eme argument, par defaut a true)
if (!is_array($options)) {
$options = ['trim' => $options];
}
if (!isset($options['trim'])) {
$options['trim'] = true;
}
if (isset($contexte['connect'])) {
$connect = $contexte['connect'];
unset($contexte['connect']);
}
$texte = '';
$pages = [];
$lang_select = '';
if (!isset($options['etoile']) || !$options['etoile']) {
// Si on a inclus sans fixer le critere de lang, on prend la langue courante
if (!isset($contexte['lang'])) {
$contexte['lang'] = $GLOBALS['spip_lang'];
}
if ($contexte['lang'] != $GLOBALS['meta']['langue_site']) {
$lang_select = lang_select($contexte['lang']);
}
}
if (!isset($GLOBALS['_INC_PUBLIC'])) {
$GLOBALS['_INC_PUBLIC'] = 0;
}
$GLOBALS['_INC_PUBLIC']++;
// fix #4235
$cache_utilise_session_appelant = ($GLOBALS['cache_utilise_session'] ?? null);
foreach (is_array($fond) ? $fond : [$fond] as $f) {
unset($GLOBALS['cache_utilise_session']); // fix #4235
$page = evaluer_fond($f, $contexte, $connect);
if ($page === '') {
$c = $options['compil'] ?? '';
$a = ['fichier' => $f];
$erreur = _T('info_erreur_squelette2', $a); // squelette introuvable
erreur_squelette($erreur, $c);
// eviter des erreurs strictes ensuite sur $page['cle'] en PHP >= 5.4
$page = ['texte' => '', 'erreur' => $erreur];
}
$page = pipeline('recuperer_fond', [
'args' => ['fond' => $f, 'contexte' => $contexte, 'options' => $options, 'connect' => $connect],
'data' => $page
]);
if (isset($options['ajax']) && $options['ajax']) {
if (!function_exists('encoder_contexte_ajax')) {
include_spip('inc/filtres');
}
$page['texte'] = encoder_contexte_ajax(
array_merge(
$contexte,
['fond' => $f],
($connect ? ['connect' => $connect] : [])
),
'',
$page['texte'],
$options['ajax']
);
}
if (isset($options['raw']) && $options['raw']) {
$pages[] = $page;
} else {
$texte .= $options['trim'] ? rtrim($page['texte'] ?? '') : $page['texte'];
}
// contamination de la session appelante, pour les inclusions statiques
if (isset($page['invalideurs']['session'])) {
$cache_utilise_session_appelant = $page['invalideurs']['session'];
}
}
// restaurer le sessionnement du contexte appelant,
// éventuellement contaminé si on vient de récupérer une inclusion statique sessionnée
if (isset($cache_utilise_session_appelant)) {
$GLOBALS['cache_utilise_session'] = $cache_utilise_session_appelant;
}
$GLOBALS['_INC_PUBLIC']--;
if ($lang_select) {
lang_select();
}
if (isset($options['raw']) && $options['raw']) {
return is_array($fond) ? $pages : reset($pages);
} else {
return $options['trim'] ? ltrim($texte) : $texte;
}
}
Ce diff est replié.
<?php
/** Diverses fonctions */
/**
* Vérifie la présence d'un plugin actif, identifié par son préfixe
*
* @param string $plugin
* @return bool
*/
function test_plugin_actif($plugin) {
return ($plugin && defined('_DIR_PLUGIN_' . strtoupper($plugin))) ? true : false;
}
/**
* Retourne un joli chemin de répertoire
*
* Pour afficher `ecrire/action/` au lieu de `action/` dans les messages
* ou `tmp/` au lieu de `../tmp/`
*
* @param string $rep Chemin d’un répertoire
* @return string
*/
function joli_repertoire($rep) {
$a = substr($rep, 0, 1);
if ($a <> '.' && $a <> '/') {
$rep = (_DIR_RESTREINT ? '' : _DIR_RESTREINT_ABS) . $rep;
}
$rep = preg_replace(',(^\.\.\/),', '', $rep);
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
*/
function spip_timer($t = 'rien', $raw = false) {
static $time;
$a = time();
$b = microtime();
// microtime peut contenir les microsecondes et le temps
$b = explode(' ', $b);
if (count($b) == 2) {
$a = end($b);
} // plus precis !
$b = reset($b);
if (!isset($time[$t])) {
$time[$t] = $a + $b;
} else {
$p = ($a + $b - $time[$t]) * 1000;
unset($time[$t]);
# echo "'$p'";exit;
if ($raw) {
return $p;
}
if ($p < 1000) {
$s = '';
} else {
$s = sprintf('%d ', $x = floor($p / 1000));
$p -= ($x * 1000);
}
return $s . sprintf($s ? '%07.3f ms' : '%.3f ms', $p);
}
}
// Renvoie False si un fichier n'est pas plus vieux que $duree secondes,
// sinon renvoie True et le date sauf si ca n'est pas souhaite
function spip_touch($fichier, $duree = 0, $touch = true) {
if ($duree) {
clearstatcache();
if (($f = @filemtime($fichier)) && $f >= time() - $duree) {
return false;
}
}
if ($touch !== false) {
if (!@touch($fichier)) {
spip_unlink($fichier);
@touch($fichier);
};
@chmod($fichier, _SPIP_CHMOD & ~0111);
}
return true;
}
/**
* Produit une balise `<script>` valide
*
* @example
* ```
* echo http_script('alert("ok");');
* echo http_script('','js/jquery.js');
* ```
*
* @param string $script
* Code source du script
* @param string $src
* Permet de faire appel à un fichier javascript distant
* @param string $noscript
* Contenu de la balise `<noscript>`
* @return string
* Balise HTML `<script>` et son contenu
**/
function http_script($script, $src = '', $noscript = '') {
static $done = [];
if ($src && !isset($done[$src])) {
$done[$src] = true;
$src = find_in_path($src, _JAVASCRIPT);
$src = " src='$src'";
} else {
$src = '';
}
if ($script) {
$script = ("/*<![CDATA[*/\n" .
preg_replace(',</([^>]*)>,', '<\/\1>', $script) .
'/*]]>*/');
}
if ($noscript) {
$noscript = "<noscript>\n\t$noscript\n</noscript>\n";
}
return ($src || $script || $noscript)
? "<script type='text/javascript'$src>$script</script>$noscript"
: '';
}
/**
* Sécurise du texte à écrire dans du PHP ou du Javascript.
*
* 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
* @return string
* texte échappé
**/
function texte_script(?string $texte): string {
if ($texte === null || $texte === '') {
return '';
}
return str_replace('\'', '\\\'', str_replace('\\', '\\\\', $texte));
}
/**
* Tester qu'une variable d'environnement est active
*
* Sur certains serveurs, la valeur 'Off' tient lieu de false dans certaines
* variables d'environnement comme `$_SERVER['HTTPS']` ou `ini_get('display_errors')`
*
* @param string|bool $truc
* La valeur de la variable d'environnement
* @return bool
* true si la valeur est considérée active ; false sinon.
**/
function test_valeur_serveur($truc) {
if (!$truc) {
return false;
}
return (strtolower($truc) !== 'off');
}
/**
* Page `exec=info` : retourne le contenu de la fonction php `phpinfo()`
*
* Si l’utiliseur est un webmestre.
*/
function exec_info_dist() {
include_spip('inc/autoriser');
if (autoriser('phpinfos')) {
$cookies_masques = ['spip_session', 'PHPSESSID'];
$cookies_backup = [];
$server_backup = ['HTTP_COOKIE' => $_SERVER['HTTP_COOKIE'] ?? []];
$env_backup = ['HTTP_COOKIE' => $_ENV['HTTP_COOKIE'] ?? []];
$mask = '******************************';
foreach ($cookies_masques as $k) {
if (!empty($_COOKIE[$k])) {
$cookies_backup[$k] = $_COOKIE[$k];
$_SERVER['HTTP_COOKIE'] = str_replace("$k=" . $_COOKIE[$k], "$k=$mask", $_SERVER['HTTP_COOKIE'] ?? []);
$_ENV['HTTP_COOKIE'] = str_replace("$k=" . $_COOKIE[$k], "$k=$mask", $_ENV['HTTP_COOKIE'] ?? []);
$_COOKIE[$k] = $mask;
}
}
phpinfo();
foreach ($cookies_backup as $k => $v) {
$_COOKIE[$k] = $v;
}
foreach ($server_backup as $k => $v) {
$_SERVER[$k] = $v;
}
foreach ($env_backup as $k => $v) {
$_ENV[$k] = $v;
}
} else {
include_spip('inc/filtres');
sinon_interdire_acces();
}
}
/**
* Indique si le code HTML5 est permis sur le site public
*
* @return bool
* true si la constante _VERSION_HTML n'est pas définie ou égale à html5
**/
function html5_permis() {
return (!defined('_VERSION_HTML') || _VERSION_HTML !== 'html4');
}
/**
* Lister les formats image acceptes par les lib et fonctions images
*/
function formats_image_acceptables(?bool $gd = null, bool $svg_allowed = true): array {
$formats = null;
if (!is_null($gd)) {
$config = ($gd ? 'gd_formats' : 'formats_graphiques');
if (isset($GLOBALS['meta'][$config])) {
$formats = $GLOBALS['meta'][$config];
$formats = explode(',', $formats);
$formats = array_filter($formats);
$formats = array_map('trim', $formats);
}
}
if (is_null($formats)) {
include_spip('inc/filtres_images_lib_mini');
$formats = _image_extensions_acceptees_en_entree();
}
if ($svg_allowed) {
if (!in_array('svg', $formats)) {
$formats[] = 'svg';
}
} else {
$formats = array_diff($formats, ['svg']);
}
return $formats;
}
/**
* Extension de la fonction getimagesize pour supporter aussi les images SVG
* @param string $fichier
* @return array|bool
*/
function spip_getimagesize($fichier) {
if (file_exists($fichier) && ($imagesize = @getimagesize($fichier))) {
return $imagesize;
}
include_spip('inc/svg');
if ($attrs = svg_lire_attributs($fichier)) {
[$width, $height, $viewbox] = svg_getimagesize_from_attr($attrs);
$imagesize = [
$width,
$height,
IMAGETYPE_SVG,
"width=\"{$width}\" height=\"{$height}\"",
'mime' => 'image/svg+xml'
];
return $imagesize;
}
return false;
}
/**
* Poser une alerte qui sera affiche aux auteurs de bon statut ('' = tous)
* au prochain passage dans l'espace prive
* chaque alerte doit avoir un nom pour eviter duplication a chaque hit
* les alertes affichees une fois sont effacees
*
* @param string $nom
* @param string $message
* @param string $statut
*/
function avertir_auteurs($nom, $message, $statut = '') {
$alertes = $GLOBALS['meta']['message_alertes_auteurs'];
if (
!$alertes || !is_array($alertes = unserialize($alertes))
) {
$alertes = [];
}
if (!isset($alertes[$statut])) {
$alertes[$statut] = [];
}
$alertes[$statut][$nom] = $message;
ecrire_meta('message_alertes_auteurs', serialize($alertes));
}
/**
* Compare 2 numéros de version entre elles.
*
* Cette fonction est identique (arguments et retours) a la fonction PHP
* version_compare() qu'elle appelle. Cependant, cette fonction reformate
* les numeros de versions pour ameliorer certains usages dans SPIP ou bugs
* dans PHP. On permet ainsi de comparer 3.0.4 à 3.0.* par exemple.
*
* @param string $v1
* Numero de version servant de base a la comparaison.
* Ce numero ne peut pas comporter d'etoile.
* @param string $v2
* Numero de version a comparer.
* Il peut posseder des etoiles tel que 3.0.*
* @param string $op
* Un operateur eventuel (<, >, <=, >=, =, == ...)
* @return int|bool
* Sans operateur : int. -1 pour inferieur, 0 pour egal, 1 pour superieur
* Avec operateur : bool.
**/
function spip_version_compare($v1, $v2, $op = null) {
$v1 = strtolower(preg_replace(',([0-9])[\s.-]?(dev|alpha|a|beta|b|rc|pl|p),i', '\\1.\\2', $v1));
$v2 = strtolower(preg_replace(',([0-9])[\s.-]?(dev|alpha|a|beta|b|rc|pl|p),i', '\\1.\\2', $v2));
$v1 = str_replace('rc', 'RC', $v1); // certaines versions de PHP ne comprennent RC qu'en majuscule
$v2 = str_replace('rc', 'RC', $v2); // certaines versions de PHP ne comprennent RC qu'en majuscule
$v1 = explode('.', $v1);
$v2 = explode('.', $v2);
// $v1 est toujours une version, donc sans etoile
while (count($v1) < count($v2)) {
$v1[] = '0';
}
// $v2 peut etre une borne, donc accepte l'etoile
$etoile = false;
foreach ($v1 as $k => $v) {
if (!isset($v2[$k])) {
$v2[] = ($etoile && (is_numeric($v) || $v == 'pl' || $v == 'p')) ? $v : '0';
} else {
if ($v2[$k] == '*') {
$etoile = true;
$v2[$k] = $v;
}
}
}
$v1 = implode('.', $v1);
$v2 = implode('.', $v2);
return $op ? version_compare($v1, $v2, $op) : version_compare($v1, $v2);
}
Ce diff est replié.
...@@ -21,7 +21,7 @@ if (defined('_ECRIRE_INC_VERSION')) { ...@@ -21,7 +21,7 @@ if (defined('_ECRIRE_INC_VERSION')) {
return; return;
} }
require_once __DIR__ . '/bootstrap/initial_config.php'; require_once __DIR__ . '/bootstrap/config/initial.php';
// inclure l'ecran de securite si il n'a pas été inclus en prepend php // inclure l'ecran de securite si il n'a pas été inclus en prepend php
if ( if (
...@@ -34,7 +34,7 @@ if ( ...@@ -34,7 +34,7 @@ if (
// et on peut lancer l'autoloader // et on peut lancer l'autoloader
require_once dirname(__DIR__) . '/vendor/autoload.php'; require_once dirname(__DIR__) . '/vendor/autoload.php';
require_once __DIR__ . '/bootstrap/globals_config.php'; require_once __DIR__ . '/bootstrap/config/globals.php';
require_once __DIR__ . '/bootstrap/proxy.php'; require_once __DIR__ . '/bootstrap/proxy.php';
require_once __DIR__ . '/bootstrap/mitigation.php'; require_once __DIR__ . '/bootstrap/mitigation.php';
...@@ -70,8 +70,7 @@ $spip_version_affichee = "$spip_version_branche"; ...@@ -70,8 +70,7 @@ $spip_version_affichee = "$spip_version_branche";
// //
// Charger les fonctions liees aux serveurs Http et Sql. // Charger les fonctions liees aux serveurs Http et Sql.
// //
require_once _ROOT_RESTREINT . 'inc/utils.php'; require_once __DIR__ . '/bootstrap/functions.php';
require_once _ROOT_RESTREINT . 'base/connect_sql.php';
// Definition personnelles eventuelles // Definition personnelles eventuelles
......
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter