| @@ -17,8 +17,9 @@ | ||
| 17 | 17 | use FluentCart\Database\Migrations\OrderTransactionsMigrator; |
| 18 | 18 | use FluentCart\Database\Migrations\ProductDetailsMigrator; |
| 19 | 19 | use FluentCart\Database\Migrations\ProductDownloadsMigrator; |
| 20 | 20 | use FluentCart\Database\Migrations\ProductMetaMigrator; |
| 21 | +use FluentCart\Database\Migrations\ProductReviewsMigrator; | |
| 21 | 22 | use FluentCart\Database\Migrations\ProductVariationMigrator; |
| 22 | 23 | use FluentCart\Database\Migrations\ScheduledActionsMigrator; |
| 23 | 24 | use FluentCart\Database\Migrations\ShippingClassesMigrator; |
| 24 | 25 | use FluentCart\Database\Migrations\SubscriptionMetaMigrator; |
| @@ -69,8 +70,9 @@ | ||
| 69 | 70 | OrderTransactionsMigrator::class, |
| 70 | 71 | ProductDetailsMigrator::class, |
| 71 | 72 | ProductDownloadsMigrator::class, |
| 72 | 73 | ProductMetaMigrator::class, |
| 74 | + ProductReviewsMigrator::class, | |
| 73 | 75 | SubscriptionMetaMigrator::class, |
| 74 | 76 | SubscriptionsMigrator::class, |
| 75 | 77 | TaxClassesMigrator::class, |
| 76 | 78 | TaxRatesMigrator::class, |
| @@ -135,8 +137,10 @@ | ||
| 135 | 137 | } |
| 136 | 138 | |
| 137 | 139 | public static function maybeMigrateDBChanges() |
| 138 | 140 | { |
| 141 | + self::maybeMigrateCustomerRecoveryIndexes(); | |
| 142 | + | |
| 139 | 143 | /* |
| 140 | 144 | * TODO We will remove this after final release |
| 141 | 145 | */ |
| 142 | 146 | $currentDBVersion = get_option('_fluent_cart_db_version'); |
| @@ -174,8 +178,18 @@ | ||
| 174 | 178 | // 2026-05-27 |
| 175 | 179 | TaxRatesMigrator::fixPostcodeRangeSeparator(); |
| 176 | 180 | OrdersMigrator::addFeeTotalColumn(); |
| 177 | 181 | |
| 182 | + // 2026-07-24 | |
| 183 | + OrdersMigrator::addUuidIndex(); | |
| 184 | + | |
| 185 | + // 2026-08-20 | |
| 186 | + ProductMetaMigrator::addObjectMetaIndex(); | |
| 187 | + | |
| 188 | + // 2026-09-07 — product reviews. A store updating from a release | |
| 189 | + // without the reviews table gets it created here. | |
| 190 | + ProductReviewsMigrator::migrate(); | |
| 191 | + | |
| 178 | 192 | // let's check the orders table sequence number |
| 179 | 193 | global $wpdb; |
| 180 | 194 | |
| 181 | 195 | // Product Meta unique index removal |
| @@ -477,9 +491,15 @@ | ||
| 477 | 491 | \FluentCart\Database\Migrations\ShippingZonesMigrator::migrated(); |
| 478 | 492 | \FluentCart\Database\Migrations\ShippingClassesMigrator::migrated(); |
| 479 | 493 | \FluentCart\Database\Migrations\SubscriptionsMigrator::migrated(); |
| 480 | 494 | |
| 495 | + // 2026-08-06 | |
| 496 | + // fct_order_transactions subscription_id index — also run here so | |
| 497 | + // in-place plugin updates deliver it; migrate() only covers the | |
| 498 | + // activation path. | |
| 499 | + \FluentCart\Database\Migrations\OrderTransactionsMigrator::migrated(); | |
| 481 | 500 | |
| 501 | + | |
| 482 | 502 | // 2026-05-06 |
| 483 | 503 | // Backfill, dedup, then add unique index — must run in this order |
| 484 | 504 | // so the constraint can be applied without "Duplicate entry" errors. |
| 485 | 505 | TaxClassesMigrator::backfillNullSlugs(); |
| @@ -583,8 +603,40 @@ | ||
| 583 | 603 | AttributeObjectRelationsMigrator::migrate(); |
| 584 | 604 | AttributeTermsMigrator::migrate(); |
| 585 | 605 | AttributeSeeder::seed(); |
| 586 | 606 | |
| 607 | + self::releaseMigrationLock(); | |
| 608 | + } | |
| 609 | + } | |
| 610 | + | |
| 611 | + /** Upgrade active stores without running index DDL on customer requests. */ | |
| 612 | + public static function maybeMigrateCustomerRecoveryIndexes(): void | |
| 613 | + { | |
| 614 | + $option = '_fluent_cart_customer_recovery_indexes_version'; | |
| 615 | + if (get_option($option) === '1') { | |
| 616 | + return; | |
| 617 | + } | |
| 618 | + if (!(defined('WP_CLI') && WP_CLI) && (!is_admin() || !current_user_can('manage_options'))) { | |
| 619 | + return; | |
| 620 | + } | |
| 621 | + if (!self::acquireMigrationLock()) { | |
| 622 | + return; | |
| 623 | + } | |
| 624 | + try { | |
| 625 | + if (get_option($option) === '1') { | |
| 626 | + return; | |
| 627 | + } | |
| 628 | + foreach ([SubscriptionsMigrator::class, OrderDownloadPermissionsMigrator::class, CartMigrator::class] as $migrator) { | |
| 629 | + if (!Schema::hasTable($migrator::$tableName)) { | |
| 630 | + return; | |
| 631 | + } | |
| 632 | + $migrator::addCustomerRecoveryIndex(); | |
| 633 | + if (!$migrator::hasCustomerRecoveryIndex()) { | |
| 634 | + return; // Keep the upgrade pending if ALTER failed. | |
| 635 | + } | |
| 636 | + } | |
| 637 | + update_option($option, '1', false); | |
| 638 | + } finally { | |
| 587 | 639 | self::releaseMigrationLock(); |
| 588 | 640 | } |
| 589 | 641 | } |
| 590 | 642 | |