Subversion Repositories Applications.annuaire

Rev

Rev 621 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
610 delphine 1
<?php
619 killian 2
 
610 delphine 3
/**
619 killian 4
 * Permet de migrer tout un tas de trucs vers le nouveau site
5
 *
6
 * Genre les utilisateurs, les actus, les évènements, etc
7
 *
8
 * /!\ BEWARE OF THE CODE /!\ (Naughty code inside)
9
 * Ce script a été écrit à la sueur de vieux pied
10
 *
11
 * *****************************************
12
 * UTILISATION :
13
 * *****************************************
14
 *
15
 * $ php migration.php <<commande>>
16
 *
17
 *  ou
18
 *
19
 * $ /usr/local/bin/php -d memory_limit=4000M cli.php migrationwp -a tous
20
 *
21
 * @WARNING Bien vérifier le config.php
22
 *
23
 *
24
 * *****************************************
25
 * TODOS
26
 * *****************************************
27
 *
28
 * Liste de @TODO (censée être exhaustive)
620 killian 29
 * - méthode de nettoyage (voir repartirDeZero) pour rendre le script i(de)mpotent
619 killian 30
 * - gérer proprement les erreurs (là ça chie des exceptions dès que ça peut) en vue d'une automatisation
31
 * - trouver un équivalent à un gros try-catch autour de chaque méthode permettant de restaurer les tables en cas de plantage
32
 * - sauvegarder les tables proprement à chaque lancement ou ne pas lancer
33
 * - méthode All permettant de tout lancer à la suite en vue d'une automatisation
34
 * - vérifier les différentes meta ayant pu changer pendant le dev (évènements et leurs champs ACF, meta utilisateurs (mapping des IDs différent entre test et preprod))
35
 * - vérifier les correspondances entre la réalité et les tables de correspondances (surtout les catégories avec les IDs et slugs pouvant différer d'une instance à l'autre)
36
 * - voir les différents @todo du script
37
 * - à compléter :) (Killian, avant ses vacances (et pas vous) le 21/07/2017)
38
 *
39
 */
610 delphine 40
 
619 killian 41
require_once "config.php";
42
 
43
$actions = array(
44
  'utilisateurs',
45
  'utilisateurs-meta',
46
  'utilisateurs-profil',
47
  'utilisateurs-activite',
48
  'actualites',
49
  'actualites-commentaires',
50
  'actualites-image-de-couverture',
51
  'evenements',
52
  'evenements-meta',
53
  'rubriques',
54
  'suicide',
620 killian 55
  'restaureLaTable',
56
  'repartirDeZero',
619 killian 57
);
58
 
59
// Si l'utilisateur à mélangé ses doigts on affiche les consignes
60
if ($argc < 2 || !in_array($argv[1], $actions)) {
61
  global $argv;
62
  global $actions;
63
  echo "Utilisation: \n\t$argv[0] action\n\n";
64
  echo "Actions: \n\t" . implode(PHP_EOL . "\t", $actions) . "\n";
65
  exit;
66
}
67
 
68
$action = $argv[1];
69
// // arguments de l'action : tout moins le nom du script et le nom de l'action
70
// array_shift($argv);
71
// array_shift($argv);
72
// $argc -= 2;
73
 
74
$modeBourrin = false;
75
if (isset($argv[2]) && '--force' === $argv[2]) {
76
  $modeBourrin = true;
77
 
78
  echo 'Mode "BOURRIN" : certaines erreurs sont ignorées (mais ce serait quand même mieux de corriger le script)';
79
}
80
 
81
// connexion aux BdDs
82
$bdSpip = connexionSpip();
83
$bdSpip->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
84
$bdTelaProd = connexionTelaProd();
85
$bdTelaProd->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
86
$bdWordpress = connexionWordpress();
87
$bdWordpress->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
88
 
89
$doc_loc = array();
90
 
91
// Détails des différentes rubriques à migrer
92
// on associe le titre et le slug d'une catégorie wordpress avec des rubriques spip
93
// les articles des rubriques seront migrés vers la catégorie donnée
94
$correspondanceCategorieRubriques = array(
95
  // Actualités
96
  array('titre' => 'Brèves', 'slug' => 'breves', 'rubrique-a-migrer' => [22, 31, 35]),
97
  array('titre' => 'Contribuez', 'slug' => 'contribuez', 'rubrique-a-migrer' => [70, 71]),
98
  array('titre' => 'En kiosque', 'slug' => 'en-kiosque', 'rubrique-a-migrer' => [30, 34]),
99
  array('titre' => 'Nouvelles du réseau', 'slug' => 'nouvelles-du-reseau', 'rubrique-a-migrer' => [54, 55]),
100
  array('titre' => 'Points de vue', 'slug' => 'points-de-vue', 'rubrique-a-migrer' => [38, 39]),
101
  // Évènements
102
  // array('titre' => 'Congrès et conférences', 'slug' => 'congres-conferences'),
103
  // array('titre' => 'Expositions', 'slug' => 'expositions'),
104
  // array('titre' => 'Sorties de terrain', 'slug' => 'sorties-de-terrain'),
105
  // array('titre' => 'Stages et ateliers', 'slug' => 'stages-ateliers'),
106
  // Offres d'emploi
107
  array('titre' => 'CDD / CDI', 'slug' => 'cdd-cdi', 'rubrique-a-migrer' => [19]),
108
  array('titre' => 'Stage', 'slug' => 'stages', 'rubrique-a-migrer' => [51])
109
  // Autres
110
  // array('titre' => 'Revue de presse', 'slug' => 'revue-de-presse', 'rubrique-a-migrer' => 69) // Poubelle
111
);
112
 
113
//$this->bdd->executer('SET wait_timeout=300');
114
 
115
switch($action) {
116
	case 'utilisateurs':
117
		migrerUtilisateurs();
118
		break;
119
	case 'utilisateurs-meta': //role
120
		migrerUtilisateursMeta();
121
    break;
122
  case 'utilisateurs-profil':
123
    migrerUtilisateursProfil();
124
		break;
125
  case 'utilisateurs-activite': // obligatoire pour affichage
126
    migrerUtilisateursActivite();
127
		break;
128
	case 'actualites':
129
		migrerActualites();
130
		break;
131
  case 'actualites-commentaires':
132
    migrerActualitesCommentaires();
133
    break;
134
  case 'actualites-image-de-couverture':
135
    migrerActualitesImageDeCouverture();
136
    break;
137
  case 'evenements':
138
    migrerEvenements();
139
    break;
140
  case 'evenements-meta': // contenu des champs ACF
141
    migrerEvenementsMeta();
142
    break;
143
	case 'rubriques':
144
		migrerRubriques();
145
		break;
146
  case 'suicide':
147
    supprimerLesTablesSauvegardees();
148
    break;
149
  case 'restaureLaTable':
150
    restaurerTable($argv[2], $argv[3]);
151
    break;
620 killian 152
  case 'repartirDeZero':
153
    repartirDeZero();
154
    break;
619 killian 155
	default:
156
    echo "commande inconnue, l'action ne correspond pas à une fonction";
157
    break;
158
}
159
 
620 killian 160
function repartirDeZero() {
161
  // vide la table users, sauf le n°1 (admin)
162
  // vide la table usermeta (si user_id != 1) (mais)
163
  // vide les tables bp_activity, bp_xprofile_data
164
  // vide les posts (WHERE post_type='post'), ainsi que slug_history et postmeta (WHERE post_id supprimé), et également term_relationships (WHERE object_id = post_id supprimé)
165
  // vide les term_taxonomy (WHERE term_id IN [listes des IDs des catégories d'articles et évènements migrés (voir correspondanceCategorieRubriques)])
166
}
167
 
619 killian 168
function restaurerTable($base, $table) {
169
  global $bdTelaProd;
170
  global $bdWordpress;
171
  global $bdSpip;
172
 
173
  switch ($base) {
174
    case 'wordpress':
175
      $base = $bdWordpress;
176
      break;
177
    case 'telaprod':
178
      $base = $bdTelaProd;
179
      break;
180
    case 'spip':
181
      $base = $bdSpip;
182
      break;
183
    default:
184
      die('base inconnue, choix possibles : wordpress | telaprod | spip');
185
      break;
186
  }
187
 
188
  if (!$table) {
189
    die('faut renseigner une table à restaurer :)');
190
  }
191
 
192
  _renommeLaTable($base, $table, $table . 'BAK');
193
  restaureLaTable($base, $table);
194
}
195
 
196
function sauvegardeLaTable($base, $table) {
197
  _copieLaTable($base, $table, $table . 'SAV');
198
}
199
 
200
function restaureLaTable($base, $table) {
201
  _copieLaTable($base, $table . 'SAV', $table, true);
202
}
203
 
204
function _renommeLaTable($base, $tableSource, $tableDestination) {
205
  $reqRenameTable = 'RENAME TABLE ' . $tableSource . ' TO ' . $tableDestination . ';';
206
  try {
207
    $base->exec($reqRenameTable);
208
  } catch(Exception $e) {
209
    echo "-- ECHEC " . __FUNCTION__ . " REQUÊTE: [$reqRenameTable]" . PHP_EOL;
210
 
211
    die(var_dump($e));
212
  }
213
 
214
  echo "-- SUCCES table $tableSource renommée $tableDestination" . PHP_EOL;;
215
}
216
 
217
function _copieLaTable($base, $tableSource, $tableDestination, $faireLeManage = false) {
218
  try {
219
    if (true === $faireLeManage) {
220
      $requeteSuppressionTable = 'DROP TABLE IF EXISTS ' . $tableDestination . ';';
221
      try {
222
        $base->exec($requeteSuppressionTable);
223
      } catch(Exception $e) {
224
        echo "-- ECHEC " . __FUNCTION__ . " REQUÊTE: [$requeteSuppressionTable]" . PHP_EOL;
225
        throw $e;
226
      }
227
    }
228
 
229
    $reqNouvelleTable = 'CREATE TABLE IF NOT EXISTS ' . $tableDestination . ' LIKE ' . $tableSource . ';';
230
    try {
231
      $base->exec($reqNouvelleTable);
232
    } catch(Exception $e) {
233
      echo "-- ECHEC " . __FUNCTION__ . " REQUÊTE: [$reqNouvelleTable]" . PHP_EOL;
234
      throw $e;
235
    }
236
 
237
    $reqInsertNouvelleTable = 'INSERT ' . $tableDestination . ' SELECT * FROM ' . $tableSource . ';';
238
    try {
239
      $base->exec($reqInsertNouvelleTable);
240
    } catch(Exception $e) {
241
      echo "-- ECHEC " . __FUNCTION__ . " REQUÊTE: [$reqInsertNouvelleTable]" . PHP_EOL;
242
      throw $e;
243
    }
244
 
245
    if (true === $faireLeManage) {
246
      $requeteSuppressionTable = 'DROP TABLE IF EXISTS ' . $tableSource . ';';
247
      try {
248
        $base->exec($requeteSuppressionTable);
249
      } catch(Exception $e) {
250
        echo "-- ECHEC " . __FUNCTION__ . " REQUÊTE: [$requeteSuppressionTable]" . PHP_EOL;
251
        throw $e;
252
      }
253
    }
254
  } catch(Exception $e) {
255
    var_dump($e);
256
 
257
    return;
258
  }
259
 
260
 
261
 
262
 
263
  echo "-- SUCCES contenu de $tableSource copié dans $tableDestination" . PHP_EOL;;
264
}
265
 
266
/**
267
 * Migre les utilisateurs vers la table WordPress
268
 *
269
 * Si ça a déjà été fait, ça écrase les valeurs éxistantes coté WordPress
270
 * Peut donc être relancé plusieurs fois avant la mise en prod
271
 */
