source: spip-zone/_plugins_/fusion_spip/trunk/inc/fusion_spip.php @ 85144

Last change on this file since 85144 was 85144, checked in by ben.spip@…, 5 years ago

Un peu de stats à la fin de la fusion si elle est réussie

File size: 26.2 KB
Line 
1<?php
2
3/**
4 * Définition des tables principales à importer
5 *
6 * @param string $connect nom du connecteur
7 * @param boolean $skip_non_existing ignorer les tables manquantes
8 * @return array liste des tables
9 */
10function fusion_spip_lister_tables_principales($connect, $skip_non_existing = false) {
11
12        // @todo : lire les descriptions des tables sources plutot que locales ?
13        // comment dissocier principales/auxiliares/jointures de la base source ?
14        $tables = lister_tables_principales();
15
16        // ne pas importer certaines tables
17        unset($tables['spip_jobs']);
18        unset($tables['spip_fusion_spip']);
19        unset($tables['spip_depots']);
20        unset($tables['spip_plugins']);
21        unset($tables['spip_paquets']);
22        unset($tables['spip_types_documents']);
23
24
25        // zapper les tables de l'hote qui ne sont pas dans la base importée
26        if( $skip_non_existing ) {
27                foreach($tables as $table => $shema){
28                        if( !sql_showtable($table, false, $connect)){
29                                unset($tables[$table]);
30                        }
31                }
32        }
33
34        return $tables;
35}
36
37/**
38 * Définition des tables auxiliaires à importer
39 *
40 * @param string $connect nom du connecteur
41 * @param boolean $skip_non_existing ignorer les tables manquantes
42 * @param boolean $stats importer les tables visites
43 * @param boolean $referers importer les tables referers
44 *
45 * @return array liste des tables
46 */
47function fusion_spip_lister_tables_auxiliaires($connect, $skip_non_existing = false, $stats = false, $referers = false) {
48
49        // @todo : lire les descriptions des tables sources plutot que locales ?
50        // comment dissocier principales/auxiliares/jointures de la base source ?
51        $tables = lister_tables_auxiliaires();
52
53        // ne pas importer certaines tables
54        unset($tables['spip_meta']);
55        unset($tables['spip_resultats']);
56        unset($tables['spip_jobs_liens']);
57        unset($tables['spip_depots_plugins']);
58
59        if (!$stats) {
60                unset($tables['spip_visites']);
61                unset($tables['spip_visites_articles']);
62        }
63        if (!$referers) {
64                unset($tables['spip_referers']);
65                unset($tables['spip_referers_articles']);
66        }
67
68        // zapper les tables de l'hote qui ne sont pas dans la base importée
69        if( $skip_non_existing ) {
70                foreach($tables as $table => $shema){
71                        if( !sql_showtable($table, false, $connect)){
72                                unset($tables[$table]);
73                        }
74                }
75        }
76
77        return $tables;
78}
79
80/**
81 * Retourne la liste des clés primaires de tables
82 *
83 * @param array $tables
84 * @return array
85 */
86function fusion_spip_lister_cles_primaires($tables) {
87        $cles_primaires = array();
88        foreach ($tables as $nom_table => $shema) {
89                $cles_primaires[$nom_table] = $shema['key']['PRIMARY KEY'];
90        }
91        return $cles_primaires;
92}
93
94/**
95 * Compare le shéma de la base source et de la base locale
96 * retourne les erreurs sur la base source :
97 * - tables manquantes
98 * - champs manquants
99 *
100 * Ne compare que la présence des tables et des champs, pas le type de champs
101 *
102 * @param string $connect nom du connecteur
103 * @param array $principales liste des tables principales
104 * @param array $auxiliaires liste des tables auxiliaires
105 * @return array liste des erreurs
106 */
107function fusion_spip_comparer_shemas($connect, $principales, $auxiliaires) {
108
109        $erreurs = array();
110        $tables = array_merge($principales, $auxiliaires);
111        foreach ($tables as $nom_table => $shema_table) {
112                // ne pas utiliser 'trouver_table' pour ne pas utiliser le cache
113                if ($shema_source = sql_showtable($nom_table, false, $connect)) {
114                        if ($diff_colonnes = array_diff(array_keys($shema_table['field']), array_keys($shema_source['field']))) {
115                                $erreurs[] = _T('fusion_spip:manque_champs_source', array('table' => $nom_table, 'diff' => join(' - ', $diff_colonnes)));
116                        }
117                } else {
118                        $erreurs[] = _T('fusion_spip:manque_table_source', array('table' => $nom_table));
119                }
120        }
121        sort($erreurs);
122        return $erreurs;
123}
124
125/**
126 * Importer une table principale
127 *
128 * @param string $nom_table nom de la table
129 * @param array $shema shema de la table
130 * @param int $secteur id du secteur dans lequel importer
131 * @param string $connect nom du connecteur
132 */
133function fusion_spip_inserer_table_principale($nom_table, $shema, $secteur, $connect) {
134        $time_start = microtime(true);
135
136        // liste des champs à recopier
137        // $champs_select = array_keys($shema['field']);
138
139        // on a déjà signalé par un warning que des champs manquaient dans la table source
140        // on va travailler sur l'intersection des champs de la table source et hote
141        $shema_source = sql_showtable($nom_table, false, $connect);
142        $champs_select = array_intersect(array_keys($shema['field']), array_keys($shema_source['field']));
143
144        // Retrouve la clé primaire à partir du nom d'objet ou de table
145        $nom_id_objet = id_table_objet($nom_table);
146        // Retrouve le type d'objet à partir du nom d'objet ou de table
147        $objet = objet_type($nom_table);
148
149        // selectionner tous les objets d'une table à importer
150        $res = sql_select($champs_select, $nom_table, '', '', '', '', '', $connect);
151        $count = sql_count($res, $connect);
152        $fusion_spips = array();
153        while ($obj_import = sql_fetch($res, $connect)) {
154
155                // garder l'id original
156                $id_origine = $obj_import[$nom_id_objet];
157
158                // mais ne pas l'insérer dans l'objet importé
159                // (sinon doublon sur la clé primaire)
160                unset($obj_import[$nom_id_objet]);
161
162                // réaffecter les secteurs et mettre à jour la profondeur
163                if ($secteur) {
164                        if (in_array('id_secteur', array_keys($shema['field']))) {
165                                $obj_import['id_secteur'] = $secteur;
166                        }
167                        if ($objet == 'rubrique' && $obj_import['id_parent'] == 0) {
168                                $obj_import['id_parent'] = $secteur;
169                        }
170                        if ($objet == 'rubrique') {
171                                $obj_import['profondeur']++;
172                        }
173                }
174
175                // inserer localement l'objet
176                $id_final = sql_insertq($nom_table, $obj_import);
177
178                $fusion_spips[] = array(
179                        'site_origine' => $connect,
180                        'objet' => $objet,
181                        'id_origine' => $id_origine,
182                        'id_final' => $id_final,
183                );
184
185        }
186        // garder les traces id_origine / id_final
187        if (count($fusion_spips)) {
188                sql_insertq_multi('spip_fusion_spip', $fusion_spips);
189        }
190
191        $time_end = microtime(true);
192        $time = $time_end - $time_start;
193        fusion_spip_log('Table '.$nom_table.' traitée ('.$count.') : '.number_format($time, 2).' secondes)', 'fusion_spip_'.$connect);
194
195}
196
197/**
198 * Importer une table auxiliaire
199 *
200 * @param string $nom_table nom de la table
201 * @param string $shema shema de la table
202 * @param array $cles_primaires clés primaires des tables principales
203 * @param string $connect nom du connecteur
204 */
205function fusion_spip_inserer_table_auxiliaire($nom_table, $shema, $cles_primaires, $connect) {
206        $time_start = microtime(true);
207
208        // liste des champs à recopier
209        $champs_select = array_keys($shema['field']);
210
211        // selectionner tous les objets d'une table à importer
212        $res = sql_select($champs_select, $nom_table, '', '', '', '', '', $connect);
213        $count = sql_count($res, $connect);
214        while ($obj_import = sql_fetch($res, $connect)) {
215
216                $skip_import_objet = false;
217
218                // pour chaque champ de la table, et si ce champ est une clé primaire d'un objet principal,
219                // retrouver l'id_final de l'objet lié
220                foreach ($shema['field'] as $nom_champ => $valeur_champ) {
221                        if (in_array($nom_champ, $cles_primaires)) {
222                                $nouveau_id = intval(sql_getfetsel('id_final', 'spip_fusion_spip', 'site_origine = '._q($connect).' and id_origine = '._q($obj_import[$nom_champ]).' and objet='._q(objet_type($nom_champ))));
223                                // mettre à jour l'id de l'objet lié
224                                if ($nouveau_id) {
225                                        $obj_import[$nom_champ] = $nouveau_id;
226                                } else {
227                                        // on n'a pas retrouvé l'objet initial ? l'enregistrement n'est plus cohérent, on le zappe
228                                        $skip_import_objet = true;
229                                }
230                        }
231                }
232
233                // si la table utilise une liaison par id_objet / objet
234                // retrouver l'id_final de l'objet lié
235                if ($shema['field']['id_objet'] && $shema['field']['objet']) {
236                        $nouveau_id = intval(sql_getfetsel('id_final', 'spip_fusion_spip', 'site_origine = '._q($connect).' and id_origine = '._q($obj_import['id_objet']).' and objet='._q($obj_import['objet'])));
237                        // mettre à jour l'id de l'objet lié
238                        if ($nouveau_id) {
239                                $obj_import['id_objet'] = $nouveau_id;
240                        } else {
241                                // on n'a pas retrouvé l'objet initial ? l'enregistrement n'est plus cohérent, on le zappe
242                                $skip_import_objet = true;
243                        }
244                }
245
246                // cas particulier pour spip_urls (id_objet / type au lieu de id_objet / objet)
247                if ($nom_table == 'spip_urls' && $shema['field']['id_objet'] && $shema['field']['type']) {
248                        $nouveau_id = intval(sql_getfetsel('id_final', 'spip_fusion_spip', 'site_origine = '._q($connect).' and id_origine = '._q($obj_import['id_objet']).' and objet='._q($obj_import['type'])));
249                        // mettre à jour l'id de l'objet lié
250                        if ($nouveau_id) {
251                                $obj_import['id_objet'] = $nouveau_id;
252                        } else {
253                                // on n'a pas retrouvé l'objet initial ? l'enregistrement n'est plus cohérent, on le zappe
254                                $skip_import_objet = true;
255                        }
256                }
257
258                if (!$skip_import_objet) {
259                        if ($nom_table == 'spip_visites') {
260                                // cas particulier pour la table spip_visites
261                                // il y a peut être déjà des visites pour cette date
262                                $res_visites = sql_fetsel('*', 'spip_visites', 'date='._q($obj_import['date']));
263                                if ($res_visites['date']) {
264                                        sql_updateq('spip_visites', array('visites' => $res_visites['visites'] + $obj_import['visites']), 'date='._q($obj_import['date']));
265                                } else {
266                                        sql_insertq($nom_table, $obj_import);
267                                }
268                        } else {
269                                sql_insertq($nom_table, $obj_import);
270                        }
271                }
272
273        }
274
275        $time_end = microtime(true);
276        $time = $time_end - $time_start;
277        fusion_spip_log('Table auxiliaire '.$nom_table.' traitée ('.$count.') : '.number_format($time, 2).' secondes)', 'fusion_spip_'.$connect);
278
279}
280
281/**
282 * Mettre à jour les liaisons entre les tables
283 *
284 * @param string $nom_table nom de la table
285 * @param string $shema shema de la table
286 * @param array $cles_primaires clés primaires des tables principales
287 * @param string $connect nom du connecteur
288 */
289function fusion_spip_liaisons_table_principale($nom_table, $shema, $cles_primaires, $connect) {
290        $time_start = microtime(true);
291
292        $objet = objet_type($nom_table);
293
294        // cle primaire de la table concernée
295        $cleprimaire = $shema['key']['PRIMARY KEY'];
296
297        // supprimer des champs de l'objet sa propre primary key
298        // (on ne met pas à jour id_auteur dans la table spip_auteurs)
299        unset($shema['field'][$cleprimaire]);
300
301        // pour chaque champ de la table, et si ce champ est une clé primaire d'un autre objet,
302        // on met à jour les liaisons (par exemple mettre à jour id_rubrique dans spip_articles)
303        foreach ($shema['field'] as $nom_champ => $valeur_champ) {
304
305                if (in_array($nom_champ, $cles_primaires)) {
306                        $objet_liaison = objet_type($nom_champ);
307                        $cle_liaison = $nom_champ;
308                        fusion_spip_mettre_a_jour_liaisons($nom_table, $objet, $cleprimaire, $objet_liaison, $cle_liaison, $connect);
309                }
310
311        }
312
313        // si la table utilise une liaison par id_objet / objet
314        // mettre à jour les liaisons (par exemple spip_forum)
315        if ($shema['field']['id_objet'] && $shema['field']['objet']) {
316                fusion_spip_mettre_a_jour_liaisons_par_objet($nom_table, $objet, $cleprimaire, $connect);
317        }
318
319        // cas particulier : pour les rubriques, mettre à jour id_parent
320        if ($objet == 'rubrique') {
321                fusion_spip_mettre_a_jour_liaisons('spip_rubriques', 'rubrique', 'id_rubrique', 'rubrique', 'id_parent', $connect);
322        }
323
324        // cas particulier : pour les forums, mettre à jour id_parent et id_thread
325        if ($objet == 'forum') {
326                fusion_spip_mettre_a_jour_liaisons('spip_forum', 'forum', 'id_forum', 'forum', 'id_parent', $connect);
327                fusion_spip_mettre_a_jour_liaisons('spip_forum', 'forum', 'id_forum', 'forum', 'id_thread', $connect);
328        }
329
330        $time_end = microtime(true);
331        $time = $time_end - $time_start;
332        fusion_spip_log('Liaisons '.$nom_table.' traitées : '.number_format($time, 2).' secondes)', 'fusion_spip_'.$connect);
333
334}
335
336/**
337 * pour tous les ($objet) importés,
338 * retrouver et mettre à jour ($cle_liaison) dans ($table) par ($cle_primaire)
339 * liaison avec l'objet ($objet_liaison)
340 *
341 * @param string $table
342 * @param string $objet
343 * @param string $cle_primaire
344 * @param string $objet_liaison
345 * @param string $cle_liaison
346 * @param string $connect
347 */
348function fusion_spip_mettre_a_jour_liaisons($table, $objet, $cle_primaire, $objet_liaison, $cle_liaison, $connect) {
349
350        $res = sql_select('id_origine,id_final', 'spip_fusion_spip', 'objet='._q($objet).' and site_origine='._q($connect));
351        while ($obj_import = sql_fetch($res)) {
352                // retrouver l'id_liaison original
353                $ancien_id = intval(sql_getfetsel($cle_liaison, $table, $cle_primaire.' = '._q($obj_import['id_origine']), '', '', '', '', $connect));
354                if ($ancien_id) {
355                        // déterminer le nouveau lien
356                        $nouveau_id = intval(sql_getfetsel('id_final', 'spip_fusion_spip', 'site_origine = '._q($connect).' and id_origine = '._q($ancien_id).' and objet='._q($objet_liaison)));
357                        // mettre à jour l'objet importé
358                        if ($nouveau_id) {
359                                sql_updateq(
360                                        $table,
361                                        array($cle_liaison => $nouveau_id),
362                                        $cle_primaire.' = '._q($obj_import['id_final'])
363                                );
364                        }
365                }
366        }
367}
368
369/**
370 * pour tous les ($objet) importés,
371 * retrouver et mettre à jour id_objet dans ($table) par ($cle_primaire)
372 *
373 * @param string $table
374 * @param string $objet
375 * @param string $cle_primaire
376 * @param string $connect
377 */
378function fusion_spip_mettre_a_jour_liaisons_par_objet($table, $objet, $cle_primaire, $connect) {
379
380        $res = sql_select('id_origine,id_final', 'spip_fusion_spip', 'objet='._q($objet).' and site_origine='._q($connect));
381        while ($obj_import = sql_fetch($res)) {
382                // retrouver l'id_liaison original
383                $ancien_objet = sql_fetsel(array('id_objet', 'objet'), $table, $cle_primaire.' = '._q($obj_import['id_origine']), '', '', '', '', $connect);
384                if ($ancien_objet['id_objet']) {
385                        // déterminer le nouveau lien
386                        $nouveau_id = intval(sql_getfetsel('id_final', 'spip_fusion_spip', 'site_origine = '._q($connect).' and id_origine = '._q($ancien_objet['id_objet']).' and objet='._q($ancien_objet['objet'])));
387                        // mettre à jour l'objet importé
388                        if ($nouveau_id) {
389                                sql_updateq(
390                                        $table,
391                                        array('id_objet' => $nouveau_id),
392                                        $cle_primaire.' = '._q($obj_import['id_final'])
393                                );
394                        }
395                }
396        }
397}
398
399/**
400 * Ajouter le flag perma=1 sur toutes les urls uniques importées
401 *
402 * Les urls uniques de chaque objet sont flaggées "perma" pour éviter
403 * que "voir en ligne" depuis le back office ne génère une nouvelle url
404 *
405 * @param string $connect base source
406 */
407function fusion_spip_maj_perma_urls($connect) {
408        $res = sql_select('id_origine, objet, id_final', 'spip_fusion_spip', 'site_origine='._q($connect));
409        while ($obj_import = sql_fetch($res)) {
410                $urls = sql_allfetsel('*', 'spip_urls', 'id_objet='._q($obj_import['id_final']).' and type='._q($obj_import['objet']));
411                if (count($urls) == 1) {
412                        sql_updateq(
413                                'spip_urls',
414                                array('perma' => 1),
415                                'id_objet='._q($obj_import['id_final']).' and type='._q($obj_import['objet'])
416                        );
417                }
418        }
419}
420
421/**
422 * Mettre à jour les liens entre les documents et leurs vignettes
423 *
424 * @param string $connect base source
425 */
426function fusion_spip_vignettes_documents($connect) {
427        $time_start = microtime(true);
428
429        $res = sql_select(
430                'a.id_final, d.id_vignette',
431                'spip_fusion_spip a join spip_documents d on (a.id_final = d.id_document)',
432                'objet="document" and site_origine='._q($connect).' and id_vignette <> 0'
433        );
434        while ($obj_import = sql_fetch($res)) {
435                $nouveau_id = intval(sql_getfetsel('id_final', 'spip_fusion_spip', 'site_origine = '._q($connect).' and id_origine = '._q($obj_import['id_vignette']).' and objet="document"'));
436                if ($nouveau_id) {
437                        sql_updateq(
438                                'spip_documents',
439                                array('id_vignette' => $nouveau_id),
440                                'id_document='._q($obj_import['id_final'])
441                        );
442                } else {
443                        // on n'a pas retrouvé l'id original ? lien cassé, on le supprime
444                        sql_updateq(
445                                'spip_documents',
446                                array('id_vignette' => 0),
447                                'id_document='._q($obj_import['id_final'])
448                        );
449                }
450        }
451
452        $time_end = microtime(true);
453        $time = $time_end - $time_start;
454        fusion_spip_log('Vignettes documents mises à jour : '.number_format($time, 2).' secondes)', 'fusion_spip_'.$connect);
455}
456
457/**
458 * Importer un par un les documents de la source
459 *
460 * @param string $img_dir répertoire IMG source
461 * @param string $connect base source
462 */
463function fusion_spip_import_documents($img_dir, $connect) {
464        include_spip('inc/documents');
465        $time_start = microtime(true);
466
467        if (substr($img_dir, -1, 1) != '/') {
468                $img_dir = $img_dir.'/';
469        }
470
471        $documents_importes = 0;
472        $logos_importes = 0;
473
474        $res = sql_select(
475                'a.id_final, d.fichier',
476                'spip_fusion_spip a join spip_documents d on (a.id_final = d.id_document)',
477                'objet="document" and site_origine='._q($connect)
478        );
479        while ($obj_import = sql_fetch($res)) {
480                $source_doc = $img_dir.$obj_import['fichier'];
481                $dest_doc = _DIR_IMG.$obj_import['fichier'];
482
483                // créer répertoire si besoin
484                $path_parts = pathinfo($source_doc);
485                $ext = $path_parts['extension'];
486                if ($ext) {
487                        creer_repertoire_documents($ext);
488                        // @todo: il existe surement mieux que copy() ?
489                        // @todo: traiter les fichiers déja existant (les renommer)
490                        if (file_exists($source_doc) && copy($source_doc, $dest_doc)) {
491                                $documents_importes++;
492                                //fusion_spip_log('Document copié : '.$source_doc.' > '.$dest_doc, 'fusion_spip_documents_'.$connect);
493                        } else {
494                                //fusion_spip_log('Document échec : '.$source_doc.' > '.$dest_doc, 'fusion_spip_documents_'.$connect);
495                        }
496                }
497        }
498
499        $logos_racines = array(
500                'arton' => 'article',
501                'artoff' => 'article',
502                'auton' => 'auteur',
503                'autoff' => 'auteur',
504                'breveon' => 'breve',
505                'breveoff' => 'breve',
506                'moton' => 'mot',
507                'motoff' => 'mot',
508                'rubon' => 'rubrique',
509                'ruboff' => 'rubrique',
510        );
511
512        // lire tous les fichiers qui peuvent être des logos
513        $liste_logos = glob($img_dir.'{'.join(',', array_keys($logos_racines)).'}*', GLOB_BRACE);
514        foreach ($liste_logos as $logo) {
515                $path_parts = pathinfo($logo);
516                $ext_logo = strtolower($path_parts['extension']);
517                $type_logo = preg_replace('#([0-9])+([\.a-z])+#i', '', basename($logo));
518                $objet_logo = $logos_racines[$type_logo];
519                $id_objet = preg_replace('#([^0-9])*#', '', basename($logo));
520
521                $nouveau_id = intval(sql_getfetsel('id_final', 'spip_fusion_spip', 'site_origine = '._q($connect).' and id_origine = '._q($id_objet).' and objet='._q($objet_logo)));
522                if ($nouveau_id) {
523                        $dest_logo = _DIR_IMG.$type_logo.$nouveau_id.'.'.$ext_logo;
524                        // @todo: il existe surement mieux que copy() ?
525                        if (copy($logo, $dest_logo)) {
526                                $logos_importes++;
527                                //fusion_spip_log('Logo copié : '.$logo.' > '.$dest_logo, 'fusion_spip_documents_'.$connect);
528                        } else {
529                                //fusion_spip_log('Logo échec : '.$logo.' > '.$dest_logo, 'fusion_spip_documents_'.$connect);
530                        }
531                } else {
532                        // objet lié pas trouvé ? logo obsolète, on ne fait rien
533                        //fusion_spip_log($logo.' : liaison pas trouvée', 'fusion_spip_documents_'.$connect);
534                }
535        }
536
537        $time_end = microtime(true);
538        $time = $time_end - $time_start;
539        fusion_spip_log('Documents importés ('.$documents_importes.' docs / '.$logos_importes.' logos) : '.number_format($time, 2).' secondes)', 'fusion_spip_'.$connect);
540}
541
542
543/** Mise à jour des liens internes [...->...]
544 *
545 * @param array $principales tables principales
546 * @param string $connect base source
547 */
548function fusion_spip_maj_liens_internes($principales, $connect) {
549        $time_start = microtime(true);
550        $objets_mis_a_jour = 0;
551
552        $objets_sources = fusion_spip_determiner_champs_texte($principales);
553
554        // liens possibles et objets auxquels ils se rapportent
555        $objets_liens = array(
556                'rub' => 'rubrique',
557                'rubrique' => 'rubrique',
558                'aut' => 'auteur',
559                'auteur' => 'auteur',
560                'br' => 'breve',
561                'breve' => 'breve',
562                'brève' => 'breve',
563                'doc' => 'document',
564                'im' => 'document',
565                'img' => 'document',
566                'image' => 'document',
567                'emb' => 'document',
568                'document' => 'document',
569                'art' => 'article',
570                'article' => 'article',
571                '' => 'article',
572        );
573
574        // pour tous les objets importés pouvant contenir des liens
575        foreach ($objets_sources as $objet => $champs) {
576                $table = table_objet_sql($objet);
577                $cle_primaire = id_table_objet($objet);
578
579                // uniquement pour les clés primaires simples
580                if(strpos($cle_primaire,',')===false){
581
582                        // selectionner les objets contenant des liens
583                        $select = array();
584                        $where = array();
585                        foreach ($champs as $champ) {
586                                $select[] = 'o.'.$champ;
587                                $where[] = 'o.'.$champ.' regexp "\[.*\->('.join('|', array_keys($objets_liens)).')*[0-9]+\]"';
588                        }
589                        $select = join(', ', $select);
590                        $where = join(' or ', $where);
591                        $objets_import = sql_allfetsel(
592                                'o.'.$cle_primaire.', '.$select,
593                                'spip_fusion_spip a join '.$table.' o on (a.id_final = o.'.$cle_primaire.' and a.objet="'.$objet.'" and a.site_origine='._q($connect).')',
594                                $where
595                        );
596
597                        foreach ($objets_import as $obj_import) {
598                                $update_array = array();
599                                foreach ($champs as $champ) {
600                                        // recenser tous les liens dans le champ
601                                        $nb_liens = preg_match_all('/\[([^][]*?([[]\w*[]][^][]*)*)->(>?)([^]]*)\]/msS', $obj_import[$champ], $liens_trouves, PREG_SET_ORDER);
602                                        if ($nb_liens) {
603                                                // pour chaque lien trouvé, remplacer id_origine par id_final
604                                                foreach ($liens_trouves as $lien_trouve) {
605                                                        // extraire l'id du quatrieme motif du preg_matchall
606                                                        $id_origine_lien = preg_replace('#[a-z]*#', '', $lien_trouve[4]);
607                                                        $type_lien = preg_replace('#[0-9]*#', '', $lien_trouve[4]);
608                                                        $objet_lien = $objets_liens[$type_lien];
609                                                        $nouveau_id = intval(sql_getfetsel('id_final', 'spip_fusion_spip', 'id_origine='._q($id_origine_lien).' and objet="'.$objet_lien.'" and site_origine="'.$connect.'"'));
610                                                        if ($nouveau_id) {
611                                                                $pattern_cherche = '#\[([^][]*?([[]\w*[]][^][]*)*)->'.$type_lien.$id_origine_lien.'\]#';
612                                                                // ajouter une signature pour éviter les remplacements en cascade
613                                                                $pattern_remplace = '[$1->__final__'.$type_lien.$nouveau_id.']';
614                                                                $obj_import[$champ] = preg_replace($pattern_cherche, $pattern_remplace, $obj_import[$champ]);
615                                                        }
616                                                }
617                                                $obj_import[$champ] = str_replace('__final__', '', $obj_import[$champ]);
618                                                $update_array[$champ] = $obj_import[$champ];
619                                        }
620                                }
621                                if ($update_array) {
622                                        sql_updateq($table, $update_array, $cle_primaire.'='._q($obj_import[$cle_primaire]));
623                                        $objets_mis_a_jour++;
624                                }
625                        }
626                }
627        }
628
629        $time_end = microtime(true);
630        $time = $time_end - $time_start;
631        fusion_spip_log('Liens internes mis à jour ('.$objets_mis_a_jour.' objets) : '.number_format($time, 2).' secondes)', 'fusion_spip_'.$connect);
632
633}
634
635/** Mise à jour des modèles <docXX> <imgXX> <embXX> ...
636 *
637 * @param array $principales tables principales
638 * @param string $connect base source
639 */
640function fusion_spip_maj_modeles($principales, $connect) {
641        $time_start = microtime(true);
642        $objets_mis_a_jour = 0;
643
644        $objets_sources = fusion_spip_determiner_champs_texte($principales);
645
646        if (function_exists('medias_declarer_tables_objets_sql')) {
647                // obtenir la liste des modeles dans la table spip_documents
648                $spip_documents = medias_declarer_tables_objets_sql($principales);
649        }
650        if ($spip_documents['modeles']) {
651                $modeles = $spip_documents['modeles'];
652        } else {
653                $modeles = array('document', 'doc', 'img', 'emb', 'image', 'video', 'text', 'audio', 'application');
654        }
655
656
657        // pour tous les objets importés pouvant contenir des modèles
658        foreach ($objets_sources as $objet => $champs) {
659                $table = table_objet_sql($objet);
660                $cle_primaire = id_table_objet($objet);
661
662                // uniquement pour les clés primaires simples
663                if(strpos($cle_primaire,',')===false){
664                        // selectionner les objets contenant les modèles recherchés
665                        $select = array();
666                        $where = array();
667                        foreach ($champs as $champ) {
668                                $select[] = 'o.'.$champ;
669                                $where[] = 'o.'.$champ.' regexp "<('.join('|', $modeles).')+[0-9]+"';
670                        }
671                        $select = join(', ', $select);
672                        $where = join(' or ', $where);
673
674                        $res = sql_select(
675                                'o.'.$cle_primaire.', '.$select,
676                                'spip_fusion_spip a join '.$table.' o on (a.id_final = o.'.$cle_primaire.' and a.objet="'.$objet.'" and a.site_origine='._q($connect).')',
677                                $where
678                        );
679                        while ($obj_import = sql_fetch($res)) {
680                                $update_array = array();
681                                foreach ($champs as $champ) {
682                                        // recenser tous les modèles dans le champ
683                                        $nb_liens = preg_match_all('#<('.join('|', $modeles).'){1}([0-9]+)#', $obj_import[$champ], $liens_trouves, PREG_SET_ORDER);
684                                        if ($nb_liens) {
685                                                // pour chaque lien trouvé, le remplacer id_origine par id_final
686                                                foreach ($liens_trouves as $lien_trouve) {
687                                                        $id_origine_lien = $lien_trouve[2];
688                                                        $modele = $lien_trouve[1];
689                                                        $nouveau_id = intval(sql_getfetsel('id_final', 'spip_fusion_spip', 'id_origine='._q($id_origine_lien).' and objet="document" and site_origine="'.$connect.'"'));
690                                                        if ($nouveau_id) {
691                                                                $pattern_cherche = '#<'.$modele.$id_origine_lien.'#';
692                                                                $pattern_remplace = '<'.$modele.$nouveau_id;
693                                                                $obj_import[$champ] = preg_replace($pattern_cherche, $pattern_remplace, $obj_import[$champ]);
694                                                        }
695                                                }
696                                                $update_array[$champ] = $obj_import[$champ];
697                                        }
698                                }
699                                if ($update_array) {
700                                        sql_updateq($table, $update_array, $cle_primaire.'='._q($obj_import[$cle_primaire]));
701                                        $objets_mis_a_jour++;
702                                }
703                        }
704                }
705        }
706
707        $time_end = microtime(true);
708        $time = $time_end - $time_start;
709        fusion_spip_log('Modèles mis à jour ('.$objets_mis_a_jour.' objets) : '.number_format($time, 2).' secondes)', 'fusion_spip_'.$connect);
710}
711
712/**
713 * Retourne un tableau de tous les objets contenant des champs texte avec les noms des champs pour chaque objet
714 *
715 * @param array $tables liste des tables à examiner
716 * @return array
717 */
718function fusion_spip_determiner_champs_texte($tables) {
719        $objets = array();
720        foreach ($tables as $nom_table => $shema_table) {
721                $champs = array();
722                foreach ($shema_table['field'] as $champ => $desc) {
723                        if (strpos($desc, 'text') !== false && strpos($desc, 'tinytext') === false
724                                && strpos($champ, 'email') === false && strpos($champ, 'site') === false && strpos($champ, 'url') === false
725                        ) {
726                                $champs[] = $champ;
727                        }
728                }
729                if ($champs) {
730                        $objets[objet_type($nom_table)] = $champs;
731                }
732        }
733        return $objets;
734}
735
736function fusion_spip_log($message, $fichier){
737        spip_log($message, 'fusion_spip_'.$fichier);
738}
Note: See TracBrowser for help on using the repository browser.