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

Last change on this file since 73277 was 73277, checked in by nicolas.dorigny@…, 6 years ago

Deux messages qui n'étaient pas en chaine de langue

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