272
function migrerUtilisateurs() {
273
  global $prefixe_tables_wp;
274
  global $bdTelaProd;
275
  global $bdWordpress;
276
  global $modeBourrin;
277
 
278
  sauvegardeLaTable($bdWordpress, $prefixe_tables_wp . 'users');
279
  sauvegardeLaTable($bdWordpress, $prefixe_tables_wp . 'bp_xprofile_data');
280
 
281
  // nicename doit être unique, de préférence l'intitulé, voir suffixé avec un rand ou l'ID
282
  // user_login pareil, sinon nom-prenom-id (champ interne à wordpress, ne change jamais, n'est jamais affiché)
283
  // nickname = intitulé, affiché sur le site
284
  // recopier ces metas dans celles de wordpress
285
 
286
  $requeteUtilisateurs = "SELECT `U_ID` AS `ID`,
287
    `U_MAIL` AS `user_login`,
288
    `U_PASSWD` AS `user_pass`,
289
    `U_MAIL` AS user_email,
290
    `U_WEB` AS user_url,
291
    `U_DATE` AS user_registered, '0' AS user_status,
292
    `U_SURNAME`,
293
    `U_NAME`,
294
    concat(`U_SURNAME`,' ',`U_NAME`) AS display_name
295
    FROM `annuaire_tela`";
296
 
297
  $utilisateurs = $bdTelaProd->query($requeteUtilisateurs)->fetchAll(PDO::FETCH_ASSOC);
298
 
299
  $compteur = 0;
300
  foreach ($utilisateurs as $utilisateur) {
301
 
302
    /*
303
    user_nicename : unique, éditable, suffixé si déjà utilisé
304
    user_login : unique, immuable, prendra la valeur de user_nicename
305
    display_name : éditable (de base WordPress le rempli en fonction d'un réglage, y'a le choix entre différents trucs genre prénom, nom, prénom + nom, ou le nickname)
306
    nickname : éditable (équivalent du pseudo, mais coté WP)
307
    xprofileData[champ 1] (c'est le pseudo BP) unique, éditable, suffixé si déjà utilisé
308
    (lorsque le profil BP est modifié, sa valeur est copiée dans user_nicename dans sa version suffixée, et en version originale [saisie par l'utilisateur] dans display_name et nickname)
309
 
310
    Donc pour l'import il faut générer un user_nicename/user_login/pseudo_bp uniques. Basés sur le pseudo, sinon sur prenom-nom
311
    Tandis que nickname aura la valeur du pseudo actuel
312
    Et display_name prendra la valeur de pseudo, et sinon prenom-nom
313
    */
314
 
315
    $pseudo = $bdTelaProd->query('SELECT amv_valeur AS pseudo FROM annu_meta_valeurs WHERE amv_ce_colonne = 99 AND amv_cle_ligne = ' . $utilisateur['ID'])->fetch(PDO::FETCH_ASSOC);
316
    $pseudo_utilise = $bdTelaProd->query('SELECT amv_valeur AS pseudo_utilise FROM annu_meta_valeurs WHERE amv_ce_colonne = 136 AND amv_cle_ligne = ' . $utilisateur['ID'])->fetch(PDO::FETCH_ASSOC);
317
 
318
    $intitule = $utilisateur['U_SURNAME'] . ' ' . $utilisateur['U_NAME'];
319
    if ($pseudo_utilise['pseudo_utilise'] && $pseudo['pseudo']) {
320
      $intitule = $pseudo['pseudo'];
321
    }
322
 
323
    $futur_pseudo = $intitule;
324
    // die(var_dump($futur_pseudo));
325
 
326
    // removes all tags
327
    $futur_pseudo = preg_replace( '@<(script|style)[^>]*?>.*?</\\1>@si', '', $futur_pseudo );
328
    $futur_pseudo = strip_tags($futur_pseudo);
329
    $futur_pseudo = preg_replace('/[\r\n\t ]+/', ' ', $futur_pseudo);
330
    // Kill octets
331
    $futur_pseudo = preg_replace( '|%([a-fA-F0-9][a-fA-F0-9])|', '', $futur_pseudo );
332
    $futur_pseudo = preg_replace( '/&.+?;/', '', $futur_pseudo ); // Kill entities
333
    // Remplace les caractères accentués par le caractère correspondant
334
    $futur_pseudo = iconv('UTF-8', 'ASCII//TRANSLIT', $futur_pseudo);
335
    // Reduce to ASCII
336
    $futur_pseudo = preg_replace( '|[^a-z0-9 _.\-@]|i', '', $futur_pseudo );
337
    // Consolidate contiguous whitespace
338
    $futur_pseudo = mb_ereg_replace( '\s+', ' ', $futur_pseudo );
339
    $futur_pseudo = trim($futur_pseudo);
340
    // on remplace les espaces par des tirets
341
    $futur_pseudo = mb_ereg_replace( ' ', '-', $futur_pseudo );
342
    // on passe tout en minuscules
343
    $futur_pseudo = mb_strtolower($futur_pseudo);
344
    // On coupe pour que ça dépasse pas 45 charactères
345
    $futur_pseudo = substr($futur_pseudo, 0, 45);
346
 
347
    // die(var_dump($futur_pseudo));
348
 
349
    $unique = $futur_pseudo;
350
    $count = 0;
351
    do {
352
      $count++;
353
      if ($count%100 === 0) {
354
        echo($count . 'ème étape pour ' . $unique);
355
      }
356
 
357
      $existant = false;
358
      // on cherche si un utilisateur existant possède déjà ces propriétés
359
      foreach (['user_nicename', 'user_login'] as $champ) {
360
        $requete_pseudo = "SELECT $champ FROM " . $prefixe_tables_wp . "users WHERE $champ = '$unique'";
361
        // die(var_dump($requete_pseudo));
362
 
363
        try {
364
          $utilisateur_existant = $bdWordpress->query($requete_pseudo)->fetchAll(PDO::FETCH_ASSOC);
365
          // die(var_dump($utilisateur_existant));
366
        } catch(Exception $e) {
367
          echo "-- ECHEC " . __FUNCTION__ . " REQUÊTE: [$requete_pseudo]" . PHP_EOL;
368
 
369
          if (true !== $modeBourrin) {
370
            restaureLaTable($bdWordpress, $prefixe_tables_wp . 'users');
371
            restaureLaTable($bdWordpress, $prefixe_tables_wp . 'bp_xprofile_data');
372
 
373
            die(var_dump($e->errorInfo));
374
          }
375
        }
376
 
377
        if (!empty($utilisateur_existant)) {
378
          $existant = true;
379
          break;
380
        }
381
      }
382
 
383
      // si ça existe déjà on suffixe et on recommence
384
      if (true === $existant) {
385
        $unique = $futur_pseudo . '-' . rand(0, 1000);
386
      }
387
    } while (true === $existant);
388
 
389
    $utilisateur['user_nicename'] = $unique;
390
    $utilisateur['user_login'] = $unique;
391
    $utilisateur['display_name'] = $intitule;
392
    // $utilisateur['nickname'] = $pseudo; // nickname est dans les user_meta
393
    unset($utilisateur['U_SURNAME']);
394
    unset($utilisateur['U_NAME']);
395
 
396
 
397
    $req = 'INSERT INTO ' . $prefixe_tables_wp . 'users '
398
      . '(`ID`, `user_login`, `user_pass`, `user_nicename`, `user_email`, `user_url`, `user_registered`, `user_status`, `display_name`) '
399
      . 'VALUES(' . implode(', ', array_map(array($bdWordpress, 'quote'), $utilisateur)) . ') '
400
      . 'ON DUPLICATE KEY UPDATE `ID`=VALUES(`ID`), `user_login`=VALUES(`user_login`), `user_pass`=VALUES(`user_pass`), `user_nicename`=VALUES(`user_nicename`), `user_email`=VALUES(`user_email`), `user_url`=VALUES(`user_url`), `user_registered`=VALUES(`user_registered`), `user_status`=VALUES(`user_status`), `display_name`=VALUES(`display_name`);'
401
    ;
402
 
403
    try {
404
      $bdWordpress->exec($req);
405
 
406
      $compteur++;
407
    } catch(Exception $e) {
408
      echo "-- ECHEC " . __FUNCTION__ . " REQUÊTE: [$req]" . PHP_EOL;
409
 
410
      if (true !== $modeBourrin) {
411
        restaureLaTable($bdWordpress, $prefixe_tables_wp . 'users');
412
        restaureLaTable($bdWordpress, $prefixe_tables_wp . 'bp_xprofile_data');
413
 
414
        die(var_dump($e->errorInfo));
415
      }
416
    }
417
 
418
    $requete_pseudo_bp = "INSERT INTO " . $prefixe_tables_wp . "bp_xprofile_data (`field_id`, `user_id`, `value`, `last_updated`) VALUES
419
      ('1', {$utilisateur['ID']}, {$bdWordpress->quote($utilisateur['user_nicename'])}, '2017-05-19 15:06:16')
420
      ON DUPLICATE KEY UPDATE `field_id`=VALUES(`field_id`), `user_id`=VALUES(`user_id`), `value`=VALUES(`value`), `last_updated`=VALUES(`last_updated`);";
421
 
422
    try {
423
      $bdWordpress->exec($requete_pseudo_bp);
424
    } catch(Exception $e) {
425
      echo "-- ECHEC " . __FUNCTION__ . " REQUÊTE: [$req]" . PHP_EOL;
426
 
427
      if (true !== $modeBourrin) {
428
        restaureLaTable($bdWordpress, $prefixe_tables_wp . 'users');
429
        restaureLaTable($bdWordpress, $prefixe_tables_wp . 'bp_xprofile_data');
430
 
431
        die(var_dump($e->errorInfo));
432
      }
433
    }
434
  }
435
 
436
  echo '-- ' . $compteur . '/' . count($utilisateurs) . ' utilisateurs migrés. ' . PHP_EOL;
437
}
438
 
439
/**
440
 * @todo il manque les metas de visibilités des champs du profil (global dans le vieux site, et granulaire dans le nouveau, voir bp_xprofile_visibility_levels)
441
 * @todo il manque les inscriptions aux projets (ou alors vérifier)
442
 *
443
 */
444
function migrerUtilisateursMeta() {
445
  global $prefixe_tables_wp;
446
  global $bdTelaProd;
447
  global $bdWordpress;
448
  global $modeBourrin;
449
 
450
  sauvegardeLaTable($bdWordpress, $prefixe_tables_wp . 'usermeta');
451
 
452
  $requeteUtilisateursMeta = "SELECT `U_ID`, `U_NAME`, `U_SURNAME` FROM `annuaire_tela`;";
453
  $utilisateursMeta = $bdTelaProd->query($requeteUtilisateursMeta)->fetchAll(PDO::FETCH_ASSOC);
454
 
455
  $compteur = 0;
456
  foreach ($utilisateursMeta as $utilisateurMeta) {
457
 
458
    $pseudo = $bdTelaProd->query('SELECT amv_valeur AS pseudo FROM annu_meta_valeurs WHERE amv_ce_colonne = 99 AND amv_cle_ligne = ' . $utilisateurMeta['U_ID'])->fetch(PDO::FETCH_ASSOC);
459
    $pseudo_utilise = $bdTelaProd->query('SELECT amv_valeur AS pseudo_utilise FROM annu_meta_valeurs WHERE amv_ce_colonne = 136 AND amv_cle_ligne = ' . $utilisateurMeta['U_ID'])->fetch(PDO::FETCH_ASSOC);
460
 
461
 
462
    // die(var_dump($utilisateur));
463
 
464
    $nickname = $utilisateurMeta['U_SURNAME'] . ' ' . $utilisateurMeta['U_NAME'];
465
    if ($pseudo_utilise['pseudo_utilise'] && $pseudo['pseudo']) {
466
      $nickname = $pseudo['pseudo'];
467
    }
468
 
469
    // _access est pour définir les catégories d'articles que l'utilisateur pourra écrire
470
    $requeteInsert = 'INSERT INTO ' . $prefixe_tables_wp . "usermeta (`user_id`, `meta_key`, `meta_value`) VALUES "
471
      . "({$utilisateurMeta['U_ID']}, 'last_activity', '2017-05-19 15:06:16'), "
472
      . "({$utilisateurMeta['U_ID']}, 'first_name', {$bdWordpress->quote($utilisateurMeta['U_SURNAME'])}), "
473
      . "({$utilisateurMeta['U_ID']}, 'last_name', {$bdWordpress->quote($utilisateurMeta['U_NAME'])}), "
474
      . "({$utilisateurMeta['U_ID']}, 'nickname', {$bdWordpress->quote($nickname)}), "
475
      . "({$utilisateurMeta['U_ID']}, 'description', ''), "
476
      . "({$utilisateurMeta['U_ID']}, 'rich_editing', 'true'), "
477
      . "({$utilisateurMeta['U_ID']}, 'comment_shortcuts', 'false'), "
478
      . "({$utilisateurMeta['U_ID']}, 'admin_color', 'fresh'), "
479
      . "({$utilisateurMeta['U_ID']}, 'use_ssl', '0'), "
480
      . "({$utilisateurMeta['U_ID']}, 'show_admin_bar_front', 'true'), "
481
      . "({$utilisateurMeta['U_ID']}, '" . $prefixe_tables_wp . "capabilities', 'a:1:{s:11:\"contributor\";b:1;}'), "
482
      . "({$utilisateurMeta['U_ID']}, '" . $prefixe_tables_wp . "user_level', '1'), "
483
      . "({$utilisateurMeta['U_ID']}, 'dismissed_wp_pointers', ''), "
484
      . "({$utilisateurMeta['U_ID']}, 'wp_dashboard_quick_press_last_post_id', '63'), " // c koi ?
485
      . "({$utilisateurMeta['U_ID']}, '_restrict_media', '1'), " // lié au plugin restrict author media
486
      . "({$utilisateurMeta['U_ID']}, '_access', 'a:4:{i:0;s:1:\"2\";i:1;s:1:\"5\";i:2;s:1:\"6\";i:3;s:1:\"7\";}'), "
487
      . "({$utilisateurMeta['U_ID']}, 'bp_xprofile_visibility_levels', 'a:12:{i:1;s:6:\"public\";i:60;s:6:\'public\';i:61;s:6:\'public\';i:49;s:6:\'public\';i:55;s:6:\'public\';i:48;s:6:\'public\';i:62;s:6:\'public\';i:63;s:6:\'public\';i:68;s:6:\'public\';i:76;s:6:\'public\';i:120;s:6:\'public\';i:81;s:6:\'public\';}') "
488
      . ";";
489
 
490
    try {
491
      $bdWordpress->exec($requeteInsert);
492
 
493
      $compteur++;
494
    } catch(Exception $e) {
495
      echo "-- ECHEC " . __FUNCTION__ . " REQUÊTE: [$requeteInsert]" . PHP_EOL;
496
 
497
      if (true !== $modeBourrin) {
498
        restaureLaTable($bdWordpress, $prefixe_tables_wp . 'usermeta');
499
 
500
        die(var_dump($e->errorInfo));
501
      }
502
    }
503
  }
504
 
505
  echo '-- ' . $compteur . '/' . count($utilisateursMeta) . 'metas d\'utilisateur migrées. ' . PHP_EOL;
506
}
507
 
