[SPIP] ~2.1.12 -->2.1.25
[velocampus/web/www.git] / www / ecrire / inc / import_insere.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
15
16 // http://doc.spip.org/@insere_1_init
17 function insere_1_init($request) {
18
19 // table des translations
20
21 $res = insere_1bis_init($request);
22 $desc = $GLOBALS['tables_principales'][_SPIP_TRANSLATE];
23 $v = sql_create(_SPIP_TRANSLATE, $desc['field'], $desc['key'], true);
24 if (!$v) {
25 spip_log("echec de la creation de la table de fusion");
26 return false;
27 }
28 // au cas ou la derniere fois ce serait terminee anormalement
29 $d = sql_delete(_SPIP_TRANSLATE);
30 spip_log("init " . _SPIP_TRANSLATE . " : $d");
31 return $res;
32 }
33
34 // http://doc.spip.org/@insere_1bis_init
35 function insere_1bis_init($request='') {
36
37 // l'insertion porte sur les tables principales ...
38 $t = array_keys($GLOBALS['tables_principales']);
39 // ... mais pas cette table a cause de la duplication des login
40 unset($t[array_search('spip_auteurs', $t)]);
41 // ni celle-ci, les qui est liee implicitement a la precedente
42 unset($t[array_search('spip_messages', $t)]);
43 // et pour celles-ci restent a programmer les regles
44 unset($t[array_search('spip_forum', $t)]);
45 unset($t[array_search('spip_syndic', $t)]);
46 unset($t[array_search('spip_signatures', $t)]);
47
48 $field = array(
49 "type" => "VARCHAR(16) NOT NULL",
50 "ajout" => "integer NOT NULL", // en fait booleen
51 "titre" => "text NOT NULL",
52 "id_old" => "bigint (21) DEFAULT '0' NOT NULL",
53 "id_new" => "bigint (21) DEFAULT '0' NOT NULL");
54
55 $key = array(
56 "PRIMARY KEY" => "id_old, id_new, type",
57 "KEY id_old" => "id_old");
58
59 define('_SPIP_TRANSLATE',
60 'spip_translate_' . $GLOBALS['visiteur_session']['id_auteur']);
61
62 // Pour que trouver_base ne fasse pas des siennes
63 // mais evidemment elle n'est pas a transferer!
64 $GLOBALS['tables_principales'][_SPIP_TRANSLATE] =
65 array('field' => $field, 'key' => $key);
66
67 return $t;
68 }
69
70 // En passe 2, relire les tables principales et les tables auxiliaires
71 // sur les mots et les documents car on sait les identifier
72
73 // http://doc.spip.org/@insere_2_init
74 function insere_2_init($request) {
75 $t = insere_1bis_init($request);
76
77 // ne pas importer cette table, son homologue est prioritaire
78 unset($t[array_search('spip_types_documents', $t)]);
79
80 $t[]= 'spip_mots_articles';
81 $t[]= 'spip_mots_breves';
82 $t[]= 'spip_mots_rubriques';
83 $t[]= 'spip_mots_syndic';
84 $t[]= 'spip_mots_forum';
85 $t[]= 'spip_mots_documents';
86 $t[]= 'spip_documents_liens';
87
88 return $t;
89 }
90
91 // construire le tableau PHP de la table spip_translate
92 // (mis en table pour pouvoir reprendre apres interruption)
93
94 // http://doc.spip.org/@translate_init
95 function translate_init($request) {
96
97 include_spip('inc/texte'); // pour les Regexp des raccourcis
98 include_spip('inc/chercher_logo'); // pour les noms des logos
99 include_spip('inc/distant'); // pour recuperer les logos
100
101 $q = sql_select('*', _SPIP_TRANSLATE);
102 $trans = array();
103 while ($r = sql_fetch($q)) {
104 $trans[$r['type']][$r['id_old']] = array($r['id_new'], $r['titre'], $r['ajout']);
105 }
106 $r = '';
107 foreach ($trans as $k =>$v) $r .= " $k: " . count($v);
108 spip_log( count($trans) . " types d'objets a transferer: $r");
109 return $trans;
110 }
111
112
113 // http://doc.spip.org/@import_insere
114 function import_insere($values, $table, $desc, $request, $atts) {
115
116 static $jesais = array();
117
118 $type_id = $desc['key']["PRIMARY KEY"];
119 // reserver une place dans les tables principales si nouveau
120 $ajout = 0;
121
122 if ((!($f = charger_fonction('identifie_' . $type_id, 'import', true)))
123 OR (!($n = $f($values, $table, $desc, $request)))) {
124 // pas d'importation de types_doc (a revoir)
125 if ($table == 'spip_types_documents') return;
126 $n = sql_insertq($table);
127 $ajout=1;
128 }
129
130 if (is_array($n))
131 list($id, $titre) = $n;
132 else {$id = $n; $titre = "";}
133 sql_insertq(_SPIP_TRANSLATE, array(
134 'id_old' => $values[$type_id],
135 'id_new' => $id,
136 'titre' => $titre,
137 'type' => $type_id,
138 'ajout' => $ajout));
139 }
140
141 // Renumerotation des entites collectees
142 // Appelle la fonction specifique a la table, ou a defaut la std.
143 // Le tableau de correspondance est global, et permet qu'un numero
144 // d'une entite soit calcule une seule fois, a sa premiere occurrence.
145 // (Mais des requetes avec jointures eviteraient sa construction. A voir)
146
147 // http://doc.spip.org/@import_translate
148 function import_translate($values, $table, $desc, $request, $atts) {
149
150 if (!($f = charger_fonction('translate_' . $table, 'import', true)))
151 $f = charger_fonction('translate_std', 'import');
152 $f($values, $table, $desc, $request, $atts);
153 }
154
155 // La fonction d'insertion apres renumerotation.
156 // Afin qu'inserer une 2e fois la meme sauvegarde ne change pas la base,
157 // chaque entree de la sauvegarde est ignoree s'il existe une entree
158 // de meme titre avec le meme contexte (parent etc) dans la base installee.
159 // Une synchronisation plus fine serait preferable, cf [8004]
160
161 // http://doc.spip.org/@import_inserer_translate
162 function import_inserer_translate($values, $table, $desc, $request, $atts) {
163 global $trans;
164 $p = $desc['key']["PRIMARY KEY"];
165 $v = $values[$p];
166 if (!isset($trans[$p]) OR !isset($trans[$p][$v]) OR $trans[$p][$v][2]){
167 sql_replace($table, $values);
168 $on = isset($atts['on']) ? ($atts['on']) : '';
169 $off = isset($atts['off']) ? ($atts['off']) : '';
170 if ($on OR $off) {
171 $t = type_du_logo($p);
172 $url = $request['url_site'];
173 if (!$url) $url = $atts['adresse_site'];
174 if (substr($url,-1) !='/') $url .='/';
175 $url .= $atts['dir_logos'];
176 $new = $trans[$p][$v][0];
177 if ($on) {
178 if ($logo = recuperer_page($url . $t . "on$v." . $on))
179 ecrire_fichier(_DIR_LOGOS. $t . "on$new." . $on, $logo);
180 }
181 if ($off) {
182 if ($logo = recuperer_page($url . $t . "off$v." . $off))
183 ecrire_fichier(_DIR_LOGOS. $t . "off$new." . $off, $logo);
184 }
185 }
186 }
187 }
188
189 // Insertion avec renumerotation, y compris des raccourcis.
190 // http://doc.spip.org/@import_translate_std
191 function import_translate_std_dist($values, $table, $desc, $request, $atts) {
192
193 foreach ($values as $k => $v) {
194 switch($k) {
195 case 'id_secteur': $type = 'id_rubrique'; break;
196 case 'id_thread': $type = 'id_forum'; break;
197 case 'id_vignette': $type = 'id_document'; break;
198 case 'id_parent': $type =
199 isset($values['id_forum']) ? 'id_forum' : 'id_rubrique'; break;
200 default: $type = $k;
201 }
202 $values[$k]= importe_raccourci(importe_translate_maj($type, $v));
203 }
204 import_inserer_translate($values, $table, $desc, $request, $atts);
205 }
206
207 // http://doc.spip.org/@import_translate_spip_articles
208 function import_translate_spip_articles_dist($values, $table, $desc, $request, $atts) {
209 $v = $values['chapo'];
210 if ($v[0]=='=' AND preg_match(_RACCOURCI_CHAPO, substr($v,1)))
211 $values['chapo'] = '=[->' . substr($v,1) . ']';
212 if ($request['statut'] == 'on' AND $values['statut'] == 'publie')
213 $values['statut'] = 'prop';
214 import_translate_std_dist($values, $table, $desc, $request, $atts);
215 }
216
217 // http://doc.spip.org/@import_translate_spip_breves
218 function import_translate_spip_breves_dist($values, $table, $desc, $request, $atts) {
219 if ($request['statut'] == 'on' AND $values['statut'] == 'publie')
220 $values['statut'] = 'prop';
221 import_translate_std_dist($values, $table, $desc, $request, $atts);
222 }
223
224 // Les doc importes deviennent distants, a fortiori s'ils etaient deja
225 // Gerer les vieilles sauvegardes oĂą le Path etait en dur
226 // http://doc.spip.org/@import_translate_spip_documents
227 function import_translate_spip_documents_dist($values, $table, $desc, $request, $atts) {
228
229 if ($values['distant'] === 'oui') {
230 $url = '';
231 } else {
232 $values['distant'] = 'oui';
233 $url = $request['url_site'];
234 if (!$url) $url = $atts['adresse_site'];
235 if (substr($url,-1) !='/') $url .='/';
236 // deja dans la BD avant cette epoque
237 if ($atts['version_base'] >= '1.934')
238 $url .= $atts['dir_img'];
239 }
240 $url .= $values['fichier'];
241 unset($values['fichier']);
242 foreach ($values as $k => $v) {
243 $values[$k]= importe_raccourci(importe_translate_maj($k, $v));
244
245 }
246 $values['fichier'] = $url;
247 import_inserer_translate($values, $table, $desc, $request, $atts);
248 }
249
250 function import_translate_spip_documents_liens_dist($values, $table, $desc, $request, $atts) {
251
252 $values['id_document']= (importe_translate_maj('id_document', $values['id_document']));
253 $values['id_objet']= (importe_translate_maj('id_' .$values['objet'], $values['id_objet']));
254
255 sql_replace($table, $values);
256 }
257
258 // Fonction de renumerotation, par delegation aux fonction specialisees
259 // Si une allocation est finalement necessaire, celles-ci doivent repercuter
260 // la renumerotation sur la table SQL temporaire pour qu'en cas de reprise
261 // sur Time-Out il n'y ait pas reallocation.
262 // En l'absence d'allocation, cet acces SQL peut etre omis, quitte a
263 // recalculer le nouveau numero si une autre occurrence est rencontree
264 // a la reprise. Pas dramatique.
265
266 // http://doc.spip.org/@importe_translate_maj
267 function importe_translate_maj($k, $v)
268 {
269 global $trans;
270 static $err = array();
271 if (!(isset($trans[$k]) AND isset($trans[$k][$v]))) return $v;
272 list($g, $titre, $ajout) = $trans[$k][$v];
273 if ($g <= 0) {
274 if (($f = charger_fonction('identifie_parent_' . $k, 'import', true))){
275 $g = $f($g, $titre, $v);
276 if ($g > 0)
277 // memoriser qu'on insere
278 $trans[$k][$v][2]=1;
279 else $g = (0-$g);
280 $trans[$k][$v][0] = $g;
281 } else {
282 if (!isset($err[$f])) spip_log("$f manquante");
283 $err[$f] = true;
284 }
285 }
286 return $g;
287 }
288
289 define('_RACCOURCI_MODELE_ALL', '@' . _RACCOURCI_MODELE .'@isS');
290
291 // http://doc.spip.org/@importe_raccourci
292 function importe_raccourci($v)
293 {
294 if (preg_match_all(_RACCOURCI_LIEN, $v, $m, PREG_SET_ORDER)) {
295 foreach ($m as $regs) {
296 // supprimer 'http://' ou 'mailto:'
297 $lien = vider_url($regs[count($regs)-1]);
298 if ($match = typer_raccourci($lien)) {
299 list($f,$objet,$id,$params,$ancre) = $match;
300 $k = 'id_' . $f;
301 $g = importe_translate_maj($k, $id);
302 if ($g != $id) {
303
304 $rac = '[' . $regs[1] . '->' . $regs[2] . $objet . $g . $params . $ancre .']';
305 $v = str_replace($regs[0], $rac, $v);
306 }
307 }
308 }
309 }
310
311 if (preg_match_all(_RACCOURCI_MODELE_ALL, $v, $m, PREG_SET_ORDER)) {
312 foreach ($m as $regs) {
313 $g = importe_translate_maj('id_document', $regs[3]);
314 if ($g != $regs[3]) {
315 $rac = '<' . $regs[2] . $g . $regs[4] . '>' . $regs[5];
316 $v = str_replace($regs[0], $rac, $v);
317 }
318 }
319 }
320 return $v;
321 }
322
323 // un document importe est considere comme identique a un document local
324 // s'ils ont meme taille et meme nom et que le present n'est pas detruit
325 // Et ne pas importer les incoherences (docs sans extension)
326 // http://doc.spip.org/@import_identifie_id_document
327 function import_identifie_id_document_dist($values, $table, $desc, $request) {
328 if (!$values['extension']) return false;
329 $t = $values['taille'];
330 $f = $values['fichier'];
331 $h = $request['url_site'] . $f;
332 $r = sql_fetsel("id_document AS id, fichier AS titre, distant", "spip_documents", "taille=" . sql_quote($t) . " AND (fichier=" . sql_quote($f) . " OR fichier= " . sql_quote($h) . ')');
333 if (!$r) return false;
334 if (($r['distant'] != 'oui')
335 AND !file_exists(_DIR_IMG . $r['titre']))
336 return false;
337 return array($r['id'], $r['titre']);
338 }
339
340 // un type de document importe est considere comme identique a un type present
341 // s'ils ont meme extension et meme titre
342 // Sinon il ne sera PAS importe
343 // http://doc.spip.org/@import_identifie_id_type
344 function import_identifie_id_type_dist($values, $table, $desc, $request) {
345 $e = $values['extension'];
346 $t = $values['titre'];
347 $r = sql_fetsel("id_type AS id, titre", "spip_types_documents", "extension=" . sql_quote($e) . " AND titre=" . sql_quote($t));
348 return $r ? array($r['id'], $r['titre']) : false;
349 }
350
351 // deux groupes de mots ne peuvent avoir le meme titre ==> identification
352 // http://doc.spip.org/@import_identifie_id_groupe
353 function import_identifie_id_groupe_dist($values, $table, $desc, $request) {
354 $r = sql_fetsel("id_groupe AS id, titre", "spip_groupes_mots", "titre=" . sql_quote($values['titre']));
355 return $r ? array($r['id'], $r['titre']) : false;
356 }
357
358 // pour un mot le titre est insuffisant, il faut aussi l'identite du groupe.
359 // Memoriser ces 2 infos et le signaler a import_translate grace a 1 negatif
360 // http://doc.spip.org/@import_identifie_id_mot
361 function import_identifie_id_mot_dist($values, $table, $desc, $request) {
362 return array((0 - $values['id_groupe']), $values['titre']);
363 }
364
365 // Passe 2: mot de meme titre et de meme groupe ==> identification
366 // http://doc.spip.org/@import_identifie_parent_id_mot
367 function import_identifie_parent_id_mot_dist($id_groupe, $titre, $v)
368 {
369 global $trans;
370 $titre = sql_quote($titre);
371 $id_groupe = 0-$id_groupe;
372 if (isset($trans['id_groupe'])
373 AND isset($trans['id_groupe'][$id_groupe])) {
374 $new = $trans['id_groupe'][$id_groupe][0];
375 $r = sql_fetsel("id_mot", "spip_mots", "titre=$titre AND id_groupe=$new" );
376 if ($r) return (0 - $r['id_mot']);
377 }
378 if ($r = sql_insertq('spip_mots'))
379 sql_replace(_SPIP_TRANSLATE, array(
380 'id_old' => $v,
381 'id_new' => $r,
382 'titre' => $titre,
383 'type' => 'id_mot',
384 'ajout' => 1),
385 $GLOBALS['tables_principales'][_SPIP_TRANSLATE]);
386 else spip_log("Impossible d'inserer dans spip_mots");
387 return $r;
388 }
389
390 // idem pour les articles
391 // http://doc.spip.org/@import_identifie_id_article
392 function import_identifie_id_article_dist($values, $table, $desc, $request) {
393 return array((0 - $values['id_rubrique']), $values['titre']);
394 }
395
396 // Passe 2 des articles comme pour les mots
397
398 // http://doc.spip.org/@import_identifie_parent_id_article
399 function import_identifie_parent_id_article_dist($id_parent, $titre, $v)
400 {
401 $id_parent = importe_translate_maj('id_rubrique', (0 - $id_parent));
402
403 $titre = sql_quote($titre);
404 $r = sql_fetsel("id_article", "spip_articles", "titre=$titre AND id_rubrique=$id_parent AND statut<>'poubelle'" );
405 if ($r) return (0 - $r['id_article']);
406
407 if ($r = sql_insertq('spip_articles'))
408 sql_replace(_SPIP_TRANSLATE, array(
409 'id_old' => $v,
410 'id_new' => $r,
411 'titre' => $titre,
412 'type' => 'id_article',
413 'ajout' => 1),
414 $GLOBALS['tables_principales'][_SPIP_TRANSLATE]
415 );
416 else spip_log("Impossible d'inserer dans spip_articles");
417 return $r;
418 }
419
420 // idem pour les breves
421 // http://doc.spip.org/@import_identifie_id_breve
422 function import_identifie_id_breve_dist($values, $table, $desc, $request) {
423 return array((0 - $values['id_rubrique']), $values['titre']);
424 }
425
426 // Passe 2 des breves comme pour les mots
427
428 // http://doc.spip.org/@import_identifie_parent_id_breve
429 function import_identifie_parent_id_breve_dist($id_parent, $titre, $v)
430 {
431 $id_parent = importe_translate_maj('id_rubrique', (0 - $id_parent));
432
433 $titre = sql_quote($titre);
434 $r = sql_fetsel("id_breve", "spip_breves", "titre=$titre AND id_rubrique=$id_parent AND statut<>'refuse'" );
435 if ($r) return (0 - $r['id_breve']);
436
437 if ($r = sql_insertq('spip_breves'))
438 sql_replace(_SPIP_TRANSLATE, array(
439 'id_old' => $v,
440 'id_new' => $r,
441 'titre' => $titre,
442 'type' => 'id_breve',
443 'ajout' => 1),
444 $GLOBALS['tables_principales'][_SPIP_TRANSLATE]
445 );
446 else spip_log("Impossible d'inserer dans spip_breves");
447 return $r;
448 }
449
450
451 // pour une rubrique le titre est insuffisant, il faut l'identite du parent
452 // Memoriser ces 2 infos et le signaler a import_translate grace a 1 negatif
453 // http://doc.spip.org/@import_identifie_id_rubrique
454 function import_identifie_id_rubrique_dist($values, $table, $desc, $request) {
455 return array((0 - $values['id_parent']), $values['titre']);
456 }
457
458 // Passe 2 des rubriques, renumerotation en cascade.
459 // rubrique de meme titre et de meme parent ==> identification
460 // http://doc.spip.org/@import_identifie_parent_id_rubrique
461 function import_identifie_parent_id_rubrique_dist($id_parent, $titre, $v)
462 {
463 global $trans;
464 if (isset($trans['id_rubrique'])) {
465 if ($id_parent < 0) {
466 $id_parent = (0 - $id_parent);
467 $gparent = $trans['id_rubrique'][$id_parent][0];
468 // parent deja renumerote depuis le debut la passe 2
469 if ($gparent >= 0)
470 $id_parent = $gparent;
471 else {
472 // premiere occurrence du parent
473 $pitre = $trans['id_rubrique'][$id_parent][1];
474 $n = import_identifie_parent_id_rubrique_dist($gparent, $pitre, $id_parent);
475 $trans['id_rubrique'][$id_parent][0] = ($n>0) ? $n: (0-$n);
476 // parent tout neuf,
477 // pas la peine de chercher un titre homonyme
478 if ($n > 0) {
479 $trans['id_rubrique'][$id_parent][2]=1; // nouvelle rub.
480 return import_alloue_id_rubrique($n, $titre, $v);
481 } else $id_parent = (0 - $n);
482 }
483 }
484
485 $r = sql_fetsel("id_rubrique", "spip_rubriques", "titre=" . sql_quote($titre) . " AND id_parent=" . intval($id_parent));
486 if ($r) {
487 return (0 - $r['id_rubrique']);
488 }
489 return import_alloue_id_rubrique($id_parent, $titre, $v);
490 }
491 }
492
493 // reserver la place en mettant titre et parent tout de suite
494 // pour que le SELECT ci-dessus fonctionne a la prochaine occurrence
495
496 // http://doc.spip.org/@import_alloue_id_rubrique
497 function import_alloue_id_rubrique($id_parent, $titre, $v) {
498 if ($r = sql_insertq('spip_rubriques', array('titre' => $titre, 'id_parent' => $id_parent)))
499 sql_replace(_SPIP_TRANSLATE, array(
500 'id_old' => $v,
501 'id_new' => $r,
502 'titre' => $titre,
503 'type' => 'id_rubrique',
504 'ajout' => 1),
505 $GLOBALS['tables_principales'][_SPIP_TRANSLATE]);
506 else spip_log("Impossible d'inserer dans spip_rubriques");
507 return $r;
508 }
509 ?>