[SPIP] ~2.1.12 -->2.1.25
[velocampus/web/www.git] / www / ecrire / base / trouver_table.php
1 <?php
2
3 /***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
5 * *
6 * Copyright (c) 2001-2014 *
7 * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
8 * *
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 \***************************************************************************/
12
13 if (!defined('_ECRIRE_INC_VERSION')) return;
14 include_spip('public/interfaces');
15
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
30
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;
35
36 if (!spip_connect($serveur)
37 OR !preg_match('/^[a-zA-Z0-9._-]*/',$nom))
38 return null;
39
40 $connexion = &$GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0];
41
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)
50 .'.txt';
51
52 // un appel avec $nom vide est une demande explicite de vidange du cache des descriptions
53 if (!$nom){
54 spip_unlink($nom_cache_desc_sql[$serveur]);
55 $connexion['tables'] = array();
56 return null;
57 }
58
59 $nom_sql = $nom;
60 if (preg_match('/\.(.*)$/', $nom, $s))
61 $nom_sql = $s[1];
62 else
63 $nom_sql = $nom;
64
65 $desc = '';
66
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;
73 }
74 }
75
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;
86 }
87 if (!isset($connexion['tables'][$nom])) {
88 include_spip('base/serial');
89
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];
98 }
99 else {
100 include_spip('base/auxiliaires');
101 if (isset($tables_auxiliaires['spip_' .$nom])) {
102 $nom_sql = 'spip_' . $nom;
103 $fdesc = &$tables_auxiliaires[$nom_sql];
104 } else { # table locale a cote de SPIP, comme non SPIP:
105 $fdesc = array();
106 }
107 }
108
109 // faut il interpreter le prefixe 'spip_' ?
110 $transposer_spip = ($nom_sql != $nom);
111
112 // La *vraie* base a la priorite
113 if (true /* !$bdesc OR !$bdesc['field'] */) {
114 $desc = sql_showtable($nom_sql, $transposer_spip, $serveur);
115 if (!$desc OR !$desc['field']) {
116 if (!$fdesc) {
117 spip_log("trouver_table: table inconnue '$serveur' '$nom'");
118 return null;
119 }
120 // on ne sait pas lire la structure de la table :
121 // on retombe sur la description donnee dans les fichiers spip
122 $desc = $fdesc;
123 }
124 }
125 // S'il n'y a pas de key (cas d'une VIEW),
126 // on va inventer une PRIMARY KEY en prenant le premier champ
127 // de la table
128 if (!$desc['key']){
129 $p = array_keys($desc['field']);
130 $desc['key']['PRIMARY KEY'] = array_shift($p);
131 }
132
133 $desc['table']= $nom_sql;
134 $desc['connexion']= $serveur;
135 // objet_type peut provoquer un appel reentrant ici.
136 // pour ne pas faire de boucle infinie, on stocke ce qu'on a deja trouve
137 $connexion['tables'][$nom] = $desc;
138
139 $table = table_objet(objet_type($nom));
140 $desc['titre'] = isset($GLOBALS['table_titre'][$table])
141 ? $GLOBALS['table_titre'][$table]
142 : (isset($desc['field']['titre']) ? 'titre' : '');
143 $connexion['tables'][$nom] = $desc;
144 // une nouvelle table a ete decrite
145 // mettons donc a jour le cache des descriptions de ce serveur
146 if (is_writeable(_DIR_CACHE))
147 ecrire_fichier($nom_cache_desc_sql[$serveur],serialize($connexion['tables']));
148 }
149
150 $connexion['tables'][$nom]['id_table']=$nom;
151 return $connexion['tables'][$nom];
152 }
153 ?>