508
function migrerUtilisateursActivite() {
509
  global $prefixe_tables_wp;
510
  global $bdTelaProd;
511
  global $bdWordpress;
512
  global $modeBourrin;
513
 
514
  sauvegardeLaTable($bdWordpress, $prefixe_tables_wp . 'bp_activity');
515
 
516
  $requete = 'SELECT `U_ID` FROM `annuaire_tela`;';
517
  $utilisateurs = $bdTelaProd->query($requete)->fetchAll(PDO::FETCH_ASSOC);
518
 
519
  $compteur = 0;
520
  foreach ($utilisateurs as $utilisateur) {
521
    $requeteInsert = 'INSERT INTO ' . $prefixe_tables_wp . "bp_activity
522
      (`id`, `user_id`, `component`, `type`, `action`, `content`, `primary_link`, `item_id`, `secondary_item_id`, `date_recorded`, `hide_sitewide`, `mptt_left`, `mptt_right`, `is_spam`)
523
      VALUES (NULL, {$utilisateur['U_ID']}, 'members', 'last_activity', '', '', '', '0', NULL, '2017-05-19 15:06:16', '0', '0', '0', '0');"; // @todo voir si ON DUPLICATE KEY UPDATE est pertinent ici mais on dirait bien
524
 
525
    try {
526
      $bdWordpress->exec($requeteInsert);
527
 
528
      $compteur++;
529
    } catch(Exception $e) {
530
      echo "-- ECHEC " . __FUNCTION__ . " REQUÊTE: [$requeteInsert]" . PHP_EOL;
531
 
532
      if (true !== $modeBourrin) {
533
        restaureLaTable($bdWordpress, $prefixe_tables_wp . 'bp_activity');
534
 
535
        die(var_dump($e->errorInfo));
536
      }
537
    }
610 delphine 538
	}
539
 
619 killian 540
  echo '-- ' . $compteur . '/' . count($utilisateurs) . ' activités d\'utilisateur migrés. ' . PHP_EOL;
541
}
542
 
