Rev 609 | Blame | Compare with Previous | Last modification | View Log | RSS feed
<?php/***************************************************************************\* SPIP, Systeme de publication pour l'internet ** ** Copyright (c) 2001-2005 ** Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James ** ** Ce programme est un logiciel libre distribue sous licence GNU/GPL. ** Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. *\***************************************************************************///// Ce fichier ne sera execute qu'une foisif (defined("_ECRIRE_INC_VERSION")) return;define("_ECRIRE_INC_VERSION", "1");function define_once ($constant, $valeur) {if (!defined($constant)) define($constant, $valeur);}// 6 constantes incontournables et prioritairesdefine('_EXTENSION_PHP', '.php3'); # a etendredefine('_DIR_RESTREINT_ABS', 'ecrire/');define('_DIR_RESTREINT', (!@is_dir(_DIR_RESTREINT_ABS) ? "" : _DIR_RESTREINT_ABS));define('_FILE_OPTIONS', _DIR_RESTREINT . 'mes_options.php3');define('_FILE_CONNECT_INS', (_DIR_RESTREINT . "inc_connect"));define('_FILE_CONNECT',(@file_exists(_FILE_CONNECT_INS . _EXTENSION_PHP) ?(_FILE_CONNECT_INS . _EXTENSION_PHP): false));//// Gestion des inclusions et infos repertoires//$included_files = array();function include_local($file) {if (@$GLOBALS['included_files'][$file]++) return;include($file);}function include_ecrire($file) {# Hack pour etre compatible avec les mes_options qui appellent cette fonctiondefine_once('_DIR_INCLUDE', _DIR_RESTREINT);$file = _DIR_INCLUDE . $file;if (@$GLOBALS['included_files'][$file]++) return;include($file);}function include_lang($file) {$file = _DIR_LANG . $file;if (@$GLOBALS['included_files'][$file]++) return;include($file);}function include_plug($file) {$file = _DIR_RESTREINT . $file;if (@$GLOBALS['included_files'][$file]++) return;if (file_exists($file)) include($file);}// *********** traiter les variables ************// Recuperer les superglobales $_GET si non definies// (en theorie c'est impossible depuis PHP 4.0.3, cf. track_vars)// et les identifier aux $HTTP_XX_VARSforeach (array('_GET', '_POST', '_COOKIE', '_SERVER') as $_table) {$http_table_vars = 'HTTP'.$_table.'_VARS';if (!is_array($GLOBALS[$_table])) {$GLOBALS[$_table] = array();if (is_array($GLOBALS[$http_table_vars]))$GLOBALS[$_table] = & $GLOBALS[$http_table_vars];}$GLOBALS[$http_table_vars] = & $GLOBALS[$_table];}// Magic quotes : on n'en veut pas sur la base,// et on nettoie les GET/POST/COOKIE le cas echeantfunction magic_unquote($_table) {// Certains hebergeurs n'activent pas $GLOBALS['GLOBALS']if ($_table == 'GLOBALS'AND !isset($GLOBALS['GLOBALS']))$GLOBALS['GLOBALS'] = &$GLOBALS;if (is_array($GLOBALS[$_table])) {foreach ($GLOBALS[$_table] as $key => $val) {if (is_string($val))$GLOBALS[$_table][$key] = stripslashes($val);}}}@set_magic_quotes_runtime(0);if (@get_magic_quotes_gpc()) {magic_unquote('_GET');magic_unquote('_POST');magic_unquote('_COOKIE');# if (@ini_get('register_globals')) // pas fiablemagic_unquote('GLOBALS');}// Dirty hack contre le register_globals a 'Off' (PHP 4.1.x)// A remplacer (un jour!) par une gestion propre des variables admissibles ;-)// Attention pour compatibilite max $_GET n'est pas superglobale// NB: c'est une fonction de maniere a ne pas pourrir $GLOBALSfunction spip_register_globals() {// Liste des variables dont on refuse qu'elles puissent provenir du client$refuse_gpc = array (# inc-public.php3'fond', 'delais',# ecrire/inc_auth.php3'REMOTE_USER','PHP_AUTH_USER', 'PHP_AUTH_PW',# ecrire/inc_texte.php3'debut_intertitre', 'fin_intertitre', 'ligne_horizontale','ouvre_ref', 'ferme_ref', 'ouvre_note', 'ferme_note','les_notes', 'compt_note', 'nombre_surligne','url_glossaire_externe', 'puce', 'puce_rtl');// Liste des variables (contexte) dont on refuse qu'elles soient cookie// (histoire que personne ne vienne fausser le cache)$refuse_c = array (# inc-calcul.php3'id_parent', 'id_rubrique', 'id_article','id_auteur', 'id_breve', 'id_forum', 'id_secteur','id_syndic', 'id_syndic_article', 'id_mot', 'id_groupe','id_document', 'date', 'lang');// Si les variables sont passees en global par le serveur, il faut// faire quelques verifications de baseif (@ini_get('register_globals')) {foreach ($refuse_gpc as $var) {if (isset($GLOBALS[$var])) {foreach (array('_GET', '_POST', '_COOKIE') as $_table) {if (// demande par le clientisset ($GLOBALS[$_table][$var])// et pas modifie par les fichiers d'appelAND $GLOBALS[$_table][$var] == $GLOBALS[$var]) // On ne sait pas si c'est un hack{# REMOTE_USER ou fond, c'est grave ;# pour le reste (cookie 'lang', par exemple), simplement# interdire la mise en cache de la page produiteswitch ($var) {case 'REMOTE_USER':case 'fond':die ("$var interdite");break;default:define ('spip_interdire_cache', true);}}}}}foreach ($refuse_c as $var) {if (isset($GLOBALS[$var])) {foreach (array('_COOKIE') as $_table) {if (// demande par le clientisset ($GLOBALS[$_table][$var])// et pas modifie par les fichiers d'appelAND $GLOBALS[$_table][$var] == $GLOBALS[$var])define ('spip_interdire_cache', true);}}}}// sinon il faut les passer nous-memes, a l'exception des interdites.// (A changer en une liste des variables admissibles...)else {foreach (array('_SERVER', '_COOKIE', '_POST', '_GET') as $_table) {foreach ($GLOBALS[$_table] as $var => $val) {if (!isset($GLOBALS[$var])AND isset($GLOBALS[$_table][$var])AND ($_table == '_SERVER' OR !in_array($var, $refuse_gpc))AND ($_table <> '_COOKIE' OR !in_array($var, $refuse_c)))$GLOBALS[$var] = $val;}}}}spip_register_globals();//// *** Parametrage par defaut de SPIP ***//// Ces parametres d'ordre technique peuvent etre modifies// dans ecrire/mes_options.php3 (_FILE_OPTIONS) Les valeurs// specifiees dans ce dernier fichier remplaceront automatiquement// les valeurs ci-dessous.//// Pour creer ecrire/mes_options.php3 : recopier simplement// les lignes ci-dessous, et ajouter le marquage de debut et// de fin de fichier PHP ("< ?php" et "? >", sans les espaces)//// Prefixe des tables dans la base de donnees// (a modifier pour avoir plusieurs sites SPIP dans une seule base)$table_prefix = "spip";// Prefixe et chemin des cookies// (a modifier pour installer des sites SPIP dans des sous-repertoires)$cookie_prefix = "spip";$cookie_path = "";// Dossier des squelettes// (a modifier si l'on veut passer rapidement d'un jeu de squelettes a un autre)$dossier_squelettes = "";// faut-il autoriser SPIP a compresser les pages a la volee quand le// navigateur l'accepte (valable pour apache >= 1.3 seulement) ?$auto_compress = true;// Type d'URLs// 'standard': article.php3?id_article=123// 'html': article123.html// 'propres': Titre-de-l-article <http://lab.spip.net/spikini/UrlsPropres>// 'propres2' : Titre-de-l-article.html (base sur 'propres')$type_urls = 'standard';// creation des vignettes avec image magick en ligne de commande : mettre// le chemin complet '/bin/convert' (Linux) ou '/sw/bin/convert' (fink/Mac OS X)// Note : preferer GD2 ou le module php imagick s'ils sont disponibles$convert_command = 'convert';// creation des vignettes avec pnmscale// Note: plus facile a installer par FTP,// voir http://gallery.menalto.com/modules.php?op=modload&name=GalleryFAQ&file=index&myfaq=yes&id_cat=2#43$pnmscale_command = 'pnmscale';// faut-il passer les connexions MySQL en mode debug ?$mysql_debug = false;// faut-il chronometrer les requetes MySQL ?$mysql_profile = false;// faut-il faire des connexions completes rappelant le nom du serveur et/ou de// la base MySQL ? (utile si vos squelettes appellent d'autres bases MySQL)// (A desactiver en cas de soucis de connexion chez certains hebergeurs)// Note: un test a l'installation peut aussi avoir desactive// $mysql_rappel_nom_base directement dans le fichier inc_connect.php3$mysql_rappel_connexion = true;$mysql_rappel_nom_base = true;// faut-il afficher en rouge les chaines non traduites ?$test_i18n = false;// faut-il souligner en gris, dans articles.php3, les espaces insecables ?$activer_revision_nbsp = false;// gestion des extras (voir inc_extra.php3 pour plus d'informations)$champs_extra = false;$champs_extra_proposes = false;// faut-il ignorer l'authentification par auth http/remote_user ?$ignore_auth_http = false;$ignore_remote_user = true; # methode obsolete et risquee// Faut-il "invalider" les caches quand on depublie ou modifie un article ?// (experimental)# NB: cette option ne concerne que articles,breves,rubriques et site# car les forums et petitions sont toujours invalidants.$invalider_caches = false;// Quota : la variable $quota_cache, si elle est > 0, indique la taille// totale maximale desiree des fichiers contenus dans le CACHE/ ;// ce quota n'est pas "dur", il ne s'applique qu'une fois par heure et// fait redescendre le cache a la taille voulue ; valeur en Mo// Si la variable vaut 0 aucun quota ne s'applique$quota_cache = 10;// code a fournir pour obtenir le debuggueur (urls &var_mode=debug)// par defaut seuls les admins : $code_activation_debug='';// pour mettre un mot de passe : $code_activation_debug='x5g8jk9';$code_activation_debug = '';//// Serveurs externes//# aide en ligne$help_server = 'http://www.spip.net/aide';# TeX$tex_server = 'http://math.spip.org/tex.php';# MathML (pas pour l'instant: manque un bon convertisseur)// $mathml_server = 'http://arno.rezo.net/tex2mathml/latex.php';# Orthographe (serveurs multiples) [pas utilise pour l'instant]$ortho_servers = array ('http://ortho.spip.net/ortho_serveur.php');// Produire du TeX ou du MathML ?$traiter_math = 'tex';// Masquer les warningerror_reporting(E_ALL ^ E_NOTICE);// Variables du compilateur de squelettes$exceptions_des_tables = array();$tables_principales = array();$table_des_tables = array();$tables_relations = array();$tables_relations_keys = array();$table_primary = array();$table_date = array();$tables_des_serveurs_sql['localhost'] = &$tables_principales;/* ATTENTION CETTE VARIABLE NE FONCTIONNE PAS ENCORE */// Extension du fichier du squelette$extension_squelette = 'html';/* / MERCI DE VOTRE ATTENTION */// Droits d'acces maximum par defaut@umask(0);//// Definition des repertoires standards, _FILE_OPTIONS ayant priorite//if (@file_exists(_FILE_OPTIONS)) {include(_FILE_OPTIONS);}// la taille maxi des logos (0 : pas de limite)define_once('_LOGO_MAX_SIZE', 0); # poids en kodefine_once('_LOGO_MAX_WIDTH', 0); # largeur en pixelsdefine_once('_LOGO_MAX_HEIGHT', 0); # hauteur en pixelsdefine_once('_DIR_INCLUDE', _DIR_RESTREINT);define_once('_DIR_PREFIX1', (_DIR_RESTREINT ? "" : "../"));define_once('_DIR_PREFIX2', _DIR_RESTREINT);// les repertoires des logos, des documents joints, du CACHE et des sessionsdefine_once('_DIR_IMG', _DIR_PREFIX1 ."IMG/");define_once('_DIR_DOC', _DIR_PREFIX1 ."IMG/");define_once('_DIR_CACHE', _DIR_PREFIX1 ."CACHE/");define_once('_DIR_SESSIONS', _DIR_PREFIX2 . "data/");define_once('_DIR_TRANSFERT', _DIR_PREFIX2 . "upload/");// exemples de redefinition possible,// SOUS RESERVE QUE php.ini N'AIT PAS pas openbasedir=. !!!!!!// il est recommande de mettre les deux premiers en dehors de l'arbo http// pour _DIR_DOC, on ne peut le faire qu'en configuration securisee// pour _DIR_IMG, NE PAS LE METTRE en dehors de l'arborescence http//define('_DIR_CACHE', "/tmp/c/");//define('_DIR_SESSIONS', "/tmp/s/");//define('_DIR_DOC', "/tmp/d/");//define('_DIR_INCLUDE', _DIR_RESTREINT ? 'Include/' : '../Include/');// globale des repertoires devant etre accessibles en ecriture// (inutile de mettre leurs sous-repertoires)$test_dirs = array(_DIR_CACHE, _DIR_IMG, _DIR_SESSIONS);// les fichiers qu'on y met, entre autres,define_once('_FILE_CRON_LOCK', _DIR_SESSIONS . 'cron.lock');define_once('_FILE_MYSQL_OUT', _DIR_SESSIONS . 'mysql_out');define_once('_FILE_GARBAGE', _DIR_SESSIONS . '.poubelle');// sous-repertoires d'images accessible en ecrituredefine_once('_DIR_IMG_ICONES', _DIR_IMG . "icones/");define_once('_DIR_IMG_ICONES_BARRE', _DIR_IMG . "icones_barre/");define_once('_DIR_TeX', _DIR_IMG . "cache-TeX/");// pour ceux qui n'aiment pas nos icones et notre vocabulaire, tout est prevudefine_once('_DIR_IMG_PACK', (_DIR_RESTREINT . 'img_pack/'));define_once('_DIR_LANG', (_DIR_RESTREINT . 'lang/'));// qq chaines standarddefine_once('_ACCESS_FILE_NAME', '.htaccess');define_once('_AUTH_USER_FILE', '.htpasswd');// tidy en ligne de commande (si on ne l'a pas en module php,// ou si le module php ne marche pas)// '/bin/tidy' ou '/usr/local/bin/tidy' ou tout simplement 'tidy'#define_once('_TIDY_COMMAND', 'tidy');// Version courante de SPIP// Stockee sous forme de nombre decimal afin de faciliter les comparaisons// (utilise pour les modifs de la base de donnees)// version de la base$spip_version = 1.821;// version de spip$spip_version_affichee = "1.8.2";// ** Securite **$auteur_session = '';$connect_statut = '';$hash_recherche = '';$hash_recherche_strict = '';//// Capacites php (en fonction de la version)//$flag_get_cfg_var = (@get_cfg_var('error_reporting') != "");$flag_ini_get = (function_exists("ini_get")&& (@ini_get('max_execution_time') > 0)); // verifier pas desactivee$flag_gz = function_exists("gzencode"); #php 4.0.4$flag_ob = ($flag_ini_get&& !ereg("ob_", ini_get('disable_functions'))&& function_exists("ob_start"));$flag_crypt = function_exists("crypt");$flag_wordwrap = function_exists("wordwrap");$flag_apc = function_exists("apc_rm");$flag_sapi_name = function_exists("php_sapi_name");$flag_utf8_decode = function_exists("utf8_decode");$flag_ldap = function_exists("ldap_connect");$flag_flock = function_exists("flock");$flag_ImageCreateTrueColor = function_exists("ImageCreateTrueColor");$flag_ImageCopyResampled = function_exists("ImageCopyResampled");$flag_ImageGif = function_exists("ImageGif");$flag_ImageJpeg = function_exists("ImageJpeg");$flag_ImagePng = function_exists("ImagePng");$flag_imagick = function_exists("imagick_readimage"); // http://pear.sourceforge.net/en/packages.imagick.php$flag_gd = $flag_ImageGif || $flag_ImageJpeg || $flag_ImagePng;$flag_revisions = function_exists("gzcompress");//// Appliquer le prefixe cookie//function spip_setcookie ($name='', $value='', $expire=0, $path='AUTO', $domain='', $secure='') {$name = ereg_replace ('^spip_', $GLOBALS['cookie_prefix'].'_', $name);if ($path == 'AUTO') $path=$GLOBALS['cookie_path'];if ($secure)@setcookie ($name, $value, $expire, $path, $domain, $secure);else if ($domain)@setcookie ($name, $value, $expire, $path, $domain);else if ($path)@setcookie ($name, $value, $expire, $path);else if ($expire)@setcookie ($name, $value, $expire);else@setcookie ($name, $value);}if ($cookie_prefix != 'spip') {foreach ($_COOKIE as $name => $value) {if (ereg('^spip_', $name)) {unset($_COOKIE[$name]);unset($$name);}}foreach ($_COOKIE as $name => $value) {if (ereg('^'.$cookie_prefix.'_', $name)) {$spipname = ereg_replace ('^'.$cookie_prefix.'_', 'spip_', $name);$_COOKIE[$spipname] = $INSECURE[$spipname] = $value;$$spipname = $value;}}}//// Sommes-nous dans l'empire du Mal ?//if (strpos($_SERVER['SERVER_SOFTWARE'], '(Win') !== false)define ('os_serveur', 'windows');//// Non ! Car le GNU veille... (Entete HTTP de frimeur)//if (!headers_sent())@header("Composed-By: SPIP $spip_version_affichee @ www.spip.net");//// Enregistrement des evenements//function spip_log($message, $logname='spip') {$pid = '(pid '.@getmypid().')';if (!$ip = $GLOBALS['REMOTE_ADDR']) $ip = '-';$message = date("M d H:i:s")." $ip $pid ".ereg_replace("\n*$", "\n", $message);$logfile = _DIR_SESSIONS . $logname . '.log';if (@file_exists($logfile) && (@filesize($logfile) > 10*1024)) {$rotate = true;$message .= "[-- rotate --]\n";}$f = @fopen($logfile, "ab");if ($f) {fputs($f, $message);fclose($f);}if ($rotate) {@unlink($logfile.'.3');@rename($logfile.'.2',$logfile.'.3');@rename($logfile.'.1',$logfile.'.2');@rename($logfile,$logfile.'.1');}// recopier les spip_log mysql (ce sont uniquement des erreurs)// dans le spip_log generalif ($logname == 'mysql')spip_log($message);}//// Infos sur le fichier courant//// Compatibilite avec serveurs ne fournissant pas $REQUEST_URIif (!$REQUEST_URI) {$REQUEST_URI = $PHP_SELF;if ($QUERY_STRING AND !strpos($REQUEST_URI, '?'))$REQUEST_URI .= '?'.$QUERY_STRING;}if (!$PATH_TRANSLATED) {if ($SCRIPT_FILENAME) $PATH_TRANSLATED = $SCRIPT_FILENAME;else if ($DOCUMENT_ROOT && $SCRIPT_URL) $PATH_TRANSLATED = $DOCUMENT_ROOT.$SCRIPT_URL;}# obsoletes: utiliser les constantes ci-dessus.# Conserver pour compatibilite vieilles contrib uniquement$flag_ecrire = !@file_exists(_DIR_RESTREINT_ABS . 'inc_version.php3');$dir_ecrire = (ereg("/ecrire/", $GLOBALS['REQUEST_URI'])) ? '' : 'ecrire/';// API d'appel a la base de donneesfunction spip_query($query) {// Remarque : si on est appele par l'install,// la connexion initiale a ete faite avantif (!$GLOBALS['db_ok']) {// Essaie de se connecterif (_FILE_CONNECT)include_local(_FILE_CONNECT);}// Erreur de connexionif (!$GLOBALS['db_ok'])return;// Vieux format de fichier connexion// Note: la version 0.1 est compatible avec la 0.2 (mais elle gere// moins bien les erreurs timeout sur SQL), on ne force donc pas l'upgradeif ($GLOBALS['spip_connect_version'] < 0.1) {if (!_DIR_RESTREINT) {$GLOBALS['db_ok'] = false; return;}@Header("Location: upgrade.php3?reinstall=oui");exit;}// Faire la requetereturn spip_query_db($query);}//// Infos de config PHP//// cf. liste des sapi_name - http://fr.php.net/php_sapi_name$php_module = (($flag_sapi_name AND eregi("apache", @php_sapi_name())) ORereg("^Apache.* PHP", $SERVER_SOFTWARE));$php_cgi = ($flag_sapi_name AND eregi("cgi", @php_sapi_name()));function http_status($status) {global $php_cgi, $REDIRECT_STATUS;if ($REDIRECT_STATUS && $REDIRECT_STATUS == $status) return;$status_string = array(200 => '200 OK',301 => '301 Moved Permanently',304 => '304 Not Modified',401 => '401 Unauthorized',403 => '403 Forbidden',404 => '404 Not Found');if ($php_cgi) Header("Status: $status");else Header("HTTP/1.0 ".$status_string[$status]);}function http_gmoddate($lastmodified) {return gmdate("D, d M Y H:i:s", $lastmodified);}function http_last_modified($lastmodified, $expire = 0) {$gmoddate = http_gmoddate($lastmodified);if ($GLOBALS['HTTP_IF_MODIFIED_SINCE']AND !preg_match(',IIS/,', $_SERVER['SERVER_SOFTWARE'])) # MSoft IIS is dumb{$if_modified_since = ereg_replace(';.*$', '', $GLOBALS['HTTP_IF_MODIFIED_SINCE']);$if_modified_since = trim(str_replace('GMT', '', $if_modified_since));if ($if_modified_since == $gmoddate) {http_status(304);$headers_only = true;}}@Header ("Last-Modified: ".$gmoddate." GMT");if ($expire)@Header ("Expires: ".http_gmoddate($expire)." GMT");return $headers_only;}$flag_upload = (!$flag_get_cfg_var || (get_cfg_var('upload_max_filesize') > 0));function tester_upload() {return $GLOBALS['flag_upload'];}//// Reglage de l'output buffering : si possible, generer une sortie// compressee pour economiser de la bande passante//function test_obgz () {return$GLOBALS['auto_compress']&& $GLOBALS['flag_ob']&& (phpversion()<>'4.0.4')&& function_exists("ob_gzhandler")// special bug de proxy&& !eregi("NetCache|Hasd_proxy", $GLOBALS['HTTP_VIA'])// special bug Netscape Win 4.0x&& !eregi("Mozilla/4\.0[^ ].*Win", $GLOBALS['HTTP_USER_AGENT'])// special bug Apache2x&& !eregi("Apache(-[^ ]+)?/2", $GLOBALS['SERVER_SOFTWARE'])&& !($GLOBALS['flag_sapi_name'] AND ereg("^apache2", @php_sapi_name()))// si la compression est deja commencee, stop&& !@ini_get("zlib.output_compression")&& !@ini_get("output_handler")&& !$GLOBALS['var_mode'] # bug avec le debugueur qui appelle ob_end_clean();}// si un buffer est deja ouvert, stopif ($flag_ob AND strlen(ob_get_contents())==0 AND !headers_sent()) {@header("Vary: Cookie, Accept-Encoding");if (test_obgz()) {ob_start('ob_gzhandler');}}class Link {var $file;var $vars;var $arrays;//// Contructeur : a appeler soit avec l'URL du lien a creer,// soit sans parametres, auquel cas l'URL est l'URL courante//// parametre $root = demander un lien a partir de la racine du serveur /function Link($url = '', $root = false) {global $_POST;static $link = '';$this->vars = array();$this->arrays = array();// Normal caseif ($link) {if ($url) {$v = split('[\?\&]', $url);list(, $this->file) = each($v);while (list(, $var) = each($v)) {list($name, $value) = split('=', $var, 2);$name = urldecode($name);$value = urldecode($value);if (ereg('^(.*)\[\]$', $name, $regs)) {$this->arrays[$regs[1]][] = $value;}else {$this->vars[$name] = $value;}}}else {$this->file = $link->file;$this->vars = $link->vars;$this->arrays = $link->arrays;}return;}// Si aucun URL n'est specifie, creer le lien "propre"// ou l'on supprime de l'URL courant les bidules inutilesif (!$url) {// GET variables are read from the original URL// (_GET may contain additional variables// introduced by rewrite-rules)$url = $GLOBALS['REQUEST_URI'];// Warning !!!!// since non encoded arguments may be present// (especially those coming from Rewrite Rule)// find the begining of the query string// to compute the script-nameif ($v = strpos($url,'?'))$v = strrpos(substr($url, 0, $v), '/');else $v = strrpos($url, '/');if (!$root) $url = substr($url, $v + 1);if (!$url) $url = "./";if (count($_POST)) {$vars = array();foreach ($_POST as $var => $val)if (preg_match('/^id_/', $var))$vars[$var] = $val;}}$v = split('[\?\&]', $url);list(, $this->file) = each($v);if (!$vars) {while (list(,$var) = each($v)) {list($name, $value) = split('=', $var, 2);$name = urldecode($name);$value = urldecode($value);if (ereg('^(.*)\[\]$', $name, $regs))$vars[$regs[1]][] = $value;else$vars[$name] = $value;}}if (is_array($vars)) {foreach ($vars as $name => $value) {// items supprimesif (!preg_match('/^('.(!_DIR_RESTREINT ?'|lang|set_options|set_couleur|set_disp|set_ecran':'var_mode|show_docs'). ')$/i', $name)) {if (is_array($value))$this->arrays[$name] = $value;else$this->vars[$name] = $value;}}}}//// Effacer une variable//function delVar($name) {if($this->vars[$name]) unset($this->vars[$name]);if($this->arrays[$name]) unset($this->arrays[$name]);}//// Ajouter une variable// (si aucune valeur n'est specifiee, prend la valeur globale actuelle)//function addVar($name, $value = '__global__') {if ($value == '__global__') $value = $GLOBALS[$name];if (is_array($value))$this->arrays[$name] = $value;else$this->vars[$name] = $value;}//// Recuperer l'URL correspondant au lien//function getUrl($anchor = '') {$url = $this->file;if (!$url) $url = './';$query = '';foreach($this->vars as $name => $value)$query .= '&'.$name.'='.urlencode($value);foreach ($this->arrays as $name => $table)foreach ($table as $value)$query .= '&'.$name.'[]='.urlencode($value);if ($query) $query = '?'. substr($query, 1);if ($anchor) $anchor = '#'.$anchor;return "$url$query$anchor";}//// Recuperer le debut de formulaire correspondant au lien// (tag ouvrant + entrees cachees representant les variables)//function getForm($method = 'get', $query = '', $enctype = '') {$form = "<form method='$method' action='".$this->file.$query."'";if ($enctype) $form .= " enctype='$enctype'";$form .= " style='border: 0px; margin: 0px;'>\n";foreach ($this->vars as $name => $value) {$value = ereg_replace('&(#[0-9]+;)', '&\1', htmlspecialchars($value));$form .= "<input type=\"hidden\" name=\"$name\" value=\"$value\" />\n";}foreach ($this->arrays as $name => $table)foreach ($table as $value) {$value = ereg_replace('&(#[0-9]+;)', '&\1', htmlspecialchars($value));$form .= "<input type=\"hidden\" name=\"".$name."[]\" value=\"".$value."\" />\n";}return $form;}}// Lien vers la page demandee et lien nettoye ne contenant que des id_objet$clean_link = new Link();// URLs avec passage & -> &function quote_amp ($url) {$url = str_replace("&", "&", $url);$url = str_replace("&", "&", $url);return $url;}//// Module de lecture/ecriture/suppression de fichiers utilisant flock()//include_ecrire('inc_flock.php3');//// Gerer les valeurs meta//function lire_meta($nom) {global $meta;return $meta[$nom];}function lire_meta_maj($nom) {global $meta_maj;return $meta_maj[$nom];}// Lire les meta cacheesif (!defined('_DATA_META_CACHE') AND !defined('_ECRIRE_INC_META')) {unset($meta); # paranoif (file_exists(_DIR_SESSIONS . 'meta_cache.php3'))include(_DIR_SESSIONS . 'meta_cache.php3');// en cas d'echec refaire le fichierif (!is_array($meta) AND _FILE_CONNECT) {include_ecrire('inc_meta.php3');ecrire_metas();}}// Verifier la conformite d'une ou plusieurs adresses email// retourne false ou la normalisation de la derniere adresse donneefunction email_valide($adresses) {foreach (explode(',', $adresses) as $v) {// nettoyer certains formats// "Marie Toto <Marie@toto.com>"$adresse = trim(eregi_replace("^[^<>\"]*<([^<>\"]+)>$", "\\1", $v));// RFC 822if (!eregi('^[^()<>@,;:\\"/[:space:]]+(@([-_0-9a-z]+\.)*[-_0-9a-z]+)$', $adresse))return false;}return $adresse;}//// Traduction des textes de SPIP//function _T($texte, $args = '') {include_ecrire('inc_lang.php3');$text = traduire_chaine($texte, $args);if (!empty($GLOBALS['xhtml'])) {include_ecrire("inc_charsets.php3");$text = html2unicode($text);}return $text ? $text :// pour les chaines non traduites(($n = strpos($texte,':')) === false ? $texte :substr($texte, $n+1));}// chaines en cours de traductionfunction _L($text) {if ($GLOBALS['test_i18n'])return "<span style='color:red;'>$text</span>";elsereturn $text;}// Langue principale du site$langue_site = lire_meta('langue_site');if (!$langue_site) include_ecrire('inc_lang.php3');$spip_lang = $langue_site;// Nommage bizarre des tables d'objetsfunction table_objet($type) {if ($type == 'site' OR $type == 'syndic')return 'syndic';else if ($type == 'forum')return 'forum';elsereturn $type.'s';}function id_table_objet($type) {if ($type == 'site' OR $type == 'syndic')return 'id_syndic';else if ($type == 'forum')return 'id_forum';elsereturn 'id_'.$type;}//// spip_timer : on l'appelle deux fois et on a la difference, affichable//function spip_timer($t='rien') {static $time;$a=time(); $b=microtime();if (isset($time[$t])) {$p = $a + $b - $time[$t];unset($time[$t]);return sprintf("%.2fs", $p);} else$time[$t] = $a + $b;}// spip_touch : verifie si un fichier existe et n'est pas vieux (duree en s)// et le cas echeant le touch() ; renvoie true si la condition est verifiee// et fait touch() sauf si ca n'est pas souhaite// (regle aussi le probleme des droits sur les fichiers touch())function spip_touch($fichier, $duree=0, $touch=true) {if (!($exists = @file_exists($fichier))|| ($duree == 0)|| (@filemtime($fichier) < time() - $duree)) {if ($touch) {if (!@touch($fichier)) { @unlink($fichier); @touch($fichier); };if (!$exists) @chmod($fichier, 0666);}return true;}return false;}//// cron() : execution des taches de fond// quand il est appele par spip_background.php3, il est gourmand ;// quand il est appele par inc-public il n'est pas gourmand//function cron($gourmand = false) {$touch = _DIR_SESSIONS.'.background';$touch_gourmand = $touch.'-gourmand';// Si on est gourmand, ou si le fichier gourmand n'existe pas// (ou est trop vieux), on va voir si un cron est necessaire.// Au passage si on est gourmand on le dit aux autresif (spip_touch($touch_gourmand, 60, $gourmand)OR $gourmand) {// Faut-il travailler ? Pas tous en meme temps svp// Au passage si on travaille on bloque les autresif (spip_touch($touch, 1)) {include_ecrire('inc_cron.php3');spip_cron();}}}//// qq fonctions service pour les 2 niveaux//function calculer_hierarchie($id_rubrique, $exclure_feuille = false) {if (!$id_rubrique)return '0';if (!$exclure_feuille)$hierarchie = ",$id_rubrique";do {$q = spip_query("SELECT id_parent FROM spip_rubriques WHERE id_rubrique=$id_rubrique");list($id_rubrique) = spip_fetch_array($q);$hierarchie = ",$id_rubrique".$hierarchie;} while ($id_rubrique);return substr($hierarchie, 1); // Attention ca demarre toujours par '0'}//// Retourne $subdir/ si le sous-repertoire peut etre cree, '' sinon//function creer_repertoire($base, $subdir) {if (@file_exists("$base/.plat")) return '';$path = $base.'/'.$subdir;if (@file_exists($path)) return "$subdir/";@mkdir($path, 0777);@chmod($path, 0777);$ok = false;if ($f = @fopen("$path/.test", "w")) {@fputs($f, '<'.'?php $ok = true; ?'.'>');@fclose($f);include("$path/.test");}if (!$ok) {$f = @fopen("$base/.plat", "w");if ($f)fclose($f);else {redirige_par_entete("spip_test_dirs.php3");}}return ($ok? "$subdir/" : '');}//// Entetes//function redirige_par_entete($url) {header("Location: $url");# include_ecrire('inc_cron.php3');# spip_cron();spip_log("redirige $url");exit;}function debut_entete($title, $entete='') {global $flag_preserver;if (!$charset = lire_meta('charset'))$charset = 'utf-8';if (!$entete)$entete = "Content-Type: text/html; charset=$charset";if (!$flag_preserver) @header($entete);return "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'>\n" ."<html lang='".$GLOBALS['spip_lang']."' dir='".($GLOBALS['spip_lang_rtl'] ? 'rtl' : 'ltr')."'>\n" ."<head>\n" .# "<base href='$base' />\n" ."<title>$title</title>\n" ."<meta http-equiv='Content-Type' content='text/html; charset=$charset'>\n";}// Transforme n'importe quel champ en une chaine utilisable// en PHP ou Javascript en toute securite// < ? php $x = '[(#TEXTE|texte_script)]'; ? >function texte_script($texte) {return str_replace('\'', '\\\'', str_replace('\\', '\\\\', $texte));}//// find_in_path() : chercher un fichier nomme x selon le chemin rep1:rep2:rep3//define_once('_SPIP_PATH', './:squelettes/:dist/:formulaires/');function find_in_path ($filename, $path='AUTO') {// Chemin standard depuis l'espace publicif ($path == 'AUTO') {$path = _SPIP_PATH;if ($GLOBALS['dossier_squelettes'])$path = $GLOBALS['dossier_squelettes'].'/:'.$path;}// Depuis l'espace prive, remonter d'un cran$racine = (_DIR_RESTREINT ? '' : '../');// Parcourir le cheminforeach (split(':', $path) as $dir) {if (substr($dir, 0,1)<>'/') $dir = "$racine$dir";if (substr($dir, -1,1)<>'/') $dir .= "/";$f = "$dir$filename";# spip_log("find_in_path: essai $f");if (@is_readable($f)) {return $f;}}}//// Que faire si Spip n'est pas installe... sauf si justement on l'installe!//if (!(_FILE_CONNECTOR defined('_ECRIRE_INSTALL')OR defined('_TEST_DIRS')OR defined('_ECRIRE_AIDE'))) {// Soit on est dans ecrire/ et on envoie sur l'installationif (@file_exists("inc_version.php3")) {header("Location: " . _DIR_RESTREINT . "install.php3");exit;}// Soit on est dans le site publicelse if (defined("_INC_PUBLIC")) {# on ne peut pas deviner ces repertoires avant l'installation !define('_DIR_INCLUDE', _DIR_RESTREINT);define('_DIR_IMG_PACK', (_DIR_RESTREINT . 'img_pack/'));define('_DIR_LANG', (_DIR_RESTREINT . 'lang/'));$db_ok = false;include_ecrire ("inc_presentation.php3");install_debut_html(_T('info_travaux_titre'));echo "<p>"._T('info_travaux_texte')."</p>";install_fin_html();exit;}// Soit on est appele de l'exterieur (spikini, etc)}?>