[PLUGINS] ~maj Crayons
[lhc/web/www.git] / www / plugins / crayons / inc / crayons.php
1 <?php
2 /**
3 * Crayons
4 * plugin for spip
5 * (c) Fil, toggg 2006-2013
6 * licence GPL
7 */
8
9 if (!defined('_ECRIRE_INC_VERSION')) {
10 return;
11 }
12
13 define('_PREG_CRAYON', ',crayon\b[^<>\'"]+?\b((\w+)-(\w+)-(\w+(?:-\w+)*))\b,');
14
15 // Compatibilite pour 1.92 : on a besoin de sql_fetch et table_objet_sql
16 if ($GLOBALS['spip_version_code'] < '1.93' and $f = charger_fonction('compat_crayons', 'inc')) {
17 $f();
18 }
19
20 // Autoriser les crayons sur les tables non SPIP ?
21 // Par defaut : oui (pour les admins complets, si autoriser_defaut_dist()) ;
22 // mettre a false en cas de mutualisation par prefixe de table,
23 // sinon on ne peut pas garantir que les sites sont hermetiques
24 if (!defined('_CRAYONS_TABLES_EXTERNES')) {
25 define('_CRAYONS_TABLES_EXTERNES', true);
26 }
27
28 // Autorisations non prevues par le core
29 include_spip('inc/autoriser');
30
31 include_spip('inc/crayons-json');
32
33 if (!function_exists('autoriser_meta_modifier_dist')) {
34 /**
35 * Autorisation d'éditer les configurations dans spip_meta
36 *
37 * Les admins complets OK pour certains champs,
38 * Sinon, il faut être webmestre
39 *
40 * @note
41 * Attention sur les SPIP < 11515 (avant 04/2008) inc/autoriser
42 * passe seulement intval($id) alors qu'ici la cle est une chaine...
43 *
44 * @param string $faire Action demandée
45 * @param string $type Type d'objet sur lequel appliquer l'action
46 * @param int $id Identifiant de l'objet
47 * @param array $qui Description de l'auteur demandant l'autorisation
48 * @param array $opt Options de cette autorisation
49 * @return bool true s'il a le droit, false sinon
50 **/
51 function autoriser_meta_modifier_dist($faire, $type, $id, $qui, $opt) {
52 // Certaines cles de configuration sont echapées ici (cf #EDIT_CONFIG{demo/truc})
53 // $id = str_replace('__', '/', $id);
54 if (in_array($id, array('nom_site', 'slogan_site', 'descriptif_site', 'email_webmaster'))) {
55 return autoriser('configurer', null, null, $qui);
56 } else {
57 return autoriser('webmestre', null, null, $qui);
58 }
59 }
60 }
61
62 // table spip_messages, la c'est tout simplement non (peut mieux faire,
63 // mais c'est a voir dans le core/organiseur ou dans autorite)
64 if (defined('_DIR_PLUGIN_ORGANISEUR')) {
65 include_spip('organiseur_autoriser');
66 }
67
68 if (!function_exists('autoriser_message_modifier_dist')) {
69 function autoriser_message_modifier_dist($faire, $type, $id, $qui, $opt) {
70 return false;
71 }
72 }
73 //compat 192 documents
74 if ($GLOBALS['spip_version_code'] < '1.93') {
75 if (!function_exists('get_spip_doc')) {
76 function get_spip_doc($fichier) {
77 // fichier distant
78 if (preg_match(',^\w+://,', $fichier)) {
79 return $fichier;
80 }
81 // gestion d'erreurs, fichier=''
82 if (!strlen($fichier)) {
83 return false;
84 }
85
86 // fichier normal
87 return (strpos($fichier, _DIR_IMG) === false) ? _DIR_IMG . $fichier : $fichier;
88 }
89 }
90 }
91
92 // Autoriser l'usage des crayons ?
93 function autoriser_crayonner_dist($faire, $type, $id, $qui, $opt) {
94 // Le type pouvant etre une table, verifier les autoriser('modifier')
95 // correspondant ; ils demandent le nom de l'objet: spip_articles => article
96 // ex: spip_articles => 'article'
97 $type = preg_replace(',^spip_(.*?)s?$,', '\1', $type);
98 if (strlen($GLOBALS['table_prefix'])) {
99 $type = preg_replace(',^'.$GLOBALS['table_prefix'].'_(.*?)s?$,', '\1', $type);
100 }
101
102 // Tables non SPIP ? Si elles sont interdites il faut regarder
103 // quelle table on appelle, et verifier si elle est "interne"
104 if (!_CRAYONS_TABLES_EXTERNES) {
105 include_spip('base/serial');
106 include_spip('base/auxiliaires');
107 include_spip('public/parametrer');
108 if (!isset($GLOBALS['tables_principales']['spip_'.table_objet($type)])
109 and !isset($GLOBALS['tables_auxiliaires']['spip_'.table_objet($type)])) {
110 return false;
111 }
112 }
113
114 // Traduire le modele en liste de champs
115 if (isset($opt['modele'])) {
116 $opt['champ'] = $opt['modele'];
117 }
118
119 // Pour un auteur, si le champ est statut ou email, signaler l'option
120 // ad hoc (cf. inc/autoriser)
121 if ($type == 'auteur'
122 and in_array($opt['champ'], array('statut', 'email'))) {
123 $opt[$opt['champ']] = true;
124 }
125
126 return (
127 autoriser('modifier', $type, $id, $qui, $opt)
128 );
129 }
130
131 // Si un logo est demande, on renvoie la date dudit logo (permettra de gerer
132 // un "modifie par ailleurs" si la date a change, rien de plus)
133 function valeur_champ_logo($table, $id, $champ) {
134 $chercher_logo = charger_fonction('chercher_logo', 'inc');
135 $on = $chercher_logo($id, id_table_objet($table), 'on');
136 return $on ? filemtime($on[0]) : false;
137 }
138
139 // Idem : si un doc est demande, on renvoie la date du doc
140 function valeur_champ_document($table, $id, $champ) {
141 $s = spip_query('SELECT date FROM spip_documents WHERE id_document=' . _q($id));
142 if ($t = sql_fetch($s)) {
143 return $t['date'];
144 }
145 }
146
147 function valeur_champ_vignette($table, $id, $champ) {
148 $vignette = sql_getfetsel('id_vignette', 'spip_documents', 'id_document=' . intval($id));
149 if (is_numeric($vignette) && ($vignette > 0)) {
150 $date = sql_getfetsel('date', 'spip_documents', 'id_document=' . intval($vignette));
151 }
152 return $date ? $date : false;
153 }
154 // cette fonction de revision recoit le fichier upload a passer en logo
155 // en reference : le nom du widget, pour aller chercher d'autres donnees
156 // (ex: supprimer)
157 function logo_revision($id, $file, $type, $ref) {
158 $chercher_logo = charger_fonction('chercher_logo', 'inc');
159 $_id_objet = id_table_objet($type);
160
161 // Chargement d'un nouveau logo ?
162 if ($file['logo']) {
163 define('FILE_UPLOAD', true); // message pour crayons_json_export :(
164
165 if (include_spip('action/editer_logo')
166 and function_exists('logo_modifier')) {
167 logo_modifier($type, $id, 'on', $file['logo']);
168 } else {
169 // compat SPIP < 3.1
170 // supprimer l'ancien logo
171 $on = $chercher_logo($id, $_id_objet, 'on');
172 if ($on) {
173 @unlink($on[0]);
174 }
175
176 // ajouter le nouveau
177 include_spip('action/iconifier');
178 action_spip_image_ajouter_dist(type_du_logo($_id_objet) . 'on' . $id, false, false); // beurk
179 }
180 } else {
181 // Suppression du logo ?
182 if ($wid = array_pop($ref)
183 and $_POST['content_'.$wid.'_logo_supprimer'] == 'on') {
184 if (include_spip('action/editer_logo')
185 and function_exists('logo_supprimer')) {
186 logo_supprimer($type, $id, 'on');
187 } else {
188 if ($on = $chercher_logo($id, $_id_objet, 'on')) {
189 @unlink($on[0]);
190 }
191 }
192 }
193 }
194
195 // Reduire le logo ?
196 if (is_array($cfg = @unserialize($GLOBALS['meta']['crayons']))
197 and $max = intval($cfg['reduire_logo'])) {
198 $on = $chercher_logo($id, $_id_objet, 'on');
199 include_spip('inc/filtres');
200 @copy($on[0], $temp = _DIR_VAR . 'tmp' . rand(0, 999) . '.' . $on[3]);
201 $img1 = filtrer('image_reduire', $temp, $max);
202 $img2 = preg_replace(',[?].*,', '', extraire_attribut($img1, 'src'));
203 if (@file_exists($img2)
204 and $img2 != $temp) {
205 if (include_spip('action/editer_logo')
206 and function_exists('logo_modifier')) {
207 logo_modifier($type, $id, 'on', $img2);
208 } else {
209 @unlink($on[0]);
210 $dest = $on[1].$on[2].'.'
211 .preg_replace(',^.*\.(gif|jpg|png)$,', '\1', $img2);
212 @rename($img2, $dest);
213 }
214 }
215 @unlink($temp);
216 }
217
218 return true;
219 }
220
221
222 // cette fonction de revision recoit le fichier upload a passer en document
223 function document_fichier_revision($id, $data, $type, $ref) {
224
225 $s = spip_query('SELECT * FROM spip_documents WHERE id_document=' . intval($id));
226 if (!$t = sql_fetch($s)) {
227 return false;
228 }
229
230 /*
231 // Envoi d'une URL de document distant ?
232 // TODO: verifier l'extension distante, sinon tout explose
233 if ($data['fichier']
234 AND preg_match(',^(https?|ftp)://.+,', $data['fichier'])) {
235 include_spip('inc/modifier');
236 modifier_contenu('document', $id,
237 array('champs' => array('fichier', 'distant')),
238 array('fichier' => $data['fichier'], 'distant' => 'oui')
239 );
240 return true;
241 }
242 else
243 */
244
245 // Chargement d'un nouveau doc ?
246 if ($data['document']) {
247 $arg = $data['document'];
248 /**
249 * Méthode >= SPIP 3.0
250 * ou SPIP 2.x + Mediathèque
251 */
252 if ($ajouter_documents = charger_fonction('ajouter_documents', 'action', true)) {
253 $actifs = $ajouter_documents($id, array($arg), '', 0, $t['mode']);
254 $x = reset($actifs);
255 if (is_numeric($x)) {
256 return true;
257 } else {
258 return false;
259 }
260 } elseif ($ajouter_documents = charger_fonction('ajouter_documents', 'inc', true)) {
261 /**
262 * Méthode SPIP < 3.0
263 */
264 check_upload_error($arg['error']);
265 $x = $ajouter_documents($arg['tmp_name'], $arg['name'],
266 'article', 0, 'document', null, $actifs);
267 // $actifs contient l'id_document nouvellement cree
268 // on recopie les donnees interessantes dans l'ancien
269 $extension = ', extension ';
270 //compat 192
271 if ($GLOBALS['spip_version_code'] < '1.93') {
272 $extension = '';
273 }
274
275 if ($id_new = array_pop($actifs)
276 and $s = spip_query("SELECT fichier, taille, largeur, hauteur $extension, distant FROM spip_documents
277 WHERE id_document="._q($id_new))
278 and $new = sql_fetch($s)) {
279 define('FILE_UPLOAD', true); // message pour crayons_json_export :(
280
281 // Une vignette doit rester une image
282 if ($t['mode'] == 'vignette'
283 and !in_array($new['extension'], array('jpg', 'gif', 'png'))) {
284 return false;
285 }
286
287 // Maintenant on est bon, on recopie les nouvelles donnees
288 // dans l'ancienne ligne spip_documents
289 include_spip('inc/modifier');
290 modifier_contenu(
291 'document',
292 $id,
293 # 'champs' inutile a partir de SPIP 11348
294 array('champs' => array_keys($new)),
295 $new
296 );
297
298 // supprimer l'ancien document (sauf s'il etait distant)
299 if ($t['distant'] != 'oui'
300 and file_exists(get_spip_doc($t['fichier']))) {
301 supprimer_fichier(get_spip_doc($t['fichier']));
302 }
303
304 // Effacer la ligne temporaire de spip_document
305 spip_query('DELETE FROM spip_documents WHERE id_document='.intval($id_new));
306
307 // oublier id_document temporaire (ca marche chez moi, sinon bof)
308 spip_query('ALTER TABLE spip_documents AUTO_INCREMENT='.intval($id_new));
309
310 return true;
311 }
312 }
313 }
314 }
315
316 // cette fonction de revision soit supprime la vignette d'un document,
317 // soit recoit le fichier upload a passer ou remplacer la vignette du document
318 function vignette_revision($id, $data, $type, $ref) {
319 $s = sql_fetsel('id_document,id_vignette', 'spip_documents', 'id_document = '.intval($id));
320 if (!is_array($s)) {
321 return false;
322 }
323
324 include_spip('inc/modifier');
325 include_spip('inc/documents');
326 include_spip('action/editer_document');//pour revision_document
327 // Chargement d'un nouveau doc ?
328 if ($data['vignette']) {
329 define('FILE_UPLOAD', true);
330 if (is_numeric($s['id_vignette']) and ($s['id_vignette'] > 0)) {
331 spip_log('suppression de la vignette');
332 // Suppression du document
333 $vignette = sql_getfetsel('fichier', 'spip_documents', 'id_document='.intval($s['id_vignette']));
334 if (@file_exists($f = get_spip_doc($vignette))) {
335 spip_log("efface $f");
336 supprimer_fichier($f);
337 }
338 sql_delete('spip_documents', 'id_document='.intval($s['id_vignette']));
339 sql_delete('spip_documents_liens', 'id_document='.intval($s['id_vignette']));
340
341 pipeline(
342 'post_edition',
343 array(
344 'args' => array(
345 'operation' => 'supprimer_document',
346 'table' => 'spip_documents',
347 'id_objet' => $s['id_vignette']
348 ),
349 'data' => null
350 )
351 );
352 $id_vignette = 0;
353 }
354
355 $arg = $data['vignette'];
356 check_upload_error($arg['error']);
357 // Ajout du document comme vignette
358
359 /**
360 * Méthode >= SPIP 3.0
361 * ou SPIP 2.x + Mediatheque
362 */
363 if ($ajouter_documents = charger_fonction('ajouter_documents', 'action', true)) {
364 $x = $ajouter_documents(null,array($arg),'', 0, 'vignette');
365 $vignette = reset($x);
366 if (intval($vignette)) {
367 document_modifier($id, array('id_vignette'=>$vignette));
368 } elseif ($id_vignette) {
369 document_modifier($id, array('id_vignette'=>$id_vignette));
370 }
371 } elseif ($ajouter_documents = charger_fonction('ajouter_documents', 'inc', true)) {
372 /**
373 * Méthode < SPIP 3.0
374 */
375 // On remet l'id_vignette a 0 si on l'a supprimé
376 if ($id_vignette) {
377 revision_document($s['id_document'], array('id_vignette' => 0));
378 }
379 $x = $ajouter_documents($arg['tmp_name'], $arg['name'],'','', 'vignette', $id, $actifs);
380 }
381 } elseif ($wid = array_pop($ref)
382 and $_POST['content_'.$wid.'_vignette_supprimer'] == 'on') {
383 if (is_numeric($s['id_vignette']) and ($s['id_vignette']>0)) {
384 // Suppression du document
385 $vignette = sql_getfetsel('fichier', 'spip_documents', 'id_document='.intval($s['id_vignette']));
386 if (@file_exists($f = get_spip_doc($vignette))) {
387 spip_log("efface $f");
388 supprimer_fichier($f);
389 }
390 sql_delete('spip_documents', 'id_document='.intval($s['id_vignette']));
391 sql_delete('spip_documents_liens', 'id_document = ' . intval($s['id_vignette']));
392
393 pipeline(
394 'post_edition',
395 array(
396 'args' => array(
397 'operation' => 'supprimer_document',
398 'table' => 'spip_documents',
399 'id_objet' => $s['id_vignette']
400 ),
401 'data' => null
402 )
403 );
404
405 // On remet l'id_vignette a 0
406 revision_document($s['id_document'], array('id_vignette'=>0));
407 }
408 }
409 return true;
410 }
411
412
413 function colonne_table($type, $col) {
414 list($distant,$table) = distant_table($type);
415 $nom_table = '';
416 if (!(($tabref = &crayons_get_table($table, $nom_table))
417 && isset($tabref['field'][$col])
418 && ($brut = $tabref['field'][$col]))) {
419 return false;
420 }
421 $ana = explode(' ', $brut);
422 $sta = 0;
423 $sep = '';
424 $ret = array('brut' => $brut,
425 'type' => '', 'notnull' => false, 'long' => 0, 'def' => '');
426 foreach ($ana as $mot) {
427 switch ($sta) {
428 case 0:
429 $ret['type'] = ($mot = strtolower($mot));
430 continue;
431 case 1:
432 if ($mot[strlen($mot) - 1] == ')') {
433 $pos = strpos($mot, '(');
434 $ret['type'] = strtolower(substr($mot, 0, $pos++));
435 $vir = explode(',', substr($mot, $pos, -1));
436 if ($ret['type'] == 'enum') {
437 $ret['enum'] = $vir;
438 } elseif (count($vir) > 1) {
439 $ret['long'] = $vir;
440 } else {
441 $ret['long'] = $vir[0];
442 }
443 $sta = 1;
444 continue;
445 }
446 if (!$sta) {
447 $sta = 1;
448 continue;
449 }
450 continue;
451 case 2:
452 switch (strtolower($mot)) {
453 case 'not':
454 $sta = 3;
455 continue;
456 case 'default':
457 $sta = 4;
458 continue;
459 }
460 continue;
461 case 3:
462 $ret['notnull'] = strtolower($mot) == 'null';
463 $sta = 2;
464 continue;
465 case 4:
466 $df1 = strpos('"\'', $mot[0]) !== false? $mot[0] : '';
467 $sta = 5;
468 continue;
469 case 5:
470 $ret['def'] .= $sep . $mot;
471 if (!$df1) {
472 $sta = 2;
473 continue;
474 }
475 if ($df1 == $mot[strlen($mot) - 1]) {
476 $ret['def'] = substr($ret['def'], 1, -1);
477 $sta = 2;
478 }
479 $sep = ' ';
480 continue;
481 }
482 }
483 return $ret;
484 }
485
486
487 /**
488 * Obtient le nom de la table ainsi que sa ou ses clés primaires
489 *
490 * @param string $type
491 * Table sur laquelle s'applique le crayon.
492 * Ce type peut contenir le nom d'un connecteur distant tel que `{connect}__{table}`
493 *
494 * @return array|bool
495 * - false si on ne trouve pas de table ou de table ayant de clé primaire
496 * - liste :
497 * - - nom de la table sql
498 * - - tableau des noms de clés primaires
499 **/
500 function crayons_get_table_name_and_primary($type) {
501 static $types = array();
502 if (isset($types[$type])) {
503 return $types[$type];
504 }
505
506 $nom_table = '';
507 if ($tabref = &crayons_get_table($type, $nom_table)
508 and ($tabid = explode(',', $tabref['key']['PRIMARY KEY']))) {
509 return $types[$type] = array($nom_table, $tabid);
510 }
511 spip_log('crayons: table ' . $type . ' inconnue');
512 return $types[$type] = false;
513 }
514
515
516 function table_where($type, $id, $where_en_tableau = false) {
517 if (!$infos = crayons_get_table_name_and_primary($type)) {
518 return array(false, false);
519 }
520
521 list($nom_table, $tabid) = $infos;
522
523 if (is_scalar($id)) {
524 $id = explode('-', $id);
525 }
526 // sortie tableau pour sql_updateq
527 if ($where_en_tableau) {
528 $where = array();
529 foreach ($id as $idcol => $idval) {
530 $where[] = '`' . (is_int($idcol) ? trim($tabid[$idcol]) : $idcol) . '`=' . sql_quote($idval);
531 }
532 // sinon sortie texte pour sql_query
533 } else {
534 $where = $and = '';
535 foreach ($id as $idcol => $idval) {
536 $where .= $and . '`' . (is_int($idcol) ? trim($tabid[$idcol]) : $idcol) . '`=' . _q($idval);
537 $and = ' AND ';
538 }
539 }
540 return array($nom_table, $where);
541 }
542 // var_dump(colonne_table('forum', 'id_syndic')); die();
543
544 function valeur_colonne_table_dist($type, $col, $id) {
545
546 // Table introuvable ou sans clé primaire
547 if (!$infos = crayons_get_table_name_and_primary($type)) {
548 return false;
549 }
550 $table = reset($infos);
551
552 $r = array();
553
554 // valeurs non SQL
555 foreach ($col as $champ) {
556 if (function_exists($f = 'valeur_champ_'.$table.'_'.$champ)
557 or function_exists($f = 'valeur_champ_'.$champ)) {
558 $r[$champ] = $f($table, $id, $champ);
559 $col = array_diff($col, array($champ));
560 }
561 }
562
563 // valeurs SQL
564 if (count($col)) {
565 list($distant, $table) = distant_table($type);
566 list($nom_table, $where) = table_where($type, $id);
567
568 if ($s = spip_query(
569 'SELECT `' . implode($col, '`, `') .
570 '` FROM ' . $nom_table . ' WHERE ' . $where,
571 $distant
572 ) and $t = sql_fetch($s)) {
573 $r = array_merge($r, $t);
574 }
575 }
576
577 return $r;
578 }
579
580 /**
581 * Extrait la valeur d'une ou plusieurs colonnes d'une table
582 *
583 * @param string $table
584 * Type d'objet de la table (article)
585 * @param string|array $col
586 * Nom de la ou des colonnes (ps)
587 * @param string $id
588 * Identifiant de l'objet
589 * @return array
590 * Couples Nom de la colonne => Contenu de la colonne
591 **/
592 function valeur_colonne_table($table, $col, $id) {
593 if (!is_array($col)) {
594 $col = array($col);
595 }
596
597 if (function_exists($f = $table . '_valeur_colonne_table_dist')
598 or function_exists($f = $table.'_valeur_colonne_table')
599 or $f = 'valeur_colonne_table_dist') {
600 return $f($table, $col, $id);
601 }
602 }
603
604 /**
605 * Extrait la valeur d'une configuration en meta
606 *
607 * Pour ces données, il n'y a toujours qu'une colonne (valeur),
608 * mais on gère l'enregistrement et la lecture via lire_config ou ecrire_config
609 * dès que l'on demande des sous parties d'une configuration.
610 *
611 * On ne retourne alors ici dans 'valeur' que la sous-partie demandée si
612 * c'est le cas.
613 *
614 * @param string $table
615 * Nom de la table (meta)
616 * @param array $col
617 * Nom des colonnes (valeur)
618 * @param string $id
619 * Nom ou clé de configuration (descriptif_site ou demo__truc pour demo/truc)
620 * @return array
621 * Couple valeur => Contenu de la configuration
622 **/
623 function meta_valeur_colonne_table_dist($table, $col, $id) {
624 // Certaines clés de configuration sont echapées ici (cf #EDIT_CONFIG{demo/truc})
625 $id = str_replace('__', '/', $id);
626
627 // Éviter de planter les vieux SPIP
628 if (false === strpos($id, '/')) {
629 $config = isset($GLOBALS['meta'][$id]) ? $GLOBALS['meta'][$id] : '';
630 // SPIP 3 ou Bonux 2 ou CFG
631 } else {
632 include_spip('inc/config');
633 $config = lire_config($id, '');
634 }
635 return array('valeur' => $config);
636 }
637
638
639 function return_log($var) {
640 die(crayons_json_export(array('$erreur'=> var_export($var, true))));
641 }
642
643 function _U($texte, $params = array()) {
644 include_spip('inc/charsets');
645 return unicode2charset(html2unicode(_T($texte, $params)));
646 }
647
648 /**
649 * Obtenir la configuration des crayons
650 *
651 * @note wdgcfg = widget config :-)
652 *
653 * @return array
654 * Couples : attribut => valeur
655 **/
656 function wdgcfg() {
657 $php = function_exists('crayons_config') ? crayons_config() : array();
658 include_spip('inc/meta');
659 lire_metas();
660 global $meta;
661 $metacrayons = empty($meta['crayons']) ? array() : unserialize($meta['crayons']);
662 $wdgcfg = array();
663 foreach (array(
664 'msgNoChange' => false,
665 'msgAbandon' => false, /* etait: true */
666 'filet' => false,
667 'yellow_fade' => false,
668 'clickhide' => false /* etait: true */
669 ) as $cfgi => $def) {
670 $wdgcfg[$cfgi] = isset($php[$cfgi]) ? $php[$cfgi] :
671 isset($metacrayons[$cfgi]) ? $metacrayons[$cfgi] : $def;
672 }
673 return $wdgcfg;
674 }
675
676 function &crayons_get_table($type, &$nom_table) {
677 list($distant,$table) = distant_table($type);
678 static $return = array();
679 static $noms = array();
680 if (!isset($return[$table])) {
681 $try = array(table_objet_sql($table), 'spip_'.table_objet($table), 'spip_' . $table . 's', $table . 's', 'spip_' . $table, $table);
682
683 // premiere possibilite (à partir de 1.9.3) : regarder directement la base
684 if (function_exists('sql_showtable')) {
685 foreach ($try as $nom) {
686 if ($q = sql_showtable($nom, !$distant, $distant)) {
687 $noms[$table] = $nom;
688 $return[$table] = $q;
689 break;
690 }
691 }
692 }
693
694 // seconde, une heuristique 1.9.2
695 if (!isset($return[$table])) {
696 include_spip('base/serial');
697 include_spip('base/auxiliaires');
698 include_spip('public/parametrer');
699 foreach (array('tables_principales', 'tables_auxiliaires') as $categ) {
700 foreach ($try as $nom) {
701 if (isset($GLOBALS[$categ][$nom])) {
702 $noms[$table] = $nom;
703 $return[$table] = & $GLOBALS[$categ][$nom];
704 break 2;
705 }
706 }
707 }
708 }
709 }
710
711 $nom_table = $noms[$table];
712 return $return[$table];
713 }
714
715 function distant_table($type) {
716 //separation $type en $distant $table
717 //separateur double underscore "__"
718 strstr($type, '__') ? list($distant,$table) = explode('__', $type) : list($distant, $table) = array(false, $type);
719 return array($distant,$table);
720 }