543
function migrerUtilisateursProfil() {
544
  global $prefixe_tables_wp;
545
  global $bdTelaProd;
546
  global $bdWordpress;
547
  global $modeBourrin;
548
 
549
  $codes_langues = [
550
    '30842'=>'Anglais',
551
    '30843'=>'Allemand',
552
    '30844'=>'Italien',
553
    '30845'=>'Espagnol',
554
    '30846'=>'Arabe',
555
    '30847'=>'Chinois',
556
    '30848'=>'Russe'
557
  ];
558
 
621 eric 559
  // Eric : ajout Saint-Pierre-et-Miquelon - 975
619 killian 560
  $departements = [
561
    '01' => 'Ain',
562
    '02' => 'Aisne',
563
    '03' => 'Allier',
564
    '04' => 'Alpes-de-Haute-Provence',
565
    '05' => 'Hautes-Alpes',
566
    '06' => 'Alpes-Maritimes',
567
    '07' => 'Ardèche',
568
    '08' => 'Ardennes',
569
    '09' => 'Arièges',
570
    '10' => 'Aube',
571
    '11' => 'Aude',
572
    '12' => 'Aveyron',
573
    '13' => 'Bouches-du-Rhône',
574
    '14' => 'Calvados',
575
    '15' => 'Cantal',
576
    '16' => 'Charente',
577
    '17' => 'Charente-Maritime',
578
    '18' => 'Cher',
579
    '19' => 'Corrèze',
580
    '201' => 'Corse-du-Sud',
581
    '202' => 'Haute-Corse',
582
    '21' => 'Côte d\'Or',
583
    '22' => 'Côtes-d\'Armor',
584
    '23' => 'Creuse',
585
    '24' => 'Dordogne',
586
    '25' => 'Doubs',
587
    '26' => 'Drôme',
588
    '27' => 'Eure',
589
    '28' => 'Eure-et-Loir',
590
    '29' => 'Finistère',
591
    '30' => 'Gard',
592
    '31' => 'Haute-Garonne',
593
    '32' => 'Gers',
594
    '33' => 'Gironde',
595
    '34' => 'Hérault',
596
    '35' => 'Ille-et-Vilaine',
597
    '36' => 'Indre',
598
    '37' => 'Indre-et-Loire',
599
    '38' => 'Isère',
600
    '39' => 'Jura',
601
    '40' => 'Landes',
602
    '41' => 'Loir-et-Cher',
603
    '42' => 'Loire',
604
    '43' => 'Haute-Loire',
605
    '44' => 'Loire-Atlantique',
606
    '45' => 'Loiret',
607
    '46' => 'Lot',
608
    '47' => 'Lot-et-Garonne',
609
    '48' => 'Lozère',
610
    '49' => 'Maine-et-Loire',
611
    '50' => 'Manche',
612
    '51' => 'Marne',
613
    '52' => 'Haute-Marne',
614
    '53' => 'Mayenne',
615
    '54' => 'Meurthe-et-Moselle',
616
    '55' => 'Meuse',
617
    '56' => 'Morbihan',
618
    '57' => 'Moselle',
619
    '58' => 'Nièvre',
620
    '59' => 'Nord',
621
    '60' => 'Oise',
622
    '61' => 'Orne',
623
    '62' => 'Pas-de-Calais',
624
    '63' => 'Puy-de-Dôme',
625
    '64' => 'Pyrénées-Atlantiques',
626
    '65' => 'Hautes-Pyrénées',
627
    '66' => 'Pyrénées-Orientales',
628
    '67' => 'Bas-Rhin',
629
    '68' => 'Haut-Rhin',
630
    '69' => 'Rhône',
631
    '70' => 'Haute-Saône',
632
    '71' => 'Saône-et-Loire',
633
    '72' => 'Sarthe',
634
    '73' => 'Savoie',
635
    '74' => 'Haute-Savoie',
636
    '75' => 'Paris',
637
    '76' => 'Seine-Maritime',
638
    '77' => 'Seine-et-Marne',
639
    '78' => 'Yvelines',
640
    '79' => 'Deux-Sèvres',
641
    '80' => 'Somme',
642
    '81' => 'Tarn',
643
    '82' => 'Tarn-et-Garonne',
644
    '83' => 'Var',
645
    '84' => 'Vaucluse',
646
    '85' => 'Vendée',
647
    '86' => 'Vienne',
648
    '87' => 'Haute-Vienne',
649
    '88' => 'Vosges',
650
    '89' => 'Yonne',
651
    '90' => 'Territoire de Belfort',
652
    '91' => 'Essonne',
653
    '92' => 'Hauts-de-Seine',
654
    '93' => 'Seine-Saint-Denis',
655
    '94' => 'Val-de-Marne',
656
    '95' => 'Val-d\'Oise',
657
    '971' => 'Guadeloupe',
658
    '972' => 'Martinique',
659
    '973' => 'Guyane',
660
    '974' => 'La Réunion',
621 eric 661
    '975' => 'Saint-Pierre-et-Miquelon',
619 killian 662
    '976' => 'Mayotte',
663
  ];
664
 
665
// Export des meta de buddypress :
666
// INSERT INTO `bp_xprofile_fields` (`id`, `group_id`, `parent_id`, `type`, `name`, `description`, `is_required`, `is_default_option`, `field_order`, `option_order`, `order_by`, `can_delete`)
667
// (1, 1, 0, 'textbox', 'Pseudo', '', 1, 0, 0, 0, '', 0),
668
// (2, 3, 0, 'datebox', 'Date de naissance', '', 0, 0, 1, 0, '', 1),
669
// (3, 1, 0, 'selectbox', 'Pays', '', 1, 0, 4, 0, 'custom', 1),
670
// (4, 1, 0, 'textbox', 'Ville', '', 1, 0, 6, 0, '', 1),
671
// (9, 1, 0, 'textbox', 'Nom', '', 1, 0, 3, 0, '', 1),
672
// (10, 1, 0, 'textbox', 'Prénom', '', 0, 0, 2, 0, '', 1),
673
// (12, 2, 0, 'selectbox', 'Expérience botanique', '', 1, 0, 0, 0, 'custom', 1),
674
// (63, 2, 0, 'textbox', 'Espèce d''intérêt', 'Pour préciser votre famille, genre voire espèce de spécialisation ou noter votre plante préférée', 0, 0, 2, 0, 'custom', 1),
675
// (61, 2, 0, 'checkbox', 'Zones géographiques d''intérêt', 'Pour préciser vos zones phytogéographiques et altitudes de prédilection.', 0, 0, 3, 0, 'custom', 1),
676
// (26, 3, 0, 'selectbox', 'Métier', '', 0, 0, 3, 0, 'custom', 1),
677
// (46, 1, 0, 'selectbox', 'Compte', 'Merci de préciser si votre compte est un compte personnel ou professionnel (utilisé par une personne) ou de structure (partagé par plusieurs personnes)', 1, 0, 1, 0, 'custom', 1),
678
// (69, 2, 0, 'selectbox', 'Membre d''une association naturaliste', '', 0, 0, 1, 0, 'custom', 1),
679
// (51, 1, 0, 'textbox', 'Adresse', 'Votre adresse ne sera pas communiquée mais nous est utile pour éditer les reçus fiscaux si vous nous faites un don.', 0, 0, 8, 0, '', 1),
680
// (52, 3, 0, 'url', 'Site web', 'Si vous avez un site web personnel', 0, 0, 2, 0, '', 1),
681
// (53, 3, 0, 'textarea', 'Présentation', '', 0, 0, 0, 0, '', 1),
682
// (54, 1, 0, 'checkbox', 'Inscription à la lettre d''actualité', '', 0, 0, 9, 0, 'custom', 1),
683
// (59, 1, 0, 'checkbox', 'Conditions d''utilisation', 'Lire les  <a href="https://www.tela-botanica.org/mentions-legales/#conditions-d-utilisation"> conditions d''utilisation du site</a>', 1, 0, 10, 0, 'custom', 1),
684
// (592, 1, 0, 'selectbox', 'Département', '', 0, 0, 5, 0, 'custom', 1),
685
 
686
// Correspondances entre les anciennes meta et celles de BP :
687
// nom du champ             ; id actuel ; id BP       ; valeurs
688
// prenom                   ; 7         ; 10
689
// experience bota          ; 4         ; 12      (également présent dans la table annuaire_tela.U_NIV mais n'est jamais mis à jour)
690
// departement (ou cp)      ; 13        ; 592         ; pas trouvé d'exemple (faut utiliser annuaire_tela.U_ZIP_CODE)
691
// conditions d'utilisation ; 15        ; 59 sur test (1035 sur preprod)          ; 1
692
// lettre d'actu            ; 14        ; 54          ; pas trouvé d'exemple
693
// presentation             ; 125       ; 53          ; juste du texte
694
// site web                 ; 134       ; 52      (n'est pas rempli, c'est la valeur de annuaire_tela.U_WEB qui est utilisée en vrai)
695
// adresse                  ; 132       ; 51          ; pas trouvé d'exemple
696
// membre asso natur        ; 133       ; 69          ; [30833, 30834, 30811, 30812, 30813]
697
// compte                   ; pas d'équivalent ; 46
698
// metier                   ; pas d'équivalent ; 26
699
// zone geo d'interet       ; 120       ; 61          ; [30806] ex: 30805;;30806;;30807
700
// espece d'interet         ; pas forcément ça 8 ; 63 ; [30829]
701
 
702
  // l'index c'est l'identifiant actuel (amv_ce_colonne), et la valeur c'est celle coté bp
703
  $correspondance_categories = [
704
    '99'  => '1', // pseudo
705
    '2'   => '137', // langues
706
    '13'  => '592', // code postal
707
    '137' => '2', // date naissance
708
    '12'  => '3', // pays
709
    '103' => '4', // ville
710
    '1'   => '9', // nom
711
    '7'   => '10', // prenom
712
    '4'   => '12', // niveau bota
713
    '8'   => '63', // espece d'interet
714
    '120' => '61', // zones géo
715
    '133' => '69', // membre asso natur
716
    '132' => '51', // adresse
717
    '134' => '52', // site web
718
    '125' => '53', // presentation
719
    '14'  => '54', // lettre d'actu
720
    '15'  => '59', // conditions d'utilisation
721
  ];
722
 
723
  // expériences pour déterminer les metas utilisées de cotre coté
724
  // résultat de la requête
725
  // SELECT amc_abreviation, amv_valeur  FROM `annu_meta_valeurs`JOIN annu_meta_colonne ON `amv_ce_colonne` = amc_id_champ WHERE `amv_ce_colonne` IN (99, 2, 13, 137, 12, 103, 1, 7, 4, 8, 120, 133, 132, 134, 125, 14, 15) AND amv_valeur != '' AND `amv_cle_ligne` = 41014;
726
  // experience_bota  30787
727
  // conditions_utilisation  1
728
  // pseudo  KillianPseudoTest
729
  // date_naissance  02/01/1990
730
  // presentation  J'ai commencé la botanique hier, après avoir fait ...
731
  // specialite_bota_groupes   30829;;30837
732
  // specialite_bota_geo   30806;;30807
733
  // langues   30842;;30847
734
  // mon_blog  http://lolilol.lol
735
  // membre_asso_bota  30833
736
  //
737
  // On voit que nombre de correspondances ne sont en fait pas
738
 
739
  $correspondances_niveau_bota = [
740
    '30786' => 'Débutant',
741
    '30787' => 'Ayant une bonne pratique',
742
    '30788' => 'Confirmé',
743
    '30790' => 'Ne se prononce pas'
744
  ];
745
 
746
  $correspondances_membre_asso_naturaliste = [
747
    '30833' => 'Oui',
748
    '30834' => 'Non',
749
    '30811' => 'Ne se prononce pas',
750
    '30812' => 'Oui',
751
    '30813' => 'Non'
752
  ];
753
 
754
  // a:8:{i:0;s:14:"Zones polaires";i:1;s:17:"Zones tempérées";i:2;s:16:"Zones tropicales";i:3;s:24:"Zones méditerranéennes";i:4;s:6:"Plaine";i:5;s:13:"Basses terres";i:6;s:13:"Hautes terres";i:7;s:8:"Montagne";}
755
  $correspondances_zones_geo = [
756
    '30805' => 'Zones tempérées', // Zones géographiques : tempérées et boréales
757
    '30806' => 'Zones méditerranéennes', // Zone géographique : Méditerranéenne
758
    '30807' => 'Zones tropicales' // Zones géographiques : subtropicales à tropicales
759
  ];
760
 
761
  // correspondance espèces d'interet
762
 
763
  sauvegardeLaTable($bdWordpress, $prefixe_tables_wp . 'bp_xprofile_data');
764
 
765
  $requete_supp = "SELECT *  FROM `annu_meta_valeurs` WHERE `amv_ce_colonne` in (99, 2, 137, 12, 103, 1, 7, 4, 8, 120, 133, 132, 134, 125, 14, 15) AND (amv_valeur != ''  AND amv_valeur != 0)";
766
  $infos_supp = $bdTelaProd->query($requete_supp)->fetchAll(PDO::FETCH_ASSOC);
767
 
768
  foreach ($infos_supp as $infos) {
769
    switch ($infos['amv_ce_colonne']) {
770
      case 2: // langues
771
        //exemple a:3:{i:0;s:7:"Anglais";i:1;s:8:"Espagnol";i:2;s:7:"Italien";}
772
        $langues = explode(';;', $infos['amv_valeur']);
773
        if (count($langues)) {
774
          $supp[$infos['amv_cle_ligne']][$infos['amv_ce_colonne']] = serialize($langues);
775
        }
776
 
777
        break;
778
      case 4: // niveau bota
779
        $supp[$infos['amv_cle_ligne']][$infos['amv_ce_colonne']] = $correspondances_niveau_bota[$infos['amv_valeur']];
780
 
781
        break;
782
      case 133: // asso naturalistes
783
        $supp[$infos['amv_cle_ligne']][$infos['amv_ce_colonne']] = $correspondances_membre_asso_naturaliste[$infos['amv_valeur']];
784
 
785
        break;
786
      case 15: // conditions d'utilisation
787
        if (1 == $infos['amv_valeur']) {
788
          $supp[$infos['amv_cle_ligne']][$infos['amv_ce_colonne']] = serialize("J\'accepte les conditions d\'utilisation");
789
        }
790
 
791
        break;
792
      case 120: // zones géo
793
        // exemple: a:3:{i:0;s:16:"Zones tropicales";i:1;s:24:"Zones méditerranéennes";i:2;s:8:"Montagne";}
794
        $zones_geo = explode(';;', $infos['amv_valeur']);
795
        if (count($zones_geo)) {
796
          $supp[$infos['amv_cle_ligne']][$infos['amv_ce_colonne']] = serialize($zones_geo);
797
        }
798
 
799
        break;
800
      default:
801
        $supp[$infos['amv_cle_ligne']][$infos['amv_ce_colonne']] = $infos['amv_valeur'];
802
 
803
        break;
804
    }
805
  }
806
 
622 mathias 807
  $requete = "SELECT `U_ID`, `U_NAME`, `U_SURNAME`, U_WEB, `U_CITY`, `U_COUNTRY`, pays, `U_ZIP_CODE` FROM `annuaire_tela`
619 killian 808
    LEFT JOIN (SELECT  `amo_nom` AS pays,  `amo_abreviation` FROM `annu_meta_ontologie` WHERE  `amo_ce_parent` = 1074) liste_pays  ON `amo_abreviation` = `U_COUNTRY`";
809
  $utilisateurs = $bdTelaProd->query($requete)->fetchAll(PDO::FETCH_ASSOC);
810
 
811
  $compteur = 0;
812
  foreach ($utilisateurs as $utilisateur) {
813
    // on va essayer de trouver le département à partir du code postal
814
    if (preg_match('@(?:^(\d{2})(\d)\d{2}.*$)|(?:^(\d{2})\s.*$)@', $utilisateur['U_ZIP_CODE'], $matches)) {
815
      $numero_departement = $matches[1];
816
      $numero_complementaire = $matches[2]; // pour la corse (201/202) ou les  // DOM (97X) et TOM (98X)
817
 
818
      switch ($numero_departement) {
819
        case 975: // Saint-Pierre-et-Miquelon
820
        case 98: // TOM (98X)
821
          // on ne gère pas ces cas, considérés comme des pays à part dans le formulaire d'inscription
822
          break;
823
        case 97: // DOM (97X)
824
        case 20: // Corse (201/202)
825
          if (isset($departements[$numero_departement . $numero_complementaire])) {
826
            $utilisateur['U_ZIP_CODE'] = $departements[$numero_departement . $numero_complementaire];
827
          }
828
          break;
829
        default:
830
          if (isset($departements[$numero_departement])) {
831
            $utilisateur['U_ZIP_CODE'] = $departements[$numero_departement];
832
          }
833
          break;
834
      }
835
    }
836
 
837
    $requeteInsert = "INSERT INTO " . $prefixe_tables_wp . "bp_xprofile_data (`field_id`, `user_id`, `value`, `last_updated`) VALUES
838
      ('3', {$utilisateur['U_ID']}, {$bdWordpress->quote($utilisateur['pays'])}, '2017-05-19 15:06:16'),
839
      ('4', {$utilisateur['U_ID']}, {$bdWordpress->quote($utilisateur['U_CITY'])}, '2017-05-19 15:06:16'),
840
      ('9', {$utilisateur['U_ID']}, {$bdWordpress->quote($utilisateur['U_NAME'])}, '2017-05-19 15:06:16'),
841
      ('10', {$utilisateur['U_ID']}, {$bdWordpress->quote($utilisateur['U_SURNAME'])}, '2017-05-19 15:06:16'),
842
      ('592', {$utilisateur['U_ID']}, {$bdWordpress->quote($utilisateur['U_ZIP_CODE'])}, '2017-05-19 15:06:16'),
843
      ('21', {$utilisateur['U_ID']}, {$bdWordpress->quote($utilisateur['U_WEB'])}, '2017-05-19 15:06:16')";
844
    if (isset($supp[$utilisateur['U_ID']])) {
845
      foreach ($supp[$utilisateur['U_ID']] as $num => $val){
846
        $requeteInsert .= ",({$correspondance_categories[$num]}, {$utilisateur['U_ID']}, {$bdWordpress->quote($val)}, '2017-05-19 15:06:16')";
847
      }
848
    }
849
    $requeteInsert .= "
850
      ON DUPLICATE KEY UPDATE `field_id`=VALUES(`field_id`), `user_id`=VALUES(`user_id`), `value`=VALUES(`value`), `last_updated`=VALUES(`last_updated`);";
851
 
852
    try {
853
      $bdWordpress->exec($requeteInsert);
854
 
855
      $compteur++;
856
    } catch(Exception $e) {
857
      echo "-- ECHEC " . __FUNCTION__ . " REQUÊTE: [$requeteInsert]" . PHP_EOL;
858
 
859
      if (true !== $modeBourrin) {
860
        restaureLaTable($bdWordpress, $prefixe_tables_wp . 'bp_xprofile_data');
861
 
862
        die(var_dump($e->errorInfo));
863
      }
864
    }
865
  }
866
 
867
  echo '-- ' . $compteur . '/' . count($utilisateurs) . ' profils d\'utilisateur migrés. ' . PHP_EOL;
868
}
869
 
