PluginProbe ʕ •ᴥ•ʔ
Backup Migration / 1.3.2
Backup Migration v1.3.2
2.1.6 2.1.5.2 trunk 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.6.1 1.4.7 1.4.8 1.4.9 1.4.9.1 2.0.0 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.5.1
backup-backup / includes / database / even-better-restore-v3.php
backup-backup / includes / database Last commit date
better-backup-v3.php 2 years ago better-backup.php 2 years ago better-restore.php 2 years ago even-better-restore-v3.php 2 years ago even-better-restore-v4.php 2 years ago manager.php 2 years ago search-replace.php 2 years ago smart-sort.php 2 years ago
even-better-restore-v3.php
867 lines
1 <?php
2
3 /**
4 * Author: Mikołaj `iClyde` Chodorowski
5 * Contact: kontakt@iclyde.pl
6 * Package: Backup Migration – WP Plugin
7 */
8
9 // Namespace
10 namespace BMI\Plugin\Database;
11
12 // Use
13 use BMI\Plugin\BMI_Logger AS Logger;
14 use BMI\Plugin\Backup_Migration_Plugin as BMP;
15 use BMI\Plugin\Progress\BMI_ZipProgress AS Progress;
16 use BMI\Plugin\Database\BMI_Search_Replace_Engine as BMISearchReplace;
17
18 // Exit on direct access
19 if (!defined('ABSPATH')) exit;
20
21 /**
22 * Database Restore Enginge v3
23 */
24 class BMI_Even_Better_Database_Restore {
25
26 // Unwanted tables
27 private $unwantedTables = [
28 'wfblockediplog',
29 'wfblocks7',
30 'wfcrawlers',
31 'wffilechanges',
32 'wffilemods',
33 'wfhits',
34 'wfhoover',
35 'wfissues',
36 'wfknownfilelist',
37 'wflivetraffichuman',
38 'wflocs',
39 'wflogins',
40 'wfnotifications',
41 'wfpendingissues',
42 'wfreversecache',
43 'wfsnipcache',
44 'wfstatus',
45 'wftrafficrate',
46 'actionscheduler_logs',
47 'slim_stats',
48 'woocommerce_sessions',
49 'yoast_indexable',
50 'slim_events',
51 'cerber_files',
52 'cerber_traffic',
53 'cerber_log',
54 'cerber_countries',
55 'cerber_blocks',
56 'cerber_acl',
57 'statistics_views',
58 'pcachewpr',
59 'statistics_visitor_relationships',
60 'statistics_visitor',
61 'statistics_visit',
62 'statistics_search',
63 'statistics_pages',
64 'icl_languages_translations',
65 'icl_string_pages',
66 'icl_string_translations',
67 'itsec_log',
68 'actionscheduler_actions',
69 'aepc_logs'
70 ];
71
72 /**
73 * __construct - Make connection
74 *
75 * @return @self
76 */
77 function __construct($storage, $firstDB, &$manifest, &$logger, $splitting, $isCLI) {
78
79 $this->isCLI = $isCLI;
80 $this->splitting = $splitting;
81 $this->storage = $storage;
82 $this->logger = &$logger;
83 $this->manifest = &$manifest;
84 $this->tablemap = BMI_INCLUDES . DIRECTORY_SEPARATOR . 'htaccess' . DIRECTORY_SEPARATOR . '.table_map';
85
86 if ($firstDB) $this->initMessage();
87
88 $this->map = $this->getTableMap();
89 $this->seek = &$this->map['seek'];
90
91 }
92
93 public function start() {
94
95 if ($this->isCLI) {
96
97 while ($nextFile = $this->getNextFile()) {
98 $this->processFile($nextFile);
99 }
100
101 return true;
102
103 } else {
104
105 $nextFile = $this->getNextFile();
106 if ($nextFile === false) return true;
107 else {
108
109 $this->processFile($nextFile);
110
111 return false;
112
113 }
114
115 }
116
117 }
118
119 private function getTableMap() {
120
121 if (file_exists($this->tablemap)) {
122
123 $data = json_decode(file_get_contents($this->tablemap), true);
124 $this->map = $data;
125
126 } else {
127
128 $data = [
129 'tables' => [],
130 'seek' => [
131 'last_seek' => 0,
132 'last_file' => '...',
133 'last_start' => 0,
134 'total_tables' => sizeof(array_diff(scandir($this->storage), ['..', '.'])),
135 'active_plugins' => 'a:1:{i:0;s:31:"backup-backup/backup-backup.php";}'
136 ]
137 ];
138
139 file_put_contents($this->tablemap, json_encode($data));
140
141 }
142
143 return $data;
144
145 }
146
147 private function getTableProgress() {
148
149 $total_tables = $this->seek['total_tables'];
150 $tables_left = sizeof(array_diff(scandir($this->storage), ['..', '.']));
151
152 $finished_tables = ($total_tables - $tables_left) + 1;
153 $percentage = number_format(($finished_tables / $total_tables) * 100, 2);
154
155 $this->logger->progress(50 + ((number_format($percentage, 0) / 2) - 10));
156
157 return $finished_tables . '/' . $total_tables . ' (' . $percentage . '%)';
158
159 }
160
161 private function queryFile(&$objFile, $filePath, $tableName, $realTableName) {
162
163 global $wpdb;
164
165 $seek = &$this->seek['last_seek'];
166 if ($seek == 0) {
167 $seek = 19;
168 $wpdb->query("DROP TABLE IF EXISTS `" . $tableName . "`;");
169
170 $str = __("Started restoration of %table_name% %total_tables% table", 'backup-backup');
171 $str = str_replace('%table_name%', $realTableName, $str);
172 $str = str_replace('%total_tables%', $this->getTableProgress(), $str);
173 $this->logger->log($str, 'STEP');
174
175 // Check if file can be cleaned
176 $this->filterFile($filePath, basename($filePath));
177 }
178
179 $qs = "/* QUERY START */\n";
180 $qe = "/* QUERY END */\n";
181
182 $vs = "/* VALUES START */\n";
183 $ve = "/* VALUES END */\n";
184
185 $wpdb->suppress_errors();
186
187 $wpdb->query('SET autocommit = 0;');
188 $wpdb->query('SET foreign_key_checks = 0;');
189 $wpdb->query("SET SQL_MODE = '';");
190 $wpdb->query('START TRANSACTION;');
191
192 $sqlStarted = false;
193
194 $sql = '';
195 while (!$objFile->eof()) {
196 $objFile->seek($seek); $seek++;
197
198 if ($objFile->current() == $qs) { $sqlStarted = true; continue; }
199 else if ($objFile->current() == $vs || $objFile->current() == $ve) {
200 continue;
201 } else if ($objFile->current() == $qe) {
202 $sqlStarted = false;
203 break;
204 }
205
206 if ($sqlStarted == true) $sql .= rtrim($objFile->current(), "\n");
207 }
208
209 $wpdb->query($sql); unset($sql);
210 $wpdb->query('COMMIT;');
211 $wpdb->query('SET autocommit = 1;');
212 $wpdb->query('SET foreign_key_checks = 1;');
213
214 $str = __("Progress of %table_name%: %progress%", 'backup-backup');
215 $str = str_replace('%table_name%', $realTableName, $str);
216
217 $objFile->seek($objFile->getSize());
218 $total_size = $objFile->key();
219 $objFile->seek($seek);
220
221 $progress = ($seek - 1) . '/' . $total_size . " (" . number_format(($seek - 1) / $total_size * 100, 2) . "%)";
222 $str = str_replace('%progress%', $progress, $str);
223 $this->logger->log($str, 'INFO');
224
225 $wpdb->show_errors();
226
227 if ($objFile->eof()) {
228 return true;
229 } else {
230 return false;
231 }
232
233 }
234
235 private function addNewTableToMap($from, $to, $file) {
236
237 if (!array_key_exists($from, $this->map['tables'])) {
238 $this->map['tables'][$from] = $to;
239 }
240
241 file_put_contents($this->tablemap, json_encode($this->map));
242
243 }
244
245 private function processFile($file) {
246
247 if ($this->seek['last_seek'] == 0) {
248 $this->seek['last_start'] = microtime(true);
249 }
250
251 $objFile = new \SplFileObject($file);
252
253 $objFile->seek(17);
254 $realTableName = explode('`', $objFile->current())[1];
255
256 $objFile->seek(18);
257 $tmpTableName = explode('`', $objFile->current())[1];
258
259 $finished = $this->queryFile($objFile, $file, $tmpTableName, $realTableName);
260
261 if ($finished && file_exists($file)) {
262 $this->seek['last_seek'] = 0;
263 $this->seek['last_file'] = '...';
264 @unlink($file);
265
266 $totalTime = microtime(true) - intval($this->seek['last_start']);
267 $totalTime = number_format($totalTime, 5);
268
269 $str = __("Table %table_name% restoration took %time% seconds", 'backup-backup');
270 $str = str_replace('%table_name%', $realTableName, $str);
271 $str = str_replace('%time%', $totalTime, $str);
272
273 $this->logger->log($str, 'SUCCESS');
274 $this->seek['last_start'] = 0;
275 }
276
277 $this->addNewTableToMap($tmpTableName, $realTableName, $file);
278
279 return true;
280
281 }
282
283 private function parseDomain($domain, $removeWWW = true) {
284
285 if (substr($domain, 0, 8) == 'https://') $domain = substr($domain, 8);
286 if (substr($domain, 0, 7) == 'http://') $domain = substr($domain, 7);
287 if ($removeWWW === true) {
288 if (substr($domain, 0, 4) == 'www.') $domain = substr($domain, 4);
289 }
290 $domain = untrailingslashit($domain);
291
292 return $domain;
293
294 }
295
296 private function replaceTableNames($tables) {
297
298 global $wpdb;
299
300 $this->logger->log(__('Performing table replacement', 'backup-backup'), 'STEP');
301
302 $wpdb->suppress_errors();
303 foreach ($tables as $oldTable => $newTable) {
304
305 $sql = "DROP TABLE IF EXISTS `" . $newTable . "`;";
306 $wpdb->query($sql);
307
308 $sql = "ALTER TABLE `" . $oldTable . "` RENAME TO `" . $newTable . "`;";
309 $wpdb->query($sql);
310
311 $str = __('Table %old% renamed to %new%', 'backup-backup');
312 $str = str_replace('%old%', $oldTable, $str);
313 $str = str_replace('%new%', $newTable, $str);
314 $this->logger->log($str, 'INFO');
315
316 }
317
318 $wpdb->show_errors();
319 $this->logger->log(__('All tables replaced', 'backup-backup'), 'SUCCESS');
320
321 }
322
323 private function performReplace($step = 0, $tableIndex = 0, $currentPage = 0, $totalPages = 0, $fieldAdjustments = 0) {
324
325 $status = [
326 'step' => $step,
327 'tableIndex' => $tableIndex,
328 'finished' => false,
329 'currentPage' => $currentPage,
330 'totalPages' => $totalPages,
331 'fieldAdjustments' => $fieldAdjustments
332 ];
333
334 require_once BMI_INCLUDES . DIRECTORY_SEPARATOR . 'database' . DIRECTORY_SEPARATOR . 'search-replace.php';
335
336 $backupRootDir = $this->manifest->config->ABSPATH;
337 $currentRootDir = ABSPATH;
338
339 $backupDomain = $this->parseDomain($this->manifest->dbdomain);
340 $currentDomain = $this->parseDomain(get_option('siteurl'), false);
341
342 $currentTable = false;
343 $allTables = array_keys($this->map['tables']);
344
345 if ($tableIndex < sizeof($allTables) && array_key_exists($tableIndex, $allTables)) {
346 $currentTable = $allTables[$tableIndex];
347 }
348
349 if ($currentTable == false && !$currentTable) {
350 if ($backupRootDir != $currentRootDir || $currentDomain != $this->parseDomain($backupDomain, false)) {
351 $this->logger->log(__('Search & Replace finished successfully.', 'backup-backup'), 'SUCCESS');
352 }
353
354 $status['finished'] = true;
355 return $status;
356 }
357
358 $replaceEngine = new BMISearchReplace([$currentTable], $currentPage, $totalPages);
359
360 if ($step == 0) {
361 if ($backupRootDir != $currentRootDir || $currentDomain != $this->parseDomain($backupDomain, false)) {
362 $this->logger->log(__('Performing Search & Replace', 'backup-backup'), 'STEP');
363 $pagesize = '?';
364 if (defined('BMI_MAX_SEARCH_REPLACE_PAGE')) $pagesize = BMI_MAX_SEARCH_REPLACE_PAGE;
365 $this->logger->log(__('Page size for that restoration: ', 'backup-backup') . $pagesize, 'INFO');
366 $status['step'] = $step + 1; $step++;
367 } else {
368 $this->logger->log(__('This backup was made on the same site, ommiting search & replace.', 'backup-backup'), 'INFO');
369 $status['finished'] = true;
370 return $status;
371 }
372 }
373
374 if ($step == 1) {
375 $replaceProgress = ($tableIndex + 1) . "/" . sizeof($allTables);
376 $replaceProgressPercentage = number_format((($tableIndex + 1) / sizeof($allTables) * 100), 2);
377 $progressLogT = __('Performing database adjustments for table %progress%: %table_name% (%progress_percentage%)', 'backup-backup');
378 $progressLogT = str_replace('%progress%', $replaceProgress, $progressLogT);
379 $progressLogT = str_replace('%table_name%', $currentTable, $progressLogT);
380 $progressLogT = str_replace('%progress_percentage%', $replaceProgressPercentage . '%', $progressLogT);
381 $this->logger->log($progressLogT, 'STEP');
382
383 $percentageProgress = number_format($replaceProgressPercentage, 0);
384 $this->logger->progress(number_format(90 + ($percentageProgress / 100) * 8, 0));
385
386 if ($backupRootDir != $currentRootDir) {
387
388 $dtables = 0; $drows = 0; $dchange = 0; $dupdates = 0;
389
390 $r = $replaceEngine->perform($backupRootDir, $currentRootDir);
391 $dtables += $r['tables']; $drows += $r['rows']; $dchange += $r['change']; $dupdates += $r['updates'];
392
393 $status['currentPage'] = $r['currentPage'];
394 $status['totalPages'] = $r['totalPages'];
395
396 if ($status['totalPages'] > 0) {
397
398 $info = __("Batch for path adjustment (%page%/%allPages%) updated: %updates% fields.", 'backup-backup');
399 $updates = $dupdates;
400 if ($updates == 0) $updates = 1;
401 $info = str_replace('%page%', $status['currentPage'], $info);
402 $info = str_replace('%allPages%', $status['totalPages'], $info);
403 $info = str_replace('%updates%', $updates, $info);
404 $this->logger->log($info, 'INFO');
405 $status['fieldAdjustments']++;
406
407 } else {
408
409 // $this->logger->log(__('Path adjustments are not required for this table.', 'backup-backup'), 'INFO');
410
411 }
412
413 if ($status['currentPage'] >= $status['totalPages']) {
414 $status['currentPage'] = 0;
415 $status['totalPages'] = 0;
416 $status['step'] = $step + 1;
417 }
418 return $status;
419
420 } else {
421
422 $status['step'] = $step + 1; $step++;
423
424 }
425 }
426
427 if ($step == 2 || $step == 3 || $step == 4 || $step == 5 || $step == 6 || $step == 7) {
428 if ($currentDomain != $this->parseDomain($backupDomain, false)) {
429 $ssl = is_ssl() == true ? 'https://' : 'http://';
430
431 $dtables = 0; $drows = 0; $dchange = 0; $dupdates = 0;
432
433 $possibleDomainsBackup = [
434 "https://www." . $backupDomain,
435 "http://www." . $backupDomain,
436 "https://" . $backupDomain,
437 "http://" . $backupDomain,
438 'www.' . $backupDomain,
439 $backupDomain
440 ];
441
442 $possibleDomainsCurrent = [
443 $ssl . $currentDomain,
444 $ssl . $currentDomain,
445 $ssl . $currentDomain,
446 $ssl . $currentDomain,
447 $currentDomain,
448 $currentDomain
449 ];
450
451 if ($step == 2) {
452 $r = $replaceEngine->perform($possibleDomainsBackup[0], $possibleDomainsCurrent[0]);
453 $dtables += $r['tables']; $drows += $r['rows']; $dchange += $r['change']; $dupdates += $r['updates'];
454 }
455
456 if ($step == 3) {
457 $r = $replaceEngine->perform($possibleDomainsBackup[1], $possibleDomainsCurrent[1]);
458 $dtables += $r['tables']; $drows += $r['rows']; $dchange += $r['change']; $dupdates += $r['updates'];
459 }
460
461 if ($step == 4) {
462 $r = $replaceEngine->perform($possibleDomainsBackup[2], $possibleDomainsCurrent[2]);
463 $dtables += $r['tables']; $drows += $r['rows']; $dchange += $r['change']; $dupdates += $r['updates'];
464 }
465
466 if ($step == 5) {
467 $r = $replaceEngine->perform($possibleDomainsBackup[3], $possibleDomainsCurrent[3]);
468 $dtables += $r['tables']; $drows += $r['rows']; $dchange += $r['change']; $dupdates += $r['updates'];
469 }
470
471 if ($step == 6) {
472 $r = $replaceEngine->perform($possibleDomainsBackup[4], $possibleDomainsCurrent[4]);
473 $dchange += $r['change']; $dupdates += $r['updates'];
474 }
475
476 if ($step == 7) {
477 if (!(substr($currentDomain, -strlen($backupDomain)) === $backupDomain)) {
478 $r = $replaceEngine->perform($possibleDomainsBackup[5], $possibleDomainsCurrent[5]);
479 $dchange += $r['change']; $dupdates += $r['updates'];
480 }
481 }
482
483 $status['currentPage'] = $r['currentPage'];
484 $status['totalPages'] = $r['totalPages'];
485
486 $variants = [
487 __('variant A', 'backup-backup'),
488 __('variant B', 'backup-backup'),
489 __('variant C', 'backup-backup'),
490 __('variant D', 'backup-backup'),
491 __('variant E', 'backup-backup'),
492 __('variant F', 'backup-backup')
493 ];
494
495 if ($status['totalPages'] > 0) {
496
497 $info = __("Batch for domain (%variant%) adjustments (%page%/%allPages%) updated: %updates% fields.", 'backup-backup');
498 $updates = $dupdates;
499 if ($updates == 0) $updates = 1;
500 $info = str_replace('%variant%', $variants[$step - 2], $info);
501 $info = str_replace('%page%', $status['currentPage'], $info);
502 $info = str_replace('%allPages%', $status['totalPages'], $info);
503 $info = str_replace('%updates%', $updates, $info);
504 $this->logger->log($info, 'INFO');
505 $status['fieldAdjustments']++;
506
507 } else {
508
509 // $info = __('Domain (%variant%) adjustments are not required for this table.', 'backup-backup');
510 // $info = str_replace('%variant%', $variants[$step - 2], $info);
511 // $this->logger->log($info, 'INFO');
512
513 }
514
515 if ($status['currentPage'] >= $status['totalPages']) {
516 $status['currentPage'] = 0;
517 $status['totalPages'] = 0;
518 $status['step'] = $step + 1;
519 }
520 return $status;
521 }
522 }
523
524 if ($step == 8) {
525 if ($fieldAdjustments === 0) {
526 $this->logger->log(__('Adjustments are not required for this table.', 'backup-backup'), 'INFO');
527 }
528
529 $status['step'] = 1;
530 $status['fieldAdjustments'] = 0;
531 $status['tableIndex'] = $tableIndex + 1;
532 return $status;
533 }
534
535 return $status;
536
537 }
538
539 private function try_activate_plugins($plugins, $sucstr_source, $failstr_source, $failed_plugins = []) {
540
541 $plugins_copy = array_values($plugins);
542 $should_continue = false;
543 $activated_plugins = [];
544 $failed_plugins = $failed_plugins;
545 $disallowed_plugins = [
546 'bluehost-wordpress-plugin/bluehost-wordpress-plugin.php',
547 'sg-cachepress/sg-cachepress.php',
548 'wordpress-starter/siteground-wizard.php',
549 'revslider/revslider.php',
550 'easy-soundcloud-shortcode/easy-soundcloud-shortcode.php',
551 'easy-soundcloud-shortcode/EasySoundcloudShortcode.php'
552 ];
553
554 for ($i = 0; $i < sizeof($plugins_copy); ++$i) {
555
556 $plugin_name = $plugins_copy[$i];
557 $plugin_display = $plugin_name;
558
559 $shouldActivate = true;
560
561 if (empty($plugin_name)) {
562 $shouldActivate = false;
563 $plugin_display = '(---)';
564 } else if (strpos($plugin_name, '/') === false) {
565 $shouldActivate = false;
566 }
567
568 $sucstr = str_replace('%plugin_name%', $plugin_display, $sucstr_source);
569 $failstr = str_replace('%plugin_name%', $plugin_display, $failstr_source);
570
571 if ($shouldActivate) {
572 try {
573
574 if (validate_plugin_requirements($plugin_name) && !in_array($plugin_name, $disallowed_plugins)) {
575
576 $resultWP = activate_plugin($plugin_name, '', true, true);
577
578 $this->logger->log($sucstr, 'INFO');
579 $activated_plugins[] = $plugin_name;
580
581 $should_continue = true;
582 break;
583
584 } else {
585
586 if (!in_array($plugin_name, $failed_plugins)) {
587 $failed_plugins[] = $plugin_name;
588 }
589
590 }
591
592 } catch (\Exception $e) {
593
594 if (!in_array($plugin_name, $failed_plugins)) {
595
596 $failed_plugins[] = $plugin_name;
597 error_log(strval($e));
598
599 }
600
601 } catch (\Throwable $e) {
602
603 if (!in_array($plugin_name, $failed_plugins)) {
604
605 $msg = $e->getMessage();
606 if (strpos($msg, 'add_rule()') != false || strpos($msg, 'rewrite.php:143') != false) {
607
608 $activated_plugins[] = $plugin_name;
609 error_log(strval($e));
610
611 } else {
612
613 $failed_plugins[] = $plugin_name;
614 error_log(strval($e));
615
616 }
617
618 }
619
620 }
621
622 } else {
623
624 $this->logger->log($failstr, 'WARN');
625
626 }
627
628 }
629
630 return [ 'failed' => $failed_plugins, 'active' => $activated_plugins, 'should_continue' => $should_continue ];
631
632 }
633
634 private function enablePlugins() {
635
636 global $wpdb;
637
638 $this->logger->log(__('Enabling plugins included in the backup', 'backup-backup'), 'STEP');
639
640 if (is_serialized($this->seek['active_plugins'])) {
641
642 $plugins = unserialize($this->seek['active_plugins']);
643 usort($plugins, function ($a, $b) { return strlen($a) - strlen($b); });
644 $plugins = array_values($plugins);
645
646 $sucstr_source = __('Plugin %plugin_name% enabled successfully.', 'backup-backup');
647 $failstr_source = __('Failed to enable plugin %plugin_name%, trying to not end at fatal error...', 'backup-backup');
648
649 $fullyActive = [];
650 $failed_plugins = [];
651
652 if (!function_exists('activate_plugin')) {
653 require_once(ABSPATH .'/wp-admin/includes/plugin.php');
654 }
655
656 $one_more_time = true;
657 $try_again = true;
658 while ($try_again) {
659
660 $res = $this->try_activate_plugins($plugins, $sucstr_source, $failstr_source, $failed_plugins);
661
662 $fullyActive = array_unique(array_merge($fullyActive, $res['active']));
663 $plugins = array_diff($plugins, $res['active']);
664 $failed_plugins = array_unique(array_diff(array_merge($failed_plugins, $res['failed']), $fullyActive));
665
666 $try_again = $res['should_continue'];
667 if ($try_again == false && $one_more_time == true) {
668 $one_more_time = false;
669 $try_again = true;
670 }
671
672 }
673
674 for ($i = 0; $i < sizeof($failed_plugins); ++$i) {
675
676 $failstr = str_replace('%plugin_name%', $failed_plugins[$i], $failstr_source);
677 $this->logger->log($failstr, 'WARN');
678
679 }
680
681 if (!in_array('backup-backup/backup-backup.php', $fullyActive)) {
682 $fullyActive[] = 'backup-backup/backup-backup.php';
683 }
684
685 update_option('active_plugins', $fullyActive);
686
687 }
688
689 $this->logger->progress(100);
690 $this->logger->log(__('All plugins enabled, you are ready to go :)', 'backup-backup'), 'SUCCESS');
691
692 }
693
694 public function searchReplace($step = 0, $tableIndex = 0, $currentPage = 0, $totalPages = 0, $fieldAdjustments = 0) {
695
696 $this->logger->progress(90);
697 return $this->performReplace($step, $tableIndex, $currentPage, $totalPages, $fieldAdjustments);
698
699 }
700
701 public function alter_tables() {
702
703 $this->logger->progress(98);
704 $this->prepareFinalDatabase();
705 $this->replaceTableNames($this->map['tables']);
706 $this->enablePlugins();
707
708 }
709
710 private function prepareFinalDatabase() {
711
712 global $wpdb;
713
714 $tables = array_keys($this->map['tables']);
715 $unique_prefix = explode('_', $tables[0])[0];
716 $backupPrefix = $this->manifest->config->table_prefix;
717
718 $options_table = $unique_prefix . '_' . $backupPrefix . 'options';
719 if (!in_array($options_table, $tables)) {
720 $tablename = false;
721 for ($i = 0; $i < sizeof($tables); ++$i) {
722 $table = $tables[$i];
723 if (substr($table, -7) == 'options') {
724 $tablename = $table;
725 break;
726 }
727 }
728
729 $options_table = $tablename;
730 }
731
732 if ($options_table != false && in_array($options_table, $tables)) {
733
734 $sql = "DELETE FROM " . $options_table . " WHERE option_name LIKE ('%\_transient\_%')";
735 $wpdb->query($sql);
736
737 $active_plugins = $wpdb->get_results('SELECT option_value FROM `' . $options_table . '` WHERE option_name = "active_plugins"');
738 if ($active_plugins && sizeof($active_plugins) > 0) {
739 $active_plugins = $active_plugins[0]->option_value;
740 } else {
741 $active_plugins = '';
742 }
743
744 $this->seek['active_plugins'] = $active_plugins;
745
746 update_option('active_plugins', ['backup-backup/backup-backup.php']);
747
748 $ssl = is_ssl() == true ? 'https://' : 'http://';
749 $currentDomain = $ssl . $this->parseDomain(get_option('siteurl'), false);
750
751 $sql = 'UPDATE ' . $options_table . ' SET option_value = %s WHERE option_name = "siteurl"';
752 $wpdb->query($wpdb->prepare($sql, $currentDomain));
753
754 $sql = 'UPDATE ' . $options_table . ' SET option_value = %s WHERE option_name = "home"';
755 $wpdb->query($wpdb->prepare($sql, $currentDomain));
756
757 }
758
759 }
760
761 private function filterFile($path, $name) {
762
763 $blacklist = $this->unwantedTables;
764 $tablename = strtolower(substr($name, 0, -4));
765
766 $shouldBeExcluded = false;
767 for ($i = 0; $i < sizeof($blacklist); ++$i) {
768
769 $rule = strtolower($blacklist[$i]);
770 if (substr($tablename, -(strlen($rule))) == $rule) {
771 $shouldBeExcluded = true;
772 break;
773 }
774
775 }
776
777 if ($shouldBeExcluded == true) {
778
779 $str = '';
780 $str .= "/" . "* QUERY START */\n";
781 $str .= "SET foreign_key_checks = 0;\n";
782 $str .= "/" . "* QUERY END */\n";
783 $str .= "\n";
784 $str .= "/" . "* QUERY START */\n";
785 $str .= "SET SQL_MODE = '';\n";
786 $str .= "/" . "* QUERY END */\n";
787 $str .= "\n";
788 $str .= "/" . "* QUERY START */\n";
789 $str .= "SET time_zone = '+00:00';\n";
790 $str .= "/" . "* QUERY END */\n";
791 $str .= "\n";
792 $str .= "/" . "* QUERY START */\n";
793 $str .= "SET NAMES 'utf8';\n";
794 $str .= "/" . "* QUERY END */\n";
795 $str .= "\n";
796
797 $file = new \SplFileObject($path);
798 $file->seek($file->getSize());
799 $total_lines = $file->key() + 1;
800
801 $query_has_not_ended = true;
802 for ($i = 16; $query_has_not_ended && $i < $total_lines; ++$i) {
803 $file->seek($i);
804 $line = trim($file->current());
805
806 if ($line == "/" . "* QUERY END */") {
807
808 $str .= $line;
809 $query_has_not_ended = false;
810 break;
811
812 } else {
813
814 $str .= $line . "\n";
815
816 }
817 }
818
819 if ($query_has_not_ended === false) {
820
821 $this->logger->log(str_replace('%s', substr($name, 0, -4), __('Cleaning up contents of %s table.', 'backup-backup')), 'INFO');
822 file_put_contents($path, $str);
823
824 }
825
826 }
827
828 }
829
830 private function getNextFile() {
831
832 if ($this->seek['last_file'] == '...') {
833
834 $nextFile = false;
835
836 $sqlFiles = array_diff(scandir($this->storage), ['..', '.']);
837 $sqlFiles = array_values($sqlFiles);
838
839 if (sizeof($sqlFiles) > 0) {
840 $nextFilePath = $this->storage . DIRECTORY_SEPARATOR . $sqlFiles[0];
841 return $nextFilePath;
842 }
843
844 $this->seek['last_file'] = $nextFile;
845 return $nextFile;
846
847 } else {
848
849 return $this->seek['last_file'];
850
851 }
852
853 }
854
855 private function initMessage() {
856
857 $this->logger->log(__('Successfully detected backup created with v2 engine, importing...', 'backup-backup'), 'INFO');
858 $this->logger->log(__('Restoring database (using v3 engine)...', 'backup-backup'), 'STEP');
859
860 if (file_exists($this->tablemap)) {
861 @unlink($this->tablemap);
862 }
863
864 }
865
866 }
867