3 /***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
6 * Copyright (c) 2001-2011 *
7 * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
9 * Ce programme est un logiciel libre distribue sous licence GNU/GPL. *
10 * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. *
11 \***************************************************************************/
13 if (!defined('_ECRIRE_INC_VERSION')) return;
14 include_spip('public/interfaces');
16 // Trouve la description d'une table, en particulier celle d'une boucle
17 // Si on ne la trouve pas, on demande au serveur SQL
18 // retourne False si lui non plus ne la trouve pas.
19 // Si on la trouve, le tableau resultat a les entrees:
20 // field (comme dans serial.php)
21 // key (comme dans serial.php)
22 // table = nom SQL de la table (avec le prefixe spip_ pour les stds)
23 // id_table = nom SPIP de la table (i.e. type de boucle)
24 // le compilateur produit FROM $r['table'] AS $r['id_table']
25 // Cette fonction intervient a la compilation,
26 // mais aussi pour la balise contextuelle EXPOSE.
27 // l'ensemble des descriptions de table d'un serveur est stocke dans un fichier cache/sql_dec.txt
28 // par soucis de performance
29 // un appel avec $nom vide est une demande explicite de vidange du cache des descriptions
31 // http://doc.spip.org/@base_trouver_table_dist
32 function base_trouver_table_dist($nom, $serveur=''){
33 static $nom_cache_desc_sql=array();
34 global $tables_principales, $tables_auxiliaires, $table_des_tables;
36 if (!spip_connect($serveur)
37 OR !preg_match('/^[a-zA-Z0-9._-]*/',$nom))
40 $connexion = &$GLOBALS['connexions'][$serveur ?
strtolower($serveur) : 0];
42 // le nom du cache depend du serveur mais aussi du nom de la db et du prefixe
43 // ce qui permet une auto invalidation en cas de modif manuelle du fichier
44 // de connexion, et tout risque d'ambiguite
45 if (!isset($nom_cache_desc_sql[$serveur]))
46 $nom_cache_desc_sql[$serveur] =
47 _DIR_CACHE
. 'sql_desc_'
48 . ($serveur ?
"$serveur_":"")
49 . substr(md5($connexion['db'].":".$connexion['prefixe']),0,8)
52 // un appel avec $nom vide est une demande explicite de vidange du cache des descriptions
54 spip_unlink($nom_cache_desc_sql[$serveur]);
55 $connexion['tables'] = array();
60 if (preg_match('/\.(.*)$/', $nom, $s))
67 // base sous SPIP: gerer les abreviations explicites des noms de table
68 if ($connexion['spip_connect_version']) {
69 include_spip('public/interfaces');
70 if (isset($table_des_tables[$nom])) {
71 $nom = $table_des_tables[$nom];
72 $nom_sql = 'spip_' . $nom;
76 // si c'est la premiere table qu'on cherche
77 // et si on est pas explicitement en recalcul
78 // on essaye de recharger le cache des decriptions de ce serveur
79 // dans le fichier cache
80 if (!isset($connexion['tables'][$nom])
81 AND $GLOBALS['var_mode']!=='recalcul'
82 AND (!isset($connexion['tables']) OR !$connexion['tables'])) {
83 if (lire_fichier($nom_cache_desc_sql[$serveur],$desc_cache)
84 AND $desc_cache=unserialize($desc_cache))
85 $connexion['tables'] = $desc_cache;
87 if (!isset($connexion['tables'][$nom])) {
88 include_spip('base/serial');
90 if (isset($tables_principales[$nom_sql]))
91 $fdesc = $tables_principales[$nom_sql];
92 // meme si pas d'abreviation declaree, trouver la table spip_$nom
93 // si c'est une table principale,
94 // puisqu'on le fait aussi pour les tables auxiliaires
95 elseif ($nom_sql==$nom AND isset($tables_principales['spip_' .$nom])){
96 $nom_sql = 'spip_' . $nom;
97 $fdesc = &$tables_principales[$nom_sql];
100 include_spip('base/auxiliaires');
101 if (isset($tables_auxiliaires['spip_' .$nom])) {
102 $nom_sql = 'spip_' . $nom;
103 $fdesc = &$tables_auxiliaires[$nom_sql];
104 } # table locale a cote de SPIP, comme non SPIP:
107 // faut il interpreter le prefixe 'spip_' ?
108 $transposer_spip = ($nom_sql != $nom);
110 // La *vraie* base a la priorite
111 if (true /* !$bdesc OR !$bdesc['field'] */) {
112 $desc = sql_showtable($nom_sql, $transposer_spip, $serveur);
113 if (!$desc OR !$desc['field']) {
115 spip_log("trouver_table: table inconnue '$serveur' '$nom'");
118 // on ne sait pas lire la structure de la table :
119 // on retombe sur la description donnee dans les fichiers spip
123 // S'il n'y a pas de key (cas d'une VIEW),
124 // on va inventer une PRIMARY KEY en prenant le premier champ
127 $desc['key']['PRIMARY KEY'] = array_shift(array_keys($desc['field']));
129 $desc['table']= $nom_sql;
130 $desc['connexion']= $serveur;
131 // objet_type peut provoquer un appel reentrant ici.
132 // pour ne pas faire de boucle infinie, on stocke ce qu'on a deja trouve
133 $connexion['tables'][$nom] = $desc;
135 $table = table_objet(objet_type($nom));
136 $desc['titre'] = isset($GLOBALS['table_titre'][$table])
137 ?
$GLOBALS['table_titre'][$table]
138 : (isset($desc['field']['titre']) ?
'titre' : '');
139 $connexion['tables'][$nom] = $desc;
140 // une nouvelle table a ete decrite
141 // mettons donc a jour le cache des descriptions de ce serveur
142 if (is_writeable(_DIR_CACHE
))
143 ecrire_fichier($nom_cache_desc_sql[$serveur],serialize($connexion['tables']));
146 $connexion['tables'][$nom]['id_table']=$nom;
147 return $connexion['tables'][$nom];