uawdijnntqw1x1x1
IP : 216.73.216.90
Hostname : webm001.cluster110.gra.hosting.ovh.net
Kernel : Linux webm001.cluster110.gra.hosting.ovh.net 6.18.42-ovh-vps-grsec-zfs+ #1 SMP PREEMPT_DYNAMIC Wed Aug 5 15:59:48 CEST 2026 x86_64
Disable Function : _dyuweyrj4,_dyuweyrj4r,dl
OS : Linux
PATH:
/
home
/
etiennec
/
www
/
tmp
/
..
/
eb1f2
/
..
/
squelettes-dist
/
..
/
f1f54
/
base.tar
/
/
create.php000066600000013331152502550120006522 0ustar00<?php /***************************************************************************\ * SPIP, Systeme de publication pour l'internet * * * * Copyright (c) 2001-2014 * * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James * * * * Ce programme est un logiciel libre distribue sous licence GNU/GPL. * * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. * \***************************************************************************/ if (!defined('_ECRIRE_INC_VERSION')) return; include_spip('inc/acces'); include_spip('base/objets'); include_spip('base/typedoc'); include_spip('base/abstract_sql'); /** * Determiner le flag autoinc pour une table * en fonction de si c'est une table principale * * @param string $table * @param array $desc * @return bool */ function base_determine_autoinc($table,$desc=array()){ if ($t=lister_tables_principales() AND isset($t[$table])) $autoinc = true; elseif ($t=lister_tables_auxiliaires() AND isset($t[$table])) $autoinc = false; else { // essayer de faire au mieux ! $autoinc = (isset($desc['key']['PRIMARY KEY']) AND strpos($desc['key']['PRIMARY KEY'],',')===false AND strpos($desc['field'][$desc['key']['PRIMARY KEY']],'default')===false); } return $autoinc; } /** * Creer une table, * ou ajouter les champs manquants si elle existe deja * * http://doc.spip.org/@creer_ou_upgrader_table * * @param string $table * @param array $desc * @param bool|string $autoinc * 'auto' pour detecter automatiquement si le champ doit etre autoinc ou non * en fonction de la table * @param bool $upgrade * @param string $serveur * @return void */ function creer_ou_upgrader_table($table,$desc,$autoinc,$upgrade=false,$serveur='') { #spip_log("creer_ou_upgrader_table table=$table autoinc=$autoinc upgrade=$upgrade","dbinstall"._LOG_INFO_IMPORTANTE); $sql_desc = $upgrade ? sql_showtable($table,true,$serveur) : false; #if (!$sql_desc) $sql_desc = false; #spip_log("table=$table sql_desc:$sql_desc","dbinstall"._LOG_INFO_IMPORTANTE); if (!$sql_desc) { if ($autoinc==='auto') $autoinc = base_determine_autoinc($table,$desc); #spip_log("sql_create $table autoinc=$autoinc","dbinstall"._LOG_INFO_IMPORTANTE); sql_create($table, $desc['field'], $desc['key'], $autoinc, false, $serveur); // verifier la bonne installation de la table (php-fpm es-tu la ?) $sql_desc = sql_showtable($table,true,$serveur); #if (!$sql_desc) $sql_desc = false; #spip_log("Resultat table=$table sql_desc:$sql_desc","dbinstall"._LOG_INFO_IMPORTANTE); if (!$sql_desc){ // on retente avec un sleep ? sleep(1); sql_create($table, $desc['field'], $desc['key'], $autoinc, false, $serveur); $sql_desc = sql_showtable($table,true,$serveur); #if (!$sql_desc) $sql_desc = false; #spip_log("Resultat table=$table sql_desc:$sql_desc","dbinstall"._LOG_INFO_IMPORTANTE); if (!$sql_desc){ spip_log("Echec creation table $table","maj"._LOG_CRITIQUE); } } } else { #spip_log("sql_alter $table ... (on s'en fiche)","dbinstall"._LOG_INFO_IMPORTANTE); // ajouter les champs manquants // on ne supprime jamais les champs, car c'est dangereux // c'est toujours a faire manuellement $last = ''; foreach($desc['field'] as $field=>$type){ if (!isset($sql_desc['field'][$field])) sql_alter("TABLE $table ADD $field $type".($last?" AFTER $last":""),$serveur); $last = $field; } foreach($desc['key'] as $key=>$type){ // Ne pas oublier les cas des cles non nommees dans la declaration et qui sont retournees // par le showtable sous la forme d'un index de tableau "KEY $type" et non "KEY" if (!isset($sql_desc['key'][$key]) AND !isset($sql_desc['key']["$key $type"])) sql_alter("TABLE $table ADD $key ($type)",$serveur); $last = $field; } } } /** * Creer ou mettre a jour un ensemble de tables * en fonction du flag $up * * @param array $tables_inc * tables avec autoincrement sur la cle primaire * @param $tables_noinc * tables sans autoincrement sur la cle primaire * @param bool|array $up * upgrader (true) ou creer (false) * si un tableau de table est fournie, seules l'intersection de ces tables * et des $tables_inc / $tables_noinc seront traitees * @param string $serveur * serveur sql * @return void */ function alterer_base($tables_inc, $tables_noinc, $up=false, $serveur='') { if ($up === false) { $old = false; $up = array(); } else { $old = true; if (!is_array($up)) $up = array($up); } foreach($tables_inc as $k => $v) if (!$old OR in_array($k, $up)) creer_ou_upgrader_table($k,$v,true,$old,$serveur); foreach($tables_noinc as $k => $v) if (!$old OR in_array($k, $up)) creer_ou_upgrader_table($k,$v,false,$old,$serveur); } /** * Creer une base de donnee * a partir des tables principales et auxiliaires * * http://doc.spip.org/@creer_base * * @param string $serveur * @return void */ function creer_base($serveur='') { // Note: les mises a jour reexecutent ce code pour s'assurer // de la conformite de la base // pas de panique sur "already exists" et "duplicate entry" donc. alterer_base(lister_tables_principales(), lister_tables_auxiliaires(), false, $serveur); } /** * Mettre a jour une liste de tables, * fonction facilitatrice utilisee pour les maj de base * dans les plugins * * @param array $upgrade_tables * @param string $serveur * @return void */ function maj_tables($upgrade_tables=array(),$serveur=''){ alterer_base(lister_tables_principales(), lister_tables_auxiliaires(), $upgrade_tables, $serveur); } ?> index.php000066600000000002152502550120006355 0ustar00X auxiliaires.php000066600000002015152502550120007573 0ustar00<?php /***************************************************************************\ * SPIP, Systeme de publication pour l'internet * * * * Copyright (c) 2001-2014 * * 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. * \***************************************************************************/ /** * Déclare la liste des tables auxiliaires * * @todo * Nettoyages à faire dans le core : on ne devrait plus appeler * Ce fichier mais directement base/objets si nécessaire * * @package SPIP\SQL\Tables **/ if (!defined('_ECRIRE_INC_VERSION')) return; include_spip('base/objets'); lister_tables_objets_sql(); ?> upgrade.php000066600000040175152502550120006714 0ustar00<?php /***************************************************************************\ * SPIP, Systeme de publication pour l'internet * * * * Copyright (c) 2001-2014 * * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James * * * * Ce programme est un logiciel libre distribue sous licence GNU/GPL. * * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. * \***************************************************************************/ if (!defined('_ECRIRE_INC_VERSION')) return; /** * Programme de mise a jour des tables SQL lors d'un chgt de version. * L'entree dans cette fonction est reservee au maj de SPIP coeur * * Marche aussi pour les plugins en appelant directement la fonction maj_plugin * Pour que ceux-ci profitent aussi de la reprise sur interruption, * ils doivent simplement indiquer leur numero de version installee dans une meta * et fournir le tableau maj a la fonction maj_plugin. * La reprise sur timeout se fait alors par la page admin_plugin et jamais par ici * * http://doc.spip.org/@base_upgrade_dist * * @param string $titre * @param string $reprise * @return */ function base_upgrade_dist($titre='', $reprise='') { if (!$titre) return; // anti-testeur automatique if ($GLOBALS['spip_version_base']!=$GLOBALS['meta']['version_installee']) { if (!is_numeric(_request('reinstall'))) { include_spip('base/create'); spip_log("recree les tables eventuellement disparues","maj."._LOG_INFO_IMPORTANTE); creer_base(); } // quand on rentre par ici, c'est toujours une mise a jour de SPIP // lancement de l'upgrade SPIP $res = maj_base(); if ($res) { // on arrete tout ici ! exit; } } spip_log("Fin de mise a jour SQL. Debut m-a-j acces et config","maj."._LOG_INFO_IMPORTANTE); // supprimer quelques fichiers temporaires qui peuvent se retrouver invalides @spip_unlink(_CACHE_RUBRIQUES); @spip_unlink(_CACHE_PIPELINES); @spip_unlink(_CACHE_PLUGINS_PATH); @spip_unlink(_CACHE_PLUGINS_OPT); @spip_unlink(_CACHE_PLUGINS_FCT); @spip_unlink(_CACHE_CHEMIN); @spip_unlink(_DIR_TMP."plugin_xml_cache.gz"); include_spip('inc/auth'); auth_synchroniser_distant(); $config = charger_fonction('config', 'inc'); $config(); } /** * MAJ de base de SPIP * * http://doc.spip.org/@maj_base * * @param int $version_cible * @param string $redirect * @return array|bool */ function maj_base($version_cible = 0, $redirect = '') { global $spip_version_base; $version_installee = @$GLOBALS['meta']['version_installee']; // // Si version nulle ou inexistante, c'est une nouvelle installation // => ne pas passer par le processus de mise a jour. // De meme en cas de version superieure: ca devait etre un test, // il y a eu le message d'avertissement il doit savoir ce qu'il fait // // version_installee = 1.702; quand on a besoin de forcer une MAJ spip_log("Version anterieure: $version_installee. Courante: $spip_version_base","maj."._LOG_INFO_IMPORTANTE); if (!$version_installee OR ($spip_version_base < $version_installee)) { sql_replace('spip_meta', array('nom' => 'version_installee', 'valeur' => $spip_version_base, 'impt' => 'non')); return false; } if (!upgrade_test()) return true; $cible = ($version_cible ? $version_cible : $spip_version_base); if ($version_installee <= 1.926) { $n = floor($version_installee * 10); while ($n < 19) { $nom = sprintf("v%03d",$n); $f = charger_fonction($nom, 'maj', true); if ($f) { spip_log( "$f repercute les modifications de la version " . ($n/10),"maj."._LOG_INFO_IMPORTANTE); $f($version_installee, $spip_version_base); } else spip_log( "pas de fonction pour la maj $n $nom","maj."._LOG_INFO_IMPORTANTE); $n++; } include_spip('maj/v019_pre193'); v019_pre193($version_installee, $version_cible); } if ($version_installee < 2000) { if ($version_installee < 2) $version_installee = $version_installee*1000; include_spip('maj/v019'); } if ($cible < 2) $cible = $cible*1000; include_spip('maj/svn10000'); ksort($GLOBALS['maj']); $res = maj_while($version_installee, $cible, $GLOBALS['maj'], 'version_installee','meta', $redirect, true); if ($res) { if (!is_array($res)) spip_log("Pb d'acces SQL a la mise a jour","maj."._LOG_INFO_ERREUR); else { echo _T('avis_operation_echec') . ' ' . join(' ', $res); echo install_fin_html(); } } return $res; } /** * Mise à jour d'un plugin de SPIP * * Fonction appelée par la fonction de maj d'un plugin. * On lui fournit un tableau de fonctions élementaires * dont l'indice est la version * * @param string $nom_meta_base_version * Nom de la meta informant de la version du schéma de données du plugin installé dans SPIP * @param string $version_cible * Version du schéma de données dans le plugin (déclaré dans paquet.xml) * @param array $maj * Tableau d'actions à faire à l'installation (clé 'create') et pour chaque * version intermédiaire entre la version actuelle du schéma du plugin dans SPIP * et la version du schéma déclaré dans le plugin (ex. clé '1.1.0'). * * Chaque valeur est un tableau contenant une liste de fonctions à exécuter, * cette liste étant elle-même un tableau avec premier paramètre le nom de la fonction * et les suivant les paramètres à lui passer * @example * array( * 'create' => array( * array('maj_tables', array('spip_rubriques', 'spip_articles')), * array('creer_base)), * '1.1.0' => array( * array('sql_alter', 'TABLE spip_articles ADD INDEX truc (truc)')) * ) * @param string $table_meta * Nom de la table meta (sans le prefixe spip_) dans laquelle trouver la meta $nom_meta_base_version * @return void */ function maj_plugin($nom_meta_base_version, $version_cible, $maj, $table_meta='meta'){ if ($table_meta!=='meta') lire_metas($table_meta); if ( (!isset($GLOBALS[$table_meta][$nom_meta_base_version]) ) || (!spip_version_compare($current_version = $GLOBALS[$table_meta][$nom_meta_base_version],$version_cible,'='))){ // $maj['create'] contient les directives propres a la premiere creation de base // c'est une operation derogatoire qui fait aboutir directement dans la version_cible if (isset($maj['create'])){ if (!isset($GLOBALS[$table_meta][$nom_meta_base_version])){ // installation : on ne fait que l'operation create $maj = array("init"=>$maj['create']); // et on lui ajoute un appel a inc/config // pour creer les metas par defaut $config = charger_fonction('config','inc'); $maj[$version_cible] = array(array($config)); } // dans tous les cas enlever cet index du tableau unset($maj['create']); } // si init, deja dans le bon ordre if (!isset($maj['init'])){ include_spip('inc/plugin'); // pour spip_version_compare uksort($maj,'spip_version_compare'); } // la redirection se fait par defaut sur la page d'administration des plugins // sauf lorsque nous sommes sur l'installation de SPIP // ou define _REDIRECT_MAJ_PLUGIN $redirect = (defined('_REDIRECT_MAJ_PLUGIN')?_REDIRECT_MAJ_PLUGIN:generer_url_ecrire('admin_plugin')); if (defined('_ECRIRE_INSTALL')) { $redirect = parametre_url(generer_url_ecrire('install'),'etape', _request('etape')); } $res = maj_while($current_version, $version_cible, $maj, $nom_meta_base_version, $table_meta, $redirect); if ($res) { if (!is_array($res)) spip_log("Pb d'acces SQL a la mise a jour","maj."._LOG_INFO_ERREUR); else { echo "<p>"._T('avis_operation_echec') . ' ' . join(' ', $res)."</p>"; } } } } /** * Relancer le hit de maj avant timeout * si pas de redirect fourni, on redirige vers exec=upgrade pour finir * ce qui doit etre une maj SPIP * * @param string $meta * @param string $table * @param string $redirect * @return void */ function relance_maj($meta,$table,$redirect=''){ include_spip('inc/headers'); if (!$redirect){ // recuperer la valeur installee en cours // on la tronque numeriquement, elle ne sert pas reellement // sauf pour verifier que ce n'est pas oui ou non // sinon is_numeric va echouer sur un numero de version 1.2.3 $installee = intval($GLOBALS[$table][$meta]); $redirect = generer_url_ecrire('upgrade',"reinstall=$installee&meta=$meta&table=$table",true); } echo redirige_formulaire($redirect); exit(); } /** * Initialiser la page pour l'affichage des progres de l'upgrade * uniquement si la page n'a pas deja ete initilalisee * * @param string $installee * @param string $meta * @param string $table * @return */ function maj_debut_page($installee,$meta,$table){ static $done = false; if ($done) return; include_spip('inc/minipres'); @ini_set("zlib.output_compression","0"); // pour permettre l'affichage au fur et a mesure $timeout = _UPGRADE_TIME_OUT*2; $titre = _T('titre_page_upgrade'); $balise_img = charger_filtre('balise_img'); $titre .= $balise_img(chemin_image('searching.gif')); echo ( install_debut_html($titre)); // script de rechargement auto sur timeout $redirect = generer_url_ecrire('upgrade',"reinstall=$installee&meta=$meta&table=$table",true); echo http_script("window.setTimeout('location.href=\"".$redirect."\";',".($timeout*1000).")"); echo "<div style='text-align: left'>\n"; ob_flush();flush(); $done = true; } define('_UPGRADE_TIME_OUT', 20); /** * A partir des > 1.926 (i.e SPIP > 1.9.2), cette fonction gere les MAJ. * Se relancer soi-meme pour eviter l'interruption pendant une operation SQL * (qu'on espere pas trop longue chacune) * evidemment en ecrivant dans la meta a quel numero on en est. * * Cette fonction peut servir aux plugins qui doivent donner comme arguments: * 1. le numero de version courant (numero de version 1.2.3 ou entier) * 2. le numero de version a atteindre (numero de version 1.2.3 ou entier) * 3. le tableau des instructions de mise a jour a executer * Pour profiter du mecanisme de reprise sur interruption il faut de plus * 4. le nom de la meta permettant de retrouver tout ca * 5. la table des meta ou elle se trouve ($table_prefix . '_meta' par defaut) * (cf debut de fichier) * en cas d'echec, cette fonction retourne un tableau (etape,sous-etape) * sinon elle retourne un tableau vide * * les fonctions sql_xx appelees lors des maj sont supposees atomiques et ne sont pas relancees * en cas de timeout * mais les fonctions specifiques sont relancees jusqu'a ce qu'elles finissent * elles doivent donc s'assurer de progresser a chaque reprise * * http://doc.spip.org/@maj_while * * @param $installee * @param $cible * @param $maj * @param string $meta * @param string $table * @param string $redirect * @param bool $debut_page * @return array */ function maj_while($installee, $cible, $maj, $meta='', $table='meta', $redirect='', $debut_page = false) { # inclusions pour que les procedures d'upgrade disposent des fonctions de base include_spip('base/create'); include_spip('base/abstract_sql'); $trouver_table = charger_fonction('trouver_table','base'); include_spip('inc/plugin'); // pour spip_version_compare $n = 0; $time = time(); // definir le timeout qui peut etre utilise dans les fonctions // de maj qui durent trop longtemps define('_TIME_OUT',$time+_UPGRADE_TIME_OUT); reset($maj); while (list($v,)=each($maj)) { // si une maj pour cette version if ($v=='init' OR (spip_version_compare($v,$installee,'>') AND spip_version_compare($v,$cible,'<='))) { if ($debut_page) maj_debut_page($v,$meta,$table); echo "MAJ $v"; $etape = serie_alter($v, $maj[$v], $meta, $table, $redirect); $trouver_table(''); // vider le cache des descriptions de table # echec sur une etape en cours ? # on sort if ($etape) return array($v, $etape); $n = time() - $time; spip_log( "$table $meta: $v en $n secondes",'maj.'._LOG_INFO_IMPORTANTE); if ($meta) ecrire_meta($meta, $installee=$v,'oui', $table); echo "<br />"; } if (time() >= _TIME_OUT) { relance_maj($meta,$table,$redirect); } } $trouver_table(''); // vider le cache des descriptions de table // indispensable pour les chgt de versions qui n'ecrivent pas en base // tant pis pour la redondance eventuelle avec ci-dessus if ($meta) ecrire_meta($meta, $cible,'oui',$table); spip_log( "MAJ terminee. $meta: $installee",'maj.'._LOG_INFO_IMPORTANTE); return array(); } /** * Appliquer une serie de chgt qui risquent de partir en timeout * (Alter cree une copie temporaire d'une table, c'est lourd) * * http://doc.spip.org/@serie_alter * * @param string $serie * numero de version upgrade * @param array $q * tableau des operations pour cette version * @param string $meta * nom de la meta qui contient le numero de version * @param string $table * nom de la table meta * @param string $redirect * url de redirection en cas d'interruption * @return int */ function serie_alter($serie, $q = array(), $meta='', $table='meta', $redirect='') { $meta2 = $meta . '_maj_' . $serie; $etape = intval(@$GLOBALS[$table][$meta2]); foreach ($q as $i => $r) { if ($i >= $etape) { $msg = "maj $table $meta2 etape $i"; if (is_array($r) AND function_exists($f = array_shift($r))) { spip_log( "$msg: $f " . join(',',$r),'maj.'._LOG_INFO_IMPORTANTE); // pour les fonctions atomiques sql_xx // on enregistre le meta avant de lancer la fonction, // de maniere a eviter de boucler sur timeout // mais pour les fonctions complexes, // il faut les rejouer jusqu'a achevement. // C'est a elle d'assurer qu'elles progressent a chaque rappel if (strncmp($f,"sql_",4)==0) ecrire_meta($meta2, $i+1, 'non', $table); echo " <span title='$i'>.</span>"; call_user_func_array($f, $r); // si temps imparti depasse, on relance sans ecrire en meta // car on est peut etre sorti sur timeout si c'est une fonction longue if (time() >= _TIME_OUT) { relance_maj($meta,$table,$redirect); } ecrire_meta($meta2, $i+1, 'non', $table); spip_log( "$meta2: ok", 'maj.'._LOG_INFO_IMPORTANTE); } else { if (!is_array($r)) spip_log("maj $i format incorrect","maj."._LOG_ERREUR); else spip_log("maj $i fonction $f non definie","maj."._LOG_ERREUR); // en cas d'erreur serieuse, on s'arrete // mais on permet de passer par dessus en rechargeant la page. return $i+1; } } } effacer_meta($meta2, $table); return 0; } // La fonction a appeler dans le tableau global $maj // quand on rajoute des types MIME. cf par exemple la 1.953 // http://doc.spip.org/@upgrade_types_documents function upgrade_types_documents() { if (include_spip('base/medias') AND function_exists('creer_base_types_doc')) creer_base_types_doc(); } // http://doc.spip.org/@upgrade_test function upgrade_test() { sql_drop_table("spip_test", true); sql_create("spip_test", array('a' => 'int')); sql_alter("TABLE spip_test ADD b INT"); sql_insertq('spip_test', array('b' => 1), array('field'=>array('b' => 'int'))); $result = sql_select('b', "spip_test"); // ne pas garder le resultat de la requete sinon sqlite3 // ne peut pas supprimer la table spip_test lors du sql_alter qui suit // car cette table serait alors 'verouillee' $result = $result?true:false; sql_alter("TABLE spip_test DROP b"); return $result; } // pour versions <= 1.926 // http://doc.spip.org/@maj_version function maj_version ($version, $test = true) { if ($test) { if ($version>=1.922) ecrire_meta('version_installee', $version, 'oui'); else { // on le fait manuellement, car ecrire_meta utilise le champs impt qui est absent sur les vieilles versions $GLOBALS['meta']['version_installee'] = $version; sql_updateq('spip_meta', array('valeur' => $version), "nom=" . sql_quote('version_installee') ); } spip_log( "mise a jour de la base en $version","maj."._LOG_INFO_IMPORTANTE); } else { echo _T('alerte_maj_impossible', array('version' => $version)); exit; } } // pour versions <= 1.926 // http://doc.spip.org/@upgrade_vers function upgrade_vers($version, $version_installee, $version_cible = 0){ return ($version_installee<$version AND (($version_cible>=$version) OR ($version_cible==0)) ); } ?> repair.php000066600000007474152502550120006554 0ustar00<?php /***************************************************************************\ * SPIP, Systeme de publication pour l'internet * * * * Copyright (c) 2001-2014 * * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James * * * * Ce programme est un logiciel libre distribue sous licence GNU/GPL. * * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. * \***************************************************************************/ if (!defined('_ECRIRE_INC_VERSION')) return; // http://doc.spip.org/@base_admin_repair_dist function base_repair_dist($titre='', $reprise='') { $res = admin_repair_tables(); if (!$res) { $res = "<div class='error'>"._T('avis_erreur_mysql').' '.sql_errno().': '.sql_error() ."</div>\n"; } else { include_spip('inc/rubriques'); calculer_rubriques(); propager_les_secteurs(); } include_spip('inc/minipres'); $res .= pipeline('base_admin_repair',$res); echo minipres(_T('texte_tentative_recuperation'), $res . generer_form_ecrire('accueil', '','',_T('public:accueil_site'))); } // http://doc.spip.org/@admin_repair_plat function admin_repair_plat(){ spip_log( "verification des documents joints", _LOG_INFO_IMPORTANTE); $out = ""; $repertoire = array(); include_spip('inc/getdocument'); $res = sql_select('*','spip_documents',"fichier REGEXP CONCAT('^',extension,'[^/\]') AND distant='non'"); while ($row=sql_fetch($res)){ $ext = $row['extension']; if (!$ext) { spip_log("document sans extension: " . $row['id_document'], _LOG_INFO_IMPORTANTE); continue; } if (!isset($repertoire[$ext])){ if (@file_exists($plat = _DIR_IMG. $ext .".plat")) spip_unlink($plat); $repertoire[$ext] = creer_repertoire_documents($ext); if (preg_match(',_$,',$repertoire[$ext])) $repertoire[$ext] = false; } if ($d=$repertoire[$ext]){ $d = substr($d,strlen(_DIR_IMG)); $src = $row['fichier']; $dest = $d . substr($src,strlen($d)); if (@copy(_DIR_IMG . $src, _DIR_IMG . $dest) AND file_exists(_DIR_IMG . $dest)) { sql_updateq('spip_documents',array('fichier'=>$dest),'id_document='.intval($row['id_document'])); spip_unlink(_DIR_IMG . $src); $out .= "$src => $dest<br />"; } } } return $out; } // http://doc.spip.org/@admin_repair_tables function admin_repair_tables() { $repair = sql_repair('repair', NULL, 'continue'); // recreer les tables manquantes eventuelles include_spip('base/create'); creer_base(); $connexion = $GLOBALS['connexions'][0]; $prefixe = $connexion['prefixe']; $res1 = sql_showbase(); $res = ""; if ($res1) { while ($r = sql_fetch($res1)) { $tab = array_shift($r); $class = ""; $m = "<strong>$tab</strong> "; spip_log("Repare $tab", _LOG_INFO_IMPORTANTE); // supprimer la meta avant de lancer la reparation // car le repair peut etre long ; on ne veut pas boucler effacer_meta('admin_repair'); if ($repair){ $result_repair = sql_repair($tab); if (!$result_repair) return false; } // essayer de maj la table (creation de champs manquants) maj_tables($tab); $count = sql_countsel($tab); if ($count>1) $m .= "("._T('texte_compte_elements', array('count' => $count)).")\n"; else if ($count==1) $m .= "("._T('texte_compte_element', array('count' => $count)).")\n"; else $m .= "("._T('texte_vide').")\n"; if ($result_repair AND $msg = join(" ", sql_fetch($result_repair)) . ' ' AND strpos($msg, ' OK ')==FALSE){ $class = " class='notice'"; $m .= "<br /><tt>".spip_htmlentities($msg)."</tt>\n"; } else $m .= " "._T('texte_table_ok'); $res .="<div$class>$m</div>"; } } return $res; } ?> dump.php000066600000061404152502550120006230 0ustar00<?php /***************************************************************************\ * SPIP, Systeme de publication pour l'internet * * * * Copyright (c) 2001-2014 * * 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. * \***************************************************************************/ /** * * Fonctions de base pour la sauvegarde * Boite a outil commune, sans prejuger de la methode de sauvegarde * */ if (!defined('_ECRIRE_INC_VERSION')) return; define('_VERSION_ARCHIVE', '1.3'); include_spip('base/serial'); include_spip('base/auxiliaires'); include_spip('public/interfaces'); // pour table_jointures // NB: Ce fichier peut ajouter des tables (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); } function base_dump_meta_name($rub){ return $meta = "status_dump_{$rub}_" . abs($GLOBALS['visiteur_session']['id_auteur']); } function base_dump_dir($meta){ include_spip('inc/documents'); // determine upload va aussi initialiser l'index "restreint" $maindir = determine_upload(); if (!$GLOBALS['visiteur_session']['restreint']) $maindir = _DIR_DUMP; $dir = sous_repertoire($maindir, $meta); return $dir; } /** * Lister toutes les tables d'un serveur * en excluant eventuellement une liste fournie * * @param string $serveur * @param array $tables * @param array $exclude * @param bool $affiche_vrai_prefixe * @return array */ function base_lister_toutes_tables($serveur='', $tables=array(), $exclude = array(),$affiche_vrai_prefixe=false) { spip_connect($serveur); $connexion = $GLOBALS['connexions'][$serveur ? $serveur : 0]; $prefixe = $connexion['prefixe']; $p = '/^' . $prefixe . '/'; $res = $tables; foreach(sql_alltable(null,$serveur) as $t) { if (preg_match($p, $t)) { $t1 = preg_replace($p, 'spip', $t); if (!in_array($t1, $tables) AND !in_array($t1, $exclude)) $res[]= ($affiche_vrai_prefixe?$t:$t1); } } sort($res); return $res; } /** * Retrouver le prefixe des tables * @param string $serveur * @return string */ function base_prefixe_tables($serveur=''){ spip_connect($serveur); $connexion = $GLOBALS['connexions'][$serveur ? $serveur : 0]; $prefixe = $connexion['prefixe']; return $prefixe; } /** * Fabrique la liste a cocher des tables a traiter (copie, delete, sauvegarde) * * @param string $name * @param array $tables * @param array $exclude * @param array|null $post * @param string $serveur * @return array */ function base_saisie_tables($name, $tables, $exclude = array(), $post=null, $serveur='') { include_spip('inc/filtres'); $res = array(); foreach ($tables as $k => $t) { // par defaut tout est coche sauf les tables dans $exclude if (is_null($post)) $check = (in_array($t,$exclude)?false:true); // mais si on a poste une selection, la reprendre else $check = in_array($t,$post); $res[$k] = "<input type='checkbox' value='$t' name='$name" . "[]' id='$name$k'" . ($check ? " checked='checked'" : '') . "/>\n" . "<label for='$name$k'>".$t."</label>" . " (" . sinon(singulier_ou_pluriel(sql_countsel($t,'','','',$serveur), 'dump:une_donnee', 'dump:nb_donnees'),_T('dump:aucune_donnee')) . ")"; } return $res; } /** * Lister les tables non exportables par defaut * (liste completable par le pipeline lister_tables_noexport * * @staticvar array $EXPORT_tables_noexport * @return array */ function lister_tables_noexport(){ // par defaut tout est exporte sauf les tables ci-dessous static $EXPORT_tables_noexport = null; if (!is_null($EXPORT_tables_noexport)) return $EXPORT_tables_noexport; $EXPORT_tables_noexport= array( 'spip_caches', // plugin invalideur 'spip_resultats', // resultats de recherche ... c'est un cache ! 'spip_test', // c'est un test ! #'spip_referers', #'spip_referers_articles', #'spip_visites', #'spip_visites_articles', #'spip_versions', #'spip_versions_fragments' ); $EXPORT_tables_noexport = pipeline('lister_tables_noexport',$EXPORT_tables_noexport); return $EXPORT_tables_noexport; } /** * Lister les tables non importables par defaut * (liste completable par le pipeline lister_tables_noimport * * @staticvar array $IMPORT_tables_noimport * @return array */ function lister_tables_noimport(){ static $IMPORT_tables_noimport=null; if (!is_null($IMPORT_tables_noimport)) return $IMPORT_tables_noimport; $IMPORT_tables_noimport = array(); // par defaut tout est importe sauf les tables ci-dessous // possibiliter de definir cela tables via la meta // compatibilite if (isset($GLOBALS['meta']['IMPORT_tables_noimport'])){ $IMPORT_tables_noimport = unserialize($GLOBALS['meta']['IMPORT_tables_noimport']); if (!is_array($IMPORT_tables_noimport)){ include_spip('inc/meta'); effacer_meta('IMPORT_tables_noimport'); } } $IMPORT_tables_noimport = pipeline('lister_tables_noimport',$IMPORT_tables_noimport); return $IMPORT_tables_noimport; } /** * Lister les tables a ne pas effacer * (liste completable par le pipeline lister_tables_noerase * * @staticvar array $IMPORT_tables_noerase * @return array */ function lister_tables_noerase(){ static $IMPORT_tables_noerase=null; if (!is_null($IMPORT_tables_noerase)) return $IMPORT_tables_noerase; $IMPORT_tables_noerase = array( 'spip_meta', // par defaut on ne vide pas les stats, car elles ne figurent pas dans les dump // et le cas echeant, un bouton dans l'admin permet de les vider a la main... 'spip_referers', 'spip_referers_articles', 'spip_visites', 'spip_visites_articles' ); $IMPORT_tables_noerase = pipeline('lister_tables_noerase',$IMPORT_tables_noerase); return $IMPORT_tables_noerase; } /** * construction de la liste des tables pour le dump : * toutes les tables principales * + toutes les tables auxiliaires hors relations * + les tables relations dont les deux tables liees sont dans la liste * * @param array $exclude_tables * @return array */ function base_liste_table_for_dump($exclude_tables = array()){ $tables_for_dump = array(); $tables_pointees = array(); $tables = array(); $tables_principales = $GLOBALS['tables_principales']; $tables_auxiliaires = $GLOBALS['tables_auxiliaires']; $tables_jointures = $GLOBALS['tables_jointures']; if (include_spip('base/objets') AND function_exists('lister_tables_objets_sql')){ $tables = lister_tables_objets_sql(); foreach($tables as $t=>$infos){ if ($infos['principale'] AND !isset($tables_principales[$t])) $tables_principales[$t] = true; if (!$infos['principale'] AND !isset($tables_auxiliaires[$t])) $tables_auxiliaires[$t] = true; if (count($infos['tables_jointures'])) $tables_jointures[$t] = array_merge(isset($tables_jointures[$t])?$tables_jointures[$t]:array(),$infos['tables_jointures']); } } // on construit un index des tables de liens // pour les ajouter SI les deux tables qu'ils connectent sont sauvegardees $tables_for_link = array(); foreach($tables_jointures as $table => $liste_relations) if (is_array($liste_relations)) { $nom = $table; if (!isset($tables_auxiliaires[$nom])&&!isset($tables_principales[$nom])) $nom = "spip_$table"; if (isset($tables_auxiliaires[$nom])||isset($tables_principales[$nom])){ foreach($liste_relations as $link_table){ if (isset($tables_auxiliaires[$link_table])/*||isset($tables_principales[$link_table])*/){ $tables_for_link[$link_table][] = $nom; } else if (isset($tables_auxiliaires["spip_$link_table"])/*||isset($tables_principales["spip_$link_table"])*/){ $tables_for_link["spip_$link_table"][] = $nom; } } } } $liste_tables = array_merge(array_keys($tables_principales),array_keys($tables_auxiliaires),array_keys($tables)); foreach($liste_tables as $table){ // $name = preg_replace("{^spip_}","",$table); if ( !isset($tables_pointees[$table]) && !in_array($table,$exclude_tables) && !isset($tables_for_link[$table])){ $tables_for_dump[] = $table; $tables_pointees[$table] = 1; } } foreach ($tables_for_link as $link_table =>$liste){ $connecte = true; foreach($liste as $connect_table) if (!in_array($connect_table,$tables_for_dump)) $connecte = false; if ($connecte) # on ajoute les liaisons en premier # si une restauration est interrompue, # cela se verra mieux si il manque des objets # que des liens array_unshift($tables_for_dump,$link_table); } return array($tables_for_dump, $tables_for_link); } /** * Vider les tables de la base de destination * pour la copie dans une base * * peut etre utilise pour l'import depuis xml, * ou la copie de base a base (mysql<->sqlite par exemple) * * @param array $tables * @param array $exclure_tables * @param string $serveur */ function base_vider_tables_destination_copie($tables, $exclure_tables = array(), $serveur=''){ $trouver_table = charger_fonction('trouver_table', 'base'); spip_log('Vider '.count($tables) . " tables sur serveur '$serveur' : " . join(', ', $tables),'base.'._LOG_INFO_IMPORTANTE); foreach($tables as $table){ if (!in_array($table,$exclure_tables)){ // sur le serveur principal, il ne faut pas supprimer l'auteur loge ! if (($table!='spip_auteurs') OR $serveur!=''){ // regarder si il y a au moins un champ impt='non' $desc = $trouver_table($table,$serveur); if (isset($desc['field']['impt'])){ sql_delete($table, "impt='oui'", $serveur); } else{ sql_delete($table, "", $serveur); } } } } // sur le serveur principal, il ne faut pas supprimer l'auteur loge ! // Bidouille pour garder l'acces admin actuel pendant toute la restauration if ($serveur=='' AND in_array('spip_auteurs',$tables) AND !in_array('spip_auteurs',$exclure_tables)) { base_conserver_copieur(true, $serveur); sql_delete("spip_auteurs", "id_auteur>0",$serveur); } } /** * Conserver le copieur si besoin * @param bool $move * @param string $serveur * @return void */ function base_conserver_copieur($move = true,$serveur=''){ // s'asurer qu'on a pas deja fait la manip ! if ($GLOBALS['visiteur_session']['id_auteur']>0 AND sql_countsel("spip_auteurs", "id_auteur>0")) { spip_log('Conserver copieur '.$GLOBALS['visiteur_statut']['id_auteur'] . " dans id_auteur=".$GLOBALS['visiteur_statut']['id_auteur']." pour le serveur '$serveur'",'dump.'._LOG_INFO_IMPORTANTE); sql_delete("spip_auteurs", "id_auteur<0",$serveur); if ($move){ sql_updateq('spip_auteurs', array('id_auteur'=>-$GLOBALS['visiteur_session']['id_auteur']), "id_auteur=".intval($GLOBALS['visiteur_session']['id_auteur']),array(),$serveur); } else { $row = sql_fetsel('*','spip_auteurs','id_auteur='.$GLOBALS['visiteur_session']['id_auteur'],'','','','',$serveur); $row['id_auteur'] = -$GLOBALS['visiteur_session']['id_auteur']; sql_insertq('spip_auteurs',$row,array(),$serveur); } } } /** * Effacement de la bidouille ci-dessus * Toutefois si la table des auteurs ne contient plus qu'elle * c'est que la copie etait incomplete et on restaure le compte * pour garder la connection au site * * (mais il doit pas etre bien beau * et ca ne marche que si l'id_auteur est sur moins de 3 chiffres) * * @param string $serveur */ function base_detruire_copieur_si_besoin($serveur='') { // rien a faire si ce n'est pas le serveur principal ! if ($serveur=='') { if (sql_countsel("spip_auteurs", "id_auteur>0")) { spip_log("Detruire copieur id_auteur<0 pour le serveur '$serveur'",'dump.'._LOG_INFO_IMPORTANTE); sql_delete("spip_auteurs", "id_auteur<0", $serveur); } else { spip_log( "Restaurer copieur id_auteur<0 pour le serveur '$serveur' (aucun autre auteur en base)",'dump.'._LOG_INFO_IMPORTANTE); sql_update('spip_auteurs', array('id_auteur'=>'-id_auteur'), "id_auteur<0"); } } else spip_log("Pas de destruction copieur sur serveur '$serveur'",'dump.'._LOG_INFO_IMPORTANTE); } /** * Preparer la table dans la base de destination : * la droper si elle existe (sauf si auteurs ou meta sur le serveur principal) * la creer si necessaire, ou ajouter simplement les champs manquants * * @param string $table * @param array $desc * @param string $serveur_dest * @param bool $init * @return array */ function base_preparer_table_dest($table, $desc, $serveur_dest, $init=false) { $upgrade = false; // si la table existe et qu'on est a l'init, la dropper if ($desc_dest=sql_showtable($table,true,$serveur_dest) AND $init) { if ($serveur_dest=='' AND in_array($table,array('spip_meta','spip_auteurs'))) { // ne pas dropper auteurs et meta sur le serveur principal // faire un simple upgrade a la place // pour ajouter les champs manquants $upgrade = true; // coherence avec le drop sur les autres tables base_vider_tables_destination_copie(array($table),array(),$serveur_dest); if ($table=='spip_meta'){ // virer les version base qui vont venir avec l'import sql_delete($table, "nom like '%_base_version'",$serveur_dest); // hum casse la base si pas version_installee a l'import ... sql_delete($table, "nom='version_installee'",$serveur_dest); } } else { sql_drop_table($table, '', $serveur_dest); spip_log( "drop table '$table' sur serveur '$serveur_dest'",'dump.'._LOG_INFO_IMPORTANTE); } $desc_dest = false; } // si la table n'existe pas dans la destination, la creer a l'identique ! if (!$desc_dest) { spip_log( "creation '$table' sur serveur '$serveur_dest'",'dump.'._LOG_INFO_IMPORTANTE); include_spip('base/create'); creer_ou_upgrader_table($table, $desc, 'auto', $upgrade,$serveur_dest); $desc_dest = sql_showtable($table,true,$serveur_dest); } if (!$desc_dest){ spip_log( "Erreur creation '$table' sur serveur '$serveur_dest'".var_export($desc,1),'dump.'._LOG_ERREUR); } return $desc_dest; } /** * Copier de base a base * * @param string $status_file * nom avec chemin complet du fichier ou est stocke le status courant * @param array $tables * liste des tables a copier * @param string $serveur_source * @param string $serveur_dest * @param array $options * parametres optionnels sous forme de tableau : * param string $callback_progression * fonction a appeler pour afficher la progression, avec les arguments (compteur,total,table) * param int $max_time * limite de temps au dela de laquelle sortir de la fonction proprement (de la forme time()+15) * param bool $drop_source * vider les tables sources apres copie * param array $no_erase_dest * liste des tables a ne pas vider systematiquement (ne seront videes que si existent dans la base source) * param array $where * liste optionnelle de condition where de selection des donnees pour chaque table * param string $racine_fonctions_dest * racine utilisee pour charger_fonction() des operations elementaires sur la base de destination. * Permet de deleguer vers une autre voie de communication. * Par defaut on utilise 'base', ce qui route vers les fonctions de ce fichier. Concerne : * - vider_tables_destination_copie * - preparer_table_dest * - detruire_copieur_si_besoin * - inserer_copie * param array $fonction_base_inserer * fonction d'insertion en base. Par defaut "inserer_copie" qui fait un insertq a l'identique. * Attention, la fonction appelee est prefixee par $racine_fonctions_dest via un charger_fonction() * Peut etre personalisee pour filtrer, renumeroter.... * param array $desc_tables_dest * description des tables de destination a utiliser de preference a la description de la table source * param int data_pool * nombre de ko de donnees a envoyer d'un coup en insertion dans la table cible (par defaut 1) * permet des envois groupes pour plus de rapidite, notamment si l'insertion est distante * * @return bool */ function base_copier_tables($status_file, $tables, $serveur_source, $serveur_dest, $options=array()){ $callback_progression = isset($options['callback_progression'])?$options['callback_progression']:''; $max_time = isset($options['max_time'])?$options['max_time']:0; $drop_source = isset($options['drop_source'])?$options['drop_source']:false; $no_erase_dest = isset($options['no_erase_dest'])?$options['no_erase_dest']:array(); $where = isset($options['where'])?$options['where']:array(); $fonction_base_inserer = isset($options['fonction_base_inserer'])?$options['fonction_base_inserer']:'inserer_copie'; $desc_tables_dest = isset($options['desc_tables_dest'])?$options['desc_tables_dest']:array(); $racine_fonctions = (isset($options['racine_fonctions_dest'])?$options['racine_fonctions_dest']:'base'); $data_pool = (isset($options['data_pool'])?$options['data_pool']:50*1024); spip_log( "Copier ".count($tables)." tables de '$serveur_source' vers '$serveur_dest'",'dump.'._LOG_INFO_IMPORTANTE); if (!$inserer_copie = charger_fonction($fonction_base_inserer,$racine_fonctions, true)) { spip_log( "Fonction '{$racine_fonctions}_$fonction_base_inserer' inconnue. Abandon",'dump.'._LOG_INFO_IMPORTANTE); return true; // echec mais on a fini, donc true } if (!$preparer_table_dest = charger_fonction('preparer_table_dest',$racine_fonctions, true)) { spip_log( "Fonction '{$racine_fonctions}_$preparer_table_dest' inconnue. Abandon",'dump.'._LOG_INFO_IMPORTANTE); return true; // echec mais on a fini, donc true } if (!lire_fichier($status_file, $status) OR !$status = unserialize($status)) $status = array(); $status['etape'] = 'basecopie'; // puis relister les tables a importer // et les vider si besoin, au moment du premier passage ici $initialisation_copie = (!isset($status["dump_status_copie"])) ? 0 : $status["dump_status_copie"]; // si init pas encore faite, vider les tables du serveur destination if (!$initialisation_copie) { if (!$vider_tables_destination_copie = charger_fonction('vider_tables_destination_copie',$racine_fonctions, true)) { spip_log( "Fonction '{$racine_fonctions}_vider_tables_destination_copie' inconnue. Abandon",'dump.'._LOG_INFO_IMPORTANTE); return true; // echec mais on a fini, donc true } $vider_tables_destination_copie($tables, $no_erase_dest, $serveur_dest); $status["dump_status_copie"]='ok'; ecrire_fichier($status_file,serialize($status)); } // les tables auteurs et meta doivent etre copiees en dernier ! if (in_array('spip_auteurs',$tables)){ $tables = array_diff($tables,array('spip_auteurs')); $tables[] = 'spip_auteurs'; } if (in_array('spip_meta',$tables)){ $tables = array_diff($tables,array('spip_meta')); $tables[] = 'spip_meta'; } spip_log( "Tables a copier :".implode(", ",$tables),'dump.'._LOG_INFO); $trouver_table = charger_fonction('trouver_table','base'); foreach ($tables as $table){ // si table commence par spip_ c'est une table SPIP, renommer le prefixe si besoin // sinon chercher la vraie table $desc_source = false; if (strncmp($table,"spip_",5)==0){ $desc_source = $trouver_table(preg_replace(",^spip_,","",$table), $serveur_source, true); } if (!$desc_source OR !isset($desc_source['exist']) OR !$desc_source['exist']) $desc_source = $trouver_table($table, $serveur_source, false); // verifier que la table est presente dans la base source if ($desc_source){ // $status['tables_copiees'][$table] contient l'avancement // de la copie pour la $table : 0 a N et -N quand elle est finie (-1 si vide et finie...) if (!isset($status['tables_copiees'][$table])) $status['tables_copiees'][$table] = 0; if (is_numeric($status['tables_copiees'][$table]) AND $status['tables_copiees'][$table]>=0 AND $desc_dest = $preparer_table_dest( $table, isset($desc_tables_dest[$table])?$desc_tables_dest[$table]:$desc_source, $serveur_dest, $status['tables_copiees'][$table] == 0)){ if ($callback_progression) $callback_progression($status['tables_copiees'][$table],0,$table); while (true) { $n = intval($status['tables_copiees'][$table]); // on copie par lot de 400 $res = sql_select('*',$table,isset($where[$table])?$where[$table]:'','','',"$n,400",'',$serveur_source); while ($row = sql_fetch($res,$serveur_source)){ $rows = array($row); // lire un groupe de donnees si demande en option // (permet un envoi par lot vers la destination) if ($data_pool>0){ $s = strlen(serialize($row)); while ($s<$data_pool AND $row = sql_fetch($res,$serveur_source)){ $s += strlen(serialize($row)); $rows[]= $row; } } // si l'enregistrement est deja en base, ca fera un echec ou un doublon // mais si ca renvoie false c'est une erreur fatale => abandon if ($inserer_copie($table,$rows,$desc_dest,$serveur_dest)===false) { // forcer la sortie, charge a l'appelant de gerer l'echec spip_log("Erreur fatale dans $inserer_copie table $table","dump"._LOG_ERREUR); $status['errors'][] = "Erreur fatale lors de la copie de la table $table"; ecrire_fichier($status_file,serialize($status)); // copie finie return true; } $status['tables_copiees'][$table]+=count($rows); if ($max_time AND time()>$max_time) break; } if ($n == $status['tables_copiees'][$table]) break; spip_log( "recopie $table ".$status['tables_copiees'][$table],'dump.'._LOG_INFO_IMPORTANTE); if ($callback_progression) $callback_progression($status['tables_copiees'][$table],0,$table); ecrire_fichier($status_file,serialize($status)); if ($max_time AND time()>$max_time) return false; // on a pas fini, mais le temps imparti est ecoule } if ($drop_source) { sql_drop_table($table,'',$serveur_source); spip_log( "drop $table sur serveur source '$serveur_source'",'dump.'._LOG_INFO_IMPORTANTE); } $status['tables_copiees'][$table]=($status['tables_copiees'][$table]?-$status['tables_copiees'][$table]:"zero"); ecrire_fichier($status_file,serialize($status)); spip_log( "tables_recopiees ".implode(',',$status['tables_copiees']),'dump.'._LOG_INFO); if ($callback_progression) $callback_progression($status['tables_copiees'][$table],$status['tables_copiees'][$table],$table); } else { if ($status['tables_copiees'][$table]<0) spip_log("Table $table deja copiee : ".$status['tables_copiees'][$table],"dump."._LOG_INFO); if ($callback_progression) $callback_progression(0,$status['tables_copiees'][$table],"$table".((is_numeric($status['tables_copiees'][$table]) AND $status['tables_copiees'][$table]>=0)?"[Echec]":"")); } } else { $status['errors'][] = "Impossible de lire la description de la table $table"; ecrire_fichier($status_file,serialize($status)); spip_log("Impossible de lire la description de la table $table","dump."._LOG_ERREUR); } } // si le nombre de tables envoyees n'est pas egal au nombre de tables demandees // abandonner if (count($status['tables_copiees'])<count($tables)){ spip_log("Nombre de tables copiees incorrect : ".count($status['tables_copiees'])."/".count($tables),"dump."._LOG_ERREUR); $status['errors'][] = "Nombre de tables copiees incorrect : ".count($status['tables_copiees'])."/".count($tables); ecrire_fichier($status_file,serialize($status)); } if ($detruire_copieur_si_besoin = charger_fonction('detruire_copieur_si_besoin',$racine_fonctions, true)) { $detruire_copieur_si_besoin($serveur_dest); } else { spip_log( "Fonction '{$racine_fonctions}_detruire_copieur_si_besoin' inconnue.",'dump.'._LOG_INFO_IMPORTANTE); } // OK, copie complete return true; } /** * fonction d'insertion en base lors de la copie de base a base * * @param string $table * @param array $rows * @param array $desc_dest * @param string $serveur_dest * @return int/bool */ function base_inserer_copie($table,$rows,$desc_dest,$serveur_dest){ // verifier le nombre d'insertion $nb1 = sql_countsel($table,'','','',$serveur_dest); // si l'enregistrement est deja en base, ca fera un echec ou un doublon $r = sql_insertq_multi($table,$rows,$desc_dest,$serveur_dest); $nb = sql_countsel($table,'','','',$serveur_dest); if ($nb-$nb1<count($rows)){ spip_log("base_inserer_copie : ".($nb-$nb1)." insertions au lieu de ".count($rows).". On retente 1 par 1","dump"._LOG_INFO_IMPORTANTE); foreach($rows as $row){ // si l'enregistrement est deja en base, ca fera un echec ou un doublon $r = sql_insertq($table,$row,$desc_dest,$serveur_dest); } // on reverifie le total $r = 0; $nb = sql_countsel($table,'','','',$serveur_dest); if ($nb-$nb1<count($rows)){ spip_log("base_inserer_copie : ".($nb-$nb1)." insertions au lieu de ".count($rows)." apres insertion 1 par 1","dump"._LOG_ERREUR); $r = false; } } return $r; } ?> serial.php000066600000002015152502550120006533 0ustar00<?php /***************************************************************************\ * SPIP, Systeme de publication pour l'internet * * * * Copyright (c) 2001-2014 * * 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. * \***************************************************************************/ /** * Déclare la liste des tables principales * * @todo * Nettoyages à faire dans le core : on ne devrait plus appeler * Ce fichier mais directement base/objets si nécessaire * * @package SPIP\SQL\Tables **/ if (!defined('_ECRIRE_INC_VERSION')) return; include_spip('base/objets'); lister_tables_objets_sql(); ?> connect_sql.php000066600000030612152502550120007570 0ustar00<?php /***************************************************************************\ * SPIP, Systeme de publication pour l'internet * * * * Copyright (c) 2001-2014 * * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James * * * * Ce programme est un logiciel libre distribue sous licence GNU/GPL. * * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. * \***************************************************************************/ if (!defined('_ECRIRE_INC_VERSION')) return; include_spip('base/objets'); // // Utilitaires indispensables autour des serveurs SQL // // API d'appel aux bases de donnees: // on charge le fichier config/$serveur ($serveur='connect' pour le principal) // qui est cense initaliser la connexion en appelant spip_connect_db // laquelle met dans la globale db_ok la description de la connexion // On la memorise dans un tableau pour permettre plusieurs serveurs. // A l'installation, il faut simuler l'existence de ce fichier // http://doc.spip.org/@spip_connect function spip_connect($serveur='', $version='') { global $connexions, $spip_sql_version; $serveur = !is_string($serveur) ? '' : strtolower($serveur); $index = $serveur ? $serveur : 0; if (!$version) $version = $spip_sql_version; if (isset($connexions[$index][$version])) return $connexions[$index]; include_spip('base/abstract_sql'); $install = (_request('exec') == 'install'); // Premiere connexion ? if (!($old = isset($connexions[$index]))) { $f = (!preg_match('/^[\w\.]*$/', $serveur)) ? '' // nom de serveur mal ecrit : ($serveur ? ( _DIR_CONNECT. $serveur . '.php') // serveur externe : (_FILE_CONNECT ? _FILE_CONNECT // serveur principal ok : ($install ? _FILE_CONNECT_TMP // init du serveur principal : ''))); // installation pas faite unset($GLOBALS['db_ok']); unset($GLOBALS['spip_connect_version']); if ($f) { if (is_readable($f)) { include($f); } elseif ($serveur AND !$install) { // chercher une declaration de serveur dans le path // qui pourra un jour servir a declarer des bases sqlite // par des plugins. Et sert aussi aux boucles POUR. find_in_path("$serveur.php",'connect/',true); } } if (!isset($GLOBALS['db_ok'])) { // fera mieux la prochaine fois if ($install) return false; if ($f AND is_readable($f)) spip_log("spip_connect: fichier de connexion '$f' OK.", _LOG_INFO_IMPORTANTE); else spip_log("spip_connect: fichier de connexion '$f' non trouve", _LOG_INFO_IMPORTANTE); spip_log("spip_connect: echec connexion ou serveur $index mal defini dans '$f'.", _LOG_HS); // ne plus reessayer si ce n'est pas l'install return $connexions[$index]=false; } $connexions[$index] = $GLOBALS['db_ok']; } // si la connexion a deja ete tentee mais a echoue, le dire! if (!$connexions[$index]) return false; // la connexion a reussi ou etait deja faite. // chargement de la version du jeu de fonctions // si pas dans le fichier par defaut $type = $GLOBALS['db_ok']['type']; $jeu = 'spip_' . $type .'_functions_' . $version; if (!isset($GLOBALS[$jeu])) { if (!find_in_path($type . '_' . $version . '.php', 'req/', true)){ spip_log("spip_connect: serveur $index version '$version' non defini pour '$type'", _LOG_HS); // ne plus reessayer return $connexions[$index][$version] = array(); } } $connexions[$index][$version] = $GLOBALS[$jeu]; if ($old) return $connexions[$index]; $connexions[$index]['spip_connect_version'] = isset($GLOBALS['spip_connect_version']) ? $GLOBALS['spip_connect_version'] : 0; // initialisation de l'alphabet utilise dans les connexions SQL // si l'installation l'a determine. // Celui du serveur principal l'impose aux serveurs secondaires // s'ils le connaissent if (!$serveur) { $charset = spip_connect_main($GLOBALS[$jeu]); if (!$charset) { unset($connexions[$index]); spip_log("spip_connect: absence de charset", _LOG_AVERTISSEMENT); return false; } } else { // spip_meta n'existe pas toujours dans la base // C'est le cas d'un dump sqlite par exemple if ($connexions[$index]['spip_connect_version'] AND sql_showtable('spip_meta', true, $serveur) AND $r = sql_getfetsel('valeur', 'spip_meta', "nom='charset_sql_connexion'",'','','','',$serveur)) $charset = $r; else $charset = -1; } if ($charset != -1) { $f = $GLOBALS[$jeu]['set_charset']; if (function_exists($f)) $f($charset, $serveur); } return $connexions[$index]; } function spip_sql_erreur($serveur='') { $connexion = spip_connect($serveur); $e = sql_errno($serveur); $t = (isset($connexion['type']) ? $connexion['type'] : 'sql'); $m = "Erreur $e de $t: " . sql_error($serveur) . "\n" . $connexion['last']; $f = $t . $serveur; spip_log($m, $f.'.'._LOG_ERREUR); } // Cette fonction ne doit etre appelee qu'a travers la fonction sql_serveur // definie dans base/abstract_sql // Elle existe en tant que gestionnaire de versions, // connue seulement des convertisseurs automatiques // http://doc.spip.org/@spip_connect_sql function spip_connect_sql($version, $ins='', $serveur='', $cont=false) { $desc = spip_connect($serveur, $version); if (function_exists($f = @$desc[$version][$ins])) return $f; if ($cont) return $desc; if ($ins) spip_log("Le serveur '$serveur' version $version n'a pas '$ins'", _LOG_ERREUR); include_spip('inc/minipres'); echo minipres(_T('info_travaux_titre'), _T('titre_probleme_technique')); exit; } /** * Fonction appelee par le fichier cree dans config/ a l'instal'. * Il contient un appel direct a cette fonction avec comme arguments * les identifants de connexion. * Si la connexion reussit, la globale db_ok memorise sa description. * C'est un tableau egalement retourne en valeur, pour les appels a l'install' * * http://doc.spip.org/@spip_connect_db * * @param string $host * @param string $port * @param string $login * @param string $pass * @param string $db * @param string $type * @param string $prefixe * @param string $auth * @return array */ function spip_connect_db($host, $port, $login, $pass, $db='', $type='mysql', $prefixe='', $auth='') { global $db_ok; // temps avant nouvelle tentative de connexion // suite a une connection echouee if (!defined('_CONNECT_RETRY_DELAY')) define('_CONNECT_RETRY_DELAY',30); $f = ""; // un fichier de identifiant par combinaison (type,host,port,db) // pour ne pas declarer tout indisponible d'un coup // si en cours d'installation ou si db=@test@ on ne pose rien // car c'est un test de connexion if (!defined('_ECRIRE_INSTALL') AND !$db=="@test@") $f = _DIR_TMP . $type . '.' . substr(md5($host.$port.$db),0,8) . '.out'; elseif ($db=='@test@') $db = ''; if ($f AND @file_exists($f) AND (time() - @filemtime($f) < _CONNECT_RETRY_DELAY)) { spip_log( "Echec : $f recent. Pas de tentative de connexion", _LOG_HS); return; } if (!$prefixe) $prefixe = isset($GLOBALS['table_prefix']) ? $GLOBALS['table_prefix'] : $db; $h = charger_fonction($type, 'req', true); if (!$h) { spip_log( "les requetes $type ne sont pas fournies", _LOG_HS); return; } if ($g = $h($host, $port, $login, $pass, $db, $prefixe)) { if (!is_array($auth)) { // compatibilite version 0.7 initiale $g['ldap'] = $auth; $auth = array('ldap' => $auth); } $g['authentification'] = $auth; $g['type'] = $type; return $db_ok = $g; } // En cas d'indisponibilite du serveur, eviter de le bombarder if ($f) { @touch($f); spip_log( "Echec connexion serveur $type : host[$host] port[$port] login[$login] base[$db]", $type.'.'._LOG_HS); } } // Premiere connexion au serveur principal: // retourner le charset donnee par la table principale // mais verifier que le fichier de connexion n'est pas trop vieux // Version courante = 0.7 // La version 0.7 indique un serveur d'authentification comme 8e arg // La version 0.6 indique le prefixe comme 7e arg // La version 0.5 indique le serveur comme 6e arg // // La version 0.0 (non numerotee) doit etre refaite par un admin // les autres fonctionnent toujours, meme si : // - la version 0.1 est moins performante que la 0.2 // - la 0.2 fait un include_ecrire('inc_db_mysql.php3'). // http://doc.spip.org/@spip_connect_main function spip_connect_main($connexion) { if ($GLOBALS['spip_connect_version']< 0.1 AND _DIR_RESTREINT){ include_spip('inc/headers'); redirige_url_ecrire('upgrade', 'reinstall=oui'); } if (!($f = $connexion['select'])) return false; // en cas d'erreur select retourne la requette (is_string=true donc) if (!$r = $f('valeur','spip_meta', "nom='charset_sql_connexion'") OR is_string($r)) return false; if (!($f = $connexion['fetch'])) return false; $r = $f($r); return ($r['valeur'] ? $r['valeur'] : -1); } // compatibilite function spip_connect_ldap($serveur='') { include_spip('auth/ldap'); return auth_ldap_connect($serveur); } // Echappement d'une valeur (num, string, array) sous forme de chaine PHP // pour un array(1,'a',"a'") renvoie la chaine "'1','a','a\''" // Usage sql un peu deprecie, a remplacer par sql_quote() // http://doc.spip.org/@_q function _q ($a) { return (is_numeric($a)) ? strval($a) : (!is_array($a) ? ("'" . addslashes($a) . "'") : join(",", array_map('_q', $a))); } // Recuperer le nom de la table de jointure xxxx sur l'objet yyyy // http://doc.spip.org/@table_jointure function table_jointure($x, $y) { $trouver_table = charger_fonction('trouver_table', 'base'); $xdesc = $trouver_table(table_objet($x)); $ydesc = $trouver_table(table_objet($y)); $ix = @$xdesc['key']["PRIMARY KEY"]; $iy = @$ydesc['key']["PRIMARY KEY"]; if ($table = $ydesc['tables_jointures'][$ix]) return $table; if ($table = $xdesc['tables_jointures'][$iy]) return $table; return ''; } /** * Echapper les textes entre ' ' ou " " d'une requete SQL * avant son pre-traitement * On renvoi la query sans textes et les textes separes, dans * leur ordre d'apparition dans la query * * @param string $query * @return array */ function query_echappe_textes($query){ static $codeEchappements = array("''"=>"\x1@##@\x1", "\'"=>"\x2@##@\x2", "\\\""=>"\x3@##@\x3"); $query = str_replace(array_keys($codeEchappements), array_values($codeEchappements), $query); if (preg_match_all("/((['])[^']*(\\2))|(([\"])[^\"]*(\\5))/S",$query,$textes)){ $textes = reset($textes); // indice 0 du match switch(count($textes)){ case 0:$replace=array();break; case 1:$replace=array('%1$s');break; case 2:$replace=array('%1$s','%2$s');break; case 3:$replace=array('%1$s','%2$s','%3$s');break; case 4:$replace=array('%1$s','%2$s','%3$s','%4$s');break; case 5:$replace=array('%1$s','%2$s','%3$s','%4$s','%5$s');break; default: $replace = range(1,count($textes)); $replace = '%'.implode('$s,%',$replace).'$s'; $replace = explode(',',$replace); break; } $query = str_replace($textes,$replace,$query); } else $textes = array(); return array($query, $textes); } /** * Reinjecter les textes d'une requete SQL a leur place initiale, * apres traitement de la requete * * @param string $query * @param array $textes * @return string */ function query_reinjecte_textes($query, $textes){ static $codeEchappements = array("''"=>"\x1@##@\x1", "\'"=>"\x2@##@\x2", "\\\""=>"\x3@##@\x3"); # debug de la substitution #if (($c1=substr_count($query,"%"))!=($c2=count($textes))){ # spip_log("$c1 ::". $query,"tradquery"._LOG_ERREUR); # spip_log("$c2 ::". var_export($textes,1),"tradquery"._LOG_ERREUR); # spip_log("ini ::". $qi,"tradquery"._LOG_ERREUR); #} switch (count($textes)){ case 0:break; case 1:$query=sprintf($query,$textes[0]);break; case 2:$query=sprintf($query,$textes[0],$textes[1]);break; case 3:$query=sprintf($query,$textes[0],$textes[1],$textes[2]);break; case 4:$query=sprintf($query,$textes[0],$textes[1],$textes[2],$textes[3]);break; case 5:$query=sprintf($query,$textes[0],$textes[1],$textes[2],$textes[3],$textes[4]);break; default: array_unshift($textes,$query); $query = call_user_func_array('sprintf',$textes); break; } $query = str_replace(array_values($codeEchappements), array_keys($codeEchappements), $query); return $query; } // Pour compatibilite. Ne plus utiliser. // http://doc.spip.org/@spip_query function spip_query($query, $serveur='') { global $spip_sql_version; $f = spip_connect_sql($spip_sql_version, 'query', $serveur, true); return function_exists($f) ? $f($query, $serveur) : false; } ?> abstract_sql.php000066600000123577152502550120007757 0ustar00<?php /* *************************************************************************\ * SPIP, Systeme de publication pour l'internet * * * * Copyright (c) 2001-2014 * * 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. * \***************************************************************************/ /** * Definition de l'API SQL * * Ce fichier definit la couche d'abstraction entre SPIP et ses serveurs SQL. * Cette version 1 est un ensemble de fonctions ecrites rapidement * pour generaliser le code strictement MySQL de SPIP <= 1.9.2 * Des retouches sont a prevoir apres l'experience des premiers portages. * Les symboles sql_* (constantes et nom de fonctions) sont reserves * a cette interface, sans quoi le gestionnaire de version dysfonctionnera. * * @package SPIP\SQL\API * @version 1 */ if (!defined('_ECRIRE_INC_VERSION')) return; /** Version de l'API SQL */ define('sql_ABSTRACT_VERSION', 1); include_spip('base/connect_sql'); /** * Charge le serveur de base de donnees * * Fonction principale. Elle charge l'interface au serveur de base de donnees * via la fonction spip_connect_version qui etablira la connexion au besoin. * Elle retourne la fonction produisant la requete SQL demandee * Erreur fatale si la fonctionnalite est absente sauf si le 3e arg <> false * * @internal Cette fonction de base est appelee par les autres fonctions sql_* * @param string $ins_sql * Instruction de l'API SQL demandee (insertq, update, select...) * @param string $serveur * Nom du connecteur ('' pour celui par defaut a l'installation de SPIP) * @param bool $continue * true pour ne pas generer d'erreur si le serveur SQL ne dispose pas de la fonction demandee * @return string|array * Nom de la fonction a appeler pour l'instruction demandee pour le type de serveur SQL correspondant au fichier de connexion. * Si l'instruction demandee n'existe pas, retourne la liste de toutes les instructions du serveur SQL avec $continue a true. * **/ function sql_serveur($ins_sql='', $serveur='', $continue=false) { static $sql_serveur = array(); if (!isset($sql_serveur[$serveur][$ins_sql])){ $f = spip_connect_sql(sql_ABSTRACT_VERSION, $ins_sql, $serveur, $continue); if (!is_string($f) OR !$f) return $f; $sql_serveur[$serveur][$ins_sql] = $f; } return $sql_serveur[$serveur][$ins_sql]; } /** * Demande si un charset est disponible * * Demande si un charset (tel que utf-8) est disponible * sur le gestionnaire de base de donnees de la connexion utilisee * * @api * @see sql_set_charset() pour utiliser un charset * * @param string $charset * Le charset souhaite * @param string $serveur * Le nom du connecteur * @param bool $option * Inutilise * @return string|bool * Retourne le nom du charset si effectivement trouve, sinon false. **/ function sql_get_charset($charset, $serveur='', $option=true){ // le nom http du charset differe parfois du nom SQL utf-8 ==> utf8 etc. $desc = sql_serveur('', $serveur, true,true); $desc = $desc[sql_ABSTRACT_VERSION]; $c = $desc['charsets'][$charset]; if ($c) { if (function_exists($f=@$desc['get_charset'])) if ($f($c, $serveur, $option!==false)) return $c; } spip_log( "SPIP ne connait pas les Charsets disponibles sur le serveur $serveur. Le serveur choisira seul.", _LOG_AVERTISSEMENT); return false; } /** * Regler le codage de connexion * * Affecte un charset (tel que utf-8) sur la connexion utilisee * avec le gestionnaire de base de donnees * * @api * @see sql_get_charset() pour tester l'utilisation d'un charset * * @param string $charset * Le charset souhaite * @param string $serveur * Le nom du connecteur * @param bool|string $option * Peut avoir 2 valeurs : * - true pour executer la requete. * - continue pour ne pas echouer en cas de serveur sql indisponible. * * @return bool * Retourne true si elle reussie. **/ function sql_set_charset($charset,$serveur='', $option=true){ $f = sql_serveur('set_charset', $serveur, $option==='continue' OR $option===false); if (!is_string($f) OR !$f) return false; return $f($charset, $serveur, $option!==false); } /** * Effectue une requete de selection * * Fonction de selection (SELECT), retournant la ressource interrogeable par sql_fetch. * * @api * @see sql_fetch() Pour boucler sur les resultats de cette fonction * * @param array|string $select * Liste des champs a recuperer (Select) * @param array|string $from * Tables a consulter (From) * @param array|string $where * Conditions a remplir (Where) * @param array|string $groupby * Critere de regroupement (Group by) * @param array|string $orderby * Tableau de classement (Order By) * @param string $limit * Critere de limite (Limit) * @param array $having * Tableau des des post-conditions a remplir (Having) * @param string $serveur * Le serveur sollicite (pour retrouver la connexion) * @param bool|string $option * Peut avoir 3 valeurs : * - false -> ne pas l'executer mais la retourner, * - continue -> ne pas echouer en cas de serveur sql indisponible, * - true|array -> executer la requete. * Le cas array est, pour une requete produite par le compilateur, * un tableau donnnant le contexte afin d'indiquer le lieu de l'erreur au besoin * * * @return mixed * Ressource SQL * - Ressource SQL pour sql_fetch, si la requete est correcte * - false en cas d'erreur * - Chaine contenant la requete avec $option=false * * Retourne false en cas d'erreur, apres l'avoir denoncee. * Les portages doivent retourner la requete elle-meme en cas d'erreur, * afin de disposer du texte brut. * **/ function sql_select ($select = array(), $from = array(), $where = array(), $groupby = array(), $orderby = array(), $limit = '', $having = array(), $serveur='', $option=true) { $f = sql_serveur('select', $serveur, $option==='continue' OR $option===false); if (!is_string($f) OR !$f) return false; $debug = (defined('_VAR_MODE') AND _VAR_MODE == 'debug'); if (($option !== false) AND !$debug) { $res = $f($select, $from, $where, $groupby, $orderby, $limit, $having, $serveur, is_array($option) ? true : $option); } else { $query = $f($select, $from, $where, $groupby, $orderby, $limit, $having, $serveur, false); if (!$option) return $query; // le debug, c'est pour ce qui a ete produit par le compilateur if (isset($GLOBALS['debug']['aucasou'])) { list($table, $id,) = $GLOBALS['debug']['aucasou']; $nom = $GLOBALS['debug_objets']['courant'] . $id; $GLOBALS['debug_objets']['requete'][$nom] = $query; } $res = $f($select, $from, $where, $groupby, $orderby, $limit, $having, $serveur, true); } // en cas d'erreur if (!is_string($res)) return $res; // denoncer l'erreur SQL dans sa version brute spip_sql_erreur($serveur); // idem dans sa version squelette (prefixe des tables non substitue) erreur_squelette(array(sql_errno($serveur), sql_error($serveur), $res), $option); return false; } /** * Recupere la syntaxe de la requete select sans l'executer * * Passe simplement $option a false au lieu de true * sans obliger a renseigner tous les arguments de sql_select. * Les autres parametres sont identiques. * * @api * @uses sql_select() * * @param array|string $select * Liste des champs a recuperer (Select) * @param array|string $from * Tables a consulter (From) * @param array|string $where * Conditions a remplir (Where) * @param array|string $groupby * Critere de regroupement (Group by) * @param array|string $orderby * Tableau de classement (Order By) * @param string $limit * Critere de limite (Limit) * @param array $having * Tableau des des post-conditions a remplir (Having) * @param string $serveur * Le serveur sollicite (pour retrouver la connexion) * * @return mixed * Chaine contenant la requete * ou false en cas d'erreur * **/ function sql_get_select($select = array(), $from = array(), $where = array(), $groupby = array(), $orderby = array(), $limit = '', $having = array(), $serveur='') { return sql_select ($select, $from, $where, $groupby, $orderby, $limit, $having, $serveur, false); } /** * Retourne le nombre de lignes d'une selection * * Ramene seulement et tout de suite le nombre de lignes * Pas de colonne ni de tri a donner donc. * * @api * * @param array|string $from * Tables a consulter (From) * @param array|string $where * Conditions a remplir (Where) * @param array|string $groupby * Critere de regroupement (Group by) * @param array $having * Tableau des des post-conditions a remplir (Having) * @param string $serveur * Le serveur sollicite (pour retrouver la connexion) * @param bool|string $option * Peut avoir 3 valeurs : * - false -> ne pas l'executer mais la retourner, * - continue -> ne pas echouer en cas de serveur sql indisponible, * - true -> executer la requete. * * @return int|bool * Nombre de lignes de resultat * ou false en cas d'erreur * **/ function sql_countsel($from = array(), $where = array(), $groupby = array(), $having = array(), $serveur='', $option=true) { $f = sql_serveur('countsel', $serveur, $option==='continue' OR $option===false); if (!is_string($f) OR !$f) return false; $r = $f($from, $where, $groupby, $having, $serveur, $option!==false); if ($r===false) spip_sql_erreur($serveur); return $r; } /** * Modifie la structure de la base de donnees * * Effectue une operation ALTER. * * @example * <code>sql_alter('DROP COLUMN supprimer');</code> * * @api * @param string $q * La requete a executer (sans la preceder de 'ALTER ') * @param string $serveur * Le serveur sollicite (pour retrouver la connexion) * @param bool|string $option * Peut avoir 2 valeurs : * - true -> executer la requete * - continue -> ne pas echouer en cas de serveur sql indisponible * @return mixed * 2 possibilites : * - Incertain en cas d'execution correcte de la requete * - false en cas de serveur indiponible ou d'erreur * Ce retour n'est pas pertinent pour savoir si l'operation est correctement realisee. **/ function sql_alter($q, $serveur='', $option=true) { $f = sql_serveur('alter', $serveur, $option==='continue' OR $option===false); if (!is_string($f) OR !$f) return false; $r = $f($q, $serveur, $option!==false); if ($r===false) spip_sql_erreur($serveur); return $r; } /** * Retourne un enregistrement d'une selection * * Retourne un resultat d'une ressource obtenue avec sql_select() * * @api * @param mixed * Ressource retournee par sql_select() * @param string $serveur * Le nom du connecteur * @param bool|string $option * Peut avoir 2 valeurs : * - true -> executer la requete * - continue -> ne pas echouer en cas de serveur sql indisponible * * @return array * Tableau de cles (colonnes SQL ou alias) / valeurs (valeurs dans la colonne de la table ou calculee) * presentant une ligne de resultat d'une selection */ function sql_fetch($res, $serveur='', $option=true) { $f = sql_serveur('fetch', $serveur, $option==='continue' OR $option===false); if (!is_string($f) OR !$f) return false; return $f($res, NULL, $serveur, $option!==false); } /** * Retourne tous les enregistrements d'une selection * * Retourne tous les resultats d'une ressource obtenue avec sql_select() * dans un tableau * * @api * @param mixed * Ressource retournee par sql_select() * @param string $serveur * Le nom du connecteur * @param bool|string $option * Peut avoir 2 valeurs : * - true -> executer la requete * - continue -> ne pas echouer en cas de serveur sql indisponible * * @return array * Tableau contenant les enregistrements. * Chaque entree du tableau est un autre tableau * de cles (colonnes SQL ou alias) / valeurs (valeurs dans la colonne de la table ou calculee) * presentant une ligne de resultat d'une selection */ function sql_fetch_all($res, $serveur='', $option=true){ $rows = array(); if (!$res) return $rows; $f = sql_serveur('fetch', $serveur, $option==='continue' OR $option===false); if (!is_string($f) OR !$f) return array(); while ($r = $f($res, NULL, $serveur, $option!==false)) $rows[] = $r; sql_free($res, $serveur); return $rows; } /** * Deplace le pointeur d'une ressource de selection * * Deplace le pointeur sur un numero de ligne precise * sur une ressource issue de sql_select, afin que * le prochain sql_fetch recupere cette ligne. * * @api * @see sql_skip() Pour sauter des enregistrements * * @param mixed $res * Ressource issue de sql_select * @param int $row_number * Numero de ligne sur laquelle placer le pointeur * @param string $serveur * Le nom du connecteur * @param bool|string $option * Peut avoir 2 valeurs : * - true -> executer la requete * - continue -> ne pas echouer en cas de serveur sql indisponible * * @return bool * Operation effectuee (true), sinon false. **/ function sql_seek($res, $row_number, $serveur='', $option=true) { $f = sql_serveur('seek', $serveur, $option==='continue' OR $option===false); if (!is_string($f) OR !$f) return false; $r = $f($res, $row_number, $serveur, $option!==false); if ($r===false) spip_sql_erreur($serveur); return $r; } /** * Liste des bases de donnees accessibles * * Retourne un tableau du nom de toutes les bases de donnees * accessibles avec les permissions de l'utilisateur SQL * de cette connexion. * Attention on n'a pas toujours les droits ! * * @api * @param string $serveur * Nom du connecteur * @param bool|string $option * Peut avoir 2 valeurs : * - true -> executer la requete * - continue -> ne pas echouer en cas de serveur sql indisponible * * @return array|bool * Tableau contenant chaque nom de base de donnees. * False en cas d'erreur. **/ function sql_listdbs($serveur='', $option=true) { $f = sql_serveur('listdbs', $serveur, $option==='continue' OR $option===false); if (!is_string($f) OR !$f) return false; $r = $f($serveur); if ($r===false) spip_sql_erreur($serveur); return $r; } /** * Demande d'utiliser d'une base de donnees * * @api * @param string $nom * Nom de la base a utiliser * @param string $serveur * Nom du connecteur * @param bool|string $option * Peut avoir 2 valeurs : * - true -> executer la requete * - continue -> ne pas echouer en cas de serveur sql indisponible * * @return bool|string * True ou nom de la base en cas de success. * False en cas d'erreur. **/ function sql_selectdb($nom, $serveur='', $option=true) { $f = sql_serveur('selectdb', $serveur, $option==='continue' OR $option===false); if (!is_string($f) OR !$f) return false; $r = $f($nom, $serveur, $option!==false); if ($r===false) spip_sql_erreur($serveur); return $r; } // http://doc.spip.org/@sql_count function sql_count($res, $serveur='', $option=true) { $f = sql_serveur('count', $serveur, $option==='continue' OR $option===false); if (!is_string($f) OR !$f) return false; $r = $f($res, $serveur, $option!==false); if ($r===false) spip_sql_erreur($serveur); return $r; } // http://doc.spip.org/@sql_free function sql_free($res, $serveur='', $option=true) { $f = sql_serveur('free', $serveur, $option==='continue' OR $option===false); if (!is_string($f) OR !$f) return false; return $f($res); } // Cette fonction ne garantit pas une portabilite totale // ===> lui preferer la suivante. // Elle est fournie pour permettre l'actualisation de vieux codes // par un Sed brutal qui peut donner des resultats provisoirement acceptables // http://doc.spip.org/@sql_insert function sql_insert($table, $noms, $valeurs, $desc=array(), $serveur='', $option=true) { $f = sql_serveur('insert', $serveur, $option==='continue' OR $option===false); if (!is_string($f) OR !$f) return false; $r = $f($table, $noms, $valeurs, $desc, $serveur, $option!==false); if ($r === false) spip_sql_erreur($serveur); return $r; } // http://doc.spip.org/@sql_insertq function sql_insertq($table, $couples=array(), $desc=array(), $serveur='', $option=true) { $f = sql_serveur('insertq', $serveur, $option==='continue' OR $option===false); if (!is_string($f) OR !$f) return false; $r = $f($table, $couples, $desc, $serveur, $option!==false); if ($r === false) spip_sql_erreur($serveur); return $r; } // http://doc.spip.org/@sql_insertq_multi function sql_insertq_multi($table, $couples=array(), $desc=array(), $serveur='', $option=true) { $f = sql_serveur('insertq_multi', $serveur, $option==='continue' OR $option===false); if (!is_string($f) OR !$f) return false; $r = $f($table, $couples, $desc, $serveur, $option!==false); if ($r === false) spip_sql_erreur($serveur); return $r; } // http://doc.spip.org/@sql_update function sql_update($table, $exp, $where='', $desc=array(), $serveur='', $option=true) { $f = sql_serveur('update', $serveur, $option==='continue' OR $option===false); if (!is_string($f) OR !$f) return false; $r = $f($table, $exp, $where, $desc, $serveur, $option!==false); if ($r === false) spip_sql_erreur($serveur); return $r; } // Update est presque toujours appelee sur des constantes ou des dates // Cette fonction est donc plus utile que la precedente,d'autant qu'elle // permet de gerer les differences de representation des constantes. // http://doc.spip.org/@sql_updateq function sql_updateq($table, $exp, $where='', $desc=array(), $serveur='', $option=true) { $f = sql_serveur('updateq', $serveur, $option==='continue' OR $option===false); if (!is_string($f) OR !$f) return false; $r = $f($table, $exp, $where, $desc, $serveur, $option!==false); if ($r === false) spip_sql_erreur($serveur); return $r; } // http://doc.spip.org/@sql_delete function sql_delete($table, $where='', $serveur='', $option=true) { $f = sql_serveur('delete', $serveur, $option==='continue' OR $option===false); if (!is_string($f) OR !$f) return false; $r = $f($table, $where, $serveur, $option!==false); if ($r === false) spip_sql_erreur($serveur); return $r; } // http://doc.spip.org/@sql_replace function sql_replace($table, $couples, $desc=array(), $serveur='', $option=true) { $f = sql_serveur('replace', $serveur, $option==='continue' OR $option===false); if (!is_string($f) OR !$f) return false; $r = $f($table, $couples, $desc, $serveur, $option!==false); if ($r === false) spip_sql_erreur($serveur); return $r; } // http://doc.spip.org/@sql_replace_multi function sql_replace_multi($table, $tab_couples, $desc=array(), $serveur='', $option=true) { $f = sql_serveur('replace_multi', $serveur, $option==='continue' OR $option===false); if (!is_string($f) OR !$f) return false; $r = $f($table, $tab_couples, $desc, $serveur, $option!==false); if ($r === false) spip_sql_erreur($serveur); return $r; } // http://doc.spip.org/@sql_drop_table function sql_drop_table($table, $exist='', $serveur='', $option=true) { $f = sql_serveur('drop_table', $serveur, $option==='continue' OR $option===false); if (!is_string($f) OR !$f) return false; $r = $f($table, $exist, $serveur, $option!==false); if ($r === false) spip_sql_erreur($serveur); return $r; } // supprimer une vue sql // http://doc.spip.org/@sql_drop_view function sql_drop_view($table, $exist='', $serveur='', $option=true) { $f = sql_serveur('drop_view', $serveur, $option==='continue' OR $option===false); if (!is_string($f) OR !$f) return false; $r = $f($table, $exist, $serveur, $option!==false); if ($r === false) spip_sql_erreur($serveur); return $r; } /** * Retourne une ressource de la liste des tables de la base de données * * @api * @param string $spip * Filtre sur tables retournées * - NULL : retourne les tables SPIP uniquement (tables préfixées avec le préfixe de la connexion) * - '%' : retourne toutes les tables de la base * @param string $serveur * Le nom du connecteur * @param bool|string $option * Peut avoir 3 valeurs : * - false -> ne pas l'executer mais la retourner, * - continue -> ne pas echouer en cas de serveur sql indisponible, * - true -> executer la requete. * @return ressource * Ressource à utiliser avec sql_fetch() **/ function sql_showbase($spip=NULL, $serveur='', $option=true) { $f = sql_serveur('showbase', $serveur, $option==='continue' OR $option===false); if (!is_string($f) OR !$f) return false; // la globale n'est remplie qu'apres l'appel de sql_serveur. if ($spip == NULL){ $connexion = $GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0]; $spip = $connexion['prefixe'] . '\_%'; } return $f($spip, $serveur, $option!==false); } /** * Retourne la liste des tables SQL * * @api * @uses sql_showbase() * @param string $spip * Filtre sur tables retournées * - NULL : retourne les tables SPIP uniquement (tables préfixées avec le préfixe de la connexion) * - '%' : retourne toutes les tables de la base * @param string $serveur * Le nom du connecteur * @param bool|string $option * Peut avoir 3 valeurs : * - false -> ne pas l'executer mais la retourner, * - continue -> ne pas echouer en cas de serveur sql indisponible, * - true -> executer la requete. * @return array * Liste des tables SQL **/ function sql_alltable($spip=NULL, $serveur='', $option=true) { $q = sql_showbase($spip, $serveur, $option); $r = array(); if ($q) while ($t = sql_fetch($q, $serveur)) { $r[] = array_shift($t);} return $r; } // http://doc.spip.org/@sql_showtable function sql_showtable($table, $table_spip = false, $serveur='', $option=true) { $f = sql_serveur('showtable', $serveur, $option==='continue' OR $option===false); if (!is_string($f) OR !$f) return false; // la globale n'est remplie qu'apres l'appel de sql_serveur. if ($table_spip){ $connexion = $GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0]; $prefixe = $connexion['prefixe']; $vraie_table = preg_replace('/^spip/', $prefixe, $table); } else $vraie_table = $table; $f = $f($vraie_table, $serveur, $option!==false); if (!$f) return array(); if (isset($GLOBALS['tables_principales'][$table]['join'])) $f['join'] = $GLOBALS['tables_principales'][$table]['join']; elseif (isset($GLOBALS['tables_auxiliaires'][$table]['join'])) $f['join'] = $GLOBALS['tables_auxiliaires'][$table]['join']; return $f; } // http://doc.spip.org/@sql_create function sql_create($nom, $champs, $cles=array(), $autoinc=false, $temporary=false, $serveur='', $option=true) { $f = sql_serveur('create', $serveur, $option==='continue' OR $option===false); if (!is_string($f) OR !$f) return false; $r = $f($nom, $champs, $cles, $autoinc, $temporary, $serveur, $option!==false); if ($r === false) spip_sql_erreur($serveur); return $r; } function sql_create_base($nom, $serveur='', $option=true) { $f = sql_serveur('create_base', $serveur, $option==='continue' OR $option===false); if (!is_string($f) OR !$f) return false; $r = $f($nom, $serveur, $option!==false); if ($r === false) spip_sql_erreur($serveur); return $r; } // Fonction pour creer une vue // nom : nom de la vue, // select_query : une requete select, idealement cree avec $req = sql_select() // (en mettant $option du sql_select a false pour recuperer la requete) // http://doc.spip.org/@sql_create_view function sql_create_view($nom, $select_query, $serveur='', $option=true) { $f = sql_serveur('create_view', $serveur, $option==='continue' OR $option===false); if (!is_string($f) OR !$f) return false; $r = $f($nom, $select_query, $serveur, $option!==false); if ($r === false) spip_sql_erreur($serveur); return $r; } // http://doc.spip.org/@sql_multi function sql_multi($sel, $lang, $serveur='', $option=true) { $f = sql_serveur('multi', $serveur, $option==='continue' OR $option===false); if (!is_string($f) OR !$f) return false; return $f($sel, $lang); } /** * Retourne la dernière erreur connue * * @api * @param string $serveur * Nom du connecteur * @return bool|string * Description de l'erreur * False si le serveur est indisponible */ function sql_error($serveur='') { $f = sql_serveur('error', $serveur, 'continue'); if (!is_string($f) OR !$f) return false; return $f('query inconnue', $serveur); } /** * Retourne le numéro de la derniere erreur connue * * @api * @param string $serveur * Nom du connecteur * @return bool|int * Numéro de l'erreur * False si le serveur est indisponible */ function sql_errno($serveur='') { $f = sql_serveur('errno', $serveur, 'continue'); if (!is_string($f) OR !$f) return false; return $f($serveur); } // http://doc.spip.org/@sql_explain function sql_explain($q, $serveur='', $option=true) { $f = sql_serveur('explain', $serveur, 'continue'); if (!is_string($f) OR !$f) return false; $r = $f($q, $serveur, $option!==false); if ($r === false) spip_sql_erreur($serveur); return $r; } // http://doc.spip.org/@sql_optimize function sql_optimize($table, $serveur='', $option=true) { $f = sql_serveur('optimize', $serveur, $option==='continue' OR $option===false); if (!is_string($f) OR !$f) return false; $r = $f($table, $serveur, $option!==false); if ($r === false) spip_sql_erreur($serveur); return $r; } // http://doc.spip.org/@sql_repair function sql_repair($table, $serveur='', $option=true) { $f = sql_serveur('repair', $serveur, $option==='continue' OR $option===false); if (!is_string($f) OR !$f) return false; $r = $f($table, $serveur, $option!==false); if ($r === false) spip_sql_erreur($serveur); return $r; } // Fonction la plus generale ... et la moins portable // A n'utiliser qu'en derniere extremite // http://doc.spip.org/@sql_query function sql_query($ins, $serveur='', $option=true) { $f = sql_serveur('query', $serveur, $option==='continue' OR $option===false); if (!is_string($f) OR !$f) return false; $r = $f($ins, $serveur, $option!==false); if ($r === false) spip_sql_erreur($serveur); return $r; } /** * Retourne la premiere ligne d'une selection * * Retourne la premiere ligne de resultat d'une selection * comme si l'on appelait successivement sql_select() puis sql_fetch() * * @example * <code> * $art = sql_fetsel(array('id_rubrique','id_secteur'), 'spip_articles', 'id_article='.sql_quote($id_article)); * $id_rubrique = $art['id_rubrique']; * </code> * * @api * @uses sql_select() * @uses sql_fetch() * * @param array|string $select * Liste des champs a recuperer (Select) * @param array|string $from * Tables a consulter (From) * @param array|string $where * Conditions a remplir (Where) * @param array|string $groupby * Critere de regroupement (Group by) * @param array|string $orderby * Tableau de classement (Order By) * @param string $limit * Critere de limite (Limit) * @param array $having * Tableau des des post-conditions a remplir (Having) * @param string $serveur * Le serveur sollicite (pour retrouver la connexion) * @param bool|string $option * Peut avoir 3 valeurs : * - true -> executer la requete. * - continue -> ne pas echouer en cas de serveur sql indisponible. * - false -> ne pas l'executer mais la retourner. * * @return array * Tableau de la premiere ligne de resultat de la selection * {@example * <code>array('id_rubrique' => 1, 'id_secteur' => 2)</code> * } * **/ function sql_fetsel($select = array(), $from = array(), $where = array(), $groupby = array(), $orderby = array(), $limit = '', $having = array(), $serveur='', $option=true) { $q = sql_select($select, $from, $where, $groupby, $orderby, $limit, $having, $serveur, $option); if ($option===false) return $q; if (!$q) return array(); $r = sql_fetch($q, $serveur, $option); sql_free($q, $serveur, $option); return $r; } /** * Retourne le tableau de toutes les lignes d'une selection * * Retourne toutes les lignes de resultat d'une selection * comme si l'on appelait successivement sql_select() puis while(sql_fetch()) * * @example * <code> * $rubs = sql_allfetsel('id_rubrique', 'spip_articles', 'id_secteur='.sql_quote($id_secteur)); * // $rubs = array(array('id_rubrique'=>1), array('id_rubrique'=>3, ...) * </code> * * @api * @uses sql_select() * @uses sql_fetch() * * @param array|string $select * Liste des champs a recuperer (Select) * @param array|string $from * Tables a consulter (From) * @param array|string $where * Conditions a remplir (Where) * @param array|string $groupby * Critere de regroupement (Group by) * @param array|string $orderby * Tableau de classement (Order By) * @param string $limit * Critere de limite (Limit) * @param array $having * Tableau des des post-conditions a remplir (Having) * @param string $serveur * Le serveur sollicite (pour retrouver la connexion) * @param bool|string $option * Peut avoir 3 valeurs : * - true -> executer la requete. * - continue -> ne pas echouer en cas de serveur sql indisponible. * - false -> ne pas l'executer mais la retourner. * * @return array * Tableau de toutes les lignes de resultat de la selection * Chaque entree contient un tableau des elements demandees dans le SELECT. * {@example * <code> * array( * array('id_rubrique' => 1, 'id_secteur' => 2) * array('id_rubrique' => 4, 'id_secteur' => 2) * ... * ) * </code> * } * **/ function sql_allfetsel($select = array(), $from = array(), $where = array(), $groupby = array(), $orderby = array(), $limit = '', $having = array(), $serveur='', $option=true) { $q = sql_select($select, $from, $where, $groupby, $orderby, $limit, $having, $serveur, $option); if ($option===false) return $q; return sql_fetch_all($q, $serveur, $option); } /** * Retourne un unique champ d'une selection * * Retourne dans la premiere ligne de resultat d'une selection * un unique champ demande * * @example * <code> * $id_rubrique = sql_getfetsel('id_rubrique', 'spip_articles', 'id_article='.sql_quote($id_article)); * </code> * * @api * @uses sql_fetsel() * * @param array|string $select * Liste des champs a recuperer (Select) * @param array|string $from * Tables a consulter (From) * @param array|string $where * Conditions a remplir (Where) * @param array|string $groupby * Critere de regroupement (Group by) * @param array|string $orderby * Tableau de classement (Order By) * @param string $limit * Critere de limite (Limit) * @param array $having * Tableau des des post-conditions a remplir (Having) * @param string $serveur * Le serveur sollicite (pour retrouver la connexion) * @param bool|string $option * Peut avoir 3 valeurs : * - true -> executer la requete. * - continue -> ne pas echouer en cas de serveur sql indisponible. * - false -> ne pas l'executer mais la retourner. * * @return mixed * Contenu de l'unique valeur demandee du premier enregistrement retourne * **/ function sql_getfetsel($select, $from = array(), $where = array(), $groupby = array(), $orderby = array(), $limit = '', $having = array(), $serveur='', $option=true) { if (preg_match('/\s+as\s+(\w+)$/i', $select, $c)) $id = $c[1]; elseif (!preg_match('/\W/', $select)) $id = $select; else {$id = 'n'; $select .= ' AS n';} $r = sql_fetsel($select, $from, $where, $groupby, $orderby, $limit, $having, $serveur, $option); if ($option===false) return $r; if (!$r) return NULL; return $r[$id]; } /** * Retourne le numero de version du serveur SQL * * @api * @param string $serveur * Nom du connecteur * @param bool|string $option * Peut avoir 2 valeurs : * - true pour executer la requete. * - continue pour ne pas echouer en cas de serveur sql indisponible. * * @return string * Numero de version du serveur SQL **/ function sql_version($serveur='', $option=true) { $row = sql_fetsel("version() AS n", '','','','','','',$serveur); return ($row['n']); } /** * Informe si le moteur SQL prefere utiliser des transactions * * Cette fonction experimentale est pour l'instant presente pour accelerer certaines * insertions multiples en SQLite, en les encadrant d'une transaction. * SQLite ne cree alors qu'un verrou pour l'ensemble des insertions * et non un pour chaque, ce qui accelere grandement le processus. * Evidemment, si une des insertions echoue, rien ne sera enregistre. * Pour ne pas perturber les autres moteurs, cette fonction permet * de verifier que le moteur prefere utiliser des transactions dans ce cas. * * @example * <code> * if (sql_preferer_transaction()) { * sql_demarrer_transaction(); * } * </code> * * @api * @see sql_demarrer_transaction() * @see sql_terminer_transaction() * * @param string $serveur * Nom du connecteur * @param bool|string $option * Peut avoir 2 valeurs : * - true pour executer la requete. * - continue pour ne pas echouer en cas de serveur sql indisponible. * * @return bool * Le serveur SQL prefere t'il des transactions pour les insertions multiples ? **/ function sql_preferer_transaction($serveur='', $option=true) { $f = sql_serveur('preferer_transaction', $serveur, 'continue'); if (!is_string($f) OR !$f) return false; $r = $f($serveur, $option!==false); if ($r === false) spip_sql_erreur($serveur); return $r; }; /** * Demarre une transaction * * @api * @see sql_terminer_transaction() Pour cloturer la transaction * * @param string $serveur * Nom du connecteur * @param bool|string $option * Peut avoir 3 valeurs : * - true pour executer la requete. * - continue pour ne pas echouer en cas de serveur sql indisponible. * - false pour obtenir le code de la requete * * @return bool * true si la transaction est demarree * false en cas d'erreur **/ function sql_demarrer_transaction($serveur='', $option=true) { $f = sql_serveur('demarrer_transaction', $serveur, 'continue'); if (!is_string($f) OR !$f) return false; $r = $f($serveur, $option!==false); if ($r === false) spip_sql_erreur($serveur); return $r; }; /** * Termine une transaction * * @api * @see sql_demarrer_transaction() Pour demarrer une transaction * * @param string $serveur * Nom du connecteur * @param bool|string $option * Peut avoir 3 valeurs : * - true pour executer la requete. * - continue pour ne pas echouer en cas de serveur sql indisponible. * - false pour obtenir le code de la requete * * @return bool * true si la transaction est demarree * false en cas d'erreur **/ function sql_terminer_transaction($serveur='', $option=true) { $f = sql_serveur('terminer_transaction', $serveur, 'continue'); if (!is_string($f) OR !$f) return false; $r = $f($serveur, $option!==false); if ($r === false) spip_sql_erreur($serveur); return $r; }; /** * Prepare une chaine hexadecimale * * Prend une chaine sur l'aphabet hexa * et retourne sa representation numerique attendue par le serveur SQL. * Par exemple : FF ==> 0xFF en MySQL mais x'FF' en PG * * @api * @param string $val * Chaine hexadecimale * @param string $serveur * Nom du connecteur * @param bool|string $option * Peut avoir 2 valeurs : * - true pour executer la demande. * - continue pour ne pas echouer en cas de serveur sql indisponible. * @return string * Retourne la valeur hexadecimale attendue par le serveur SQL **/ function sql_hex($val, $serveur='', $option=true) { $f = sql_serveur('hex', $serveur, $option==='continue' OR $option===false); if (!is_string($f) OR !$f) return false; return $f($val); } /** * Echapper du contenu * * Echappe du contenu selon ce qu'attend le type de serveur SQL * et en fonction du type de contenu. * * Cette fonction est automatiquement appelee par les fonctions sql_*q * tel que sql_instertq ou sql_updateq * * @api * @param string $val * Chaine a echapper * @param string $serveur * Nom du connecteur * @param string $type * Peut contenir une declaration de type de champ SQL * {@example <code>int NOT NULL</code>} qui sert alors aussi a calculer le type d'echappement * @return string * La chaine echappee **/ function sql_quote($val, $serveur='', $type='') { $f = sql_serveur('quote', $serveur, true); if (!is_string($f) OR !$f) $f = '_q'; return $f($val, $type); } function sql_date_proche($champ, $interval, $unite, $serveur='', $option=true) { $f = sql_serveur('date_proche', $serveur, true); if (!is_string($f) OR !$f) return false; return $f($champ, $interval, $unite); } /** * Retourne une expression IN pour le gestionnaire de base de données * * Retourne un code à insérer dans une requête SQL pour récupérer * les éléments d'une colonne qui appartiennent à une liste donnée * * @example * sql_in('id_rubrique', array(3,4,5)) * retourne approximativement «id_rubrique IN (3,4,5)» selon ce qu'attend * le gestionnaire de base de donnée du connecteur en cours. * * @api * @param string $val * Colonne SQL sur laquelle appliquer le test * @param string|array $valeurs * Liste des valeurs possibles (séparés par des virgules si string) * @param string $not * - '' sélectionne les éléments correspondant aux valeurs * - 'NOT' inverse en sélectionnant les éléments ne correspondant pas aux valeurs * @param string $serveur * Nom du connecteur * @param bool|string $option * Peut avoir 2 valeurs : * - continue -> ne pas echouer en cas de serveur sql indisponible * - true ou false -> retourne l'expression * @return string * Expression de requête SQL **/ function sql_in($val, $valeurs, $not='', $serveur='', $option=true) { if (is_array($valeurs)) { $f = sql_serveur('quote', $serveur, true); if (!is_string($f) OR !$f) return false; $valeurs = join(',', array_map($f, array_unique($valeurs))); } elseif (isset($valeurs[0]) AND $valeurs[0]===',') $valeurs = substr($valeurs,1); if (!strlen(trim($valeurs))) return ($not ? "0=0" : '0=1'); $f = sql_serveur('in', $serveur, $option==='continue' OR $option===false); if (!is_string($f) OR !$f) return false; return $f($val, $valeurs, $not, $serveur, $option!==false); } // Penser a dire dans la description du serveur // s'il accepte les requetes imbriquees afin d'optimiser ca // http://doc.spip.org/@sql_in_select function sql_in_select($in, $select, $from = array(), $where = array(), $groupby = array(), $orderby = array(), $limit = '', $having = array(), $serveur='') { $liste = array(); $res = sql_select($select, $from, $where, $groupby, $orderby, $limit, $having, $serveur); while ($r = sql_fetch($res)) {$liste[] = array_shift($r);} sql_free($res); return sql_in($in, $liste); } /** * Implementation securisee du saut en avant, * qui ne depend pas de la disponibilite de la fonction sql_seek * ne fait rien pour une valeur negative ou nulle de $saut * retourne la position apres le saut * * @see sql_seek() * * @param resource $res * Ressource issue d'une selection sql_select * @param int $pos * position courante * @param int $saut * saut demande * @param int $count * position maximale * (nombre de resultat de la requete OU position qu'on ne veut pas depasser) * @param string $serveur * Nom du connecteur * @param bool|string $option * Peut avoir 2 valeurs : * - true -> executer la requete * - continue -> ne pas echouer en cas de serveur sql indisponible * * @return int * Position apres le saut. */ function sql_skip($res, $pos, $saut, $count, $serveur='', $option=true){ // pas de saut en arriere qu'on ne sait pas faire sans sql_seek if (($saut=intval($saut))<=0) return $pos; $seek = $pos + $saut; // si le saut fait depasser le maxi, on libere la resource // et on sort if ($seek>=$count) {sql_free($res, $serveur, $option); return $count;} if (sql_seek($res, $seek)) $pos = $seek; else while ($pos<$seek AND sql_fetch($res, $serveur, $option)) $pos++; return $pos; } // http://doc.spip.org/@sql_test_int function sql_test_int($type, $serveur='', $option=true) { return preg_match('/^(TINYINT|SMALLINT|MEDIUMINT|INT|INTEGER|BIGINT)/i',trim($type)); } // http://doc.spip.org/@sql_test_date function sql_test_date($type, $serveur='', $option=true) { return preg_match('/^(DATE|DATETIME|TIMESTAMP|TIME)/i',trim($type)); } /** * Formate une date * * Formater une date Y-m-d H:i:s sans passer par mktime * qui ne sait pas gerer les dates < 1970 * * http://doc.spip.org/@format_mysql_date * * @param int $annee Annee * @param int $mois Numero du mois * @param int $jour Numero du jour dans le mois * @param int $h Heures * @param int $m Minutes * @param int $s Secondes * @param string $serveur * Le serveur sollicite (pour retrouver la connexion) * @return string * La date formatee */ function sql_format_date($annee=0, $mois=0, $jour=0, $h=0, $m=0, $s=0, $serveur=''){ $annee = sprintf("%04s",$annee); $mois = sprintf("%02s",$mois); if ($annee == "0000") $mois = 0; if ($mois == "00") $jour = 0; return sprintf("%04u",$annee) . '-' . sprintf("%02u",$mois) . '-' . sprintf("%02u",$jour) . ' ' . sprintf("%02u",$h) . ':' . sprintf("%02u",$m) . ':' . sprintf("%02u",$s); } /** * Retourne la description de la table SQL * * Retrouve la description de la table SQL en privilegiant * la structure reelle de la base de donnees. * En absence, ce qui arrive lors de l'installation, la fonction * s'appuie sur la declaration des tables SQL principales ou auxiliaires. * * @internal Cette fonction devrait disparaître * * @param string $nom * Nom de la table dont on souhait la description * @param string $serveur * Nom du connecteur * @return array|bool * Description de la table ou false si elle n'est pas trouvee ou declaree. **/ function description_table($nom, $serveur=''){ global $tables_principales, $tables_auxiliaires; static $trouver_table; /* toujours utiliser trouver_table qui renverra la description theorique car sinon on va se comporter differement selon que la table est declaree ou non */ if (!$trouver_table) $trouver_table = charger_fonction('trouver_table', 'base'); if ($desc = $trouver_table($nom, $serveur)) return $desc; // sauf a l'installation : include_spip('base/serial'); if (isset($tables_principales[$nom])) return $tables_principales[$nom]; include_spip('base/auxiliaires'); if (isset($tables_auxiliaires[$nom])) return $tables_auxiliaires[$nom]; return false; } ?> delete_all.php000066600000002654152502550120007357 0ustar00<?php /***************************************************************************\ * SPIP, Systeme de publication pour l'internet * * * * Copyright (c) 2001-2014 * * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James * * * * Ce programme est un logiciel libre distribue sous licence GNU/GPL. * * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. * \***************************************************************************/ if (!defined('_ECRIRE_INC_VERSION')) return; // http://doc.spip.org/@base_delete_all_dist function base_delete_all_dist($titre) { $delete = _request('delete'); $res = array(); if (is_array($delete)) { foreach ($delete as $table) { if (sql_drop_table($table)) $res[] = $table; else spip_log( "SPIP n'a pas pu detruire $table.", _LOG_ERREUR); } // un pipeline pour detruire les tables installees par les plugins pipeline('delete_tables', ''); spip_unlink(_FILE_CONNECT); spip_unlink(_FILE_CHMOD); spip_unlink(_FILE_META); spip_unlink(_ACCESS_FILE_NAME); spip_unlink(_CACHE_RUBRIQUES); } $d = count($delete); $r = count($res); spip_log("Tables detruites: $r sur $d: " . join(', ',$res), _LOG_INFO_IMPORTANTE); } ?> objets.php000066600000110504152502550120006545 0ustar00<?php /***************************************************************************\ * SPIP, Systeme de publication pour l'internet * * * * Copyright (c) 2001-2014 * * 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. * \***************************************************************************/ /** * Fonctions relatives aux objets éditoriaux et SQL * * @package SPIP\SQL\Tables **/ if (!defined('_ECRIRE_INC_VERSION')) return; /** * Merge dans un tableau une de ses clés avec une valeur * * @param array $table * Tableau dont on veut compléter une clé * @param string $index * Clé du tableau que l'on souhaite compléter * @param array $valeur * Sous tableau à merger dans la clé. * @return void **/ function array_set_merge(&$table,$index,$valeur){ if (!isset($table[$index])) $table[$index] = $valeur; else $table[$index] = array_merge($table[$index],$valeur); } /** * Lister les infos de toutes les tables sql declarées * * Si un argument est fourni, on ne renvoie que les infos de cette table. * Elle est auto-declarée si inconnue jusqu'alors. * * @api * @param string $table_sql * table_sql demandee explicitement * @param array $desc * description connue de la table sql demandee * @return array|bool */ function lister_tables_objets_sql($table_sql=null, $desc=array()){ static $deja_la = false; static $infos_tables = null; static $md5 = null; static $plugin_hash = null; // prealablement recuperer les tables_principales if (is_null($infos_tables) OR $plugin_hash!==_PLUGINS_HASH){ // pas de reentrance (cas base/serial) if ($deja_la) { spip_log ("Re-entrance anormale sur lister_tables_objets_sql :" . var_export(debug_backtrace(),true),_LOG_CRITIQUE); return ($table_sql==="::md5"?$md5:array()); } $deja_la = true; $plugin_hash = _PLUGINS_HASH; // avant de lancer les pipelines // recuperer les declarations explicites ancienne mode // qui servent a completer declarer_tables_objets_sql base_serial($GLOBALS['tables_principales']); base_auxiliaires($GLOBALS['tables_auxiliaires']); $infos_tables = array( 'spip_articles'=> array( 'page'=>'article', 'texte_retour' => 'icone_retour_article', 'texte_modifier' => 'icone_modifier_article', 'texte_creer' => 'icone_ecrire_article', 'texte_objets' => 'public:articles', 'texte_objet' => 'public:article', 'texte_signale_edition' => 'texte_travail_article', 'info_aucun_objet'=> 'info_aucun_article', 'info_1_objet' => 'info_1_article', 'info_nb_objets' => 'info_nb_articles', 'texte_logo_objet' => 'logo_article', 'texte_langue_objet' => 'titre_langue_article', 'texte_definir_comme_traduction_objet' => 'trad_lier', 'titre' => 'titre, lang', 'date' => 'date', 'principale' => 'oui', 'champs_editables' => array('surtitre', 'titre', 'soustitre', 'descriptif','nom_site', 'url_site', 'chapo', 'texte', 'ps','virtuel'), 'champs_versionnes' => array('id_rubrique', 'surtitre', 'titre', 'soustitre', 'jointure_auteurs', 'descriptif', 'nom_site', 'url_site', 'chapo', 'texte', 'ps'), 'field' => array( "id_article" => "bigint(21) NOT NULL", "surtitre" => "text DEFAULT '' NOT NULL", "titre" => "text DEFAULT '' NOT NULL", "soustitre" => "text DEFAULT '' NOT NULL", "id_rubrique" => "bigint(21) DEFAULT '0' NOT NULL", "descriptif" => "text DEFAULT '' NOT NULL", "chapo" => "mediumtext DEFAULT '' NOT NULL", "texte" => "longtext DEFAULT '' NOT NULL", "ps" => "mediumtext DEFAULT '' NOT NULL", "date" => "datetime DEFAULT '0000-00-00 00:00:00' NOT NULL", "statut" => "varchar(10) DEFAULT '0' NOT NULL", "id_secteur" => "bigint(21) DEFAULT '0' NOT NULL", "maj" => "TIMESTAMP", "export" => "VARCHAR(10) DEFAULT 'oui'", "date_redac" => "datetime DEFAULT '0000-00-00 00:00:00' NOT NULL", "visites" => "integer DEFAULT '0' NOT NULL", "referers" => "integer DEFAULT '0' NOT NULL", "popularite" => "DOUBLE DEFAULT '0' NOT NULL", "accepter_forum" => "CHAR(3) DEFAULT '' NOT NULL", "date_modif" => "datetime DEFAULT '0000-00-00 00:00:00' NOT NULL", "lang" => "VARCHAR(10) DEFAULT '' NOT NULL", "langue_choisie" => "VARCHAR(3) DEFAULT 'non'", "id_trad" => "bigint(21) DEFAULT '0' NOT NULL", "nom_site" => "tinytext DEFAULT '' NOT NULL", "url_site" => "VARCHAR(255) DEFAULT '' NOT NULL", "virtuel" => "VARCHAR(255) DEFAULT '' NOT NULL", ), 'key' => array( "PRIMARY KEY" => "id_article", "KEY id_rubrique" => "id_rubrique", "KEY id_secteur" => "id_secteur", "KEY id_trad" => "id_trad", "KEY lang" => "lang", "KEY statut" => "statut, date", ), 'join' => array( "id_article"=>"id_article", "id_rubrique"=>"id_rubrique" ), 'rechercher_champs' => array( 'surtitre' => 5, 'titre' => 8, 'soustitre' => 5, 'chapo' => 3, 'texte' => 1, 'ps' => 1, 'nom_site' => 1, 'url_site' => 1, 'descriptif' => 4 ), 'rechercher_jointures' => array( 'auteur' => array('nom' => 10), ), 'statut'=> array( array( 'champ' => 'statut', 'publie' => 'publie', 'previsu' => 'publie,prop,prepa/auteur', 'post_date' => 'date', 'exception' => 'statut' ) ), 'statut_titres' => array( 'prepa'=>'info_article_redaction', 'prop'=>'info_article_propose', 'publie'=>'info_article_publie', 'refuse'=>'info_article_refuse', 'poubelle'=>'info_article_supprime' ), 'statut_textes_instituer' => array( 'prepa' => 'texte_statut_en_cours_redaction', 'prop' => 'texte_statut_propose_evaluation', 'publie' => 'texte_statut_publie', 'refuse' => 'texte_statut_refuse', 'poubelle' => 'texte_statut_poubelle', ), 'texte_changer_statut' => 'texte_article_statut', 'aide_changer_statut' => 'artstatut', 'tables_jointures' => array( 'profondeur' => 'rubriques', #'id_auteur' => 'auteurs_liens' // declaration generique plus bas ), ), 'spip_auteurs' => array( 'page'=>'auteur', 'texte_retour' => 'icone_retour', 'texte_ajouter' => 'titre_ajouter_un_auteur', 'texte_modifier' => 'admin_modifier_auteur', 'texte_objets' => 'icone_auteurs', 'texte_objet' => 'public:auteur', 'info_aucun_objet'=> 'info_aucun_auteur', 'info_1_objet' => 'info_1_auteur', 'info_nb_objets' => 'info_nb_auteurs', 'texte_logo_objet' => 'logo_auteur', 'texte_creer_associer' => 'creer_et_associer_un_auteur', 'titre' => "nom AS titre, '' AS lang", 'date' => 'date', 'principale' => 'oui', 'champs_editables' => array('nom','email','bio','nom_site','url_site','imessage','pgp'), 'champs_versionnes' => array('nom', 'bio', 'email', 'nom_site', 'url_site', 'login'), 'field' => array( "id_auteur" => "bigint(21) NOT NULL", "nom" => "text DEFAULT '' NOT NULL", "bio" => "text DEFAULT '' NOT NULL", "email" => "tinytext DEFAULT '' NOT NULL", "nom_site" => "tinytext DEFAULT '' NOT NULL", "url_site" => "text DEFAULT '' NOT NULL", "login" => "VARCHAR(255) BINARY", "pass" => "tinytext DEFAULT '' NOT NULL", "low_sec" => "tinytext DEFAULT '' NOT NULL", "statut" => "varchar(255) DEFAULT '0' NOT NULL", "webmestre" => "varchar(3) DEFAULT 'non' NOT NULL", "maj" => "TIMESTAMP", "pgp" => "TEXT DEFAULT '' NOT NULL", "htpass" => "tinytext DEFAULT '' NOT NULL", "en_ligne" => "datetime DEFAULT '0000-00-00 00:00:00' NOT NULL", "alea_actuel" => "tinytext", "alea_futur" => "tinytext", "prefs" => "tinytext", "cookie_oubli" => "tinytext", "source" => "VARCHAR(10) DEFAULT 'spip' NOT NULL", "lang" => "VARCHAR(10) DEFAULT '' NOT NULL" ), 'key' => array( "PRIMARY KEY" => "id_auteur", "KEY login" => "login", "KEY statut" => "statut", "KEY en_ligne" => "en_ligne", ), 'join' => array( "id_auteur"=>"id_auteur", "login"=>"login" ), 'rechercher_champs' => array( 'nom' => 5, 'bio' => 1, 'email' => 1, 'nom_site' => 1, 'url_site' => 1, 'login' => 1 ), // 2 conditions pour les auteurs : statut!=poubelle, // et avoir des articles publies 'statut'=> array( array( 'champ' => 'statut', 'publie' => '!5poubelle', 'previsu' => '!5poubelle', 'exception' => 'statut' ), array( 'champ' => array( array('spip_auteurs_liens', 'id_auteur'), array( 'spip_articles', array('id_objet','id_article','objet','article') ), 'statut' ), 'publie' => 'publie', 'previsu' => '!', 'post_date' => 'date', 'exception' => array('statut','lien','tout') ), ), 'statut_images' => array( 'auteur-6forum-16.png', '0minirezo'=>'auteur-0minirezo-16.png', '1comite'=>'auteur-1comite-16.png', '6forum'=>'auteur-6forum-16.png', '5poubelle'=>'auteur-5poubelle-16.png', 'nouveau'=>'' ), 'statut_titres' => array( 'titre_image_visiteur', '0minirezo'=>'titre_image_administrateur', '1comite'=>'titre_image_redacteur_02', '6forum'=>'titre_image_visiteur', '5poubelle'=>'titre_image_auteur_supprime', ), 'tables_jointures' => array( #'auteurs_liens' // declaration generique plus bas ), ), 'spip_rubriques' => array( 'page'=>'rubrique', 'url_voir' => 'rubrique', 'url_edit' => 'rubrique_edit', 'texte_retour' => 'icone_retour', 'texte_objets' => 'public:rubriques', 'texte_objet' => 'public:rubrique', 'texte_modifier' => 'icone_modifier_rubrique', 'texte_creer' => 'icone_creer_rubrique', 'texte_ajouter' => 'titre_ajouter_une_rubrique', 'texte_creer_associer' => 'creer_et_associer_une_rubrique', 'info_aucun_objet'=> 'info_aucun_rubrique', 'info_1_objet' => 'info_1_rubrique', 'info_nb_objets' => 'info_nb_rubriques', 'texte_logo_objet' => 'logo_rubrique', 'texte_langue_objet' => 'titre_langue_rubrique', 'titre'=>'titre, lang', 'date' => 'date', 'principale' => 'oui', 'champs_editables' => array('titre', 'texte', 'descriptif', 'extra'), 'champs_versionnes' => array('titre', 'descriptif', 'texte'), 'field' => array( "id_rubrique" => "bigint(21) NOT NULL", "id_parent" => "bigint(21) DEFAULT '0' NOT NULL", "titre" => "text DEFAULT '' NOT NULL", "descriptif" => "text DEFAULT '' NOT NULL", "texte" => "longtext DEFAULT '' NOT NULL", "id_secteur" => "bigint(21) DEFAULT '0' NOT NULL", "maj" => "TIMESTAMP", "statut" => "varchar(10) DEFAULT '0' NOT NULL", "date" => "datetime DEFAULT '0000-00-00 00:00:00' NOT NULL", "lang" => "VARCHAR(10) DEFAULT '' NOT NULL", "langue_choisie" => "VARCHAR(3) DEFAULT 'non'", "statut_tmp" => "varchar(10) DEFAULT '0' NOT NULL", "date_tmp" => "datetime DEFAULT '0000-00-00 00:00:00' NOT NULL", "profondeur" => "smallint(5) DEFAULT '0' NOT NULL" ), 'key' => array( "PRIMARY KEY" => "id_rubrique", "KEY lang" => "lang", "KEY id_parent" => "id_parent", ), 'rechercher_champs' => array( 'titre' => 8, 'descriptif' => 5, 'texte' => 1 ), 'statut' => array( array( 'champ' => 'statut', 'publie' => 'publie', 'previsu' => '!', 'exception' => array('statut','tout') ), ), 'tables_jointures' => array( #'id_auteur' => 'auteurs_liens' // declaration generique plus bas ), ), // toutes les tables ont le droit a une jointure sur les auteurs array('tables_jointures'=>array('id_auteur'=>'auteurs_liens')) ); // avant d'appeller les pipeline qui peuvent generer une reentrance a l'install // initialiser la signature $md5 = md5(serialize($infos_tables)); $GLOBALS['tables_principales'] = pipeline('declarer_tables_principales',$GLOBALS['tables_principales']); $GLOBALS['tables_auxiliaires'] = pipeline('declarer_tables_auxiliaires',$GLOBALS['tables_auxiliaires']); $infos_tables = pipeline('declarer_tables_objets_sql',$infos_tables); // completer les informations manquantes ou implicites $all = array(); foreach(array_keys($infos_tables) as $t) { // les cles numeriques servent a declarer // les proprietes applicables a tous les objets // on les mets de cote if (is_numeric($t)) { $all = array_merge_recursive($all,$infos_tables[$t]); unset($infos_tables[$t]); } else $infos_tables[$t] = renseigner_table_objet_sql($t,$infos_tables[$t]); } // repercuter les proprietes generales communes a tous les objets foreach(array_keys($infos_tables) as $t) { foreach($all as $i=>$v) if (in_array($i,array('tables_jointures','champs_versionnes'))){ $add = $all[$i]; // eviter les doublons de declaration de table jointure (ex des mots sur auteurs) // pour les declarations generiques avec cles numeriques if ($i=='tables_jointures' AND isset($infos_tables[$t][$i]) AND count($infos_tables[$t][$i])) { $doublons = array_intersect($infos_tables[$t][$i],$add); foreach($doublons as $d){ if (is_numeric(array_search($d,$infos_tables[$t][$i])) AND is_numeric($k=array_search($d,$add))) unset($add[$k]); } } $infos_tables[$t][$i] = array_merge(isset($infos_tables[$t][$i])?$infos_tables[$t][$i]:array(),$add); } else $infos_tables[$t][$i] = array_merge_recursive(isset($infos_tables[$t][$i])?$infos_tables[$t][$i]:array(),$all[$i]); } // completer les tables principales et auxiliaires // avec celles declarees uniquement dans declarer_table_objets_sql // pour assurer la compat en transition foreach($infos_tables as $table=>$infos) { $principale_ou_auxiliaire = ($infos['principale']?'tables_principales':'tables_auxiliaires'); // memoriser des champs eventuels declares par des plugins dans le pipeline tables_xxx // qui a ete appelle avant $mem = (isset($GLOBALS[$principale_ou_auxiliaire][$table])?$GLOBALS[$principale_ou_auxiliaire][$table]:array()); // l'ajouter au tableau $GLOBALS[$principale_ou_auxiliaire][$table] = array(); if (isset($infos['field']) AND isset($infos['key'])){ foreach(array('field','key','join') as $k) if (isset($infos_tables[$table][$k])) $GLOBALS[$principale_ou_auxiliaire][$table][$k] = &$infos_tables[$table][$k]; } else { // ici on ne renvoie que les declarations, donc RIEN // pour avoir la vrai description en base, il faut passer par trouver_table $GLOBALS[$principale_ou_auxiliaire][$table] = array(); } if (count($mem)){ foreach(array_keys($mem) as $k) if (isset($GLOBALS[$principale_ou_auxiliaire][$table][$k])) $GLOBALS[$principale_ou_auxiliaire][$table][$k] = array_merge($GLOBALS[$principale_ou_auxiliaire][$table][$k],$mem[$k]); else $GLOBALS[$principale_ou_auxiliaire][$table][$k] = $mem[$k]; } } // recuperer les interfaces (table_titre, table_date) // on ne le fait que dans un second temps pour que table_objet soit fonctionnel // dans le pipeline de declarer_tables_interfaces include_spip('public/interfaces'); foreach(array_keys($infos_tables) as $t) { $infos_tables[$t] = renseigner_table_objet_interfaces($t,$infos_tables[$t]); } $deja_la = false; // signature $md5 = md5(serialize($infos_tables)); } if ($table_sql==="::md5") return $md5; if ($table_sql AND !isset($infos_tables[$table_sql])){ #$desc = renseigner_table_objet_sql($table_sql,$desc); $desc = renseigner_table_objet_interfaces($table_sql,$desc); return $desc; } if ($table_sql) return isset($infos_tables[$table_sql])?$infos_tables[$table_sql]:array(); return $infos_tables; } /** * Déclare les tables principales du Core * * Tables principales, hors objets éditoriaux. * * @param array $tables_principales * Description des tables principales déjà déclarées * @return void **/ function base_serial(&$tables_principales){ $spip_jobs = array( "id_job" => "bigint(21) NOT NULL", "descriptif" => "text DEFAULT '' NOT NULL", "fonction" => "varchar(255) NOT NULL", //nom de la fonction "args"=> "longblob DEFAULT '' NOT NULL", // arguments "md5args"=> "char(32) NOT NULL default ''", // signature des arguments "inclure" => "varchar(255) NOT NULL", // fichier a inclure ou path/ pour charger_fonction "priorite" => "smallint(6) NOT NULL default 0", "date" => "datetime DEFAULT '0000-00-00 00:00:00' NOT NULL", // date au plus tot "status" => "tinyint NOT NULL default 1", ); $spip_jobs_key = array( "PRIMARY KEY" => "id_job", "KEY date" => "date", "KEY status" => "status", ); /// Attention: mes_fonctions peut avoir deja defini cette variable /// il faut donc rajouter, mais pas reinitialiser $tables_principales['spip_jobs'] = array('field' => &$spip_jobs, 'key' => &$spip_jobs_key); } /** * Déclare les tables auxiliaires du Core * * @param array $tables_auxiliaires * Description des tables auxiliaires déjà déclarées * @return void **/ function base_auxiliaires(&$tables_auxiliaires){ $spip_resultats = array( "recherche" => "char(16) DEFAULT '' NOT NULL", "id" => "INT UNSIGNED NOT NULL", "points" => "INT UNSIGNED DEFAULT '0' NOT NULL", "table_objet" => "varchar(30) DEFAULT '' NOT NULL", "serveur" => "char(16) DEFAULT '' NOT NULL", // hash md5 partiel du serveur de base ('' pour le serveur principal) "maj" => "TIMESTAMP" ); $spip_resultats_key = array( // pas de cle ni index, ca fait des insertions plus rapides et les requetes jointes utilisees en recheche ne sont pas plus lentes ... ); $spip_auteurs_liens = array( "id_auteur" => "bigint(21) DEFAULT '0' NOT NULL", "id_objet" => "bigint(21) DEFAULT '0' NOT NULL", "objet" => "VARCHAR (25) DEFAULT '' NOT NULL", "vu" => "VARCHAR(6) DEFAULT 'non' NOT NULL"); $spip_auteurs_liens_key = array( "PRIMARY KEY" => "id_auteur,id_objet,objet", "KEY id_auteur" => "id_auteur", "KEY id_objet" => "id_objet", "KEY objet" => "objet", ); $spip_meta = array( "nom" => "VARCHAR (255) NOT NULL", "valeur" => "text DEFAULT ''", "impt" => "ENUM('non', 'oui') DEFAULT 'oui' NOT NULL", "maj" => "TIMESTAMP"); $spip_meta_key = array( "PRIMARY KEY" => "nom"); $spip_jobs_liens = array( "id_job" => "bigint(21) DEFAULT '0' NOT NULL", "id_objet" => "bigint(21) DEFAULT '0' NOT NULL", "objet" => "VARCHAR (25) DEFAULT '' NOT NULL", ); $spip_jobs_liens_key = array( "PRIMARY KEY" => "id_job,id_objet,objet", "KEY id_job" => "id_job"); $tables_auxiliaires['spip_auteurs_liens'] = array( 'field' => &$spip_auteurs_liens, 'key' => &$spip_auteurs_liens_key); $tables_auxiliaires['spip_meta'] = array( 'field' => &$spip_meta, 'key' => &$spip_meta_key); $tables_auxiliaires['spip_resultats'] = array( 'field' => &$spip_resultats, 'key' => &$spip_resultats_key); $tables_auxiliaires['spip_jobs_liens'] = array( 'field' => &$spip_jobs_liens, 'key' => &$spip_jobs_liens_key); } /** * Auto remplissage des informations non explicites * sur un objet d'une table sql * * - table_objet * - table_objet_surnoms * - type * - type_surnoms * - url_voir * - url_edit * - icone_objet * * - texte_retour * - texte_modifier * - texte_creer * - texte_creer_associer * - texte_ajouter * - texte_objets * - texte_objet * * - info_aucun_objet * - info_1_objet * - info_nb_objets * * - texte_logo_objet * - texte_langue_objet * - texte_definir_comme_traduction_objet * * - principale * - champs_contenu : utlisé pour générer l'affichage par défaut du contenu * - editable * - champs_editables : utilisé pour prendre en compte le post lors de l'édition * * - champs_versionnes * * statut * statut_images * statut_titres * statut_textes_instituer * texte_changer_statut * aide_changer_statut * * - modeles : permet de declarer les modeles associes a cet objet * * Les infos non renseignées sont auto-déduites par conventions * ou laissées vides * * @param string $table_sql * @param array $infos * @return array */ function renseigner_table_objet_sql($table_sql,&$infos){ if (!isset($infos['type'])){ // si on arrive de base/trouver_table, on a la cle primaire : // s'en servir pour extrapoler le type if (isset($infos['key']["PRIMARY KEY"])){ $primary = $infos['key']["PRIMARY KEY"]; $primary = explode(',',$primary); $primary = reset($primary); $infos['type'] = preg_replace(',^spip_|^id_|s$,', '', $primary); } else $infos['type'] = preg_replace(',^spip_|s$,', '', $table_sql); } if (!isset($infos['type_surnoms'])) $infos['type_surnoms'] = array(); if (!isset($infos['table_objet'])) $infos['table_objet'] = preg_replace(',^spip_,', '', $table_sql); if (!isset($infos['table_objet_surnoms'])) $infos['table_objet_surnoms'] = array(); if (!isset($infos['principale'])) $infos['principale'] = (isset($GLOBALS['tables_principales'][$table_sql])?'oui':false); // normaliser pour pouvoir tester en php $infos['principale']? // et dans une boucle {principale=oui} $infos['principale'] = (($infos['principale'] AND $infos['principale']!='non')?'oui':false); // declarer et normaliser pour pouvoir tester en php $infos['editable']? // et dans une boucle {editable=oui} if (!isset($infos['editable'])) $infos['editable'] = 'oui'; $infos['editable'] = (($infos['editable'] AND $infos['editable']!='non')?'oui':false); // les urls publiques sont par defaut page=type pour les tables principales, et rien pour les autres // seules les exceptions sont donc a declarer if (!isset($infos['page'])) $infos['page'] = ($infos['principale']?$infos['type']:''); if (!isset($infos['url_voir'])) $infos['url_voir'] = $infos['type']; if (!isset($infos['url_edit'])) $infos['url_edit'] = $infos['url_voir'].($infos['editable']?"_edit":''); if (!isset($infos['icone_objet'])) $infos['icone_objet'] = $infos['type']; // chaines de langue // par defaut : objet:icone_xxx_objet if (!isset($infos['texte_retour'])) $infos['texte_retour'] = 'icone_retour'; if (!isset($infos['texte_modifier'])) $infos['texte_modifier'] = $infos['type'].':'.'icone_modifier_'.$infos['type']; if (!isset($infos['texte_creer'])) $infos['texte_creer'] = $infos['type'].':'.'icone_creer_'.$infos['type']; if (!isset($infos['texte_creer_associer'])) $infos['texte_creer_associer'] = $infos['type'].':'.'texte_creer_associer_'.$infos['type']; if (!isset($infos['texte_ajouter'])) // Ajouter un X $infos['texte_ajouter'] = $infos['type'].':'.'texte_ajouter_'.$infos['type']; if (!isset($infos['texte_objets'])) $infos['texte_objets'] = $infos['type'].':'.'titre_'.$infos['table_objet']; if (!isset($infos['texte_objet'])) $infos['texte_objet'] = $infos['type'].':'.'titre_'.$infos['type']; if (!isset($infos['texte_logo_objet'])) // objet:titre_logo_objet "Logo de ce X" $infos['texte_logo_objet'] = $infos['type'].':'.'titre_logo_'.$infos['type']; if (!isset($infos['texte_langue_objet'])) // objet:texte_langue_objet "Langue de ce X" $infos['texte_langue_objet'] = $infos['type'].':'.'titre_langue_'.$infos['type']; if (!isset($infos['texte_definir_comme_traduction_objet'])) // "Ce X est une traduction du X numéro :" $infos['texte_definir_comme_traduction_objet'] = $infos['type'].':'.'texte_definir_comme_traduction_'.$infos['type']; // objet:info_aucun_objet if (!isset($infos['info_aucun_objet'])) $infos['info_aucun_objet'] = $infos['type'].':'.'info_aucun_'.$infos['type']; // objet:info_1_objet if (!isset($infos['info_1_objet'])) $infos['info_1_objet'] = $infos['type'].':'.'info_1_'.$infos['type']; // objet:info_nb_objets if (!isset($infos['info_nb_objets'])) $infos['info_nb_objets'] = $infos['type'].':'.'info_nb_'.$infos['table_objet']; if (!isset($infos['champs_editables'])) $infos['champs_editables'] = array(); if (!isset($infos['champs_versionnes'])) $infos['champs_versionnes'] = array(); if (!isset($infos['rechercher_champs'])) $infos['rechercher_champs'] = array(); if (!isset($infos['rechercher_jointures'])) $infos['rechercher_jointures'] = array(); if (!isset($infos['modeles'])) $infos['modeles'] = array($infos['type']); return $infos; } /** * Renseigner les infos d'interface compilateur pour les tables objets * complete la declaration precedente * * titre * date * statut * tables_jointures * * @param $table_sql * @param $infos * @return array */ function renseigner_table_objet_interfaces($table_sql,&$infos){ if (!isset($infos['titre'])){ if (isset($infos['table_objet']) AND isset($GLOBALS['table_titre'][$infos['table_objet']])) $infos['titre'] = $GLOBALS['table_titre'][$infos['table_objet']]; else { $infos['titre'] = ((isset($infos['field']['titre']))?"titre,":"'' as titre,"); $infos['titre'] .= ((isset($infos['field']['lang']))?"lang":"'' as lang"); } } if (!isset($infos['date'])){ if (isset($infos['table_objet']) and isset($GLOBALS['table_date'][$infos['table_objet']])) $infos['date'] = $GLOBALS['table_date'][$infos['table_objet']]; else $infos['date'] = ((isset($infos['field']['date']))?"date":''); } if (!isset($infos['statut'])) $infos['statut'] = isset($GLOBALS['table_statut'][$table_sql]) ? $GLOBALS['table_statut'][$table_sql] : ''; if (!isset($infos['tables_jointures'])) $infos['tables_jointures'] = array(); if (isset($GLOBALS['tables_jointures'][$table_sql])) $infos['tables_jointures'] = array_merge($infos['tables_jointures'],$GLOBALS['tables_jointures'][$table_sql]); return $infos; } /** * Retourne la liste des tables principales et leurs descriptions * * @api * @return array * Liste et descriptions des tables principales **/ function lister_tables_principales(){ static $done = false; if (!$done OR !count($GLOBALS['tables_principales'])){ lister_tables_objets_sql(); $done = true; } return $GLOBALS['tables_principales']; } /** * Retourne la liste des tables auxiliaires et leurs descriptions * * @api * @return array * Liste et descriptions des tables auxiliaires **/ function lister_tables_auxiliaires(){ static $done = false; if (!$done OR !count($GLOBALS['tables_auxiliaires'])){ lister_tables_objets_sql(); $done = true; } return $GLOBALS['tables_auxiliaires']; } /** * Recenser les surnoms de table_objet * @return array */ function lister_tables_objets_surnoms(){ static $surnoms = null; static $md5 = null; if (!$surnoms OR $md5 != lister_tables_objets_sql('::md5')){ // passer dans un pipeline qui permet aux plugins de declarer leurs exceptions // pour compatibilite, car il faut dorenavent utiliser // declarer_table_objets_sql $surnoms = pipeline('declarer_tables_objets_surnoms', array( # pour les modeles # a enlever ? 'doc' => 'documents', 'img' => 'documents', 'emb' => 'documents', )); $infos_tables = lister_tables_objets_sql(); foreach($infos_tables as $t=>$infos){ // cas de base type=>table // et preg_replace(',^spip_|^id_|s$,',table)=>table if ($infos['table_objet']){ // securite, si la fonction est appelee trop tot, c'est vide // optimisations pour table_objet //$surnoms[$infos['type']] = $infos['table_objet']; $surnoms[preg_replace(',^spip_|^id_|s$,', '', $infos['table_objet'])] = $infos['table_objet']; $surnoms[preg_replace(',^spip_|^id_|s$,', '', $infos['type'])] = $infos['table_objet']; if (is_array($infos['table_objet_surnoms']) AND count($infos['table_objet_surnoms'])) foreach($infos['table_objet_surnoms'] as $surnom) $surnoms[$surnom] = $infos['table_objet']; } } $md5 = lister_tables_objets_sql('::md5'); } return $surnoms; } /** * Recenser les surnoms de table_objet * @return array */ function lister_types_surnoms(){ static $surnoms = null; static $md5 = null; if (!$surnoms OR $md5 != lister_tables_objets_sql('::md5')){ // passer dans un pipeline qui permet aux plugins de declarer leurs exceptions // pour compatibilite, car il faut dorenavent utiliser // declarer_table_objets_sql $surnoms = pipeline('declarer_type_surnoms', array('racine-site'=>'site')); $infos_tables = lister_tables_objets_sql(); foreach($infos_tables as $t=>$infos){ if ($infos['type']){ // securite, si la fonction est appelee trop tot, c'est vide // optimisations pour objet_type //$surnoms[$infos['type']] = $infos['type']; $surnoms[preg_replace(',^spip_|^id_|s$,', '', $infos['table_objet'])] = $infos['type']; $surnoms[preg_replace(',^spip_|^id_|s$,', '', $infos['type'])] = $infos['type']; // surnoms declares if (is_array($infos['type_surnoms']) AND count($infos['type_surnoms'])) foreach($infos['type_surnoms'] as $surnom) $surnoms[$surnom] = $infos['type']; } } $md5 = lister_tables_objets_sql('::md5'); } return $surnoms; } function lister_tables_spip($serveur=''){ static $tables = array(); if (!isset($tables[$serveur])){ $tables[$serveur] = array(); if (!function_exists("sql_alltable")) include_spip("base/abstract_sql"); $ts = sql_alltable(null,$serveur); // toutes les tables "spip_" (ou prefixe perso) $connexion = $GLOBALS['connexions'][$serveur ? $serveur : 0]; $spip = $connexion['prefixe'] . '_'; foreach ($ts as $t){ $t = substr($t,strlen($spip)); $tables[$serveur]["spip_$t"] = $t; } } return $tables[$serveur]; } function lister_toutes_tables($serveur){ static $tables = array(); if (!isset($tables[$serveur])){ $tables[$serveur] = array(); if (!function_exists("sql_alltable")) include_spip("base/abstract_sql"); $ts = sql_alltable('%',$serveur); // toutes les tables foreach ($ts as $t){ $tables[$serveur][$t] = $t; } } return $tables[$serveur]; } /** * Retrouve le nom d'objet à partir de la table * * - spip_articles -> articles * - id_article -> articles * - article -> articles * * @api * @param string $type * Nom de la table SQL (le plus souvent) * Tolère un nom de clé primaire. * @param string $serveur * Nom du connecteur * @return string * Nom de l'objet **/ function table_objet($type,$serveur='') { $surnoms = lister_tables_objets_surnoms(); $type = preg_replace(',^spip_|^id_|s$,', '', $type); if (!$type) return; if (isset($surnoms[$type])) return $surnoms[$type]; if ($serveur!==false){ $t=lister_tables_spip($serveur); $trouver_table = charger_fonction('trouver_table', 'base'); $typetrim = rtrim($type,'s')."s"; if ( (isset($t[$typetrim]) OR in_array($typetrim,$t)) AND ($desc = $trouver_table(rtrim($type,'s')."s",$serveur)) ) return $desc['id_table']; elseif ( (isset($t[$type]) OR in_array($type,$t)) AND ($desc = $trouver_table($type,$serveur)) ) return $desc['id_table']; spip_log( 'table_objet('.$type.') calculee sans verification'); } return rtrim($type,'s')."s"; # cas historique ne devant plus servir, sauf si $serveur=false } /** * Retrouve la table sql à partir de l'objet ou du type * * - articles -> spip_articles * - article -> spip_articles * - id_article -> spip_articles * * @api * @param string $type * Nom ou type de l'objet * Tolère un nom de clé primaire. * @param string $serveur * Nom du connecteur * @return string * Nom de la table SQL **/ function table_objet_sql($type,$serveur='') { global $table_des_tables; $nom = table_objet($type, $serveur); if (!isset($table_des_tables['articles'])) // eviter de multiples inclusions include_spip('public/interfaces'); if (isset($table_des_tables[$nom])) { $nom = $table_des_tables[$nom]; $nom = "spip_$nom"; } else { $infos_tables = lister_tables_objets_sql(); if (isset($infos_tables["spip_$nom"])) $nom = "spip_$nom"; elseif($serveur!==false) { $t=lister_tables_spip($serveur); if (isset($t[$nom]) OR in_array($nom,$t)){ $trouver_table = charger_fonction('trouver_table', 'base'); if ($desc = $trouver_table($nom,$serveur)) return $desc['table_sql']; } } } return $nom ; } /** * Retrouve la clé primaire à partir du nom d'objet ou de table * * - articles -> id_article * - article -> id_article * - spip_articles -> id_article * * @api * @param string $type * Nom de la table SQL ou de l'objet * @param string $serveur * Nom du connecteur * @return string * Nom de la clé primaire **/ function id_table_objet($type,$serveur='') { static $trouver_table = null; $type = objet_type($type,$serveur); if (!$type) return; $t = table_objet($type); if (!$trouver_table) $trouver_table = charger_fonction('trouver_table', 'base'); $ts=lister_tables_spip($serveur); if (in_array($t,$ts) OR in_array($t,lister_toutes_tables($serveur))){ $desc = $trouver_table($t,$serveur); if (isset($desc['key']['PRIMARY KEY'])) return $desc['key']['PRIMARY KEY']; if (!$desc OR isset($desc['field']["id_$type"])) return "id_$type"; // sinon renvoyer le premier champ de la table... $keys = array_keys($desc['field']); return array_shift($keys); } return "id_$type"; } /** * Retrouve le type d'objet à partir du nom d'objet ou de table * * - articles -> article * - spip_articles -> article * - id_article -> article * * @api * @param string $table_objet * Nom de l'objet ou de la table SQL * @param string $serveur * Nom du connecteur * @return string * Type de l'objet **/ function objet_type($table_objet, $serveur=''){ if (!$table_objet) return; $surnoms = lister_types_surnoms(); // scenario de base // le type est decline a partir du nom de la table en enlevant le prefixe eventuel // et la marque du pluriel // on accepte id_xx en entree aussi $type = preg_replace(',^spip_|^id_|s$,', '', $table_objet); if (isset($surnoms[$type])) return $surnoms[$type]; // securite : eliminer les caracteres non \w $type = preg_replace(',[^\w-],','',$type); // si le type redonne bien la table c'est bon // oui si table_objet ressemblait deja a un type if ( $type==$table_objet OR (table_objet($type,$serveur)==$table_objet) OR (table_objet_sql($type,$serveur)==$table_objet)) return $type; // si on ne veut pas chercher en base if ($serveur===false) return $type; // sinon on passe par la cle primaire id_xx pour trouver le type // car le s a la fin est incertain // notamment en cas de pluriel derogatoire // id_jeu/spip_jeux id_journal/spip_journaux qui necessitent tout deux // une declaration jeu => jeux, journal => journaux // dans le pipeline declarer_tables_objets_surnoms $trouver_table = charger_fonction('trouver_table', 'base'); $ts=lister_tables_spip($serveur); if (in_array($table_objet,$ts)) $desc = $trouver_table($table_objet); if (!$desc AND in_array($table_objet=table_objet($type,$serveur),$ts)) $desc = $trouver_table($table_objet,$serveur); // si le type est declare : bingo ! if ($desc AND isset($desc['type'])) return $desc['type']; // on a fait ce qu'on a pu return $type; } /** * Determininer si un objet est publie ou non * * On se base pour cela sur sa declaration de statut * pour des cas particuliers non declarables, on permet de fournir une fonction * base_xxxx_test_si_publie qui sera appele par la fonction * * @param string $objet * @param int $id_objet * @param string $serveur * @return bool */ function objet_test_si_publie($objet,$id_objet, $serveur=''){ // voir si une fonction est definie pour faire le boulot // elle a la priorite dans ce cas if ($f = charger_fonction($objet."_test_si_publie","base",true)) return $f($objet,$id_objet, $serveur); // sinon on se fie a la declaration de l'objet si presente $id_table = $table_objet = table_objet($objet); $id_table_objet = id_table_objet($objet, $serveur); $trouver_table = charger_fonction('trouver_table', 'base'); if ($desc = $trouver_table($table_objet, $serveur) AND isset($desc['statut']) AND $desc['statut']){ $boucle = new Boucle(); $boucle->show = $desc; $boucle->nom = 'objet_test_si_publie'; $boucle->id_boucle = $id_table; $boucle->id_table = $id_table; $boucle->sql_serveur = $serveur; $boucle->select[] = $id_table_objet; $boucle->from[$table_objet] = table_objet_sql($objet, $serveur); $boucle->where[] = $id_table.".".$id_table_objet.'='.intval($id_objet); include_spip('public/compiler'); include_spip('public/composer'); instituer_boucle($boucle, false, true); $res = calculer_select($boucle->select,$boucle->from,$boucle->from_type,$boucle->where,$boucle->join,$boucle->group,$boucle->order,$boucle->limit,$boucle->having,$table_objet,$id_table,$serveur); if (sql_fetch($res)) return true; return false; } // si pas d'info statut ni de fonction : l'objet est publie return true; } trouver_table.php000066600000015131152502550120010134 0ustar00<?php /***************************************************************************\ * SPIP, Systeme de publication pour l'internet * * * * Copyright (c) 2001-2014 * * 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. * \***************************************************************************/ /** * Gestion de l'obtention des descriptions de tables SQL * * @package SPIP\SQL\Tables **/ if (!defined('_ECRIRE_INC_VERSION')) return; include_spip('base/objets'); /** * Retourne la description d'une table SQL * * Cela sert notamment au moment de la compilation des boucles, critères et balise. * * Les champs et clés de la tables sont retrouvés prioritairement via le * gestionnaire de base de données. Les descriptions sont complétées, * pour les tables éditoriales, des informations déclarées ou construites * par la déclaration des objets éditoriaux. * * @example * $trouver_table = charger_fonction('trouver_table', 'base'); * $desc = $trouver_table('spip_groupes_mots'); * * Cette fonction intervient à la compilation, mais aussi pour la balise * contextuelle EXPOSE ou certains critères. * * L'ensemble des descriptions de table d'un serveur est stocké dans un * fichier cache/sql_desc.txt par soucis de performance. Un appel * avec $nom vide est une demande explicite de vidange de ce cache * * @see lister_tables_objets_sql() * * @api * @param string $nom * Nom de la table * Vide '' demande de vider le cache des discriptions * @param string $serveur * Nom du connecteur * @param bool $table_spip * Indique s'il faut transformer le préfixe de table * @return array|bool * false si table introuvable * tableau de description de la table sinon, en particulier : * - field : tableau des colonnes SQL et leur description (comme dans serial.php ou objets.php) * - key : tableau des KEY (comme dans serial.php ou objets.php) * - table et table_sql : nom de la table (avec spip_ en préfixe) * - id_table : nom SPIP de la table (type de boucle) * le compilateur produit FROM $r['table'] AS $r['id_table'] * - Toutes les autres informations des objets éditoriaux si la table est l'un d'eux. * * **/ function base_trouver_table_dist($nom, $serveur='', $table_spip = true){ static $nom_cache_desc_sql=array(); global $tables_principales, $tables_auxiliaires, $table_des_tables; if (!spip_connect($serveur) OR !preg_match('/^[a-zA-Z0-9._-]*/',$nom)) return null; $connexion = &$GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0]; $objets_sql = lister_tables_objets_sql("::md5"); // le nom du cache depend du serveur mais aussi du nom de la db et du prefixe // ce qui permet une auto invalidation en cas de modif manuelle du fichier // de connexion, et tout risque d'ambiguite if (!isset($nom_cache_desc_sql[$serveur][$objets_sql])){ $nom_cache_desc_sql[$serveur][$objets_sql] = _DIR_CACHE . 'sql_desc_' . ($serveur ? "{$serveur}_":"") . substr(md5($connexion['db'].":".$connexion['prefixe'].":$objets_sql"),0,8) .'.txt'; // nouveau nom de cache = nouvelle version en memoire unset($connexion['tables']); } // un appel avec $nom vide est une demande explicite de vidange du cache des descriptions if (!$nom){ spip_unlink($nom_cache_desc_sql[$serveur][$objets_sql]); $connexion['tables'] = array(); return null; } $nom_sql = $nom; if (preg_match('/\.(.*)$/', $nom, $s)) $nom_sql = $s[1]; else $nom_sql = $nom; $fdesc = $desc = ''; $connexion = &$GLOBALS['connexions'][$serveur ? $serveur : 0]; // base sous SPIP: gerer les abreviations explicites des noms de table if ($connexion['spip_connect_version']) { if ($table_spip AND isset($table_des_tables[$nom])) { $nom = $table_des_tables[$nom]; $nom_sql = 'spip_' . $nom; } } // si c'est la premiere table qu'on cherche // et si on est pas explicitement en recalcul // on essaye de recharger le cache des decriptions de ce serveur // dans le fichier cache if (!isset($connexion['tables'][$nom_sql]) AND defined('_VAR_MODE') AND _VAR_MODE!=='recalcul' AND (!isset($connexion['tables']) OR !$connexion['tables'])) { if (lire_fichier($nom_cache_desc_sql[$serveur][$objets_sql],$desc_cache) AND $desc_cache=unserialize($desc_cache)) $connexion['tables'] = $desc_cache; } if ($table_spip AND !isset($connexion['tables'][$nom_sql])) { if (isset($tables_principales[$nom_sql])) $fdesc = $tables_principales[$nom_sql]; // meme si pas d'abreviation declaree, trouver la table spip_$nom // si c'est une table principale, // puisqu'on le fait aussi pour les tables auxiliaires elseif ($nom_sql==$nom AND isset($tables_principales['spip_' .$nom])){ $nom_sql = 'spip_' . $nom; $fdesc = &$tables_principales[$nom_sql]; } elseif (isset($tables_auxiliaires[$n=$nom]) OR isset($tables_auxiliaires[$n='spip_'.$nom])) { $nom_sql = $n; $fdesc = &$tables_auxiliaires[$n]; } # table locale a cote de SPIP, comme non SPIP: } if (!isset($connexion['tables'][$nom_sql])) { // La *vraie* base a la priorite $desc = sql_showtable($nom_sql, $table_spip, $serveur); if (!$desc OR !$desc['field']) { if (!$fdesc) { spip_log("trouver_table: table inconnue '$serveur' '$nom'",_LOG_INFO_IMPORTANTE); return null; } // on ne sait pas lire la structure de la table : // on retombe sur la description donnee dans les fichiers spip $desc = $fdesc; } else { $desc['exist'] = true; } $desc['table'] = $desc['table_sql'] = $nom_sql; $desc['connexion']= $serveur; // charger les infos declarees pour cette table // en lui passant les infos connues // $desc est prioritaire pour la description de la table $desc = array_merge(lister_tables_objets_sql($nom_sql,$desc),$desc); // si tables_objets_sql est bien fini d'init, on peut cacher $connexion['tables'][$nom_sql] = $desc; $res = &$connexion['tables'][$nom_sql]; // une nouvelle table a ete decrite // mettons donc a jour le cache des descriptions de ce serveur if (is_writeable(_DIR_CACHE)) ecrire_fichier($nom_cache_desc_sql[$serveur][$objets_sql],serialize($connexion['tables']),true); } else $res = &$connexion['tables'][$nom_sql]; // toujours retourner $nom dans id_table $res['id_table']=$nom; return $res; } ?> restaurer.php000066600000006467152503073450007316 0ustar00<?php /***************************************************************************\ * SPIP, Systeme de publication pour l'internet * * * * Copyright (c) 2001-2014 * * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James * * * * Ce programme est un logiciel libre distribue sous licence GNU/GPL. * * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. * \***************************************************************************/ if (!defined("_ECRIRE_INC_VERSION")) return; include_spip('inc/dump'); include_spip('inc/actions'); function base_restaurer_dist($titre='', $reprise=false) { $status_file = _DUMP_STATUS_FILE; $status_file = _DIR_TMP.basename($status_file).".txt"; if (!lire_fichier($status_file, $status) OR !$status = unserialize($status)) { } else { $redirect = parametre_url(generer_action_auteur('restaurer',_DUMP_STATUS_FILE),"step",intval(_request('step')+1),'&'); $timeout = ini_get('max_execution_time'); // valeur conservatrice si on a pas reussi a lire le max_execution_time if (!$timeout) $timeout=30; // parions sur une valeur tellement courante ... $max_time = time()+$timeout/2; include_spip('inc/minipres'); @ini_set("zlib.output_compression","0"); // pour permettre l'affichage au fur et a mesure $titre = _T('dump:restauration_en_cours') . " (".count($status['tables']).") "; $balise_img = chercher_filtre('balise_img'); $titre .= $balise_img(chemin_image('searching.gif')); echo ( install_debut_html($titre)); // script de rechargement auto sur timeout echo http_script("window.setTimeout('location.href=\"".$redirect."\";',".($timeout*1000).")"); echo "<div style='text-align: left'>\n"; dump_serveur($status['connect']); spip_connect('dump'); // au premier coup on ne fait rien sauf afficher l'ecran de sauvegarde if (_request('step')) { $options = array( 'callback_progression' => 'dump_afficher_progres', 'max_time' => $max_time, 'no_erase_dest' => lister_tables_noerase(), 'where' => $status['where']?$status['where']:array(), 'desc_tables_dest' => array() ); if ($desc = sql_getfetsel('valeur','spip_meta',"nom='dump_structure_temp'",'','','','','dump') AND $desc = unserialize($desc)) $options['desc_tables_dest'] = $desc; #var_dump(sql_allfetsel('nom,valeur','spip_meta',"",'','','','','dump')); #die(); $res = base_copier_tables($status_file, $status['tables'], 'dump', '', $options); } else { // mais on en profite pour reparer les version base pour etre sur de ne pas les perdre sql_updateq("spip_meta",array('impt'=>'oui'),"nom='version_installee'",'','dump'); sql_updateq("spip_meta",array('impt'=>'oui'),"nom LIKE '%_base_version'",'','dump'); } echo ( "</div>\n"); if (!$res) echo dump_relance($redirect); echo (install_fin_html()); ob_end_flush(); flush(); if (!$res) exit; // quand on sort de $export avec true c'est qu'on a fini dump_end(_DUMP_STATUS_FILE,'restaurer'); include_spip('inc/headers'); echo redirige_formulaire(generer_url_ecrire("restaurer",'status='._DUMP_STATUS_FILE,'',true, true)); } } ?> forum.php000066600000012607152503076340006424 0ustar00<?php /***************************************************************************\ * SPIP, Systeme de publication pour l'internet * * * * Copyright (c) 2001-2014 * * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James * * * * Ce programme est un logiciel libre distribue sous licence GNU/GPL. * * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. * \***************************************************************************/ if (!defined('_ECRIRE_INC_VERSION')) return; /** * Interfaces de la table forum pour le compilateur * * @param array $interfaces * @return array $interfaces */ function forum_declarer_tables_interfaces($interfaces){ $interfaces['table_des_tables']['forums']='forum'; $interfaces['exceptions_des_tables']['forums']['date']='date_heure'; $interfaces['exceptions_des_tables']['forums']['nom']='auteur'; $interfaces['exceptions_des_tables']['forums']['email']='email_auteur'; // il ne faut pas essayer de chercher le forum du mot cle, mais bien le mot cle associe au forum $interfaces['exceptions_des_jointures']['spip_forum']['id_secteur'] = array('spip_articles','id_secteur'); $interfaces['exceptions_des_jointures']['spip_forum']['id_mot'] = array('spip_mots','id_mot'); $interfaces['exceptions_des_jointures']['spip_forum']['titre_mot'] = array('spip_mots','titre'); $interfaces['exceptions_des_jointures']['spip_forum']['type_mot'] = array('spip_mots','type'); $interfaces['exceptions_des_jointures']['spip_forum']['id_groupe'] = array('spip_mots','id_groupe'); #$interfaces['table_titre']['forums']= "titre, '' AS lang"; #$interfaces['table_date']['forums']='date_heure'; $interfaces['table_statut']['spip_forum'][] = array('champ'=>'statut','publie'=>'publie','previsu'=>'publie,prop','exception'=>'statut'); $interfaces['table_des_traitements']['PARAMETRES_FORUM'][]= 'spip_htmlspecialchars(%s)'; $interfaces['table_des_traitements']['TEXTE']['forums']= "liens_nofollow(safehtml(".str_replace("%s","interdit_html(%s)",_TRAITEMENT_RACCOURCIS)."))"; $interfaces['table_des_traitements']['TITRE']['forums']= "liens_nofollow(safehtml(".str_replace("%s","interdit_html(%s)",_TRAITEMENT_TYPO)."))"; $interfaces['table_des_traitements']['NOTES']['forums']= "liens_nofollow(safehtml(".str_replace("%s","interdit_html(%s)",_TRAITEMENT_RACCOURCIS)."))"; $interfaces['table_des_traitements']['NOM_SITE']['forums']= "liens_nofollow(safehtml(".str_replace("%s","interdit_html(%s)",_TRAITEMENT_TYPO)."))"; $interfaces['table_des_traitements']['URL_SITE']['forums']= 'safehtml(vider_url(%s))'; $interfaces['table_des_traitements']['AUTEUR']['forums']= 'liens_nofollow(safehtml(vider_url(%s)))'; $interfaces['table_des_traitements']['EMAIL_AUTEUR']['forums']= 'safehtml(vider_url(%s))'; return $interfaces; } /** * Déclaration de la table spip_forum et de l'objet forum * * @param array $tables Tableau des objets déclarés * @return array $tables Tableau des objets complété */ function forum_declarer_tables_objets_sql($tables){ $tables['spip_forum'] = array( 'table_objet'=>'forums', # ??? hum hum redevient spip_forum par table_objet_sql mais casse par un bete "spip_".table_objet() 'type'=>'forum', 'url_voir'=>'controler_forum', 'url_edit'=>'controler_forum', 'editable'=>'non', 'principale' => 'oui', 'page'=>'', // pas de page editoriale pour un forum 'texte_retour' => 'icone_retour', 'texte_objets' => 'forum:forum', 'texte_objet' => 'forum:forum', 'info_aucun_objet'=> 'forum:aucun_message_forum', 'info_1_objet' => 'forum:info_1_message_forum', 'info_nb_objets' => 'forum:info_nb_messages_forum', 'titre' => "titre, '' AS lang", 'date' => 'date_heure', 'champs_editables' => array('titre', 'texte', 'nom_site', 'url_site'), 'field'=> array( "id_forum" => "bigint(21) NOT NULL", "id_objet" => "bigint(21) DEFAULT '0' NOT NULL", "objet" => "VARCHAR (25) DEFAULT '' NOT NULL", "id_parent" => "bigint(21) DEFAULT '0' NOT NULL", "id_thread" => "bigint(21) DEFAULT '0' NOT NULL", "date_heure" => "datetime DEFAULT '0000-00-00 00:00:00' NOT NULL", "date_thread" => "datetime DEFAULT '0000-00-00 00:00:00' NOT NULL", "titre" => "text DEFAULT '' NOT NULL", "texte" => "mediumtext DEFAULT '' NOT NULL", "auteur" => "text DEFAULT '' NOT NULL", "email_auteur" => "text DEFAULT '' NOT NULL", "nom_site" => "text DEFAULT '' NOT NULL", "url_site" => "text DEFAULT '' NOT NULL", "statut" => "varchar(8) DEFAULT '0' NOT NULL", "ip" => "varchar(40) DEFAULT '' NOT NULL", "maj" => "TIMESTAMP", "id_auteur" => "bigint DEFAULT '0' NOT NULL" ), 'key' => array( "PRIMARY KEY" => "id_forum", "KEY id_auteur" => "id_auteur", "KEY id_parent" => "id_parent", "KEY id_thread" => "id_thread", "KEY optimal" => "statut,id_parent,id_objet,objet,date_heure" ), 'join' => array( "id_forum"=>"id_forum", "id_parent"=>"id_parent", "id_objet"=>"id_objet", "objet"=>"objet", "id_auteur"=>"id_auteur", ), 'rechercher_champs' => array( 'titre' => 3, 'texte' => 1, 'auteur' => 2, 'email_auteur' => 2, 'nom_site' => 1, 'url_site' => 1 ), ); // jointures sur les forum pour tous les objets $tables[]['tables_jointures'][]= 'forums'; return $tables; } ?> medias.php000066600000022552152503076400006533 0ustar00<?php /***************************************************************************\ * SPIP, Systeme de publication pour l'internet * * * * Copyright (c) 2001-2014 * * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James * * * * Ce programme est un logiciel libre distribue sous licence GNU/GPL. * * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. * \***************************************************************************/ if (!defined('_ECRIRE_INC_VERSION')) return; /** * Interfaces des tables breves pour le compilateur * * @param array $interfaces * @return array */ function medias_declarer_tables_interfaces($interfaces) { $interfaces['table_des_tables']['documents']='documents'; $interfaces['table_des_tables']['types_documents']='types_documents'; $interfaces['exceptions_des_tables']['documents']['type_document']=array('types_documents', 'titre'); $interfaces['exceptions_des_tables']['documents']['extension_document']=array('types_documents', 'extension'); $interfaces['exceptions_des_tables']['documents']['mime_type']=array('types_documents', 'mime_type'); $interfaces['exceptions_des_tables']['documents']['media_document']=array('types_documents', 'media'); $interfaces['exceptions_des_jointures']['spip_documents']['id_forum']=array('spip_documents_liens','id_forum'); $interfaces['exceptions_des_jointures']['spip_documents']['vu']=array('spip_documents_liens', 'vu'); $interfaces['table_date']['types_documents']='date'; $interfaces['table_des_traitements']['FICHIER']['documents']= 'get_spip_doc(%s)'; return $interfaces; } /** * Table principale spip_documents et spip_types_documents * * @param array $tables_principales * @return array */ function medias_declarer_tables_principales($tables_principales) { $spip_types_documents = array( "extension" => "varchar(10) DEFAULT '' NOT NULL", "titre" => "text DEFAULT '' NOT NULL", "descriptif" => "text DEFAULT '' NOT NULL", "mime_type" => "varchar(100) DEFAULT '' NOT NULL", "inclus" => "ENUM('non', 'image', 'embed') DEFAULT 'non' NOT NULL", "upload" => "ENUM('oui', 'non') DEFAULT 'oui' NOT NULL", "media_defaut" => "varchar(10) DEFAULT 'file' NOT NULL", "maj" => "TIMESTAMP"); $spip_types_documents_key = array( "PRIMARY KEY" => "extension", "KEY inclus" => "inclus"); $tables_principales['spip_types_documents'] = array('field' => &$spip_types_documents, 'key' => &$spip_types_documents_key); return $tables_principales; } /** * Table des liens documents-objets spip_documents_liens * @param array $tables_auxiliaires * @return array */ function medias_declarer_tables_auxiliaires($tables_auxiliaires) { $spip_documents_liens = array( "id_document" => "bigint(21) DEFAULT '0' NOT NULL", "id_objet" => "bigint(21) DEFAULT '0' NOT NULL", "objet" => "VARCHAR (25) DEFAULT '' NOT NULL", "vu" => "ENUM('non', 'oui') DEFAULT 'non' NOT NULL"); $spip_documents_liens_key = array( "PRIMARY KEY" => "id_document,id_objet,objet", "KEY id_document" => "id_document", "KEY id_objet" => "id_objet", "KEY objet" => "objet", ); $tables_auxiliaires['spip_documents_liens'] = array( 'field' => &$spip_documents_liens, 'key' => &$spip_documents_liens_key); return $tables_auxiliaires; } /** * Declarer le surnom des breves * * @param array $surnoms * @return array */ function medias_declarer_tables_objets_surnoms($surnoms) { $surnoms['type_document'] = "types_documents"; # hum #$surnoms['extension'] = "types_documents"; # hum #$surnoms['type'] = "types_documents"; # a ajouter pour id_table_objet('type')=='extension' ? return $surnoms; } function medias_declarer_tables_objets_sql($tables){ $tables['spip_articles']['champs_versionnes'][] = 'jointure_documents'; $tables['spip_documents'] = array( 'table_objet_surnoms'=>array('doc','img','emb'), 'type_surnoms' => array(), 'url_voir' => 'document_edit', 'url_edit' => 'document_edit', 'page'=>'', 'texte_retour' => 'icone_retour', 'texte_objets' => 'medias:objet_documents', 'texte_objet' => 'medias:objet_document', 'texte_modifier' => 'medias:info_modifier_document', 'info_aucun_objet'=> 'medias:aucun_document', 'info_1_objet' => 'medias:un_document', 'info_nb_objets' => 'medias:des_documents', 'titre' => "CASE WHEN length(titre)>0 THEN titre ELSE fichier END as titre, '' AS lang", 'date' => 'date', 'principale'=>'oui', 'field' => array( "id_document" => "bigint(21) NOT NULL", "id_vignette" => "bigint(21) DEFAULT '0' NOT NULL", "extension" => "VARCHAR(10) DEFAULT '' NOT NULL", "titre" => "text DEFAULT '' NOT NULL", "date" => "datetime DEFAULT '0000-00-00 00:00:00' NOT NULL", "descriptif" => "text DEFAULT '' NOT NULL", "fichier" => "text NOT NULL DEFAULT ''", "taille" => "bigint", "largeur" => "integer", "hauteur" => "integer", "media" => "varchar(10) DEFAULT 'file' NOT NULL", "mode" => "varchar(10) DEFAULT 'document' NOT NULL", "distant" => "VARCHAR(3) DEFAULT 'non'", "statut" => "varchar(10) DEFAULT '0' NOT NULL", "credits" => "varchar(255) DEFAULT '' NOT NULL", "date_publication" => "datetime DEFAULT '0000-00-00 00:00:00' NOT NULL", "brise" => "tinyint DEFAULT 0", "maj" => "TIMESTAMP" ), 'key' => array( "PRIMARY KEY" => "id_document", "KEY id_vignette" => "id_vignette", "KEY mode" => "mode", "KEY extension" => "extension" ), 'join' => array( "id_document"=>"id_document", "extension"=>"extension" ), 'statut'=> array( array( 'champ' => 'statut', 'publie' => 'publie', 'previsu' => 'publie,prop,prepa', 'post_date' => 'date_publication', 'exception' => array('statut','tout') ) ), 'tables_jointures' => array('types_documents'), 'rechercher_champs' => array( 'titre' => 3, 'descriptif' => 1, 'fichier' => 1, 'credits' => 1, ), 'champs_editables' => array('titre', 'descriptif', 'date', 'taille', 'largeur','hauteur','mode','credits','fichier','distant','extension', 'id_vignette', 'media'), 'champs_versionnes' => array('id_vignette', 'titre', 'descriptif', 'hauteur', 'largeur', 'mode','credits','distant'), 'modeles' => array('document','doc','img','emb','image','video','text','audio','application'), ); // jointures sur les forum pour tous les objets $tables[]['tables_jointures'][]= 'documents_liens'; // recherche jointe sur les documents pour les articles et rubriques $tables['spip_articles']['rechercher_jointures']['document'] = array('titre' => 2, 'descriptif' => 1); $tables['spip_rubriques']['rechercher_jointures']['document'] = array('titre' => 2, 'descriptif' => 1); return $tables; } /** * Creer la table des types de document * * http://code.spip.net/@creer_base_types_doc * * @param string $serveur * @return void */ function creer_base_types_doc($serveur='', $champ_media="media_defaut") { global $tables_images, $tables_sequences, $tables_documents, $tables_mime; include_spip('base/typedoc'); include_spip('base/abstract_sql'); // charger en memoire tous les types deja definis pour limiter les requettes $rows = sql_allfetsel('mime_type,titre,inclus,extension,'.$champ_media.',upload,descriptif','spip_types_documents','','','','','',$serveur); $deja = array(); foreach ($rows as $k=>$row){ $deja[$row['extension']] = &$rows[$k]; } $insertions = array(); $updates = array(); foreach ($tables_mime as $extension => $type_mime) { if (isset($tables_images[$extension])) { $titre = $tables_images[$extension]; $inclus='image'; } else if (isset($tables_sequences[$extension])) { $titre = $tables_sequences[$extension]; $inclus='embed'; } else { $inclus='non'; if (isset($tables_documents[$extension])) $titre = $tables_documents[$extension]; else $titre = ''; } // type de media $media = "file"; if (preg_match(",^image/,",$type_mime) OR in_array($type_mime,array('application/illustrator'))) $media = "image"; elseif (preg_match(",^audio/,",$type_mime)) $media = "audio"; elseif (preg_match(",^video/,",$type_mime) OR in_array($type_mime,array('application/ogg','application/x-shockwave-flash','application/mp4'))) $media = "video"; $set = array( 'mime_type' => $type_mime, 'titre' => $titre, 'inclus' => $inclus, 'extension' => $extension, $champ_media => $media, 'upload' => 'oui', 'descriptif' => '', ); if (!isset($deja[$extension])){ $insertions[] = $set; } elseif (array_diff($deja[$extension],$set)){ $updates[$extension] = $set; } } if (count($updates)){ foreach ($updates as $extension=>$set){ sql_updateq('spip_types_documents',$set,'extension='.sql_quote($extension)); } } if ($insertions) sql_insertq_multi('spip_types_documents', $insertions, '', $serveur); } /** * Optimiser la base de donnee en supprimant les liens orphelins * * @param int $n * @return int */ function medias_optimiser_base_disparus($flux){ include_spip('action/editer_liens'); // optimiser les liens morts : // entre documents vers des objets effaces // depuis des documents effaces $flux['data'] += objet_optimiser_liens(array('document'=>'*'),'*'); // on ne nettoie volontairement pas automatiquement les documents orphelins return $flux; } ?>typedoc.php000066600000032457152503076400006745 0ustar00<?php /***************************************************************************\ * SPIP, Systeme de publication pour l'internet * * * * Copyright (c) 2001-2014 * * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James * * * * Ce programme est un logiciel libre distribue sous licence GNU/GPL. * * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. * \***************************************************************************/ if (!defined('_ECRIRE_INC_VERSION')) return; global $tables_images, $tables_sequences, $tables_documents, $tables_mime, $mime_alias; $tables_images = array( // Images reconnues par PHP 'jpg' => 'JPEG', 'png' => 'PNG', 'gif' => 'GIF', // Autres images (peuvent utiliser le tag <img>) 'bmp' => 'BMP', ); // Multimedia (peuvent utiliser le tag <embed>) $tables_sequences = array( 'aac' => 'Advanced Audio Coding', 'ac3' => 'AC-3 Compressed Audio', 'aifc' => 'Compressed AIFF Audio', 'aiff' => 'AIFF', 'amr' => 'Adaptive Multi-Rate Audio', 'anx' => 'Annodex', 'ape' => 'Monkey\'s Audio File', 'axa' => 'Annodex Audio', 'axv' => 'Annodex Video', 'asf' => 'Windows Media', 'avi' => 'AVI', 'dv' => 'Digital Video', 'f4a' => 'Audio for Adobe Flash Player', 'f4b' => 'Audio Book for Adobe Flash Player', 'f4p' => 'Protected Video for Adobe Flash Player', 'f4v' => 'Video for Adobe Flash Player', 'flac' => 'Free Lossless Audio Codec', 'flv' => 'Flash Video', 'm2p' => 'MPEG-PS', 'm2ts' => 'BDAV MPEG-2 Transport Stream', 'm4a' => 'MPEG4 Audio', 'm4b' => 'MPEG4 Audio', 'm4p' => 'MPEG4 Audio', 'm4r' => 'iPhone Ringtone', 'm4v' => 'MPEG4 Video', 'mid' => 'Midi', 'mng' => 'MNG', 'mka' => 'Matroska Audio', 'mkv' => 'Matroska Video', 'mov' => 'QuickTime', 'mp3' => 'MP3', 'mp4' => 'MPEG4', 'mpc' => 'Musepack', 'mpg' => 'MPEG', 'mts' => 'AVCHD MPEG-2 transport stream', 'oga' => 'Ogg Audio', 'ogg' => 'Ogg Vorbis', 'ogv' => 'Ogg Video', 'ogx' => 'Ogg Multiplex', 'qt' => 'QuickTime', 'ra' => 'RealAudio', 'ram' => 'RealAudio', 'rm' => 'RealAudio', 'spx' => 'Ogg Speex', 'svg' => 'Scalable Vector Graphics', 'svgz' => 'Compressed Scalable Vector Graphic', 'swf' => 'Flash', 'tif' => 'TIFF', 'ts' => 'MPEG transport stream', 'wav' => 'WAV', 'webm' => 'WebM', 'wma' => 'Windows Media Audio', 'wmv' => 'Windows Media Video', 'y4m' => 'YUV4MPEG2', '3ga' => '3GP Audio File', '3gp' => '3rd Generation Partnership Project' ); // Documents varies $tables_documents = array( '7z' => '7 Zip', 'abw' => 'Abiword', 'ai' => 'Adobe Illustrator', 'asx' => 'Advanced Stream Redirector', 'bib' => 'BibTeX', 'bz2' => 'BZip', 'bin' => 'Binary Data', 'blend' => 'Blender', 'c' => 'C source', 'cls' => 'LaTeX Class', 'csl' => 'Citation Style Language', 'css' => 'Cascading Style Sheet', 'csv' => 'Comma Separated Values', 'deb' => 'Debian', 'doc' => 'Word', 'dot' => 'Word Template', 'djvu' => 'DjVu', 'dvi' => 'LaTeX DVI', 'emf' => 'Enhanced Metafile', 'enl' => 'EndNote Library', 'ens' => 'EndNote Style', 'epub' => 'EPUB', 'eps' => 'PostScript', 'gpx' => 'GPS eXchange Format', 'gz' => 'GZ', 'h' => 'C header', 'html' => 'HTML', 'jar' => 'Java Archive', 'json' => 'JSON', 'kml' => 'Keyhole Markup Language', 'kmz' => 'Google Earth Placemark File', 'lyx' => 'Lyx file', 'mathml' => 'MathML', 'mbtiles' => 'MBTiles', 'm3u' => 'M3U Playlist', 'm3u8' => 'M3U8 Playlist', 'm4u' => 'MPEG4 Playlist', 'pas' => 'Pascal', 'pdf' => 'PDF', 'pgn' => 'Portable Game Notation', 'pls' => 'Playlist', 'pot' => 'PowerPoint Template', 'ppt' => 'PowerPoint', 'ps' => 'PostScript', 'psd' => 'Photoshop', 'rar' => 'WinRAR', 'rdf' => 'Resource Description Framework', 'ris' => 'RIS', 'rpm' => 'RedHat/Mandrake/SuSE', 'rtf' => 'RTF', 'sdc' => 'StarOffice Spreadsheet', 'sdd' => 'StarOffice Presentation', 'sdw' => 'StarOffice Writer document', 'sit' => 'Stuffit', 'sla' => 'Scribus', 'srt' => 'SubRip Subtitle', 'ssa' => 'SubStation Alpha Subtitle', 'sty' => 'LaTeX Style Sheet', 'sxc' => 'OpenOffice.org Calc', 'sxi' => 'OpenOffice.org Impress', 'sxw' => 'OpenOffice.org', 'tar' => 'Tar', 'tex' => 'LaTeX', 'tgz' => 'TGZ', 'torrent' => 'BitTorrent', 'ttf' => 'TTF Font', 'txt' => 'Texte', 'usf' => 'Universal Subtitle Format', 'wmf' => 'Windows Metafile', 'wpl' => 'Windows Media Player Playlist', 'xcf' => 'GIMP multi-layer', 'xspf' => 'XSPF', 'xls' => 'Excel', 'xlt' => 'Excel Template', 'xml' => 'XML', 'y4m' => 'YUV4MPEG2', 'yaml' => 'YAML', 'zip' => 'Zip', // open document format 'odb' => 'OpenDocument Database', 'odc' => 'OpenDocument Chart', 'odf' => 'OpenDocument Formula', 'odg' => 'OpenDocument Graphics', 'odi' => 'OpenDocument Image', 'odm' => 'OpenDocument Text-master', 'odp' => 'OpenDocument Presentation', 'ods' => 'OpenDocument Spreadsheet', 'odt' => 'OpenDocument Text', 'otg' => 'OpenDocument Graphics-template', 'otp' => 'OpenDocument Presentation-template', 'ots' => 'OpenDocument Spreadsheet-template', 'ott' => 'OpenDocument Text-template', // Open XML File Formats 'docm' => 'Word', 'docx' => 'Word', 'dotm' => 'Word template', 'dotx' => 'Word template', 'potm' => 'Powerpoint template', 'potx' => 'Powerpoint template', 'ppam' => 'Powerpoint addin', 'ppsm' => 'Powerpoint slideshow', 'ppsx' => 'Powerpoint slideshow', 'pptm' => 'Powerpoint', 'pptx' => 'Powerpoint', 'xlam' => 'Excel', 'xlsb' => 'Excel binary', 'xlsm' => 'Excel', 'xlsx' => 'Excel', 'xltm' => 'Excel template', 'xltx' => 'Excel template' ); $tables_mime = array( // Images reconnues par PHP 'jpg' => 'image/jpeg', 'png' => 'image/png', 'gif' => 'image/gif', // Autres images (peuvent utiliser le tag <img>) 'bmp' => 'image/x-ms-bmp', // pas enregistre par IANA, variante: image/bmp 'tif' => 'image/tiff', // Multimedia (peuvent utiliser le tag <embed>) 'aac' => 'audio/mp4a-latm', 'ac3' => 'audio/x-aac', 'aifc' => 'audio/x-aifc', 'aiff' => 'audio/x-aiff', 'amr' => 'audio/amr', 'ape' => 'audio/x-monkeys-audio', 'asf' => 'video/x-ms-asf', 'avi' => 'video/x-msvideo', 'anx' => 'application/annodex', 'axa' => 'audio/annodex', 'axv' => 'video/annodex', 'dv' => 'video/x-dv', 'f4a' => 'audio/mp4', 'f4b' => 'audio/mp4', 'f4p' => 'video/mp4', 'f4v' => 'video/mp4', 'flac' => 'audio/x-flac', 'flv' => 'video/x-flv', 'm2p' => 'video/MP2P', 'm2ts' => 'video/MP2T', 'm4a' => 'audio/mp4a-latm', 'm4b' => 'audio/mp4a-latm', 'm4p' => 'audio/mp4a-latm', 'm4r' => 'audio/aac', 'm4u' => 'video/vnd.mpegurl', 'm4v' => 'video/x-m4v', 'mid' => 'audio/midi', 'mka' => 'audio/mka', 'mkv' => 'video/mkv', 'mng' => 'video/x-mng', 'mov' => 'video/quicktime', 'mp3' => 'audio/mpeg', 'mp4' => 'application/mp4', 'mpc' => 'audio/x-musepack', 'mpg' => 'video/mpeg', 'mts' => 'video/MP2T', 'oga' => 'audio/ogg', 'ogg' => 'audio/ogg', 'ogv' => 'video/ogg', 'ogx' => 'application/ogg', 'qt' => 'video/quicktime', 'ra' => 'audio/x-pn-realaudio', 'ram' => 'audio/x-pn-realaudio', 'rm' => 'audio/x-pn-realaudio', 'spx' => 'audio/ogg', 'svg' => 'image/svg+xml', 'svgz' => 'image/svg+xml', 'swf' => 'application/x-shockwave-flash', 'ts' => 'video/MP2T', 'wav' => 'audio/x-wav', 'webm' => 'video/webm', 'wma' => 'audio/x-ms-wma', 'wmv' => 'video/x-ms-wmv', 'y4m' => 'video/x-raw-yuv', '3gp' => 'video/3gpp', '3ga' => 'audio/3ga', // Documents varies '7z' => 'application/x-7z-compressed', 'ai' => 'application/illustrator', 'abw' => 'application/abiword', 'asx' => 'video/x-ms-asf', 'bib' => 'application/x-bibtex', 'bin' => 'application/octet-stream', # le tout-venant 'blend' => 'application/x-blender', 'bz2' => 'application/x-bzip2', 'c' => 'text/x-csrc', 'csl' => 'application/xml', 'css' => 'text/css', 'csv' => 'text/csv', 'deb' => 'application/x-debian-package', 'doc' => 'application/msword', 'dot' => 'application/msword', 'djvu' => 'image/vnd.djvu', 'dvi' => 'application/x-dvi', 'emf' => 'image/x-emf', 'enl' => 'application/octet-stream', 'ens' => 'application/octet-stream', 'eps' => 'application/postscript', 'epub' => 'application/epub+zip', // pas enregistre par IANA 'gpx' => 'application/gpx+xml', // pas enregistre par IANA 'gz' => 'application/x-gzip', 'h' => 'text/x-chdr', 'html' => 'text/html', 'jar' => 'application/java-archive', 'json' => 'application/json', 'kml' => 'application/vnd.google-earth.kml+xml', 'kmz' => 'application/vnd.google-earth.kmz', 'lyx' => 'application/x-lyx', 'm3u' => 'text/plain', 'm3u8' => 'text/plain', 'mathml' => 'application/mathml+xml', 'mbtiles' => 'application/x-sqlite3', 'pas' => 'text/x-pascal', 'pdf' => 'application/pdf', 'pgn' => 'application/x-chess-pgn', 'pls' => 'text/plain', 'ppt' => 'application/vnd.ms-powerpoint', 'pot' => 'application/vnd.ms-powerpoint', 'ps' => 'application/postscript', 'psd' => 'image/x-photoshop', // pas enregistre par IANA 'rar' => 'application/x-rar-compressed', 'rdf' => 'application/rdf+xml', 'ris' => 'application/x-research-info-systems', 'rpm' => 'application/x-redhat-package-manager', 'rtf' => 'application/rtf', 'sdc' => 'application/vnd.stardivision.calc', 'sdd' => 'application/vnd.stardivision.impress', 'sdw' => 'application/vnd.stardivision.writer', 'sit' => 'application/x-stuffit', 'sla' => 'application/x-scribus', 'srt' => 'text/plain', 'ssa' => 'text/plain', 'sxc' => 'application/vnd.sun.xml.calc', 'sxi' => 'application/vnd.sun.xml.impress', 'sxw' => 'application/vnd.sun.xml.writer', 'tar' => 'application/x-tar', 'tex' => 'text/x-tex', 'tgz' => 'application/x-gtar', 'torrent' => 'application/x-bittorrent', 'ttf' => 'application/x-font-ttf', 'txt' => 'text/plain', 'usf' => 'application/xml', 'xcf' => 'application/x-xcf', 'xls' => 'application/vnd.ms-excel', 'xlt' => 'application/vnd.ms-excel', 'wmf' => 'image/x-emf', 'wpl' => 'application/vnd.ms-wpl', 'xspf' => 'application/xspf+xml', 'xml' => 'application/xml', 'yaml' => 'text/yaml', 'zip' => 'application/zip', // Open Document format 'odt' => 'application/vnd.oasis.opendocument.text', 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', 'odp' => 'application/vnd.oasis.opendocument.presentation', 'odg' => 'application/vnd.oasis.opendocument.graphics', 'odc' => 'application/vnd.oasis.opendocument.chart', 'odf' => 'application/vnd.oasis.opendocument.formula', 'odb' => 'application/vnd.oasis.opendocument.database', 'odi' => 'application/vnd.oasis.opendocument.image', 'odm' => 'application/vnd.oasis.opendocument.text-master', 'ott' => 'application/vnd.oasis.opendocument.text-template', 'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template', 'otp' => 'application/vnd.oasis.opendocument.presentation-template', 'otg' => 'application/vnd.oasis.opendocument.graphics-template', 'cls' => 'text/x-tex', 'sty' => 'text/x-tex', // Open XML File Formats 'docm' => 'application/vnd.ms-word.document.macroEnabled.12', 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'dotm' => 'application/vnd.ms-word.template.macroEnabled.12', 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', 'potm' => 'application/vnd.ms-powerpoint.template.macroEnabled.12', 'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template', 'ppam' => 'application/vnd.ms-powerpoint.addin.macroEnabled.12', 'ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12', 'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', 'pptm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12', 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12', 'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12', 'xlsm' => 'application/vnd.ms-excel.sheet.macroEnabled.12', 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'xltm' => 'application/vnd.ms-excel.template.macroEnabled.12', 'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template' ); $mime_alias = array ( 'application/x-ogg' => 'application/ogg', 'audio/3gpp' => 'video/3gpp', 'audio/x-mpeg' => 'audio/mpeg', 'audio/x-musepack' => 'audio/musepack', 'audio/webm' => 'video/webm', 'video/flv' => 'video/x-flv', 'video/mp4' => 'application/mp4', 'image/jpg' => 'image/jpeg' ); ?> stats.php000066600000004754152503077120006433 0ustar00<?php /***************************************************************************\ * SPIP, Systeme de publication pour l'internet * * * * Copyright (c) 2001-2014 * * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James * * * * Ce programme est un logiciel libre distribue sous licence GNU/GPL. * * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. * \***************************************************************************/ if (!defined("_ECRIRE_INC_VERSION")) return; function stats_declarer_tables_auxiliaires($tables_auxiliaires){ $spip_visites = array( "date" => "DATE NOT NULL", "visites" => "int UNSIGNED DEFAULT '0' NOT NULL", "maj" => "TIMESTAMP"); $spip_visites_key = array( "PRIMARY KEY" => "date"); $spip_visites_articles = array( "date" => "DATE NOT NULL", "id_article" => "int UNSIGNED NOT NULL", "visites" => "int UNSIGNED DEFAULT '0' NOT NULL", "maj" => "TIMESTAMP"); $spip_visites_articles_key = array( "PRIMARY KEY" => "date, id_article"); $spip_referers = array( "referer_md5" => "bigint UNSIGNED NOT NULL", "date" => "DATE NOT NULL", "referer" => "VARCHAR (255)", "visites" => "int UNSIGNED NOT NULL", "visites_jour" => "int UNSIGNED NOT NULL", "visites_veille"=> "int UNSIGNED NOT NULL", "maj" => "TIMESTAMP"); $spip_referers_key = array( "PRIMARY KEY" => "referer_md5"); $spip_referers_articles = array( "id_article" => "int UNSIGNED NOT NULL", "referer_md5" => "bigint UNSIGNED NOT NULL", "referer" => "VARCHAR (255) DEFAULT '' NOT NULL", "visites" => "int UNSIGNED NOT NULL", "maj" => "TIMESTAMP"); $spip_referers_articles_key = array( "PRIMARY KEY" => "id_article, referer_md5", "KEY referer_md5" => "referer_md5"); $tables_auxiliaires['spip_visites'] = array( 'field' => &$spip_visites, 'key' => &$spip_visites_key); $tables_auxiliaires['spip_visites_articles'] = array( 'field' => &$spip_visites_articles, 'key' => &$spip_visites_articles_key); $tables_auxiliaires['spip_referers'] = array( 'field' => &$spip_referers, 'key' => &$spip_referers_key); $tables_auxiliaires['spip_referers_articles'] = array( 'field' => &$spip_referers_articles, 'key' => &$spip_referers_articles_key); return $tables_auxiliaires; } ?> delete_referers.php000066600000002771152503077120010431 0ustar00<?php /***************************************************************************\ * SPIP, Systeme de publication pour l'internet * * * * Copyright (c) 2001-2014 * * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James * * * * Ce programme est un logiciel libre distribue sous licence GNU/GPL. * * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. * \***************************************************************************/ if (!defined("_ECRIRE_INC_VERSION")) return; // securiser // faudrait plutot recuperer dans inc_serialbase et inc_auxbase // mais il faudra prevenir ceux qui affectent les globales qui s'y trouvent // Afficher la liste de ce qu'on va detruire et demander confirmation // ca vaudrait mieux /** * Supprimer les referers * @param strinf $titre * @param bool $reprise * @return string */ function base_delete_referers_dist($titre='', $reprise='') { if (!$titre) return; // anti-testeur automatique sql_delete("spip_referers"); sql_delete("spip_referers_articles"); sql_update("spip_articles", array('referers'=>0)); // un pipeline pour detruire les tables de referers installees par les plugins ? //pipeline('delete_referers', ''); spip_log("raz des referers operee redirige vers " . _request('redirect')); } ?> delete_stats.php000066600000003115152503077120007743 0ustar00<?php /***************************************************************************\ * SPIP, Systeme de publication pour l'internet * * * * Copyright (c) 2001-2014 * * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James * * * * Ce programme est un logiciel libre distribue sous licence GNU/GPL. * * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. * \***************************************************************************/ if (!defined("_ECRIRE_INC_VERSION")) return; // securiser // faudrait plutot recuperer dans inc_serialbase et inc_auxbase // mais il faudra prevenir ceux qui affectent les globales qui s'y trouvent // Afficher la liste de ce qu'on va detruire et demander confirmation // ca vaudrait mieux /** * Supprimer les stats * @param strinf $titre * @param bool $reprise * @return string */ function base_delete_stats_dist($titre='', $reprise='') { if (!$titre) return; // anti-testeur automatique sql_delete("spip_visites"); sql_delete("spip_visites_articles"); sql_delete("spip_referers"); sql_delete("spip_referers_articles"); sql_update("spip_articles", array('visites'=>0, 'referers'=>0, 'popularite'=>0)); // un pipeline pour detruire les tables de stats installees par les plugins pipeline('delete_statistiques', ''); spip_log("raz des stats operee redirige vers " . _request('redirect')); } ?> petitions.php000066600000012204152503077710007305 0ustar00<?php /***************************************************************************\ * SPIP, Systeme de publication pour l'internet * * * * Copyright (c) 2001-2014 * * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James * * * * Ce programme est un logiciel libre distribue sous licence GNU/GPL. * * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. * \***************************************************************************/ if (!defined('_ECRIRE_INC_VERSION')) return; /** * Interfaces des tables petitions et signatures pour le compilateur * * @param array $interfaces * @return array */ function petitions_declarer_tables_interfaces($interfaces){ $interfaces['table_des_tables']['petitions']='petitions'; $interfaces['table_des_tables']['signatures']='signatures'; $interfaces['exceptions_des_tables']['signatures']['date']='date_time'; $interfaces['exceptions_des_tables']['signatures']['nom']='nom_email'; $interfaces['exceptions_des_tables']['signatures']['email']='ad_email'; $interfaces['tables_jointures']['spip_articles'][]= 'petitions'; $interfaces['tables_jointures']['spip_articles'][]= 'signatures'; $interfaces['exceptions_des_jointures']['petition'] = array('spip_petitions', 'texte'); $interfaces['exceptions_des_jointures']['id_signature']= array('spip_signatures', 'id_signature'); $interfaces['table_des_traitements']['MESSAGE'][]= _TRAITEMENT_RACCOURCIS; // Signatures : passage des donnees telles quelles, sans traitement typo // la securite et conformite XHTML de ces champs est assuree par safehtml() foreach(array('NOM_EMAIL','AD_EMAIL','NOM_SITE','URL_SITE','MESSAGE') as $balise) if (!isset($interfaces['table_des_traitements'][$balise]['signatures'])) $interfaces['table_des_traitements'][$balise]['signatures'] = 'liens_nofollow(safehtml(%s))'; else if (strpos($interfaces['table_des_traitements'][$balise]['signatures'],'safehtml')==false) $interfaces['table_des_traitements'][$balise]['signatures'] = 'liens_nofollow(safehtml('.$interfaces['table_des_traitements'][$balise]['signatures'].'))'; return $interfaces; } function petitions_declarer_tables_objets_sql($tables){ $tables['spip_petitions'] = array( 'url_voir'=>'controler_petition', 'url_edit'=>'controler_petition', 'editable'=>'non', 'principale' => 'oui', 'page'=>'', // pas de page editoriale pour une petition 'texte_retour' => 'icone_retour', 'texte_objets' => 'petitions:titre_petitions', 'texte_objet' => 'petitions:titre_petition', 'titre' => "texte as titre, '' AS lang", 'field'=> array( "id_petition" => "bigint(21) NOT NULL", "id_article" => "bigint(21) DEFAULT '0' NOT NULL", "email_unique" => "CHAR (3) DEFAULT '' NOT NULL", "site_obli" => "CHAR (3) DEFAULT '' NOT NULL", "site_unique" => "CHAR (3) DEFAULT '' NOT NULL", "message" => "CHAR (3) DEFAULT '' NOT NULL", "texte" => "LONGTEXT DEFAULT '' NOT NULL", "statut" => "VARCHAR (10) DEFAULT 'publie' NOT NULL", "maj" => "TIMESTAMP" ), 'key' => array( "PRIMARY KEY" => "id_petition", "UNIQUE id_article" => "id_article" ), 'statut' => array( array('champ'=>'statut','publie'=>'publie,off','previsu'=>'publie,off','exception'=>array('statut')), ), ); $tables['spip_signatures'] = array( 'url_voir'=>'controler_petition', 'url_edit'=>'controler_petition', 'editable'=>'non', 'principale' => 'oui', 'page'=>'', // pas de page editoriale pour une signature 'texte_retour' => 'icone_retour', 'texte_objets' => 'public:signatures_petition', 'texte_objet' => 'entree_signature', 'info_aucun_objet'=> 'petitions:aucune_signature', 'info_1_objet' => 'petitions:une_signature', 'info_nb_objets' => 'petitions:nombre_signatures', 'titre' => "nom_email as titre, '' AS lang", 'date' => 'date_time', 'field'=> array( "id_signature" => "bigint(21) NOT NULL", "id_petition" => "bigint(21) DEFAULT '0' NOT NULL", # "id_article" => "bigint(21) DEFAULT '0' NOT NULL", "date_time" => "datetime DEFAULT '0000-00-00 00:00:00' NOT NULL", "nom_email" => "text DEFAULT '' NOT NULL", "ad_email" => "text DEFAULT '' NOT NULL", "nom_site" => "text DEFAULT '' NOT NULL", "url_site" => "text DEFAULT '' NOT NULL", "message" => "mediumtext DEFAULT '' NOT NULL", "statut" => "varchar(10) DEFAULT '0' NOT NULL", "maj" => "TIMESTAMP" ), 'key' => array( "PRIMARY KEY" => "id_signature", "KEY id_petition" => "id_petition", # "KEY id_article" => "id_article", "KEY statut" => "statut" ), 'join' => array( "id_signature"=>"id_signature", "id_petition"=>"id_petition" ), 'tables_jointures'=> array( 'petitions' ), 'statut' => array( array('champ'=>'statut','publie'=>'publie','previsu'=>'publie','exception'=>array('statut','tout')), ), 'rechercher_champs' => array( 'nom_email' => 2, 'ad_email' => 4, 'nom_site' => 2, 'url_site' => 4, 'message' => 1 ), 'icone_objet' => 'petition', ); return $tables; } ?>
/home/etiennec/www/tmp/../eb1f2/../squelettes-dist/../f1f54/base.tar