Dépôt officiel du core SPIP Les plugins-dist faisant partie de la distribution SPIP sont présents dans https://git.spip.net/spip/[nom du plugin dist] https://www.spip.net
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

811 lines
24 KiB

<?php
18 years ago
/***************************************************************************\
* SPIP, Système de publication pour l'internet *
18 years ago
* *
* Copyright © avec tendresse depuis 2001 *
* Arnaud Martin, Antoine Pitrou, Philippe Rivière, Emmanuel Saint-James *
18 years ago
* *
* Ce programme est un logiciel libre distribué sous licence GNU/GPL. *
18 years ago
\***************************************************************************/
8 years ago
/**
* Ce fichier regroupe les fonctions permettant de calculer la page et les entêtes
*
* Determine le contexte donne par l'URL (en tenant compte des reecritures)
8 years ago
* grace a la fonction de passage d'URL a id (reciproque dans urls/*php)
*
8 years ago
* @package SPIP\Core\Compilateur\Assembler
**/
8 years ago
if (!defined('_ECRIRE_INC_VERSION')) {
return;
}
// En cas de modification, il faut aussi actualiser la regexp de nettoyer_uri_var() dans inc/utils.php
if (!defined('_CONTEXTE_IGNORE_VARIABLES')) {
define('_CONTEXTE_IGNORE_VARIABLES', '/(^var_|^PHPSESSID$|^fbclid$|^utm_)/');
}
Résolution de #1510, cette double redirection d'action conduisant à plusieurs changements: * réintégration dans le script {{{../public.php}}} de tous les cas ne suivant pas le déroulement complet d'utilisation d'un squelette (action, CVT) afin de migrer tous les appels à {{{exit}}} de {{{public/assembler}}} dans le script initial (il en reste un, dans la fonction repérant un violation de sécurité CVT ça peut se justifier). * abandon de la possibilité d'avoir et des actions et des formulaires CVT dont l'URL soit indifféremment au niveau de la racine ou au niveau de {{{ecrire}}}: il ne faut pas obscuricr et ralentir l'accès aux scripts de {{{ecrire/}}}. * le traitement de la variable {{{redirect}}} dans la requête HTTP est modifié pour tenir compte des incohérences de PHP signalé dans #1510: * si la requête est en GET, cette variable a dû être encodée par {{{rawurlencode}}} * si la requête est en POST, elle ne doit pas avoir été encodée. Ce traitement est assuré par {{{generer_action_auteur}}} et ses fonctions annes, les extensions de SPIP utilisant cette fonction de manière standard ne seront pas affectées par ce changement interne. - vérification de tous les cas d'utilisation de cette variable de redirection, en particulier pour éliminer la production d'URL absolue dans le cas GET, le mod_security d'APACHE faisant de la parano là-dessus. En particulier, la solution de #1510 a imposé d'expliciter le script de retour des bouton de contrôle de forum, le double retour s'effectue à l'endroit attendu de {{{articles_forum}}}, ce qui est le cas aussi de {{{controle_forum}}} à présent, même en utilisation AJAX.
15 years ago
function assembler($fond, string $connect = '') {
Résolution de #1510, cette double redirection d'action conduisant à plusieurs changements: * réintégration dans le script {{{../public.php}}} de tous les cas ne suivant pas le déroulement complet d'utilisation d'un squelette (action, CVT) afin de migrer tous les appels à {{{exit}}} de {{{public/assembler}}} dans le script initial (il en reste un, dans la fonction repérant un violation de sécurité CVT ça peut se justifier). * abandon de la possibilité d'avoir et des actions et des formulaires CVT dont l'URL soit indifféremment au niveau de la racine ou au niveau de {{{ecrire}}}: il ne faut pas obscuricr et ralentir l'accès aux scripts de {{{ecrire/}}}. * le traitement de la variable {{{redirect}}} dans la requête HTTP est modifié pour tenir compte des incohérences de PHP signalé dans #1510: * si la requête est en GET, cette variable a dû être encodée par {{{rawurlencode}}} * si la requête est en POST, elle ne doit pas avoir été encodée. Ce traitement est assuré par {{{generer_action_auteur}}} et ses fonctions annes, les extensions de SPIP utilisant cette fonction de manière standard ne seront pas affectées par ce changement interne. - vérification de tous les cas d'utilisation de cette variable de redirection, en particulier pour éliminer la production d'URL absolue dans le cas GET, le mod_security d'APACHE faisant de la parano là-dessus. En particulier, la solution de #1510 a imposé d'expliciter le script de retour des bouton de contrôle de forum, le double retour s'effectue à l'endroit attendu de {{{articles_forum}}}, ce qui est le cas aussi de {{{controle_forum}}} à présent, même en utilisation AJAX.
15 years ago
$chemin_cache = null;
$lastmodified = null;
$res = null;
// flag_preserver est modifie ici, et utilise en globale
// use_cache sert a informer le bouton d'admin pr savoir s'il met un *
// contexte est utilise en globale dans le formulaire d'admin
Résolution de #1510, cette double redirection d'action conduisant à plusieurs changements: * réintégration dans le script {{{../public.php}}} de tous les cas ne suivant pas le déroulement complet d'utilisation d'un squelette (action, CVT) afin de migrer tous les appels à {{{exit}}} de {{{public/assembler}}} dans le script initial (il en reste un, dans la fonction repérant un violation de sécurité CVT ça peut se justifier). * abandon de la possibilité d'avoir et des actions et des formulaires CVT dont l'URL soit indifféremment au niveau de la racine ou au niveau de {{{ecrire}}}: il ne faut pas obscuricr et ralentir l'accès aux scripts de {{{ecrire/}}}. * le traitement de la variable {{{redirect}}} dans la requête HTTP est modifié pour tenir compte des incohérences de PHP signalé dans #1510: * si la requête est en GET, cette variable a dû être encodée par {{{rawurlencode}}} * si la requête est en POST, elle ne doit pas avoir été encodée. Ce traitement est assuré par {{{generer_action_auteur}}} et ses fonctions annes, les extensions de SPIP utilisant cette fonction de manière standard ne seront pas affectées par ce changement interne. - vérification de tous les cas d'utilisation de cette variable de redirection, en particulier pour éliminer la production d'URL absolue dans le cas GET, le mod_security d'APACHE faisant de la parano là-dessus. En particulier, la solution de #1510 a imposé d'expliciter le script de retour des bouton de contrôle de forum, le double retour s'effectue à l'endroit attendu de {{{articles_forum}}}, ce qui est le cas aussi de {{{controle_forum}}} à présent, même en utilisation AJAX.
15 years ago
$GLOBALS['contexte'] = calculer_contexte();
$page = ['contexte_implicite' => calculer_contexte_implicite()];
$page['contexte_implicite']['cache'] = $fond . preg_replace(
',\.[a-zA-Z0-9]*$,',
'',
preg_replace('/[?].*$/', '', $GLOBALS['REQUEST_URI'])
);
// Cette fonction est utilisee deux fois
$cacher = charger_fonction('cacher', 'public', true);
// Les quatre derniers parametres sont modifies par la fonction:
// emplacement, validite, et, s'il est valide, contenu & age
if ($cacher) {
$res = $cacher($GLOBALS['contexte'], $GLOBALS['use_cache'], $chemin_cache, $page, $lastmodified);
} else {
$GLOBALS['use_cache'] = -1;
}
// Si un resultat est retourne, c'est un message d'impossibilite
if ($res) {
return ['texte' => $res];
}
if (!$chemin_cache || !$lastmodified) {
$lastmodified = time();
}
Faciliter l'envoi d'en-tetes http dans les squelettes, afin de remplacer les variables PHP $flag_preserver et $flag_dynamique par des entitees independantes du langage d'execution. Pour cela: - introduction d'une balise #HTTP{e1, ... en} utilisable en debut de squelette, et dont les arguments sont des chaines, entourees de guillemets ou d'apostrophes, conforme au protocole HTTP1/1 : http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4 - cette balise est compilee en une sequence <?php header(e1); .... ;header(en) ?> - Spip repere une telle sequence initiale (c'est donc valable aussi pour un code php ecrit directement sous-reserve que la syntaxe soit exactement la meme) et en fait une meta-donnee pour chaque page produite par l'execution du squelette, afin de disposer facilement des en-tetes au moment de l'envoi; - Spip repere dans ces meta-donnees la presence de la directive Content-Type. Si elle est absente, elle est automatiquement rajoutee avec comme habituellement la valeur: Content-Type: text/html; charset=#CHARSET Spip n'enverra les boutons d'administration et de previsualisation et n'inserera leur CSS associee que si cette directive a pour valeur text/html ou que le mode debug est actif. Cette assertion simple reflete l'usage de la variable $flag_preserver qui n'a ainsi plus de raison d'etre. - Spip repere aussi dans ces meta-donnees la presence d'une directive "Cache-control", auquel cas il n'enverra aucune autre directive concernant le cache du client. Ainsi, le positionnement a "vrai" de la variable $flag_dynamique, jamais documentee, est equivalent a #HTTP{'Pragma: no-cache', 'Cache-Control: no-cache; must-revalidate'}
17 years ago
$headers_only = ($_SERVER['REQUEST_METHOD'] == 'HEAD');
$calculer_page = true;
Faciliter l'envoi d'en-tetes http dans les squelettes, afin de remplacer les variables PHP $flag_preserver et $flag_dynamique par des entitees independantes du langage d'execution. Pour cela: - introduction d'une balise #HTTP{e1, ... en} utilisable en debut de squelette, et dont les arguments sont des chaines, entourees de guillemets ou d'apostrophes, conforme au protocole HTTP1/1 : http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4 - cette balise est compilee en une sequence <?php header(e1); .... ;header(en) ?> - Spip repere une telle sequence initiale (c'est donc valable aussi pour un code php ecrit directement sous-reserve que la syntaxe soit exactement la meme) et en fait une meta-donnee pour chaque page produite par l'execution du squelette, afin de disposer facilement des en-tetes au moment de l'envoi; - Spip repere dans ces meta-donnees la presence de la directive Content-Type. Si elle est absente, elle est automatiquement rajoutee avec comme habituellement la valeur: Content-Type: text/html; charset=#CHARSET Spip n'enverra les boutons d'administration et de previsualisation et n'inserera leur CSS associee que si cette directive a pour valeur text/html ou que le mode debug est actif. Cette assertion simple reflete l'usage de la variable $flag_preserver qui n'a ainsi plus de raison d'etre. - Spip repere aussi dans ces meta-donnees la presence d'une directive "Cache-control", auquel cas il n'enverra aucune autre directive concernant le cache du client. Ainsi, le positionnement a "vrai" de la variable $flag_dynamique, jamais documentee, est equivalent a #HTTP{'Pragma: no-cache', 'Cache-Control: no-cache; must-revalidate'}
17 years ago
// Pour les pages non-dynamiques (indiquees par #CACHE{duree,cache-client})
// une perennite valide a meme reponse qu'une requete HEAD (par defaut les
// pages sont dynamiques)
if (
isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])
and (!defined('_VAR_MODE') or !_VAR_MODE)
and $chemin_cache
and isset($page['entetes'])
and isset($page['entetes']['Cache-Control'])
and strstr($page['entetes']['Cache-Control'], 'max-age=')
and !strstr($_SERVER['SERVER_SOFTWARE'], 'IIS/')
) {
$since = preg_replace(
'/;.*/',
'',
$_SERVER['HTTP_IF_MODIFIED_SINCE']
);
$since = str_replace('GMT', '', $since);
if (trim($since) == gmdate('D, d M Y H:i:s', $lastmodified)) {
$page['status'] = 304;
$headers_only = true;
$calculer_page = false;
Faciliter l'envoi d'en-tetes http dans les squelettes, afin de remplacer les variables PHP $flag_preserver et $flag_dynamique par des entitees independantes du langage d'execution. Pour cela: - introduction d'une balise #HTTP{e1, ... en} utilisable en debut de squelette, et dont les arguments sont des chaines, entourees de guillemets ou d'apostrophes, conforme au protocole HTTP1/1 : http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4 - cette balise est compilee en une sequence <?php header(e1); .... ;header(en) ?> - Spip repere une telle sequence initiale (c'est donc valable aussi pour un code php ecrit directement sous-reserve que la syntaxe soit exactement la meme) et en fait une meta-donnee pour chaque page produite par l'execution du squelette, afin de disposer facilement des en-tetes au moment de l'envoi; - Spip repere dans ces meta-donnees la presence de la directive Content-Type. Si elle est absente, elle est automatiquement rajoutee avec comme habituellement la valeur: Content-Type: text/html; charset=#CHARSET Spip n'enverra les boutons d'administration et de previsualisation et n'inserera leur CSS associee que si cette directive a pour valeur text/html ou que le mode debug est actif. Cette assertion simple reflete l'usage de la variable $flag_preserver qui n'a ainsi plus de raison d'etre. - Spip repere aussi dans ces meta-donnees la presence d'une directive "Cache-control", auquel cas il n'enverra aucune autre directive concernant le cache du client. Ainsi, le positionnement a "vrai" de la variable $flag_dynamique, jamais documentee, est equivalent a #HTTP{'Pragma: no-cache', 'Cache-Control: no-cache; must-revalidate'}
17 years ago
}
}
Faciliter l'envoi d'en-tetes http dans les squelettes, afin de remplacer les variables PHP $flag_preserver et $flag_dynamique par des entitees independantes du langage d'execution. Pour cela: - introduction d'une balise #HTTP{e1, ... en} utilisable en debut de squelette, et dont les arguments sont des chaines, entourees de guillemets ou d'apostrophes, conforme au protocole HTTP1/1 : http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4 - cette balise est compilee en une sequence <?php header(e1); .... ;header(en) ?> - Spip repere une telle sequence initiale (c'est donc valable aussi pour un code php ecrit directement sous-reserve que la syntaxe soit exactement la meme) et en fait une meta-donnee pour chaque page produite par l'execution du squelette, afin de disposer facilement des en-tetes au moment de l'envoi; - Spip repere dans ces meta-donnees la presence de la directive Content-Type. Si elle est absente, elle est automatiquement rajoutee avec comme habituellement la valeur: Content-Type: text/html; charset=#CHARSET Spip n'enverra les boutons d'administration et de previsualisation et n'inserera leur CSS associee que si cette directive a pour valeur text/html ou que le mode debug est actif. Cette assertion simple reflete l'usage de la variable $flag_preserver qui n'a ainsi plus de raison d'etre. - Spip repere aussi dans ces meta-donnees la presence d'une directive "Cache-control", auquel cas il n'enverra aucune autre directive concernant le cache du client. Ainsi, le positionnement a "vrai" de la variable $flag_dynamique, jamais documentee, est equivalent a #HTTP{'Pragma: no-cache', 'Cache-Control: no-cache; must-revalidate'}
17 years ago
// Si requete HEAD ou Last-modified compatible, ignorer le texte
// et pas de content-type (pour contrer le bouton admin de inc-public)
if (!$calculer_page) {
$page['texte'] = '';
Faciliter l'envoi d'en-tetes http dans les squelettes, afin de remplacer les variables PHP $flag_preserver et $flag_dynamique par des entitees independantes du langage d'execution. Pour cela: - introduction d'une balise #HTTP{e1, ... en} utilisable en debut de squelette, et dont les arguments sont des chaines, entourees de guillemets ou d'apostrophes, conforme au protocole HTTP1/1 : http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4 - cette balise est compilee en une sequence <?php header(e1); .... ;header(en) ?> - Spip repere une telle sequence initiale (c'est donc valable aussi pour un code php ecrit directement sous-reserve que la syntaxe soit exactement la meme) et en fait une meta-donnee pour chaque page produite par l'execution du squelette, afin de disposer facilement des en-tetes au moment de l'envoi; - Spip repere dans ces meta-donnees la presence de la directive Content-Type. Si elle est absente, elle est automatiquement rajoutee avec comme habituellement la valeur: Content-Type: text/html; charset=#CHARSET Spip n'enverra les boutons d'administration et de previsualisation et n'inserera leur CSS associee que si cette directive a pour valeur text/html ou que le mode debug est actif. Cette assertion simple reflete l'usage de la variable $flag_preserver qui n'a ainsi plus de raison d'etre. - Spip repere aussi dans ces meta-donnees la presence d'une directive "Cache-control", auquel cas il n'enverra aucune autre directive concernant le cache du client. Ainsi, le positionnement a "vrai" de la variable $flag_dynamique, jamais documentee, est equivalent a #HTTP{'Pragma: no-cache', 'Cache-Control: no-cache; must-revalidate'}
17 years ago
} else {
// si la page est prise dans le cache
if (!$GLOBALS['use_cache']) {
// Informer les boutons d'admin du contexte
// (fourni par urls_decoder_url ci-dessous lors de la mise en cache)
$GLOBALS['contexte'] = $page['contexte'];
// vider les globales url propres qui ne doivent plus etre utilisees en cas
// d'inversion url => objet
// plus necessaire si on utilise bien la fonction urls_decoder_url
#unset($_SERVER['REDIRECT_url_propre']);
#unset($_ENV['url_propre']);
} else {
// Compat ascendante :
// 1. $contexte est global
// (a evacuer car urls_decoder_url gere ce probleme ?)
// et calculer la page
if (!test_espace_prive()) {
include_spip('inc/urls');
[$fond, $GLOBALS['contexte'], $url_redirect] = urls_decoder_url(
nettoyer_uri(),
$fond,
$GLOBALS['contexte'],
true
);
}
// squelette par defaut
if (!strlen($fond ?? '')) {
$fond = 'sommaire';
}
// produire la page : peut mettre a jour $lastmodified
$produire_page = charger_fonction('produire_page', 'public');
$page = $produire_page(
$fond,
$GLOBALS['contexte'],
$GLOBALS['use_cache'],
$chemin_cache,
null,
$page,
$lastmodified,
$connect
);
if ($page === '') {
$erreur = _T(
'info_erreur_squelette2',
['fichier' => spip_htmlspecialchars($fond) . '.' . _EXTENSION_SQUELETTES]
);
erreur_squelette($erreur);
// eviter des erreurs strictes ensuite sur $page['cle'] en PHP >= 5.4
$page = ['texte' => '', 'erreur' => $erreur];
}
}
if ($page and $chemin_cache) {
$page['cache'] = $chemin_cache;
}
auto_content_type($page);
$GLOBALS['flag_preserver'] |= headers_sent();
// Definir les entetes si ce n'est fait
if (!$GLOBALS['flag_preserver']) {
// Si la page est vide, produire l'erreur 404 ou message d'erreur pour les inclusions
if (
trim($page['texte']) === ''
and _VAR_MODE !== 'debug'
and !isset($page['entetes']['Location']) // cette page realise une redirection, donc pas d'erreur
) {
$GLOBALS['contexte']['fond_erreur'] = $fond;
$page = message_page_indisponible($page, $GLOBALS['contexte']);
}
// pas de cache client en mode 'observation'
if (defined('_VAR_MODE') and _VAR_MODE) {
$page['entetes']['Cache-Control'] = 'no-cache,must-revalidate';
$page['entetes']['Pragma'] = 'no-cache';
}
}
}
// Entete Last-Modified:
// eviter d'etre incoherent en envoyant un lastmodified identique
// a celui qu'on a refuse d'honorer plus haut (cf. #655)
if (
$lastmodified
and !isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])
and !isset($page['entetes']['Last-Modified'])
) {
$page['entetes']['Last-Modified'] = gmdate('D, d M Y H:i:s', $lastmodified) . ' GMT';
}
Faciliter l'envoi d'en-tetes http dans les squelettes, afin de remplacer les variables PHP $flag_preserver et $flag_dynamique par des entitees independantes du langage d'execution. Pour cela: - introduction d'une balise #HTTP{e1, ... en} utilisable en debut de squelette, et dont les arguments sont des chaines, entourees de guillemets ou d'apostrophes, conforme au protocole HTTP1/1 : http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4 - cette balise est compilee en une sequence <?php header(e1); .... ;header(en) ?> - Spip repere une telle sequence initiale (c'est donc valable aussi pour un code php ecrit directement sous-reserve que la syntaxe soit exactement la meme) et en fait une meta-donnee pour chaque page produite par l'execution du squelette, afin de disposer facilement des en-tetes au moment de l'envoi; - Spip repere dans ces meta-donnees la presence de la directive Content-Type. Si elle est absente, elle est automatiquement rajoutee avec comme habituellement la valeur: Content-Type: text/html; charset=#CHARSET Spip n'enverra les boutons d'administration et de previsualisation et n'inserera leur CSS associee que si cette directive a pour valeur text/html ou que le mode debug est actif. Cette assertion simple reflete l'usage de la variable $flag_preserver qui n'a ainsi plus de raison d'etre. - Spip repere aussi dans ces meta-donnees la presence d'une directive "Cache-control", auquel cas il n'enverra aucune autre directive concernant le cache du client. Ainsi, le positionnement a "vrai" de la variable $flag_dynamique, jamais documentee, est equivalent a #HTTP{'Pragma: no-cache', 'Cache-Control: no-cache; must-revalidate'}
17 years ago
// fermer la connexion apres les headers si requete HEAD
if ($headers_only) {
$page['entetes']['Connection'] = 'close';
}
return $page;
}
8 years ago
/**
* Calcul le contexte de la page
*
8 years ago
* lors du calcul d'une page spip etablit le contexte a partir
* des variables $_GET et $_POST, purgees des fausses variables var_*
*
8 years ago
* Note : pour hacker le contexte depuis le fichier d'appel (page.php),
* il est recommande de modifier $_GET['toto'] (meme si la page est
* appelee avec la methode POST).
*
8 years ago
* @return array Un tableau du contexte de la page
*/
function calculer_contexte() {
$contexte = [];
foreach ($_GET as $var => $val) {
if (!preg_match(_CONTEXTE_IGNORE_VARIABLES, $var)) {
$contexte[$var] = $val;
}
}
foreach ($_POST as $var => $val) {
if (!preg_match(_CONTEXTE_IGNORE_VARIABLES, $var)) {
$contexte[$var] = $val;
}
}
return $contexte;
}
13 years ago
/**
* Calculer le contexte implicite, qui n'apparait pas dans le ENV d'un cache
* mais est utilise pour distinguer deux caches differents
*
* @staticvar string $notes
* @return array
*/
function calculer_contexte_implicite() {
13 years ago
static $notes = null;
if (is_null($notes)) {
$notes = charger_fonction('notes', 'inc', true);
}
$contexte_implicite = [
'squelettes' => $GLOBALS['dossier_squelettes'], // devrait etre 'chemin' => $GLOBALS['path_sig'], ?
'host' => ($_SERVER['HTTP_HOST'] ?? null),
'https' => ($_SERVER['HTTPS'] ?? ''),
'espace' => test_espace_prive(),
'marqueur' => ($GLOBALS['marqueur'] ?? ''),
'marqueur_skel' => ($GLOBALS['marqueur_skel'] ?? ''),
'notes' => $notes ? $notes('', 'contexter_cache') : '',
'spip_version_code' => $GLOBALS['spip_version_code'],
];
if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
$contexte_implicite['host'] .= '|' . $_SERVER['HTTP_X_FORWARDED_HOST'];
}
13 years ago
return $contexte_implicite;
}
Faciliter l'envoi d'en-tetes http dans les squelettes, afin de remplacer les variables PHP $flag_preserver et $flag_dynamique par des entitees independantes du langage d'execution. Pour cela: - introduction d'une balise #HTTP{e1, ... en} utilisable en debut de squelette, et dont les arguments sont des chaines, entourees de guillemets ou d'apostrophes, conforme au protocole HTTP1/1 : http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4 - cette balise est compilee en une sequence <?php header(e1); .... ;header(en) ?> - Spip repere une telle sequence initiale (c'est donc valable aussi pour un code php ecrit directement sous-reserve que la syntaxe soit exactement la meme) et en fait une meta-donnee pour chaque page produite par l'execution du squelette, afin de disposer facilement des en-tetes au moment de l'envoi; - Spip repere dans ces meta-donnees la presence de la directive Content-Type. Si elle est absente, elle est automatiquement rajoutee avec comme habituellement la valeur: Content-Type: text/html; charset=#CHARSET Spip n'enverra les boutons d'administration et de previsualisation et n'inserera leur CSS associee que si cette directive a pour valeur text/html ou que le mode debug est actif. Cette assertion simple reflete l'usage de la variable $flag_preserver qui n'a ainsi plus de raison d'etre. - Spip repere aussi dans ces meta-donnees la presence d'une directive "Cache-control", auquel cas il n'enverra aucune autre directive concernant le cache du client. Ainsi, le positionnement a "vrai" de la variable $flag_dynamique, jamais documentee, est equivalent a #HTTP{'Pragma: no-cache', 'Cache-Control: no-cache; must-revalidate'}
17 years ago
//
// fonction pour compatibilite arriere, probablement superflue
Faciliter l'envoi d'en-tetes http dans les squelettes, afin de remplacer les variables PHP $flag_preserver et $flag_dynamique par des entitees independantes du langage d'execution. Pour cela: - introduction d'une balise #HTTP{e1, ... en} utilisable en debut de squelette, et dont les arguments sont des chaines, entourees de guillemets ou d'apostrophes, conforme au protocole HTTP1/1 : http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4 - cette balise est compilee en une sequence <?php header(e1); .... ;header(en) ?> - Spip repere une telle sequence initiale (c'est donc valable aussi pour un code php ecrit directement sous-reserve que la syntaxe soit exactement la meme) et en fait une meta-donnee pour chaque page produite par l'execution du squelette, afin de disposer facilement des en-tetes au moment de l'envoi; - Spip repere dans ces meta-donnees la presence de la directive Content-Type. Si elle est absente, elle est automatiquement rajoutee avec comme habituellement la valeur: Content-Type: text/html; charset=#CHARSET Spip n'enverra les boutons d'administration et de previsualisation et n'inserera leur CSS associee que si cette directive a pour valeur text/html ou que le mode debug est actif. Cette assertion simple reflete l'usage de la variable $flag_preserver qui n'a ainsi plus de raison d'etre. - Spip repere aussi dans ces meta-donnees la presence d'une directive "Cache-control", auquel cas il n'enverra aucune autre directive concernant le cache du client. Ainsi, le positionnement a "vrai" de la variable $flag_dynamique, jamais documentee, est equivalent a #HTTP{'Pragma: no-cache', 'Cache-Control: no-cache; must-revalidate'}
17 years ago
//
function auto_content_type($page) {
if (!isset($GLOBALS['flag_preserver'])) {
$GLOBALS['flag_preserver'] = ($page && preg_match(
'/header\s*\(\s*.content\-type:/isx',
$page['texte']
) || (isset($page['entetes']['Content-Type'])));
}
Faciliter l'envoi d'en-tetes http dans les squelettes, afin de remplacer les variables PHP $flag_preserver et $flag_dynamique par des entitees independantes du langage d'execution. Pour cela: - introduction d'une balise #HTTP{e1, ... en} utilisable en debut de squelette, et dont les arguments sont des chaines, entourees de guillemets ou d'apostrophes, conforme au protocole HTTP1/1 : http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4 - cette balise est compilee en une sequence <?php header(e1); .... ;header(en) ?> - Spip repere une telle sequence initiale (c'est donc valable aussi pour un code php ecrit directement sous-reserve que la syntaxe soit exactement la meme) et en fait une meta-donnee pour chaque page produite par l'execution du squelette, afin de disposer facilement des en-tetes au moment de l'envoi; - Spip repere dans ces meta-donnees la presence de la directive Content-Type. Si elle est absente, elle est automatiquement rajoutee avec comme habituellement la valeur: Content-Type: text/html; charset=#CHARSET Spip n'enverra les boutons d'administration et de previsualisation et n'inserera leur CSS associee que si cette directive a pour valeur text/html ou que le mode debug est actif. Cette assertion simple reflete l'usage de la variable $flag_preserver qui n'a ainsi plus de raison d'etre. - Spip repere aussi dans ces meta-donnees la presence d'une directive "Cache-control", auquel cas il n'enverra aucune autre directive concernant le cache du client. Ainsi, le positionnement a "vrai" de la variable $flag_dynamique, jamais documentee, est equivalent a #HTTP{'Pragma: no-cache', 'Cache-Control: no-cache; must-revalidate'}
17 years ago
}
function inclure_page($fond, $contexte, string $connect = '') {
$use_cache = null;
$chemin_cache = null;
$lastinclude = null;
$res = null;
static $cacher, $produire_page;
// enlever le fond de contexte inclus car sinon il prend la main
// dans les sous inclusions -> boucle infinie d'inclusion identique
// (cette precaution n'est probablement plus utile)
unset($contexte['fond']);
$page = ['contexte_implicite' => calculer_contexte_implicite()];
13 years ago
$page['contexte_implicite']['cache'] = $fond;
if (is_null($cacher)) {
$cacher = charger_fonction('cacher', 'public', true);
}
// Les quatre derniers parametres sont modifies par la fonction:
// emplacement, validite, et, s'il est valide, contenu & age
if ($cacher) {
$res = $cacher($contexte, $use_cache, $chemin_cache, $page, $lastinclude);
} else {
$use_cache = -1;
}
13 years ago
// $res = message d'erreur : on sort de la
if ($res) {
return ['texte' => $res];
}
// Si use_cache ne vaut pas 0, la page doit etre calculee
// produire la page : peut mettre a jour $lastinclude
13 years ago
// le contexte_cache envoye a cacher() a ete conserve et est passe a produire
if ($use_cache) {
if (is_null($produire_page)) {
$produire_page = charger_fonction('produire_page', 'public');
}
$page = $produire_page($fond, $contexte, $use_cache, $chemin_cache, $contexte, $page, $lastinclude, $connect);
}
// dans tous les cas, mettre a jour $GLOBALS['lastmodified']
$GLOBALS['lastmodified'] = max(($GLOBALS['lastmodified'] ?? 0), $lastinclude);
return $page;
}
/**
* Produire la page et la mettre en cache
* lorsque c'est necessaire
*
* @param string $fond
* @param array $contexte
* @param int $use_cache
* @param string $chemin_cache
* @param array $contexte_cache
* @param array $page
* @param int $lastinclude
* @param string $connect
* @return array
*/
function public_produire_page_dist(
$fond,
$contexte,
$use_cache,
$chemin_cache,
$contexte_cache,
&$page,
&$lastinclude,
$connect = ''
) {
static $parametrer, $cacher;
if (!$parametrer) {
$parametrer = charger_fonction('parametrer', 'public');
}
$page = $parametrer($fond, $contexte, $chemin_cache, $connect);
// et on l'enregistre sur le disque
if (
$chemin_cache
and $use_cache > -1
and is_array($page)
and count($page)
and isset($page['entetes']['X-Spip-Cache'])
and $page['entetes']['X-Spip-Cache'] > 0
) {
if (is_null($cacher)) {
$cacher = charger_fonction('cacher', 'public', true);
}
$lastinclude = time();
if ($cacher) {
$cacher($contexte_cache, $use_cache, $chemin_cache, $page, $lastinclude);
} else {
$use_cache = -1;
}
}
return $page;
}
// Fonction inseree par le compilateur dans le code compile.
// Elle recoit un contexte pour inclure un squelette,
// et les valeurs du contexte de compil prepare par memoriser_contexte_compil
// elle-meme appelee par calculer_balise_dynamique dans references.php:
// 0: sourcefile
// 1: codefile
// 2: id_boucle
// 3: ligne
// 4: langue
function inserer_balise_dynamique($contexte_exec, $contexte_compil) {
arguments_balise_dyn_depuis_modele(null, 'reset');
if (!is_array($contexte_exec)) {
echo $contexte_exec;
} // message d'erreur etc
else {
inclure_balise_dynamique($contexte_exec, true, $contexte_compil);
}
}
8 years ago
/**
* Inclusion de balise dynamique
* Attention, un appel explicite a cette fonction suppose certains include
*
8 years ago
* @param string|array $texte
* @param bool $echo Faut-il faire echo ou return
* @param array $contexte_compil contexte de la compilation
* @return string|void
8 years ago
*/
function inclure_balise_dynamique($texte, $echo = true, $contexte_compil = []) {
if (is_array($texte)) {
[$fond, $delainc, $contexte_inclus] = $texte;
// delais a l'ancienne, c'est pratiquement mort
$d = $GLOBALS['delais'] ?? null;
$GLOBALS['delais'] = $delainc;
$page = recuperer_fond(
$fond,
$contexte_inclus,
['trim' => false, 'raw' => true, 'compil' => $contexte_compil]
);
$texte = $page['texte'];
$GLOBALS['delais'] = $d;
// Faire remonter les entetes
if (
isset($page['entetes'])
and is_array($page['entetes'])
) {
// mais pas toutes
unset($page['entetes']['X-Spip-Cache']);
unset($page['entetes']['Content-Type']);
if (isset($GLOBALS['page']) and is_array($GLOBALS['page'])) {
if (!is_array($GLOBALS['page']['entetes'])) {
$GLOBALS['page']['entetes'] = [];
}
$GLOBALS['page']['entetes'] =
array_merge($GLOBALS['page']['entetes'], $page['entetes']);
}
}
// _pipelines au pluriel array('nom_pipeline' => $args...) avec une syntaxe permettant plusieurs pipelines
if (
isset($page['contexte']['_pipelines'])
and is_array($page['contexte']['_pipelines'])
and count($page['contexte']['_pipelines'])
) {
foreach ($page['contexte']['_pipelines'] as $pipe => $args) {
$args['contexte'] = $page['contexte'];
unset($args['contexte']['_pipelines']); // par precaution, meme si le risque de boucle infinie est a priori nul
$texte = pipeline(
$pipe,
[
'data' => $texte,
'args' => $args
]
);
}
}
}
if (defined('_VAR_MODE') and _VAR_MODE == 'debug') {
// compatibilite : avant on donnait le numero de ligne ou rien.
$ligne = intval($contexte_compil[3] ?? $contexte_compil);
$GLOBALS['debug_objets']['resultat'][$ligne] = $texte;
}
if ($echo) {
echo $texte;
} else {
return $texte;
}
}
function message_page_indisponible($page, $contexte) {
static $deja = false;
if ($deja) {
return 'erreur';
}
$codes = [
'404' => '404 Not Found',
'503' => '503 Service Unavailable',
];
$contexte['status'] = ($page !== false) ? '404' : '503';
$contexte['code'] = $codes[$contexte['status']];
$contexte['fond'] = '404'; // gere les 2 erreurs
if (!isset($contexte['lang'])) {
include_spip('inc/lang');
$contexte['lang'] = $GLOBALS['spip_lang'];
}
$deja = true;
// passer aux plugins qui peuvent decider d'une page d'erreur plus pertinent
// ex restriction d'acces => 401
$contexte = pipeline('page_indisponible', $contexte);
// produire la page d'erreur
$page = inclure_page($contexte['fond'], $contexte);
if (!$page) {
$page = inclure_page('404', $contexte);
}
$page['status'] = $contexte['status'];
return $page;
}
/**
* gerer le flag qui permet de reperer qu'une balise dynamique a ete inseree depuis un modele
* utilisee dans les #FORMULAIRE_xx
*
* @param string|null $arg
* @param string $operation
* @return mixed
*/
function arguments_balise_dyn_depuis_modele($arg, $operation = 'set') {
static $balise_dyn_appellee_par_modele = null;
switch ($operation) {
case 'read':
return $balise_dyn_appellee_par_modele;
case 'reset':
$balise_dyn_appellee_par_modele = null;
return null;
case 'set':
default:
$balise_dyn_appellee_par_modele = $arg;
return $arg;
}
}
// temporairement ici : a mettre dans le futur inc/modeles
// creer_contexte_de_modele('left', 'autostart=true', ...) renvoie un array()
function creer_contexte_de_modele($args) {
$contexte = [];
foreach ($args as $var => $val) {
if (is_int($var)) { // argument pas formate
if (in_array($val, ['left', 'right', 'center'])) {
$var = 'align';
$contexte[$var] = $val;
} else {
$args = explode('=', $val);
if (count($args) >= 2) { // Flashvars=arg1=machin&arg2=truc genere plus de deux args
$contexte[trim($args[0])] = substr($val, strlen($args[0]) + 1);
} else // notation abregee
{