Exporter
1 day ago
QueryBuilder
1 day ago
CustomTable.php
1 day ago
DbInfo.php
1 day ago
ExcludedTables.php
1 day ago
ExternalDatabaseConfiguration.php
1 day ago
OptionPreservationHandler.php
1 day ago
SearchReplace.php
1 day ago
SelectedTables.php
1 day ago
TableDto.php
1 day ago
TableService.php
1 day ago
TablesRenamer.php
1 day ago
WpDbInfo.php
1 day ago
WpOptionsInfo.php
1 day ago
iDbInfo.php
2 years ago
TablesRenamer.php
1241 lines
| 1 | <?php |
| 2 | |
| 3 | namespace WPStaging\Framework\Database; |
| 4 | |
| 5 | use WPStaging\Backup\Dto\Task\Restore\RenameDatabaseTaskDto; |
| 6 | use WPStaging\Core\Utils\Logger; |
| 7 | use WPStaging\Framework\Adapter\PhpAdapter; |
| 8 | use WPStaging\Framework\Facades\Hooks; |
| 9 | use WPStaging\Framework\Traits\SerializeTrait; |
| 10 | |
| 11 | |
| 12 | |
| 13 | |
| 14 | |
| 15 | class TablesRenamer |
| 16 | { |
| 17 | use SerializeTrait; |
| 18 | |
| 19 | |
| 20 | const OPTION_ACTIVE_PLUGINS = 'active_plugins'; |
| 21 | |
| 22 | |
| 23 | const OPTION_ACTIVE_SITEWIDE_PLUGINS = 'active_sitewide_plugins'; |
| 24 | |
| 25 | |
| 26 | const PLUGIN_BASE_SLUG = 'wp-staging'; |
| 27 | |
| 28 | |
| 29 | private $tableService; |
| 30 | |
| 31 | |
| 32 | |
| 33 | |
| 34 | |
| 35 | |
| 36 | |
| 37 | |
| 38 | |
| 39 | protected $tablesBeingRenamed = []; |
| 40 | |
| 41 | |
| 42 | |
| 43 | |
| 44 | |
| 45 | |
| 46 | |
| 47 | |
| 48 | |
| 49 | protected $tablesBeingRenamedUnprefixed = []; |
| 50 | |
| 51 | |
| 52 | |
| 53 | |
| 54 | |
| 55 | |
| 56 | |
| 57 | |
| 58 | |
| 59 | protected $existingTables = []; |
| 60 | |
| 61 | |
| 62 | |
| 63 | |
| 64 | |
| 65 | |
| 66 | |
| 67 | |
| 68 | |
| 69 | protected $existingTablesUnprefixed = []; |
| 70 | |
| 71 | |
| 72 | protected $customTablesBeingRenamed = []; |
| 73 | |
| 74 | |
| 75 | protected $shortNamedTablesToRename = []; |
| 76 | |
| 77 | |
| 78 | protected $shortNamedTablesToDrop = []; |
| 79 | |
| 80 | |
| 81 | protected $excludedTables = []; |
| 82 | |
| 83 | |
| 84 | protected $tablesToBeDropped = []; |
| 85 | |
| 86 | |
| 87 | protected $tablesToPreserve = []; |
| 88 | |
| 89 | |
| 90 | protected $destinationSubsiteBlogIds = []; |
| 91 | |
| 92 | |
| 93 | protected $totalTables = 0; |
| 94 | |
| 95 | |
| 96 | |
| 97 | |
| 98 | |
| 99 | protected $tablesRenamed = 0; |
| 100 | |
| 101 | |
| 102 | protected $tablesRemainingToBeDropped = 0; |
| 103 | |
| 104 | |
| 105 | protected $productionTablePrefix = ''; |
| 106 | |
| 107 | |
| 108 | protected $productionTableBasePrefix = ''; |
| 109 | |
| 110 | |
| 111 | protected $tmpPrefix = ''; |
| 112 | |
| 113 | |
| 114 | protected $customTableTmpPrefix = ''; |
| 115 | |
| 116 | |
| 117 | protected $dropPrefix = ''; |
| 118 | |
| 119 | |
| 120 | protected $renameViews = false; |
| 121 | |
| 122 | |
| 123 | protected $renameCustomTables = false; |
| 124 | |
| 125 | |
| 126 | protected $logEachRename = false; |
| 127 | |
| 128 | |
| 129 | protected $logger = null; |
| 130 | |
| 131 | |
| 132 | protected $phpAdapter; |
| 133 | |
| 134 | |
| 135 | protected $thresholdCallable = null; |
| 136 | |
| 137 | |
| 138 | protected $conflictingTablesRenamed = 0; |
| 139 | |
| 140 | |
| 141 | protected $nonConflictingTablesRenamed = 0; |
| 142 | |
| 143 | |
| 144 | protected $customTablesRenamed = 0; |
| 145 | |
| 146 | |
| 147 | protected $isNonConflictingTablesRenamingTaskExecuted = false; |
| 148 | |
| 149 | |
| 150 | protected $isRenamingForSubsite = false; |
| 151 | |
| 152 | |
| 153 | protected $errors = []; |
| 154 | |
| 155 | public function __construct(TableService $tableService, PhpAdapter $phpAdapter) |
| 156 | { |
| 157 | $this->tableService = $tableService; |
| 158 | $this->phpAdapter = $phpAdapter; |
| 159 | } |
| 160 | |
| 161 | |
| 162 | |
| 163 | |
| 164 | |
| 165 | public function setProductionTablePrefix(string $productionTablePrefix): TablesRenamer |
| 166 | { |
| 167 | $this->productionTablePrefix = $productionTablePrefix; |
| 168 | return $this; |
| 169 | } |
| 170 | |
| 171 | |
| 172 | |
| 173 | |
| 174 | |
| 175 | |
| 176 | public function setProductionTableBasePrefix(string $productionTableBasePrefix, bool $isRenamingForSubsite = true): TablesRenamer |
| 177 | { |
| 178 | $this->productionTableBasePrefix = $productionTableBasePrefix; |
| 179 | $this->isRenamingForSubsite = $isRenamingForSubsite; |
| 180 | return $this; |
| 181 | } |
| 182 | |
| 183 | |
| 184 | |
| 185 | |
| 186 | |
| 187 | public function setTmpPrefix(string $tmpPrefix): TablesRenamer |
| 188 | { |
| 189 | $this->tmpPrefix = $tmpPrefix; |
| 190 | return $this; |
| 191 | } |
| 192 | |
| 193 | |
| 194 | |
| 195 | |
| 196 | |
| 197 | public function setCustomTableTmpPrefix(string $customTableTmpPrefix): TablesRenamer |
| 198 | { |
| 199 | $this->customTableTmpPrefix = $customTableTmpPrefix; |
| 200 | return $this; |
| 201 | } |
| 202 | |
| 203 | |
| 204 | |
| 205 | |
| 206 | |
| 207 | public function setDropPrefix(string $dropPrefix): TablesRenamer |
| 208 | { |
| 209 | $this->dropPrefix = $dropPrefix; |
| 210 | return $this; |
| 211 | } |
| 212 | |
| 213 | |
| 214 | |
| 215 | |
| 216 | |
| 217 | public function setRenameViews(bool $renameViews): TablesRenamer |
| 218 | { |
| 219 | $this->renameViews = $renameViews; |
| 220 | return $this; |
| 221 | } |
| 222 | |
| 223 | |
| 224 | |
| 225 | |
| 226 | |
| 227 | public function setRenameCustomTables(bool $renameCustomTables): TablesRenamer |
| 228 | { |
| 229 | $this->renameCustomTables = $renameCustomTables; |
| 230 | return $this; |
| 231 | } |
| 232 | |
| 233 | |
| 234 | |
| 235 | |
| 236 | |
| 237 | public function setLogEachRename(bool $logEachRename): TablesRenamer |
| 238 | { |
| 239 | $this->logEachRename = $logEachRename; |
| 240 | return $this; |
| 241 | } |
| 242 | |
| 243 | |
| 244 | |
| 245 | |
| 246 | |
| 247 | public function setLogger(Logger $logger): TablesRenamer |
| 248 | { |
| 249 | $this->logger = $logger; |
| 250 | return $this; |
| 251 | } |
| 252 | |
| 253 | |
| 254 | |
| 255 | |
| 256 | |
| 257 | public function setThresholdCallable($thresholdCallable): TablesRenamer |
| 258 | { |
| 259 | $this->thresholdCallable = $thresholdCallable; |
| 260 | return $this; |
| 261 | } |
| 262 | |
| 263 | |
| 264 | |
| 265 | |
| 266 | |
| 267 | public function setShortNamedTablesToRename(array $shortNamedTablesToRename): TablesRenamer |
| 268 | { |
| 269 | $this->shortNamedTablesToRename = $shortNamedTablesToRename; |
| 270 | return $this; |
| 271 | } |
| 272 | |
| 273 | |
| 274 | |
| 275 | |
| 276 | |
| 277 | public function setShortNamedTablesToDrop(array $shortNamedTablesToDrop): TablesRenamer |
| 278 | { |
| 279 | $this->shortNamedTablesToDrop = $shortNamedTablesToDrop; |
| 280 | return $this; |
| 281 | } |
| 282 | |
| 283 | |
| 284 | |
| 285 | |
| 286 | |
| 287 | public function setExcludedTables(array $excludedTables): TablesRenamer |
| 288 | { |
| 289 | $this->excludedTables = $excludedTables; |
| 290 | return $this; |
| 291 | } |
| 292 | |
| 293 | |
| 294 | |
| 295 | |
| 296 | |
| 297 | public function setTablesToPreserve(array $tablesToPreserve): TablesRenamer |
| 298 | { |
| 299 | $this->tablesToPreserve = $tablesToPreserve; |
| 300 | return $this; |
| 301 | } |
| 302 | |
| 303 | |
| 304 | |
| 305 | |
| 306 | |
| 307 | public function setDestinationSubsiteBlogIds(array $blogIds): TablesRenamer |
| 308 | { |
| 309 | $this->destinationSubsiteBlogIds = []; |
| 310 | foreach ($blogIds as $blogId) { |
| 311 | $blogId = (int) $blogId; |
| 312 | if ($blogId > 1) { |
| 313 | $this->destinationSubsiteBlogIds[$blogId] = true; |
| 314 | } |
| 315 | } |
| 316 | |
| 317 | return $this; |
| 318 | } |
| 319 | |
| 320 | |
| 321 | public function getRenamedTables(): int |
| 322 | { |
| 323 | return $this->tablesRenamed; |
| 324 | } |
| 325 | |
| 326 | |
| 327 | public function getTotalTables(): int |
| 328 | { |
| 329 | return $this->totalTables; |
| 330 | } |
| 331 | |
| 332 | |
| 333 | public function getTablesRemainingToBeDropped(): int |
| 334 | { |
| 335 | return $this->tablesRemainingToBeDropped; |
| 336 | } |
| 337 | |
| 338 | |
| 339 | public function getViewsToBeRenamed(): array |
| 340 | { |
| 341 | return $this->tablesBeingRenamedUnprefixed['views']; |
| 342 | } |
| 343 | |
| 344 | |
| 345 | |
| 346 | |
| 347 | public function getConflictingTablesRenamed(): int |
| 348 | { |
| 349 | return $this->conflictingTablesRenamed; |
| 350 | } |
| 351 | |
| 352 | |
| 353 | |
| 354 | |
| 355 | public function getNonConflictingTablesRenamed(): int |
| 356 | { |
| 357 | return $this->nonConflictingTablesRenamed; |
| 358 | } |
| 359 | |
| 360 | |
| 361 | |
| 362 | |
| 363 | public function getCustomTablesRenamed(): int |
| 364 | { |
| 365 | return $this->customTablesRenamed; |
| 366 | } |
| 367 | |
| 368 | |
| 369 | |
| 370 | |
| 371 | public function getIsNonConflictingTablesRenamingTaskExecuted(): bool |
| 372 | { |
| 373 | return $this->isNonConflictingTablesRenamingTaskExecuted; |
| 374 | } |
| 375 | |
| 376 | public function getErrors(): array |
| 377 | { |
| 378 | return $this->errors; |
| 379 | } |
| 380 | |
| 381 | |
| 382 | |
| 383 | |
| 384 | public function resetErrors() |
| 385 | { |
| 386 | $this->errors = []; |
| 387 | } |
| 388 | |
| 389 | |
| 390 | |
| 391 | |
| 392 | public function setupRenamer(): RenameDatabaseTaskDto |
| 393 | { |
| 394 | $taskDto = new RenameDatabaseTaskDto(); |
| 395 | $taskDto->tablesBeingRenamed = $this->tableService->findTableNamesStartWith($this->tmpPrefix) ?: []; |
| 396 | $taskDto->viewsBeingRenamed = []; |
| 397 | if ($this->renameViews) { |
| 398 | $taskDto->viewsBeingRenamed = $this->tableService->findViewsNamesStartWith($this->tmpPrefix) ?: []; |
| 399 | } |
| 400 | |
| 401 | $taskDto->customTablesBeingRenamed = []; |
| 402 | if ($this->renameCustomTables) { |
| 403 | $taskDto->customTablesBeingRenamed = $this->tableService->findTableNamesStartWith($this->customTableTmpPrefix) ?: []; |
| 404 | } |
| 405 | |
| 406 | $taskDto->existingTables = $this->tableService->findTableNamesStartWith($this->productionTablePrefix) ?: []; |
| 407 | if ($this->isRenamingForSubsite && !in_array($this->productionTableBasePrefix . 'users', $taskDto->existingTables)) { |
| 408 | $taskDto->existingTables[] = $this->productionTableBasePrefix . 'users'; |
| 409 | $taskDto->existingTables[] = $this->productionTableBasePrefix . 'usermeta'; |
| 410 | } |
| 411 | |
| 412 | $taskDto->existingViews = []; |
| 413 | if ($this->renameViews) { |
| 414 | $taskDto->existingViews = $this->tableService->findViewsNamesStartWith($this->productionTablePrefix) ?: []; |
| 415 | } |
| 416 | |
| 417 | $taskDto->conflictingTablesRenamed = 0; |
| 418 | $taskDto->nonConflictingTablesRenamed = 0; |
| 419 | $taskDto->customTablesRenamed = 0; |
| 420 | $this->setTaskDto($taskDto); |
| 421 | |
| 422 | return $taskDto; |
| 423 | } |
| 424 | |
| 425 | |
| 426 | |
| 427 | |
| 428 | |
| 429 | public function setTaskDto(RenameDatabaseTaskDto $taskDto) |
| 430 | { |
| 431 | $this->tablesBeingRenamed = []; |
| 432 | $this->tablesBeingRenamed['tables'] = $taskDto->tablesBeingRenamed ?: []; |
| 433 | $this->tablesBeingRenamed['views'] = $taskDto->viewsBeingRenamed ?: []; |
| 434 | $this->tablesBeingRenamed['custom'] = $taskDto->customTablesBeingRenamed ?: []; |
| 435 | $this->tablesBeingRenamed['all'] = array_merge($this->tablesBeingRenamed['tables'], $this->tablesBeingRenamed['views']); |
| 436 | |
| 437 | $this->existingTables = []; |
| 438 | $this->existingTables['tables'] = $taskDto->existingTables ?: []; |
| 439 | $this->existingTables['views'] = $taskDto->existingViews ?: []; |
| 440 | $this->existingTables['all'] = array_merge($this->existingTables['tables'], $this->existingTables['views']); |
| 441 | |
| 442 | $this->totalTables = count($this->tablesBeingRenamed['tables']) + count($this->tablesBeingRenamed['custom']); |
| 443 | $tmpDatabasePrefix = $this->tmpPrefix; |
| 444 | |
| 445 | foreach ($this->tablesBeingRenamed as $viewsOrTables => $tableName) { |
| 446 | $this->tablesBeingRenamedUnprefixed[$viewsOrTables] = array_map(function ($tableName) use ($tmpDatabasePrefix) { |
| 447 | $tableName = $this->getFullNameTableFromShortName($tableName, $tmpDatabasePrefix); |
| 448 | return substr($tableName, strlen($tmpDatabasePrefix)); |
| 449 | }, $this->tablesBeingRenamed[$viewsOrTables]); |
| 450 | } |
| 451 | |
| 452 | $productionTablePrefix = $this->productionTablePrefix; |
| 453 | $isSubsiteRestore = $this->isRenamingForSubsite; |
| 454 | $baseProdTablePrefix = $this->productionTableBasePrefix; |
| 455 | |
| 456 | foreach ($this->existingTables as $viewsOrTables => $tableName) { |
| 457 | $this->existingTablesUnprefixed[$viewsOrTables] = array_map(function ($tableName) use ($productionTablePrefix, $baseProdTablePrefix, $isSubsiteRestore) { |
| 458 | if ($isSubsiteRestore && in_array($tableName, [ $baseProdTablePrefix . 'users', $baseProdTablePrefix . 'usermeta' ])) { |
| 459 | return substr($tableName, strlen($baseProdTablePrefix)); |
| 460 | } |
| 461 | |
| 462 | return substr($tableName, strlen($productionTablePrefix)); |
| 463 | }, $this->existingTables[$viewsOrTables]); |
| 464 | } |
| 465 | |
| 466 | $this->conflictingTablesRenamed = (int)$taskDto->conflictingTablesRenamed; |
| 467 | $this->nonConflictingTablesRenamed = (int)$taskDto->nonConflictingTablesRenamed; |
| 468 | $this->customTablesRenamed = (int)$taskDto->customTablesRenamed; |
| 469 | } |
| 470 | |
| 471 | |
| 472 | |
| 473 | |
| 474 | |
| 475 | |
| 476 | |
| 477 | public function getFullNameTableFromShortName(string $table, string $prefix): string |
| 478 | { |
| 479 | $shortTables = []; |
| 480 | if ($prefix === $this->tmpPrefix) { |
| 481 | $shortTables = $this->shortNamedTablesToRename; |
| 482 | } elseif ($prefix === $this->dropPrefix) { |
| 483 | $shortTables = $this->shortNamedTablesToDrop; |
| 484 | } |
| 485 | |
| 486 | if (!array_key_exists($table, $shortTables)) { |
| 487 | return $table; |
| 488 | } |
| 489 | |
| 490 | return $shortTables[$table]; |
| 491 | } |
| 492 | |
| 493 | |
| 494 | |
| 495 | |
| 496 | |
| 497 | |
| 498 | public function getTableShortName(string $table, string $prefix) |
| 499 | { |
| 500 | $shortTables = []; |
| 501 | if ($prefix === $this->tmpPrefix) { |
| 502 | $shortTables = $this->shortNamedTablesToRename; |
| 503 | } elseif ($prefix === $this->dropPrefix) { |
| 504 | $shortTables = $this->shortNamedTablesToDrop; |
| 505 | } |
| 506 | |
| 507 | return array_search($table, $shortTables); |
| 508 | } |
| 509 | |
| 510 | |
| 511 | |
| 512 | |
| 513 | |
| 514 | public function renameConflictingTables(): bool |
| 515 | { |
| 516 | $conflictingTablesWithoutPrefix = array_values($this->getTablesThatExistInBothExistingAndTempUnprefixed()); |
| 517 | |
| 518 | if (empty($conflictingTablesWithoutPrefix)) { |
| 519 | return true; |
| 520 | } |
| 521 | |
| 522 | |
| 523 | if (count($conflictingTablesWithoutPrefix) <= $this->conflictingTablesRenamed) { |
| 524 | return true; |
| 525 | } |
| 526 | |
| 527 | $this->tableService->getDatabase()->exec('START TRANSACTION;'); |
| 528 | for ($i = $this->conflictingTablesRenamed; $i < count($conflictingTablesWithoutPrefix); $i++) { |
| 529 | $conflictingTableWithoutPrefix = $conflictingTablesWithoutPrefix[$i]; |
| 530 | if ($this->isExcludedTable($conflictingTableWithoutPrefix)) { |
| 531 | $this->tablesRenamed++; |
| 532 | $this->conflictingTablesRenamed++; |
| 533 | continue; |
| 534 | } |
| 535 | |
| 536 | if ($this->isTableToPreserve($conflictingTableWithoutPrefix)) { |
| 537 | $this->tablesRenamed++; |
| 538 | $this->nonConflictingTablesRenamed++; |
| 539 | continue; |
| 540 | } |
| 541 | |
| 542 | $currentTable = $this->getCurrentSiteTable($conflictingTableWithoutPrefix); |
| 543 | $tableToDrop = $this->getTableShortName($currentTable, $this->dropPrefix); |
| 544 | if ($tableToDrop === false) { |
| 545 | $tableToDrop = $this->dropPrefix . $conflictingTableWithoutPrefix; |
| 546 | } |
| 547 | |
| 548 | |
| 549 | $result = $this->tableService->getDatabase()->exec(sprintf( |
| 550 | "RENAME TABLE `%s` TO `%s`;", |
| 551 | $currentTable, |
| 552 | $tableToDrop |
| 553 | )); |
| 554 | |
| 555 | if ($result === false && ($this->logEachRename && $this->logger instanceof Logger)) { |
| 556 | |
| 557 | $wpdb = $this->tableService->getDatabase()->getWpdba()->getClient(); |
| 558 | $error = $wpdb->last_error; |
| 559 | $this->logger->warning("DB Rename: Unable to rename table {$currentTable} to {$tableToDrop}. Error: " . $error); |
| 560 | } |
| 561 | |
| 562 | $this->renameTable($conflictingTableWithoutPrefix, $this->conflictingTablesRenamed); |
| 563 | |
| 564 | if ($this->isThresholdReached()) { |
| 565 | $this->tableService->getDatabase()->exec('COMMIT;'); |
| 566 | return false; |
| 567 | } |
| 568 | } |
| 569 | |
| 570 | $this->tableService->getDatabase()->exec('COMMIT;'); |
| 571 | |
| 572 | return true; |
| 573 | } |
| 574 | |
| 575 | |
| 576 | |
| 577 | |
| 578 | |
| 579 | public function renameNonConflictingTables(): bool |
| 580 | { |
| 581 | $nonConflictingTables = array_values($this->getTablesThatExistInTempButNotInSite()); |
| 582 | |
| 583 | if (empty($nonConflictingTables)) { |
| 584 | return true; |
| 585 | } |
| 586 | |
| 587 | |
| 588 | if (count($nonConflictingTables) <= $this->nonConflictingTablesRenamed) { |
| 589 | return true; |
| 590 | } |
| 591 | |
| 592 | $this->tableService->getDatabase()->exec('START TRANSACTION;'); |
| 593 | for ($i = $this->nonConflictingTablesRenamed; $i < count($nonConflictingTables); $i++) { |
| 594 | $nonConflictingTable = $nonConflictingTables[$i]; |
| 595 | if ($this->isExcludedTable($nonConflictingTable)) { |
| 596 | $this->tablesRenamed++; |
| 597 | $this->nonConflictingTablesRenamed++; |
| 598 | continue; |
| 599 | } |
| 600 | |
| 601 | if ($this->isTableToPreserve($nonConflictingTable)) { |
| 602 | $this->tablesRenamed++; |
| 603 | $this->nonConflictingTablesRenamed++; |
| 604 | continue; |
| 605 | } |
| 606 | |
| 607 | $this->renameTable($nonConflictingTable, $this->nonConflictingTablesRenamed); |
| 608 | $this->isNonConflictingTablesRenamingTaskExecuted = true; |
| 609 | |
| 610 | if ($this->isThresholdReached()) { |
| 611 | $this->tableService->getDatabase()->exec('COMMIT;'); |
| 612 | return false; |
| 613 | } |
| 614 | } |
| 615 | |
| 616 | $this->tableService->getDatabase()->exec('COMMIT;'); |
| 617 | |
| 618 | return true; |
| 619 | } |
| 620 | |
| 621 | |
| 622 | |
| 623 | |
| 624 | public function cleanTemporaryBackupTables(): bool |
| 625 | { |
| 626 | |
| 627 | if ($this->nonConflictingTablesRenamed !== 0 || $this->conflictingTablesRenamed !== 0) { |
| 628 | return true; |
| 629 | } |
| 630 | |
| 631 | $this->tablesToBeDropped = $this->tableService->findTableNamesStartWith($this->dropPrefix) ?: []; |
| 632 | $this->tablesRemainingToBeDropped = count($this->tablesToBeDropped); |
| 633 | |
| 634 | $this->tableService->getDatabase()->exec('SET autocommit=0;'); |
| 635 | $this->tableService->getDatabase()->exec('SET FOREIGN_KEY_CHECKS=0;'); |
| 636 | $this->tableService->getDatabase()->exec('START TRANSACTION;'); |
| 637 | foreach ($this->tablesToBeDropped as $table) { |
| 638 | $result = $this->tableService->getDatabase()->exec(sprintf( |
| 639 | "DROP TABLE `%s`;", |
| 640 | $table |
| 641 | )); |
| 642 | |
| 643 | |
| 644 | if ($result === false) { |
| 645 | $this->tableService->getDatabase()->exec('COMMIT;'); |
| 646 | $this->tableService->getDatabase()->exec('SET autocommit=1;'); |
| 647 | return false; |
| 648 | } |
| 649 | |
| 650 | $this->tablesRemainingToBeDropped--; |
| 651 | } |
| 652 | |
| 653 | $this->tableService->getDatabase()->exec('COMMIT;'); |
| 654 | $this->tableService->getDatabase()->exec('SET autocommit=1;'); |
| 655 | return true; |
| 656 | } |
| 657 | |
| 658 | |
| 659 | |
| 660 | |
| 661 | public function renameTablesToDrop() |
| 662 | { |
| 663 | foreach ($this->getTablesThatExistInSiteButNotInTemp() as $table) { |
| 664 | if ($this->isTableToPreserve($table) || $this->isExistingDestinationSubsiteTable($table)) { |
| 665 | continue; |
| 666 | } |
| 667 | |
| 668 | $fullTableName = $this->productionTablePrefix . $table; |
| 669 | $tableToDrop = $this->getTableShortName($fullTableName, $this->dropPrefix); |
| 670 | if ($tableToDrop === false) { |
| 671 | $tableToDrop = $this->dropPrefix . $table; |
| 672 | } |
| 673 | |
| 674 | $this->tableService->getDatabase()->exec(sprintf( |
| 675 | "RENAME TABLE `%s` TO `%s`;", |
| 676 | $fullTableName, |
| 677 | $tableToDrop |
| 678 | )); |
| 679 | } |
| 680 | } |
| 681 | |
| 682 | |
| 683 | |
| 684 | |
| 685 | |
| 686 | public function renameCustomTables(): bool |
| 687 | { |
| 688 | $customTablesToRename = $this->tablesBeingRenamed['custom']; |
| 689 | |
| 690 | if (empty($customTablesToRename)) { |
| 691 | return true; |
| 692 | } |
| 693 | |
| 694 | foreach ($customTablesToRename as $tmpCustomTable) { |
| 695 | $customTable = substr($tmpCustomTable, strlen($this->customTableTmpPrefix)); |
| 696 | |
| 697 | $result = true; |
| 698 | if ($this->tableExists($customTable)) { |
| 699 | $result = $this->renameQuery($customTable, $this->dropPrefix . $customTable); |
| 700 | } |
| 701 | |
| 702 | if ($result === false) { |
| 703 | throw new \RuntimeException("Unable to rename custom table {$customTable} to {$this->dropPrefix}{$customTable}."); |
| 704 | } |
| 705 | |
| 706 | $result = $this->renameQuery($tmpCustomTable, $customTable); |
| 707 | if ($result === false) { |
| 708 | throw new \RuntimeException("Unable to rename custom table {$tmpCustomTable} to {$customTable}."); |
| 709 | } |
| 710 | |
| 711 | $this->customTablesRenamed++; |
| 712 | if ($this->isThresholdReached()) { |
| 713 | return false; |
| 714 | } |
| 715 | } |
| 716 | |
| 717 | return true; |
| 718 | } |
| 719 | |
| 720 | |
| 721 | |
| 722 | |
| 723 | |
| 724 | |
| 725 | public function getActivePluginsToPreserve(): string |
| 726 | { |
| 727 | $tmpOptionsTable = $this->tmpPrefix . 'options'; |
| 728 | if (!$this->tableExists($tmpOptionsTable)) { |
| 729 | return ''; |
| 730 | } |
| 731 | |
| 732 | $productionOptionsTable = $this->productionTablePrefix . 'options'; |
| 733 | $activePluginsToPreserve = $this->getOptionValue($tmpOptionsTable, self::OPTION_ACTIVE_PLUGINS); |
| 734 | $currentActivePlugins = $this->getOptionValue($productionOptionsTable, self::OPTION_ACTIVE_PLUGINS); |
| 735 | |
| 736 | if (empty($activePluginsToPreserve)) { |
| 737 | return $activePluginsToPreserve; |
| 738 | } |
| 739 | |
| 740 | |
| 741 | $wpstgActivePlugins = $this->safeMaybeUnserialize($currentActivePlugins); |
| 742 | |
| 743 | if (!is_array($wpstgActivePlugins)) { |
| 744 | |
| 745 | $this->insertOrUpdateOptionValue($productionOptionsTable, self::OPTION_ACTIVE_PLUGINS . '_bak', $currentActivePlugins); |
| 746 | $this->errors[] = 'The active plugins option in the database is corrupted in the current site. WP Staging has disabled all plugins during the restore process to avoid fatal errors. Nothing to worry about, the active plugins list is going to be replaced. However, the original value has been backed up in the options table with the name "active_plugins_bak".'; |
| 747 | $wpstgActivePlugins = []; |
| 748 | } |
| 749 | |
| 750 | $wpstgActivePlugins = array_filter($wpstgActivePlugins, function ($pluginSlug) { |
| 751 | return is_string($pluginSlug) && strpos($pluginSlug, self::PLUGIN_BASE_SLUG) === 0; |
| 752 | }); |
| 753 | |
| 754 | $wpstgActivePlugins = serialize($wpstgActivePlugins); |
| 755 | $this->updateOptionValue($tmpOptionsTable, self::OPTION_ACTIVE_PLUGINS, $wpstgActivePlugins); |
| 756 | $this->updateOptionValue($productionOptionsTable, self::OPTION_ACTIVE_PLUGINS, $wpstgActivePlugins); |
| 757 | |
| 758 | return $activePluginsToPreserve; |
| 759 | } |
| 760 | |
| 761 | |
| 762 | |
| 763 | |
| 764 | |
| 765 | |
| 766 | public function getActiveSitewidePluginsToPreserve(): string |
| 767 | { |
| 768 | $tmpSiteMetaTable = $this->tmpPrefix . 'sitemeta'; |
| 769 | if (!$this->tableExists($tmpSiteMetaTable)) { |
| 770 | return ''; |
| 771 | } |
| 772 | |
| 773 | $productionSiteMetaTable = $this->productionTablePrefix . 'sitemeta'; |
| 774 | $activePluginsToPreserve = $this->getNetworkOptionValue($tmpSiteMetaTable, self::OPTION_ACTIVE_SITEWIDE_PLUGINS); |
| 775 | $currentActivePlugins = $this->getNetworkOptionValue($productionSiteMetaTable, self::OPTION_ACTIVE_SITEWIDE_PLUGINS); |
| 776 | |
| 777 | |
| 778 | $wpstgActivePlugins = $this->safeMaybeUnserialize($currentActivePlugins); |
| 779 | |
| 780 | if (!is_array($wpstgActivePlugins)) { |
| 781 | |
| 782 | $this->insertOrUpdateNetworkOptionValue($productionSiteMetaTable, self::OPTION_ACTIVE_SITEWIDE_PLUGINS . '_bak', $currentActivePlugins); |
| 783 | $this->errors[] = 'The active sitewide plugins option in the database is corrupted in the current site. WP Staging has disabled all sitewide plugins during the restore process to avoid fatal errors. Nothing to worry about, the active sitewide plugins option is going to be replaced anyway after the restore. However, the original value has been backed up in the sitemeta table with the name "active_sitewide_plugins_bak".'; |
| 784 | $wpstgActivePlugins = []; |
| 785 | } |
| 786 | |
| 787 | $wpstgActivePlugins = array_filter($wpstgActivePlugins, function ($pluginSlug) { |
| 788 | return is_string($pluginSlug) && strpos($pluginSlug, self::PLUGIN_BASE_SLUG) === 0; |
| 789 | }, ARRAY_FILTER_USE_KEY); |
| 790 | |
| 791 | $wpstgActivePlugins = serialize($wpstgActivePlugins); |
| 792 | $this->updateNetworkOptionValue($tmpSiteMetaTable, self::OPTION_ACTIVE_SITEWIDE_PLUGINS, $wpstgActivePlugins); |
| 793 | $this->updateNetworkOptionValue($productionSiteMetaTable, self::OPTION_ACTIVE_SITEWIDE_PLUGINS, $wpstgActivePlugins); |
| 794 | |
| 795 | return $activePluginsToPreserve; |
| 796 | } |
| 797 | |
| 798 | |
| 799 | |
| 800 | |
| 801 | |
| 802 | |
| 803 | |
| 804 | public function restorePreservedActivePlugins(string $activePlugins, string $activeWpstgPlugin, bool $isNetworkActivatedPlugin): bool |
| 805 | { |
| 806 | $productionOptionsTable = $this->productionTablePrefix . 'options'; |
| 807 | $preservedPlugins = $this->safeMaybeUnserialize($activePlugins); |
| 808 | |
| 809 | if ($isNetworkActivatedPlugin) { |
| 810 | if (!is_array($preservedPlugins)) { |
| 811 | $this->addRejectedActivePluginsError($activePlugins); |
| 812 | $preservedPlugins = []; |
| 813 | } |
| 814 | |
| 815 | $preservedPlugins = array_values(array_filter($preservedPlugins, 'is_string')); |
| 816 | |
| 817 | return $this->updateOptionValue($productionOptionsTable, self::OPTION_ACTIVE_PLUGINS, serialize($preservedPlugins)); |
| 818 | } |
| 819 | |
| 820 | |
| 821 | if (!is_array($preservedPlugins)) { |
| 822 | |
| 823 | $this->insertOrUpdateOptionValue($productionOptionsTable, self::OPTION_ACTIVE_PLUGINS . '_bak', $activePlugins); |
| 824 | $this->errors[] = 'The active plugins option in the database is corrupted after the renamed table. WP Staging has disabled all plugins during the restore process to avoid fatal errors. You can re-activate your plugins from the WordPress admin dashboard after the restore is complete. The original value has been backed up in the options table with the name "active_plugins_bak".'; |
| 825 | $preservedPlugins = []; |
| 826 | } |
| 827 | |
| 828 | $preservedPlugins = array_filter($preservedPlugins, function ($pluginSlug) { |
| 829 | if (!is_string($pluginSlug)) { |
| 830 | return false; |
| 831 | } |
| 832 | |
| 833 | |
| 834 | if (strpos($pluginSlug, self::PLUGIN_BASE_SLUG) !== false) { |
| 835 | return false; |
| 836 | } |
| 837 | |
| 838 | return true; |
| 839 | }); |
| 840 | |
| 841 | |
| 842 | $preservedPlugins[] = $activeWpstgPlugin; |
| 843 | sort($preservedPlugins); |
| 844 | |
| 845 | return $this->updateOptionValue($productionOptionsTable, self::OPTION_ACTIVE_PLUGINS, serialize($preservedPlugins)); |
| 846 | } |
| 847 | |
| 848 | |
| 849 | |
| 850 | |
| 851 | |
| 852 | protected function addRejectedActivePluginsError(string $originalValue) |
| 853 | { |
| 854 | if ($originalValue === '') { |
| 855 | return; |
| 856 | } |
| 857 | |
| 858 | $this->errors[] = 'The active plugins option in the backup is corrupted or contains a serialized PHP object. WP Staging has disabled all plugins during the restore process to avoid fatal errors. You can re-activate your plugins from the WordPress admin dashboard after the restore is complete.'; |
| 859 | } |
| 860 | |
| 861 | |
| 862 | |
| 863 | |
| 864 | |
| 865 | |
| 866 | |
| 867 | public function restorePreservedActiveSitewidePlugins(string $activeSitewidePlugins, string $activeWpstgPlugin, $time = null): bool |
| 868 | { |
| 869 | $preservedSitewidePlugins = $this->safeMaybeUnserialize($activeSitewidePlugins); |
| 870 | |
| 871 | if (!is_array($preservedSitewidePlugins)) { |
| 872 | |
| 873 | $this->insertOrUpdateNetworkOptionValue($this->productionTablePrefix . 'sitemeta', self::OPTION_ACTIVE_SITEWIDE_PLUGINS . '_bak', $activeSitewidePlugins); |
| 874 | $this->errors[] = 'The active sitewide plugins option in the database is corrupted after the renamed table. WP Staging has disabled all sitewide plugins during the restore process to avoid fatal errors. You can re-activate your sitewide plugins from the WordPress admin dashboard after the restore is complete. The original value has been backed up in the sitemeta table with the name "active_sitewide_plugins_bak".'; |
| 875 | $preservedSitewidePlugins = []; |
| 876 | } |
| 877 | |
| 878 | $activeSitewidePlugins = array_filter($preservedSitewidePlugins, function ($pluginSlug) { |
| 879 | |
| 880 | |
| 881 | if (strpos($pluginSlug, self::PLUGIN_BASE_SLUG) !== false) { |
| 882 | return false; |
| 883 | } |
| 884 | |
| 885 | return true; |
| 886 | }); |
| 887 | |
| 888 | if (!empty($activeWpstgPlugin)) { |
| 889 | $activeSitewidePlugins[$activeWpstgPlugin] = empty($time) ? time() : $time; |
| 890 | } |
| 891 | |
| 892 | return $this->updateNetworkOptionValue($this->productionTablePrefix . 'sitemeta', self::OPTION_ACTIVE_SITEWIDE_PLUGINS, serialize($activeSitewidePlugins)); |
| 893 | } |
| 894 | |
| 895 | public function preserveTmpOption(string $optionName): bool |
| 896 | { |
| 897 | $tmpOptionsTable = $this->tmpPrefix . 'options'; |
| 898 | if (!$this->tableExists($tmpOptionsTable)) { |
| 899 | return false; |
| 900 | } |
| 901 | |
| 902 | $optionsTable = $this->productionTablePrefix . 'options'; |
| 903 | $optionValue = $this->getOptionValue($optionsTable, $optionName); |
| 904 | if (empty($optionValue)) { |
| 905 | return false; |
| 906 | } |
| 907 | |
| 908 | if ($this->getOptionValue($tmpOptionsTable, $optionName)) { |
| 909 | return $this->updateOptionValue($tmpOptionsTable, $optionName, $optionValue); |
| 910 | } |
| 911 | |
| 912 | return $this->insertOptionValue($tmpOptionsTable, $optionName, $optionValue); |
| 913 | } |
| 914 | |
| 915 | |
| 916 | |
| 917 | |
| 918 | |
| 919 | protected function isExcludedTable(string $tableName): bool |
| 920 | { |
| 921 | return in_array($tableName, $this->excludedTables); |
| 922 | } |
| 923 | |
| 924 | |
| 925 | |
| 926 | |
| 927 | |
| 928 | protected function isTableToPreserve(string $tableName): bool |
| 929 | { |
| 930 | return in_array($tableName, $this->tablesToPreserve, true); |
| 931 | } |
| 932 | |
| 933 | |
| 934 | |
| 935 | |
| 936 | |
| 937 | protected function isExistingDestinationSubsiteTable(string $tableName): bool |
| 938 | { |
| 939 | if (!$this->isRenamingForSubsite || strcasecmp($this->productionTablePrefix, $this->productionTableBasePrefix) !== 0) { |
| 940 | return false; |
| 941 | } |
| 942 | |
| 943 | if (preg_match('/^(\d+)_/', $tableName, $matches) !== 1) { |
| 944 | return false; |
| 945 | } |
| 946 | |
| 947 | $blogId = (int) $matches[1]; |
| 948 | return (string) $blogId === $matches[1] && isset($this->destinationSubsiteBlogIds[$blogId]); |
| 949 | } |
| 950 | |
| 951 | |
| 952 | |
| 953 | |
| 954 | protected function getTablesThatExistInBothExistingAndTempUnprefixed(): array |
| 955 | { |
| 956 | return array_intersect($this->tablesBeingRenamedUnprefixed['all'], $this->existingTablesUnprefixed['all']); |
| 957 | } |
| 958 | |
| 959 | |
| 960 | |
| 961 | |
| 962 | protected function getTablesThatExistInSiteButNotInTemp(): array |
| 963 | { |
| 964 | return array_diff($this->existingTablesUnprefixed['all'], $this->tablesBeingRenamedUnprefixed['all']); |
| 965 | } |
| 966 | |
| 967 | |
| 968 | |
| 969 | |
| 970 | protected function getTablesThatExistInTempButNotInSite(): array |
| 971 | { |
| 972 | return array_diff($this->tablesBeingRenamedUnprefixed['all'], $this->existingTablesUnprefixed['all']); |
| 973 | } |
| 974 | |
| 975 | |
| 976 | |
| 977 | |
| 978 | |
| 979 | |
| 980 | protected function renameTable(string $tableWithoutPrefix, int &$tablesRenamed) |
| 981 | { |
| 982 | $tmpDatabasePrefix = $this->tmpPrefix; |
| 983 | $tableToRename = $tmpDatabasePrefix . $tableWithoutPrefix; |
| 984 | $tmpName = $this->getTableShortName($tableToRename, $tmpDatabasePrefix); |
| 985 | $tableAfterRenamed = $this->getCurrentSiteTable($tableWithoutPrefix); |
| 986 | |
| 987 | if ($tmpName !== false) { |
| 988 | $tableToRename = $tmpName; |
| 989 | } |
| 990 | |
| 991 | |
| 992 | $database = $this->tableService->getDatabase(); |
| 993 | $result = $database->exec(sprintf( |
| 994 | "RENAME TABLE `%s` TO `%s`;", |
| 995 | $tableToRename, |
| 996 | $tableAfterRenamed |
| 997 | )); |
| 998 | |
| 999 | if ($result !== false) { |
| 1000 | $this->tablesRenamed++; |
| 1001 | $tablesRenamed++; |
| 1002 | if ($this->logEachRename && $this->logger instanceof Logger) { |
| 1003 | $this->logger->info("DB Rename: Renamed table {$tableToRename} to {$tableAfterRenamed}."); |
| 1004 | } |
| 1005 | |
| 1006 | return; |
| 1007 | } |
| 1008 | |
| 1009 | if ($this->logEachRename && $this->logger instanceof Logger) { |
| 1010 | |
| 1011 | $wpdb = $database->getWpdba()->getClient(); |
| 1012 | $error = $wpdb->last_error; |
| 1013 | $this->logger->warning("DB Rename: Unable to rename table {$tableToRename} to {$tableAfterRenamed}. Error: " . $error); |
| 1014 | } |
| 1015 | } |
| 1016 | |
| 1017 | |
| 1018 | |
| 1019 | |
| 1020 | |
| 1021 | protected function tableExists(string $tableName): bool |
| 1022 | { |
| 1023 | $database = $this->tableService->getDatabase()->getWpdba()->getClient(); |
| 1024 | $result = $database->get_results( |
| 1025 | $database->prepare("SHOW TABLES LIKE %s", $database->esc_like($tableName)), |
| 1026 | ARRAY_A |
| 1027 | ); |
| 1028 | |
| 1029 | return !empty($result); |
| 1030 | } |
| 1031 | |
| 1032 | |
| 1033 | |
| 1034 | |
| 1035 | |
| 1036 | |
| 1037 | protected function getOptionValue(string $tableName, string $optionName): string |
| 1038 | { |
| 1039 | $database = $this->tableService->getDatabase()->getWpdba()->getClient(); |
| 1040 | $result = $database->get_results( |
| 1041 | $database->prepare( |
| 1042 | "SELECT option_value FROM `{$tableName}` WHERE option_name LIKE %s", |
| 1043 | $database->esc_like($optionName) |
| 1044 | ), |
| 1045 | ARRAY_A |
| 1046 | ); |
| 1047 | if (empty($result)) { |
| 1048 | return ''; |
| 1049 | } |
| 1050 | |
| 1051 | return $result[0]['option_value']; |
| 1052 | } |
| 1053 | |
| 1054 | |
| 1055 | |
| 1056 | |
| 1057 | |
| 1058 | |
| 1059 | |
| 1060 | protected function updateOptionValue(string $tableName, string $optionName, string $optionValue): bool |
| 1061 | { |
| 1062 | $database = $this->tableService->getDatabase()->getWpdba()->getClient(); |
| 1063 | |
| 1064 | return $database->query( |
| 1065 | $database->prepare( |
| 1066 | "UPDATE `{$tableName}` SET option_value = %s WHERE option_name LIKE %s", |
| 1067 | $optionValue, |
| 1068 | $database->esc_like($optionName) |
| 1069 | ) |
| 1070 | ); |
| 1071 | } |
| 1072 | |
| 1073 | |
| 1074 | |
| 1075 | |
| 1076 | |
| 1077 | |
| 1078 | |
| 1079 | |
| 1080 | protected function insertOptionValue(string $tableName, string $optionName, string $optionValue, bool $autoload = false): bool |
| 1081 | { |
| 1082 | $database = $this->tableService->getDatabase()->getWpdba()->getClient(); |
| 1083 | |
| 1084 | return $database->query( |
| 1085 | $database->prepare( |
| 1086 | "INSERT INTO `{$tableName}` (option_name, option_value, autoload) VALUES (%s, %s, %s)", |
| 1087 | $optionName, |
| 1088 | $optionValue, |
| 1089 | $autoload ? 'yes' : 'no' |
| 1090 | ) |
| 1091 | ); |
| 1092 | } |
| 1093 | |
| 1094 | |
| 1095 | |
| 1096 | |
| 1097 | |
| 1098 | |
| 1099 | |
| 1100 | |
| 1101 | protected function insertOrUpdateOptionValue(string $tableName, string $optionName, string $optionValue, bool $autoload = false): bool |
| 1102 | { |
| 1103 | if ($this->getOptionValue($tableName, $optionName)) { |
| 1104 | return $this->updateOptionValue($tableName, $optionName, $optionValue); |
| 1105 | } |
| 1106 | |
| 1107 | return $this->insertOptionValue($tableName, $optionName, $optionValue, $autoload); |
| 1108 | } |
| 1109 | |
| 1110 | |
| 1111 | |
| 1112 | |
| 1113 | |
| 1114 | |
| 1115 | protected function getNetworkOptionValue(string $tableName, string $optionName): string |
| 1116 | { |
| 1117 | $database = $this->tableService->getDatabase()->getWpdba()->getClient(); |
| 1118 | $result = $database->get_results( |
| 1119 | $database->prepare( |
| 1120 | "SELECT meta_value FROM `{$tableName}` WHERE meta_key LIKE %s", |
| 1121 | $database->esc_like($optionName) |
| 1122 | ), |
| 1123 | ARRAY_A |
| 1124 | ); |
| 1125 | if (empty($result)) { |
| 1126 | return ''; |
| 1127 | } |
| 1128 | |
| 1129 | return $result[0]['meta_value']; |
| 1130 | } |
| 1131 | |
| 1132 | |
| 1133 | |
| 1134 | |
| 1135 | |
| 1136 | |
| 1137 | |
| 1138 | protected function insertNetworkOptionValue(string $tableName, string $optionName, string $optionValue): bool |
| 1139 | { |
| 1140 | $database = $this->tableService->getDatabase()->getWpdba()->getClient(); |
| 1141 | |
| 1142 | return $database->query( |
| 1143 | $database->prepare( |
| 1144 | "INSERT INTO `{$tableName}` (meta_key, meta_value) VALUES (%s, %s)", |
| 1145 | $optionName, |
| 1146 | $optionValue |
| 1147 | ) |
| 1148 | ); |
| 1149 | } |
| 1150 | |
| 1151 | |
| 1152 | |
| 1153 | |
| 1154 | |
| 1155 | |
| 1156 | |
| 1157 | protected function updateNetworkOptionValue(string $tableName, string $optionName, string $optionValue): bool |
| 1158 | { |
| 1159 | $database = $this->tableService->getDatabase()->getWpdba()->getClient(); |
| 1160 | |
| 1161 | return $database->query( |
| 1162 | $database->prepare( |
| 1163 | "UPDATE `{$tableName}` SET meta_value = %s WHERE meta_key LIKE %s", |
| 1164 | $optionValue, |
| 1165 | $database->esc_like($optionName) |
| 1166 | ) |
| 1167 | ); |
| 1168 | } |
| 1169 | |
| 1170 | |
| 1171 | |
| 1172 | |
| 1173 | |
| 1174 | |
| 1175 | |
| 1176 | protected function insertOrUpdateNetworkOptionValue(string $tableName, string $optionName, string $optionValue): bool |
| 1177 | { |
| 1178 | if ($this->getNetworkOptionValue($tableName, $optionName)) { |
| 1179 | return $this->updateNetworkOptionValue($tableName, $optionName, $optionValue); |
| 1180 | } |
| 1181 | |
| 1182 | return $this->insertNetworkOptionValue($tableName, $optionName, $optionValue); |
| 1183 | } |
| 1184 | |
| 1185 | |
| 1186 | |
| 1187 | |
| 1188 | protected function isThresholdReached(): bool |
| 1189 | { |
| 1190 | if (!$this->phpAdapter->isCallable($this->thresholdCallable)) { |
| 1191 | return $this->customThreshold(false); |
| 1192 | } |
| 1193 | |
| 1194 | $result = call_user_func($this->thresholdCallable); |
| 1195 | return $this->customThreshold($result); |
| 1196 | } |
| 1197 | |
| 1198 | |
| 1199 | |
| 1200 | |
| 1201 | |
| 1202 | private function customThreshold(bool $isThreshold): bool |
| 1203 | { |
| 1204 | return Hooks::applyFilters('wpstg.tests.tablesRenamingThreshold', $isThreshold); |
| 1205 | } |
| 1206 | |
| 1207 | |
| 1208 | |
| 1209 | |
| 1210 | |
| 1211 | |
| 1212 | private function renameQuery(string $tableToRename, string $tableAfterRenamed): bool |
| 1213 | { |
| 1214 | $result = $this->tableService->renameTable($tableToRename, $tableAfterRenamed); |
| 1215 | if ($result !== false) { |
| 1216 | return true; |
| 1217 | } |
| 1218 | |
| 1219 | if ($this->logEachRename && $this->logger instanceof Logger) { |
| 1220 | |
| 1221 | $error = $this->tableService->getLastWpdbError(); |
| 1222 | $this->logger->warning(sprintf("DB Rename: Unable to rename table %s to %s. Error: %s", $tableToRename, $tableAfterRenamed, $error)); |
| 1223 | } |
| 1224 | |
| 1225 | return false; |
| 1226 | } |
| 1227 | |
| 1228 | private function getCurrentSiteTable(string $tableWithoutPrefix): string |
| 1229 | { |
| 1230 | if ($tableWithoutPrefix !== 'users' && $tableWithoutPrefix !== 'usermeta') { |
| 1231 | return $this->productionTablePrefix . $tableWithoutPrefix; |
| 1232 | } |
| 1233 | |
| 1234 | if (!$this->isRenamingForSubsite) { |
| 1235 | return $this->productionTablePrefix . $tableWithoutPrefix; |
| 1236 | } |
| 1237 | |
| 1238 | return $this->productionTableBasePrefix . $tableWithoutPrefix; |
| 1239 | } |
| 1240 | } |
| 1241 |