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

Last change on this file since 94607 was 94607, checked in by kent1@…, 5 years ago

Passer par charger_fonction sur les fonctions fusion_spip_* permettant de les surcharger (ajout de _dist pour cela)

_q remplacé par sql_quote

Tester la présence des tables et ne rien faire si non présente

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