870
function migrerEvenements() {
871
  global $prefixe_tables_wp;
872
  global $bdTelaProd;
873
  global $bdWordpress;
874
  global $modeBourrin;
875
 
876
  sauvegardeLaTable($bdWordpress, $prefixe_tables_wp . 'posts');
877
 
878
  $requeteEvenements = "SELECT `bf_id_fiche`+10000 AS `ID`, `bf_ce_utilisateur` AS  `post_author`, `bf_date_creation_fiche` AS  `post_date`, `bf_date_creation_fiche` AS  `post_date_gmt`, '' AS  `post_content`, `bf_titre` AS  `post_title`, '' AS  `post_excerpt`, 'publish' AS  `post_status`, 'open' AS  `comment_status`, 'open' AS  `ping_status`, '' AS  `post_password`, `bf_id_fiche`+10000 AS  `post_name`, '' AS  `to_ping`, '' AS  `pinged`, `bf_date_maj_fiche` AS  `post_modified`, `bf_date_maj_fiche` AS  `post_modified_gmt`, '' AS  `post_content_filtered`, 0 AS  `post_parent`, `bf_id_fiche`+10000 AS  `guid`, 0 AS  `menu_order`, 'post' AS  `post_type`, '' AS  `post_mime_type`, 0 AS  `comment_count` FROM `bazar_fiche` WHERE year(`bf_date_debut_validite_fiche`) >= 2017;";
879
 
880
  $evenements = $bdTelaProd->query($requeteEvenements)->fetchAll(PDO::FETCH_ASSOC);
881
 
882
  $compteur = 0;
883
  foreach ($evenements as $evenement) {
884
    // gestion des dates normales et dates en GMT
885
    $date = new DateTime($evenement['post_date'], new DateTimeZone('Europe/Paris'));
886
    $evenement['post_date_gmt'] = $date->setTimezone(new DateTimeZone('GMT'))->format('Y-m-d H:i:s');
887
    $date = new DateTime($evenement['post_modified'], new DateTimeZone('Europe/Paris'));
888
    $evenement['post_modified_gmt'] = $date->setTimezone(new DateTimeZone('GMT'))->format('Y-m-d H:i:s');
889
 
890
    $requete = 'INSERT INTO ' . $prefixe_tables_wp . 'posts (`ID`, `post_author`, `post_date`, `post_date_gmt`, `post_content`, `post_title`, `post_excerpt`, `post_status`, `comment_status`, `ping_status`, `post_password`, `post_name`, `to_ping`, `pinged`, `post_modified`, `post_modified_gmt`, `post_content_filtered`, `post_parent`, `guid`, `menu_order`, `post_type`, `post_mime_type`, `comment_count`) VALUES'
891
      . '(' . implode(', ', array_map(array($bdWordpress, 'quote'), $evenement)) . ')'
892
      . 'ON DUPLICATE KEY UPDATE `ID`=VALUES(`ID`), `post_author`=VALUES(`post_author`), `post_date`=VALUES(`post_date`), `post_date_gmt`=VALUES(`post_date_gmt`), `post_content`=VALUES(`post_content`), `post_title`=VALUES(`post_title`), `post_excerpt`=VALUES(`post_excerpt`), `post_status`=VALUES(`post_status`), `comment_status`=VALUES(`comment_status`), `ping_status`=VALUES(`ping_status`), `post_password`=VALUES(`post_password`), `post_name`=VALUES(`post_name`), `to_ping`=VALUES(`to_ping`), `pinged`=VALUES(`pinged`), `post_modified`=VALUES(`post_modified`), `post_modified_gmt`=VALUES(`post_modified_gmt`), `post_content_filtered`=VALUES(`post_content_filtered`), `post_parent`=VALUES(`post_parent`), `guid`=VALUES(`guid`), `menu_order`=VALUES(`menu_order`), `post_type`=VALUES(`post_type`), `post_mime_type`=VALUES(`post_mime_type`), `comment_count`=VALUES(`comment_count`);'
893
    ;
894
 
895
    try {
896
      $bdWordpress->exec($requete);
897
 
898
      $compteur++;
899
    } catch(Exception $e) {
900
      echo "-- ECHEC " . __FUNCTION__ . " REQUÊTE: [$requete]" . PHP_EOL;
901
 
902
      if (true !== $modeBourrin) {
903
        restaureLaTable($bdWordpress, $prefixe_tables_wp . 'posts');
904
 
905
        die(var_dump($e->errorInfo));
906
      }
907
    }
908
 
909
    // collecte les infos pour l'enregistrement des redirections 301 des articles
910
    $ancienne_url = 'http://www.tela-botanica.org/page:evenements?action=8&id_fiche=' . $evenement['ID'] - 10000;
911
    $insert_redirection[] = '(' . $article['ID'] . ', ' . $bdWordpress->quote($ancienne_url) . ')';
912
 
913
    $requeteInsertRedirection = 'INSERT INTO ' . $prefixe_tables_wp . 'slug_history (`post_id`, `url`)
914
      VALUES ' . implode(', ', $insert_redirection) . '
915
      ON DUPLICATE KEY UPDATE `post_id`=VALUES(`post_id`), `url`=VALUES(`url`);';
916
 
917
    try {
918
        $bdWordpress->exec($requeteInsertRedirection);
919
      } catch(Exception $e) {
920
        echo "-- ECHEC " . __FUNCTION__ . " REQUÊTE: [$requeteInsertRedirection]" . PHP_EOL;
921
 
922
        if (true !== $modeBourrin) {
923
          restaureLaTable($bdWordpress, $prefixe_tables_wp . 'posts');
924
          restaureLaTable($bdWordpress, $prefixe_tables_wp . 'slug_history');
925
 
926
          die(var_dump($e->errorInfo));
927
        }
928
      }
929
  }
930
 
931
  echo '-- ' . $compteur . '/' . count($evenements) . ' évènements migrés. ' . PHP_EOL;
932
}
933
/*
934
 * @todo vérifier que les metas sont bien synchros avec l'actuel
935
 */
936
function migrerEvenementsMeta() {
937
  global $prefixe_tables_wp;
938
  global $bdTelaProd;
939
  global $bdWordpress;
940
  global $modeBourrin;
941
 
942
  sauvegardeLaTable($bdWordpress, $prefixe_tables_wp . 'postmeta');
943
 
944
  $fin = 'AS meta_value FROM `bazar_fiche` WHERE year(`bf_date_debut_validite_fiche`) >= 2017';
945
 
946
	$requeteEvenementsChampsACF = "SELECT `bf_id_fiche`+10000 AS post_id,  '_edit_lock' AS meta_key, CONVERT(CONVERT('1476892394:1'  USING utf8)  USING utf8) $fin UNION
947
SELECT `bf_id_fiche`+10000 AS post_id,  '_edit_last' AS meta_key, CONVERT('1'  USING utf8) $fin UNION
948
SELECT `bf_id_fiche`+10000 AS post_id,  '_alp_processed' AS meta_key, CONVERT('1476891070'  USING utf8) $fin UNION
949
 
950
SELECT `bf_id_fiche`+10000 AS post_id,  '_place' AS meta_key, CONVERT('field_580366d5a9e01'  USING utf8) $fin UNION
951
SELECT `bf_id_fiche`+10000 AS post_id,  'place' AS meta_key, CONVERT('a:3:{s:7:\"address\";s:47:\"53 Bd Bonne Nouvelle, 34000 Montpellier, France\";s:3:\"lat\";s:17:\"43.61335152461514\";s:3:\"lng\";s:17:\"3.880716562271118\";}'  USING utf8) $fin UNION
952
 
953
SELECT `bf_id_fiche`+10000 AS post_id,  '_contact_0_description' AS meta_key, CONVERT('field_580e45789024f'  USING utf8) $fin UNION
954
SELECT `bf_id_fiche`+10000 AS post_id,  'contact_0_description' AS meta_key, CONVERT(bf_nom_contact  USING utf8) $fin UNION
955
 
956
SELECT `bf_id_fiche`+10000 AS post_id,  '_prices' AS meta_key, CONVERT('field_5803a6059a5d1'  USING utf8) $fin UNION
957
SELECT `bf_id_fiche`+10000 AS post_id,  'prices' AS meta_key, CONVERT(bf_tarif_individuel  USING utf8) $fin UNION
958
SELECT `bf_id_fiche`+10000 AS post_id,  '_is_free' AS meta_key, CONVERT('field_5803a5d09a5d0'  USING utf8) $fin UNION
959
SELECT `bf_id_fiche`+10000 AS post_id,  'is_free' AS meta_key, CONVERT('0'  USING utf8) $fin UNION
960
 
961
SELECT `bf_id_fiche`+10000 AS post_id,  '_image' AS meta_key, CONVERT('field_5803a65a08014'  USING utf8) $fin UNION
962
SELECT `bf_id_fiche`+10000 AS post_id,  'image' AS meta_key, CONVERT('7669'  USING utf8) $fin UNION
963
SELECT `bf_id_fiche`+10000 AS post_id,  '_contact' AS meta_key, CONVERT('field_580e45279024d'  USING utf8) $fin UNION
964
SELECT `bf_id_fiche`+10000 AS post_id,  'contact' AS meta_key, CONVERT('1'  USING utf8) $fin UNION
965
 
966
SELECT `bf_id_fiche`+10000 AS post_id,  '_description' AS meta_key, CONVERT('field_580366bfa9e00'  USING utf8) $fin UNION
967
SELECT `bf_id_fiche`+10000 AS post_id,  'description' AS meta_key, CONVERT(bf_description  USING utf8) $fin UNION
968
 
969
SELECT `bf_id_fiche`+10000 AS post_id,  '_date' AS meta_key, CONVERT('field_580364c892ee1'  USING utf8) $fin UNION
970
SELECT `bf_id_fiche`+10000 AS post_id,  'date' AS meta_key, CONVERT(date_format(bf_date_fin_evenement, '%Y%m%d') USING utf8) $fin UNION
971
SELECT `bf_id_fiche`+10000 AS post_id,  '_date_end' AS meta_key, CONVERT('field_5803659792ee5'  USING utf8) $fin UNION
972
SELECT `bf_id_fiche`+10000 AS post_id,  'date_end' AS meta_key, CONVERT(date_format(bf_date_debut_evenement, '%Y%m%d') USING utf8) $fin;";
973
 
974
	$evenementsChampsACF = $bdTelaProd->query($requeteEvenementsChampsACF)->fetchAll(PDO::FETCH_ASSOC);
975
 
976
  $compteur = 0;
977
  foreach ($evenementsChampsACF as $champACF) {
978
    $requete = 'INSERT INTO ' . $prefixe_tables_wp . 'postmeta (`post_id`, `meta_key`, `meta_value`) VALUES'
979
      . '(' . implode(', ', array_map(array($bdWordpress, 'quote'), $champACF)) . ')'
980
      . 'ON DUPLICATE KEY UPDATE `post_id`=VALUES(`post_id`), `meta_key`=VALUES(`meta_key`), `meta_value`=VALUES(`meta_value`);'
981
      ;
982
 
983
    try {
984
      $bdWordpress->exec($requete);
985
 
986
      $compteur++;
987
    } catch(Exception $e) {
988
      echo "-- ECHEC " . __FUNCTION__ . " REQUÊTE: [$requete]" . PHP_EOL;
989
 
990
      if (true !== $modeBourrin) {
991
        restaureLaTable($bdWordpress, $prefixe_tables_wp . 'postmeta');
992
 
993
        die(var_dump($e->errorInfo));
994
      }
995
    }
996
  }
997
 
998
  echo '-- ' . $compteur . '/' . count($evenementsChampsACF) . ' meta d\'évènements migrées. ' . PHP_EOL;
999
}
1000
 
1001
// private function migrerEvenementsRubrique() {
1002
// 	$requete = "INSERT INTO ".$this->basewp."term_relationships (`object_id`, `term_taxonomy_id`)
1003
// 		SELECT `bf_id_fiche` +10000, replace( replace( replace( replace( `bf_ce_nature` , '3', '39' ) , '4', '38' ) , '2', '37' ) , '1', '40' )
1004
// 			FROM `bazar_fiche`
1005
// 			WHERE year( `bf_date_debut_validite_fiche` ) =2016
1006
// 			UNION SELECT `bf_id_fiche` +10000, 36 AS cat_evnt
1007
// 			FROM `bazar_fiche`
1008
// 			WHERE year( `bf_date_debut_validite_fiche` ) =2016";
1009
// 	$retour = $this->bdd->executer($requete);
1010
// 	echo 'Il y a '.count($retour).' actualités migrées '."--";
1011
// }
1012
 
1013
 
1014
 /**
1015
  * Explication des champs de la table wp_posts : https://deliciousbrains.com/tour-wordpress-database/#wp_posts
1016
  *
1017
  * @todo : revoir la méthode d'ajout, là c'est un peu violent, ça écrase les menus, le footer, toussa
1018
  * (wai les menus c'est stocké dans la table posts, deal with it)
1019
  * Vérifier l'auto-incrément de la table Posts, 20000 ids sont censés être réservés aux articles importés
1020
  * Voir : https://wordpress.stackexchange.com/a/78317
1021
  */
1022
function migrerActualites() {
1023
  global $prefixe_tables_wp;
1024
  global $bdSpip;
1025
  global $bdWordpress;
1026
  global $modeBourrin;
1027
  global $doc_loc;
1028
 
1029
  sauvegardeLaTable($bdWordpress, $prefixe_tables_wp . 'posts');
1030
  sauvegardeLaTable($bdWordpress, $prefixe_tables_wp . 'slug_history');
1031
 
1032
  $requete_doc = "SELECT d.`id_document`, `fichier`, `id_article` FROM `spip_documents` d LEFT JOIN spip_documents_articles da ON da.`id_document` = d.`id_document`";
1033
  $documents = $bdSpip->query($requete_doc)->fetchAll(PDO::FETCH_ASSOC);
1034
 
1035
  foreach ($documents as $doc) {
1036
    $doc_loc[$doc['id_document']] = $doc['fichier'];
1037
  }
1038
 
1039
	/*INSERT INTO `wp4_posts`
1040
	 SELECT spip_articles.`id_article` as ID, `id_auteur` as post_author, `date` as post_date, `date` as post_date_gmt,
1041
	 replace(replace(replace(replace(replace(replace(replace(replace(replace(convert( convert( texte USING latin1 ) USING utf8 ),'{{{{',''), '}}}}', '<!--more-->'), '{{{','<h2>'), '}}}', '</h2>'), '{{', '<strong>'), '}}', '</strong>'), '{', '<em>'), '}', '</em>'), '_ ', '') as post_content,
1042
	 `titre` as post_title,  "" as post_excerpt, replace(replace(replace(replace(replace(`statut`,'poubelle', 'trash'),'publie', 'publish'), 'prepa', 'private'), 'prop', 'pending'), 'refuse', 'trash') as post_status,  "open" as comment_status, "open" as ping_status, "" as post_password, spip_articles.`id_article` as post_name, "" as to_ping, "" as pinged, `date_modif` as post_modified,`date_modif` as post_modified_gmt, "" as post_content_filtered, "" as post_parent,
1043
	 concat("http://tela-botanica.net/wpsite/actu",spip_articles.`id_article`) as guid, "0" as menu_order, "post" as post_type, "" as post_mime_type, "" as comment_count FROM tela_prod_spip_actu.`spip_articles` left join tela_prod_spip_actu.spip_auteurs_articles on spip_auteurs_articles.`id_article` =  spip_articles.`id_article` WHERE id_rubrique in (22,54,70,30,19,51)
1044
	*/
1045
	$requete = "SELECT spip_articles.`id_article` AS ID, `id_auteur` AS post_author, `date` AS post_date, `date` AS post_date_gmt,
1046
		replace(replace(replace(replace(replace(replace(replace(replace(replace(convert( convert( texte USING latin1 ) USING utf8 ),'{{{{',''), '}}}}', '<!--more-->'), '{{{','<h2>'), '}}}', '</h2>'), '{{', '<strong>'), '}}', '</strong>'), '{', '<em>'), '}', '</em>'), '_ ', '') AS post_content,
1047
		`titre` AS post_title,  \"\" AS post_excerpt, replace(replace(replace(replace(replace(`statut`,'poubelle', 'trash'),'publie', 'publish'), 'prepa', 'private'), 'prop', 'pending'), 'refuse', 'trash') AS post_status,  \"open\" AS comment_status, \"open\" AS ping_status, \"\" AS post_password, concat(\"article\",spip_articles.`id_article`) AS post_name, \"\" AS to_ping, \"\" AS pinged, `date_modif` AS post_modified,`date_modif` AS post_modified_gmt, \"\" AS post_content_filtered, \"\" AS post_parent,
1048
		concat(\"http://tela-botanica.org/?p=\",spip_articles.`id_article`) AS guid, \"0\" AS menu_order, \"post\" AS post_type, \"\" AS post_mime_type, \"\" AS comment_count FROM `spip_articles` LEFT JOIN spip_auteurs_articles ON spip_auteurs_articles.`id_article` =  spip_articles.`id_article` WHERE id_rubrique in ( " . _rubriquesSpipAMigrer() . " )";
1049
	$articles = $bdSpip->query($requete)->fetchAll(PDO::FETCH_ASSOC);
1050
 
1051
	$i = 0;
1052
  $compteurSucces = 0;
1053
  $length = count($articles);
1054
	foreach ($articles as $article) {
1055
 
1056
		$article['post_content'] = preg_replace("/\[([^\[]*)\-\>([^\[]*)\]/", '<a href="\2">\1</a>', $article['post_content']);
1057
		//$images = preg_grep("\<img([0-9]*)\|[a-z]*\>", $article['post_content']);
1058
		$article['post_content'] = preg_replace_callback("/\<img([0-9]*)\|[a-z]*\>/", 'transformerNumEnUrl', $article['post_content']);
1059
 
1060
    // gestion des dates normales et dates en GMT
1061
    $date = new DateTime($article['post_date'], new DateTimeZone('Europe/Paris'));
1062
    $article['post_date_gmt'] = $date->setTimezone(new DateTimeZone('GMT'))->format('Y-m-d H:i:s');
1063
    $date = new DateTime($article['post_modified'], new DateTimeZone('Europe/Paris'));
1064
    $article['post_modified_gmt'] = $date->setTimezone(new DateTimeZone('GMT'))->format('Y-m-d H:i:s');
1065
 
1066
		$insert[] = '(' . implode(', ', array_map(array($bdWordpress, 'quote'), $article)) . ')';
1067
 
1068
		// collecte les infos pour l'enregistrement des redirections 301 des articles
1069
		$ancienne_url = 'http://www.tela-botanica.org/actu/article' . $article['ID'] . '.html';
1070
		$insert_redirection[] = '(' . $article['ID'] . ', ' . $bdWordpress->quote($ancienne_url) . ')';
1071
 
1072
		$i++;
1073
 
1074
    // Permet de d'insérer par lot de 50 ou bien à la fin
1075
		if (0 === $i % 50 || $i === $length -1) {
1076
			$requeteInsert = 'INSERT INTO ' . $prefixe_tables_wp . 'posts (`ID`, `post_author`, `post_date`, `post_date_gmt`, `post_content`, `post_title`, `post_excerpt`, `post_status`, `comment_status`, `ping_status`, `post_password`, `post_name`, `to_ping`, `pinged`, `post_modified`, `post_modified_gmt`, `post_content_filtered`, `post_parent`, `guid`, `menu_order`, `post_type`, `post_mime_type`, `comment_count`) VALUES ' . implode(', ', $insert) . '
1077
        ON DUPLICATE KEY UPDATE `ID`=VALUES(`ID`), `post_author`=VALUES(`post_author`), `post_date`=VALUES(`post_date`), `post_date_gmt`=VALUES(`post_date_gmt`), `post_content`=VALUES(`post_content`), `post_title`=VALUES(`post_title`), `post_excerpt`=VALUES(`post_excerpt`), `post_status`=VALUES(`post_status`), `comment_status`=VALUES(`comment_status`), `ping_status`=VALUES(`ping_status`), `post_password`=VALUES(`post_password`), `post_name`=VALUES(`post_name`), `to_ping`=VALUES(`to_ping`), `pinged`=VALUES(`pinged`), `post_modified`=VALUES(`post_modified`), `post_modified_gmt`=VALUES(`post_modified_gmt`), `post_content_filtered`=VALUES(`post_content_filtered`), `post_parent`=VALUES(`post_parent`), `guid`=VALUES(`guid`), `menu_order`=VALUES(`menu_order`), `post_type`=VALUES(`post_type`), `post_mime_type`=VALUES(`post_mime_type`), `comment_count`=VALUES(`comment_count`);';
1078
			try {
1079
        $bdWordpress->exec($requeteInsert);
1080
 
1081
        $compteurSucces += count($insert);
1082
      } catch(Exception $e) {
1083
        echo "-- ECHEC " . __FUNCTION__ . " REQUÊTE: [$requeteInsert]" . PHP_EOL;
1084
 
1085
        if (true !== $modeBourrin) {
1086
          restaureLaTable($bdWordpress, $prefixe_tables_wp . 'posts');
1087
          restaureLaTable($bdWordpress, $prefixe_tables_wp . 'slug_history');
1088
 
1089
          die(var_dump($e->errorInfo));
1090
        }
1091
      }
1092
			$insert = array();
1093
 
1094
			$requeteInsertRedirection = 'INSERT INTO ' . $prefixe_tables_wp . 'slug_history (`post_id`, `url`)
1095
        VALUES ' . implode(', ', $insert_redirection) . '
1096
        ON DUPLICATE KEY UPDATE `post_id`=VALUES(`post_id`), `url`=VALUES(`url`);';
1097
			try {
1098
        $bdWordpress->exec($requeteInsertRedirection);
1099
      } catch(Exception $e) {
1100
        echo "-- ECHEC " . __FUNCTION__ . " REQUÊTE: [$requeteInsertRedirection]" . PHP_EOL;
1101
 
1102
        if (true !== $modeBourrin) {
1103
          restaureLaTable($bdWordpress, $prefixe_tables_wp . 'posts');
1104
          restaureLaTable($bdWordpress, $prefixe_tables_wp . 'slug_history');
1105
 
1106
          die(var_dump($e->errorInfo));
1107
        }
1108
      }
1109
			$insert_redirection = array();
610 delphine 1110
		}
1111
	}
619 killian 1112
 
1113
  echo '-- ' . $compteurSucces . '/' . count($articles) . ' actualités migrées. ' . PHP_EOL;
1114
}
1115
 
1116
function transformerNumEnUrl($matches) {
1117
  global $doc_loc;
1118
 
1119
	$remplace = '';
1120
	if (isset($matches[1])) {
1121
		$remplace = '<img src="http://www.tela-botanica.org/actu/'.$doc_loc[$matches[1]].'" \/\>';
610 delphine 1122
	}
619 killian 1123
 
1124
	return $remplace;
610 delphine 1125
}
619 killian 1126
 
1127
// Retourne les id des rubriques SPIP à migrer
1128
function _rubriquesSpipAMigrer() {
1129
  global $correspondanceCategorieRubriques;
1130
 
1131
  $rubriquesAMigrer = [];
1132
  foreach ($correspondanceCategorieRubriques as $correspondance) {
1133
    $rubriquesAMigrer[] = implode(',', $correspondance['rubrique-a-migrer']);
1134
  }
1135
 
1136
  return implode(',', $rubriquesAMigrer);
1137
}
1138
 
1139
/**
1140
 * Ça c'est fait pour que les articles importés avant se retrouvent dans la bonne catégorie
1141
 * (Du coup faut gerer les correspondances et tout, folie!)
1142
 * Là dans l'état faut créer les catégories correctement coté Wordpress avant de lancer le script, puis corriger les noms/slugs toussa
1143
 *
1144
 * @todo revoir l'insertion, ça défonce les menus là... Voir : https://wordpress.stackexchange.com/a/78317
1145
 * @todo vérifier que les évènements sont aussi migrés ou alors créer la fonction de migration équivalente pour eux
1146
 */
1147
function migrerRubriques() {
1148
  global $prefixe_tables_wp;
1149
  global $bdSpip;
1150
  global $bdWordpress;
1151
  global $modeBourrin;
1152
  global $correspondanceCategorieRubriques;
1153
 
1154
  // Contient la table de correspondances rubrique(SPIP)-categorie(WP), indexée par rubrique
1155
  $rubriqueCategorie = [];
1156
  foreach ($correspondanceCategorieRubriques as $correspondance) {
1157
    $requeteCategorie = 'SELECT term_id FROM ' . $prefixe_tables_wp . 'terms WHERE name = ' . $bdWordpress->quote($correspondance['titre']) . ' AND slug = ' . $bdWordpress->quote($correspondance['slug']) . ';';
1158
 
1159
    $categorie = $bdWordpress->query($requeteCategorie)->fetchAll(PDO::FETCH_ASSOC);
1160
 
1161
    if (0 === count($categorie)) {
1162
      var_dump($correspondance);
1163
      die('catégorie inéxistante, est-elle bien créée coté wordpress ? est-ce le bon slug ?');
1164
    } elseif (1 < count($categorie)) {
1165
      die('catégorie multiple, je suis censé deviner laquelle est la bonne ? merci de faire le ménage :)');
1166
    }
1167
 
1168
    // On fait correspondre à chaque rubrique à migrer sa catégorie
1169
    foreach ($correspondance['rubrique-a-migrer'] as $rubrique) {
1170
      $rubriqueCategorie[$rubrique] = $categorie[0]['term_id'];
1171
    }
1172
 
1173
    // Initialisation des compteurs
1174
    $compteur[$categorie[0]['term_id']] = 0;
1175
  }
1176
 
1177
  sauvegardeLaTable($bdWordpress, $prefixe_tables_wp . 'term_relationships');
1178
  sauvegardeLaTable($bdWordpress, $prefixe_tables_wp . 'term_taxonomy');
1179
 
1180
  $requeteActualitesRubriques = 'SELECT `id_article`, `id_rubrique`
1181
    FROM `spip_articles` WHERE id_rubrique IN (' . _rubriquesSpipAMigrer() . ');' ;
1182
 
1183
  $actualites = $bdSpip->query($requeteActualitesRubriques)->fetchAll(PDO::FETCH_ASSOC);
1184
 
1185
  $compteur = 0;
1186
  foreach ($actualites as $actualite) {
1187
    $requete = 'INSERT INTO ' . $prefixe_tables_wp . 'term_relationships (`object_id`, `term_taxonomy_id`)
1188
      VALUES(' . $actualite['id_article'] . ', ' . $rubriqueCategorie[$actualite['id_rubrique']] . ')
1189
      ON DUPLICATE KEY UPDATE `object_id`=VALUES(`object_id`), `term_taxonomy_id`=VALUES(`term_taxonomy_id`);';
1190
 
1191
    $updateCompteur = 'INSERT INTO ' . $prefixe_tables_wp . 'term_taxonomy (`term_id`, `taxonomy`, `count`) '
1192
      . 'VALUES(' . $rubriqueCategorie[$actualite['id_rubrique']] . ', "category", 1)'
1193
      . 'ON DUPLICATE KEY UPDATE `term_id`=VALUES(`term_id`), `taxonomy`=VALUES(`taxonomy`), `count`=`count`+1'
1194
    ;
1195
 
1196
    try {
1197
      $bdWordpress->exec($requete);
1198
      $bdWordpress->exec($updateCompteur);
1199
 
1200
      $compteur++;
1201
    } catch(Exception $e) {
1202
      echo "-- ECHEC " . __FUNCTION__ . " REQUÊTE: [$requete]" . PHP_EOL;
1203
 
1204
      if (true !== $modeBourrin) {
1205
        restaureLaTable($bdWordpress, $prefixe_tables_wp . 'term_relationships');
1206
        restaureLaTable($bdWordpress, $prefixe_tables_wp . 'term_taxonomy');
1207
 
1208
        die(var_dump($e->errorInfo));
1209
      }
1210
    }
1211
  }
1212
 
1213
  echo '-- ' . $compteur . '/' . count($actualites) . ' rubriques d\'actualités migrées. ' . PHP_EOL;
1214
}
1215
 
1216
function migrerActualitesCommentaires() {
1217
  global $prefixe_tables_wp;
1218
  global $bdSpip;
1219
  global $bdWordpress;
1220
  global $modeBourrin;
1221
 
1222
  sauvegardeLaTable($bdWordpress, $prefixe_tables_wp . 'comments');
1223
  sauvegardeLaTable($bdWordpress, $prefixe_tables_wp . 'posts');
1224
 
1225
  $requeteActualitesCommentaires = 'SELECT `id_forum` , `id_article` , `auteur` , `email_auteur` , "" AS url, `ip` , `date_heure` , `date_heure` AS gmt, `texte` , "0" AS karma, replace(`statut`, "publie", "1") , "" AS agent, "" AS TYPE , `id_parent` , `id_auteur`
1226
    FROM `spip_forum`
1227
    WHERE id_article IN (SELECT `id_article` FROM `spip_articles` WHERE id_rubrique IN (' . _rubriquesSpipAMigrer() . ')) AND statut = "publie"';
1228
 
1229
  $actualitesCommentaires = $bdSpip->query($requeteActualitesCommentaires)->fetchAll(PDO::FETCH_ASSOC);
1230
 
1231
  $compteur = 0;
1232
  foreach ($actualitesCommentaires as $actualiteCommentaire) {
1233
    $requete = 'INSERT INTO ' . $prefixe_tables_wp . 'comments (`comment_ID`, `comment_post_ID`, `comment_author`, `comment_author_email`, `comment_author_url`, `comment_author_IP`, `comment_date`, `comment_date_gmt`, `comment_content`, `comment_karma`, `comment_approved`, `comment_agent`, `comment_type`, `comment_parent`, `user_id`) '
1234
      . 'VALUES(' . implode(', ', array_map(array($bdWordpress, 'quote'), $actualiteCommentaire)) . ')
1235
      ON DUPLICATE KEY UPDATE `comment_ID`=VALUES(`comment_ID`), `comment_post_ID`=VALUES(`comment_post_ID`), `comment_author`=VALUES(`comment_author`), `comment_author_email`=VALUES(`comment_author_email`), `comment_author_url`=VALUES(`comment_author_url`), `comment_author_IP`=VALUES(`comment_author_IP`), `comment_date`=VALUES(`comment_date`), `comment_date_gmt`=VALUES(`comment_date_gmt`), `comment_content`=VALUES(`comment_content`), `comment_karma`=VALUES(`comment_karma`), `comment_approved`=VALUES(`comment_approved`), `comment_agent`=VALUES(`comment_agent`), `comment_type`=VALUES(`comment_type`), `comment_parent`=VALUES(`comment_parent`), `user_id`=VALUES(`user_id`);';
1236
 
1237
    $updateCompteurCommentaires = 'UPDATE ' . $prefixe_tables_wp . 'posts SET comment_count = comment_count + 1 WHERE ID = ' . $actualiteCommentaire['id_article'] . ';';
1238
 
1239
    try {
1240
      $bdWordpress->exec($requete);
1241
      $bdWordpress->exec($updateCompteurCommentaires);
1242
 
1243
      $compteur++;
1244
    } catch(Exception $e) {
1245
      echo "-- ECHEC " . __FUNCTION__ . " REQUÊTE: [$requete]" . PHP_EOL;
1246
 
1247
      if (true !== $modeBourrin) {
1248
        restaureLaTable($bdWordpress, $prefixe_tables_wp . 'comments');
1249
        restaureLaTable($bdWordpress, $prefixe_tables_wp . 'posts');
1250
 
1251
        die(var_dump($e->errorInfo));
1252
      }
1253
    }
1254
  }
1255
 
1256
  echo '-- ' . $compteur . '/' . count($actualitesCommentaires) . ' commentaires d\'actualité migrés. ' . PHP_EOL;
1257
}
1258
 
1259
function migrerActualitesImageDeCouverture() {
1260
  global $prefixe_tables_wp;
1261
  global $wordpress_dir;
1262
  global $bdWordpress;
1263
  global $bdSpip;
1264
  global $modeBourrin;
1265
 
1266
 
1267
  // On vérifie qu'on peut bosser
1268
  // Faut être au bon endroit, le repertoire de wordpress
1269
  // Et avoir wp-cli installé
1270
  // Un peu plus loin on va charger les images depuis un dossier spécifique
1271
  $old_path = getcwd();
1272
  chdir($wordpress_dir);
1273
 
1274
  echo '-- exécution de "wp --info"' . PHP_EOL;
1275
  exec('wp --info', $output, $exit_code);
1276
  if (0 !== $exit_code) {
1277
    die('Faut lancer la commande depuis le repertoire de wordpress (et avoir wp-cli installé)');
1278
  } else {
1279
    var_dump($output);
1280
  }
1281
 
1282
  echo '-- recherche du dossier d\'images' . PHP_EOL;
1283
  if (!file_exists($wordpress_dir . '/IMG')) {
1284
    die('Faut rsync les images dans wordpress/IMG avant de commencer');
1285
  }
1286
 
1287
  // chdir($old_path); // commenté car inutile de rechanger de répertoire avant la fin du script
1288
 
1289
  sauvegardeLaTable($bdWordpress, $prefixe_tables_wp . 'posts');
1290
  sauvegardeLaTable($bdWordpress, $prefixe_tables_wp . 'postmeta');
1291
 
1292
  $requete = sprintf('SELECT spip_articles.`id_article` AS ID, `date`, titre FROM `spip_articles` WHERE id_rubrique in ( %s ) ORDER BY id_article', _rubriquesSpipAMigrer());
1293
  $articles = $bdSpip->query($requete)->fetchAll(PDO::FETCH_ASSOC);
1294
 
1295
  $i = 0;
1296
  $compteurSucces = 0;
1297
  $compteurEchecs = 0;
1298
  $compteurAbusay = 0;
1299
  $length = count($articles);
1300
  foreach ($articles as $article) {
1301
 
1302
 
1303
    $wpcli_meta = 'wp post meta list ' . $article['ID'] . ' --format=json';
1304
 
1305
    exec($wpcli_meta, $wpcli_meta_command_output, $exit_code);
1306
 
1307
    // die(var_dump($wpcli_meta_command_output));
1308
 
1309
    // on va commencer par vérifier si l'article n'a pas déjà une image de couv
1310
    // [comme la sortie de "wp post meta get ID" est merdique (toujours à 1 et vide) on va ruser]
1311
    // cas 1 : le post n'existe pas ; code de sortie  1, tableau vide
1312
    // cas 2 : listes des metas à gérer
1313
    if (0 === $exit_code) {
1314
      $metas = json_decode($wpcli_meta_command_output[0], true);
1315
      unset($wpcli_meta_command_output);
1316
 
1317
      // on va fouiller les metas, si on trouve une image de couverture (_thumbnail_id), on passe à la suite
1318
      foreach ($metas as $meta) {
1319
        if ($meta['meta_key'] === '_thumbnail_id') {
1320
          echo 'han!! le post ' . $article['ID'] . ' bah il a déjà une image, trop abusééééééé' . PHP_EOL;
1321
          // echo 'id du post de l\'image ' . $meta['meta_value'] . PHP_EOL;
1322
          $compteurAbusay++;
1323
 
1324
          continue 2; // y'a déjà une couverture, on passe au prochain article
1325
        }
1326
      }
1327
    } else {
1328
      // cas d'erreur, genre le post existe pas, on arrète tout (ou pas)
1329
      echo $wpcli_meta . PHP_EOL;
1330
      var_dump($wpcli_meta_command_output);
1331
      var_dump($exit_code);
1332
      $compteurEchecs++;
1333
      // die('Erreur à l\'exécution de la commande');
1334
      echo('Erreur à l\'exécution de la commande (17)');
622 mathias 1335
      echo('Faut resynchroniser les actus, merci\n');
619 killian 1336
    }
1337
 
1338
    // on va pas aller télécharger les images sur le site, on les mets
1339
    // dans un dossier exprès
1340
    // genre :
622 mathias 1341
    //    rsync -avz telabotap@sequoia:/home/telabotap/www/actu/IMG/arton* wp-content/uploads/2017/03/
619 killian 1342
    //
1343
    // on recherche l'image de couverture dans le dossier
1344
    $images = glob('IMG/arton' . $article['ID'] . '.*');
1345
    if (!empty($images)) {
1346
      $imageChemin = $images[0]; // normalement y'a qu'une image correspondant au filtre
1347
 
1348
      if (file_exists($imageChemin)) {
1349
        $imageNom = strtolower(pathinfo($imageChemin, PATHINFO_FILENAME));
1350
 
1351
        $wpcli_commande = 'wp media import ' . $imageChemin . ' --featured_image'
1352
          . ' --post_id=' . $article['ID']
1353
          . ' --title="image de couverture de l\'article ' . $article['ID'] . '"'
1354
          . ' --alt="image de couverture"'
1355
          . ' --desc="image de couverture de l\'article ' . $article['ID'] . '"' // post_content field
1356
          . ' --caption="image de couverture de l\'article ' . $article['ID'] . '"' // post_except field
1357
        ;
1358
 
1359
        exec($wpcli_commande, $command_output, $exit_code);
1360
 
1361
        if (0 === $exit_code) {
1362
          foreach ($command_output as $message) {
1363
            echo $message;
1364
          }
1365
          echo PHP_EOL;
1366
 
1367
          $compteurSucces++;
1368
 
1369
          unset($command_output);
1370
        } else {
1371
          echo 'commande en échec : "' . $wpcli_commande . '"' . PHP_EOL;
1372
          echo PHP_EOL;
1373
          var_dump($command_output);
1374
 
1375
          die('Erreur à l\'exécution de la commande (42)');
1376
        }
1377
      } else {
1378
        echo 'Image manquante : ' . $article['ID'];
1379
      }
1380
    }
1381
    // foreach ($imagesPaths as $path) {
1382
    //   if (file_exists($path) && is_file($path)) {
1383
    //     $imageChemin = $path;
1384
    //     break;
1385
    //   }
1386
    // }
1387
 
1388
 
1389
    // Si la méthode avec wp-cli fonctionne pas voir plus bas
1390
    // En mode sql dessous :
1391
 
1392
 
1393
    // vérifier si artonID.ext
1394
    // comment gérer les ids supplémentaires ? Y'avait une marge de 10k pour les articles, pareil pour les évènement, c'est bien ça ?
1395
    //
1396
    //
1397
    // Description de la table
1398
    //
1399
    // post_author sera admin "1"
1400
    // post_content sera une description, genre : image de couverture / titre de l'article
1401
    // post_title c'est le nom de l'image en minuscules sans l'extension
1402
    // post_excerpt c'est la légende
1403
    // post_status "inherit" avec post_parent à "0"
1404
    // comment_status "open"
1405
    // ping_status "closed"
1406
    // post_password vide
1407
    // post_name c'est comme post_title
1408
    // to_ping / pinged vides
1409
    // post_content_filtered vide
1410
    // post_parent c koi ?
1411
    // guid c koi ? dans mon exemple c'est l'url absolue de l'image
1412
    // menu_order à 0
1413
    // post_type attachment
1414
    // post_mime_type image/[gif,png,jpeg]
1415
    // comment_count à 0
1416
    //
1417
    //
1418
    // une image dans la galerie ça consiste en :
1419
    //  - un post de type attachment comme vu au dessus
1420
    //  - des meta, à savoir (exemples) :
1421
    //    - _wp_attached_file 2017/03/acab-11219026_10208737059251108_4677167688813950172_n.jpg
1422
    //    - _wp_attachment_metadata a:4:{s:5:"width";i:800;s:6:"height";i:815;s:4:"file";s:65:"2017/03/acab-11219026_10208737059251108_4677167688813950172_n.jpg";s:10:"image_meta";a:12:{s:8:"aperture";s:1:"0";s:6:"credit";s:0:"";s:6:"camera";s:0:"";s:7:"caption";s:0:"";s:17:"created_timestamp";s:1:"0";s:9:"copyright";s:0:"";s:12:"focal_length";s:1:"0";s:3:"iso";s:1:"0";s:13:"shutter_speed";s:1:"0";s:5:"title";s:0:"";s:11:"orientation";s:1:"0";s:8:"keywords";a:0:{}}}
1423
    //    - Dans cette dernière meta les seules choses importantes (sauf erreur) c'est les dimensions et l'emplacement du fichier, donc image_meta = osef
1424
    //
1425
    //    getimagesize() avec GD pour les tailles, ou mieux suivant ce qu'on a dans le serveur
1426
    //
1427
    // et une image de la galerie attachée à un article en tant qu'image à la une ça consite en :
1428
    //  une ligne de meta sur le post avec _thumbnail_id qui pointe sur l'ID du post de l'image ex: _thumbnail_id 7870
1429
 
1430
    // $image = array(
1431
    //   'post_author' => 1,
1432
    //   'post_date' => $article['date'],
1433
    //   'post_date_gmt' => $article['date'],
1434
    //   'post_content' => 'Image à la une de l\'article ' . $article['titre'],
1435
    //   'post_title' => $imagesNom,
1436
    //   'post_excerpt' => 'Image à la une de l\'article ' . $article['titre'],
1437
    //   'post_status' => 'inherit',
1438
    //   'comment_status' => 'open',
1439
    //   'ping_status' => 'closed',
1440
    //   'post_password' => '',
1441
    //   'post_name' => $imagesNom,
1442
    //   'to_ping' => '',
1443
    //   'pinged' => '',
1444
    //   'post_modified' => $article['date'],
1445
    //   'post_modified_gmt' => $article['date'],
1446
    //   'post_content_filtered' => '',
1447
    //   'post_parent' => 0,
1448
    //   'guid' => 'https://www.tela-botanica.org/wp-content/uploads/2017/03/' . basename($imageChemin),
1449
    //   'menu_order' => 0,
1450
    //   'post_type' => 'attachment',
1451
    //   'post_mime_type' => mime_content_type($imageChemin),
1452
    //   'comment_count' => 0
1453
    // );
1454
 
1455
    // $i++;
1456
 
1457
 
1458
    // // gestion des dates normales et dates en GMT
1459
    // $date = new DateTime($image['post_date'], new DateTimeZone('Europe/Paris'));
1460
    // $image['post_date_gmt'] = $date->setTimezone(new DateTimeZone('GMT'))->format('Y-m-d H:i:s');
1461
    // $date = new DateTime($image['post_modified'], new DateTimeZone('Europe/Paris'));
1462
    // $image['post_modified_gmt'] = $date->setTimezone(new DateTimeZone('GMT'))->format('Y-m-d H:i:s');
1463
 
1464
    // $requeteInsertAttachment = 'INSERT INTO ' . $prefixe_tables_wp . 'posts (`post_author`, `post_date`, `post_date_gmt`, `post_content`, `post_title`, `post_excerpt`, `post_status`, `comment_status`, `ping_status`, `post_password`, `post_name`, `to_ping`, `pinged`, `post_modified`, `post_modified_gmt`, `post_content_filtered`, `post_parent`, `guid`, `menu_order`, `post_type`, `post_mime_type`, `comment_count`) VALUES ' . implode(', ', array_map(array($bdWordpress, 'quote'), $image)) . '
1465
    //   ON DUPLICATE KEY UPDATE `ID`=VALUES(`ID`), `post_author`=VALUES(`post_author`), `post_date`=VALUES(`post_date`), `post_date_gmt`=VALUES(`post_date_gmt`), `post_content`=VALUES(`post_content`), `post_title`=VALUES(`post_title`), `post_excerpt`=VALUES(`post_excerpt`), `post_status`=VALUES(`post_status`), `comment_status`=VALUES(`comment_status`), `ping_status`=VALUES(`ping_status`), `post_password`=VALUES(`post_password`), `post_name`=VALUES(`post_name`), `to_ping`=VALUES(`to_ping`), `pinged`=VALUES(`pinged`), `post_modified`=VALUES(`post_modified`), `post_modified_gmt`=VALUES(`post_modified_gmt`), `post_content_filtered`=VALUES(`post_content_filtered`), `post_parent`=VALUES(`post_parent`), `guid`=VALUES(`guid`), `menu_order`=VALUES(`menu_order`), `post_type`=VALUES(`post_type`), `post_mime_type`=VALUES(`post_mime_type`), `comment_count`=VALUES(`comment_count`);'
1466
    // ;
1467
 
1468
    // $attachmentMetas = array(
1469
    //   'post_id' => article['ID'],
1470
    //   'meta_key' => '_thumbnail_id',
1471
    //   'meta_value' => $artucle['ID'] + 10000;
1472
    // );
1473
 
1474
    // $requeteInsertPostmeta = 'INSERT INTO ' . $prefixe_tables_wp . 'postmeta (`post_id`, `meta_key`, `meta_value`) VALUES'
1475
    //   . '(' . implode(', ', array_map(array($bdWordpress, 'quote'), $attachmentMetas)) . ')'
1476
    //   . 'ON DUPLICATE KEY UPDATE `post_id`=VALUES(`post_id`), `meta_key`=VALUES(`meta_key`), `meta_value`=VALUES(`meta_value`);'
1477
    // ;
1478
 
1479
    // $postMetas = array(
1480
    //   'post_id' => article['ID'],
1481
    //   'meta_key' => '_thumbnail_id',
1482
    //   'meta_value' => $artucle['ID'] + 10000;
1483
    // );
1484
 
1485
    // $requeteInsertPostmeta = 'INSERT INTO ' . $prefixe_tables_wp . 'postmeta (`post_id`, `meta_key`, `meta_value`) VALUES'
1486
    //   . '(' . implode(', ', array_map(array($bdWordpress, 'quote'), $postMetas)) . ')'
1487
    //   . 'ON DUPLICATE KEY UPDATE `post_id`=VALUES(`post_id`), `meta_key`=VALUES(`meta_key`), `meta_value`=VALUES(`meta_value`);'
1488
    // ;
1489
 
1490
    // try {
1491
    //   $bdWordpress->exec($requeteInsertAttachment);
1492
 
1493
    //   $compteurSucces += count($insert);
1494
    // } catch(Exception $e) {
1495
    //   echo "-- ECHEC " . __FUNCTION__ . " REQUÊTE: [$requeteInsert]" . PHP_EOL;
1496
 
1497
    //   if (true !== $modeBourrin) {
1498
    //     restaureLaTable($bdWordpress, $prefixe_tables_wp . 'posts');
1499
    //     restaureLaTable($bdWordpress, $prefixe_tables_wp . 'postmeta');
1500
 
1501
    //     die(var_dump($e->errorInfo));
1502
    //   }
1503
    // }
1504
  }
1505
 
1506
  echo '-- ' . $compteurSucces . ' images de couverture actualités migrées. ' . PHP_EOL;
1507
  echo '-- ' . $compteurEchecs . ' erreurs rencontrées pendant la migration (mais rien de grave). ' . PHP_EOL;
1508
  echo '-- ' . $compteurAbusay . ' images déjà migrées ' . PHP_EOL;
1509
  echo '-- ' . $length . ' articles au total ' . PHP_EOL;
1510
}
1511
 
1512
// @wphints : https://stackoverflow.com/questions/28643654/where-is-the-post-featured-image-link-stored-in-the-wordpress-database
1513
// @wphints : https://deliciousbrains.com/tour-wordpress-database/#wp_posts
1514
//
1515
// Une photo éligible en couverture est stockée dans la table *_posts avec un post_type = attachment.
1516
// Pour lier une image à un article il faut une ligne dans *_postmeta avec un type _thumbnail_id.
1517
//
1518
// Dans spip : l'image correspond à IMG/arton<<numarticle>>.png exemple : IMG/arton7965.png
1519
//
1520
// @TODO trouver une solution ? (ça marche pas car l'image doit être présente "dans" wordpress, connue de son gestionnaire de docs)
1521
// function migrerActualitesLogo() {
1522
//   global $prefixe_tables_wp;
1523
//   global $bdSpip;
1524
//   global $bdWordpress;
1525
//   global $modeBourrin;
1526
 
1527
//   sauvegardeLaTable($bdWordpress, $prefixe_tables_wp . 'term_relationships');
1528
 
1529
//   $requeteActualitesLogo = 'SELECT `id_article`, replace(replace(replace(replace(replace(replace(`id_rubrique`, 22, 20), 54, 21), 30, 23), 19, 24), 51, 25), 70, 22)
1530
//     FROM `spip_articles` WHERE id_rubrique in (22,54,70,30,19,51)';
1531
 
1532
//   $actualitesLogo = $bdSpip->query($requeteActualitesLogo)->fetchAll(PDO::FETCH_ASSOC);
1533
 
1534
//   $compteur = 0;
1535
//   foreach ($actualitesLogo as $actualiteLogo) {
1536
//     $requete = 'INSERT INTO ' . $prefixe_tables_wp . 'term_relationships (`object_id`, `term_taxonomy_id`) '
1537
//       . 'VALUES(' . implode(', ', array_map(array($bdWordpress, 'quote'), $actualiteLogo)) . ');';
1538
 
1539
//     try {
1540
//       $bdWordpress->exec($requete);
1541
 
1542
//       $compteur++;
1543
//     } catch(Exception $e) {
1544
//       echo "-- ECHEC " . __FUNCTION__ . " REQUÊTE: [$requete]" . PHP_EOL;
1545
 
1546
//       if (true !== $modeBourrin) {
1547
//         restaureLaTable($bdWordpress, $prefixe_tables_wp . 'term_relationships');
1548
 
1549
//         die(var_dump($e->errorInfo));
1550
//       }
1551
//     }
1552
//   }
1553
 
1554
//   echo '-- ' . $compteur . '/' . count($actualitesLogo) . ' logos d\'actualité migrés. ' . PHP_EOL;
1555
// }
1556
 
1557
function supprimerLesTablesSauvegardees($table = false) {
1558
  global $modeBourrin;
1559
  global $prefixe_tables_wp;
1560
  global $bdWordpress;
1561
 
1562
  if (true === $modeBourrin) {
1563
    if (false !== $table) {
1564
      $tables = [$table];
1565
    } else {
1566
      $tables = array(
1567
        $prefixe_tables_wp . 'users',
1568
        $prefixe_tables_wp . 'usermeta',
1569
        $prefixe_tables_wp . 'bp_activity',
1570
        $prefixe_tables_wp . 'bp_xprofile_data',
1571
        $prefixe_tables_wp . 'posts',
1572
        $prefixe_tables_wp . 'postmeta',
1573
        $prefixe_tables_wp . 'slug_history',
1574
        $prefixe_tables_wp . 'term_relationships',
1575
        $prefixe_tables_wp . 'term_taxonomy',
1576
        $prefixe_tables_wp . 'comments'
1577
      );
1578
    }
1579
 
1580
    foreach ($tables as $table) {
1581
      $requeteSuppressionTable = 'DROP TABLE IF EXISTS ' . $table . 'SAV;';
1582
      try {
1583
        $bdWordpress->exec($requeteSuppressionTable);
1584
      } catch(Exception $e) {
1585
        echo "-- ECHEC " . __FUNCTION__ . " REQUÊTE: [$requeteSuppressionTable]" . PHP_EOL;
1586
        throw $e;
1587
      }
1588
    }
1589
 
1590
    echo '-- tables SAV supprimées' . PHP_EOL;
1591
  }
1592
}
1593