PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.6.5
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.6.5
1.6.5 1.6.4 1.6.3 1.6.2 1.6.1 1.6.0 1.5.4 1.5.5 1.5.3 1.5.2 1.5.1 1.5.0 1.4.2 1.4.1 1.4.0 1.3.28 1.3.27 1.3.26 1.3.25 1.3.23 1.3.22 1.3.21 1.3.20 1.3.19 trunk All 48 releases
← All changes | database/DBMigrator.php +72 -0 1.5.2 → 1.6.5 View file →
@@ -135,8 +135,10 @@
135 135 }
136 136
137 137 public static function maybeMigrateDBChanges()
138 138 {
139 + self::maybeMigrateCustomerRecoveryIndexes();
140 +
139 141 /*
140 142 * TODO We will remove this after final release
141 143 */
142 144 $currentDBVersion = get_option('_fluent_cart_db_version');
@@ -154,15 +156,34 @@
154 156 }
155 157
156 158 update_option('_fluent_cart_db_version', FLUENTCART_DB_VERSION, 'no');
157 159
160 + if (!$currentDBVersion) {
161 + // Brand-new store: default tax display to the simplified single line.
162 + // Existing stores fall through to the read-time default 'itemized'.
163 + $taxSettings = get_option('fluent_cart_tax_configuration_settings', []);
164 + if (!isset($taxSettings['checkout_tax_breakdown_display'])) {
165 + $taxSettings['checkout_tax_breakdown_display'] = 'simplified';
166 + update_option('fluent_cart_tax_configuration_settings', $taxSettings, true);
167 + }
168 + }
169 +
158 170 // 2026-04-25
159 171 TaxRatesMigrator::upgradeShippingOverridePrecision();
160 172
173 + // 2026-07-01
174 + OrderTaxRateMigrator::allowVirtualTaxRateIds();
175 +
161 176 // 2026-05-27
162 177 TaxRatesMigrator::fixPostcodeRangeSeparator();
163 178 OrdersMigrator::addFeeTotalColumn();
164 179
180 + // 2026-07-24
181 + OrdersMigrator::addUuidIndex();
182 +
183 + // 2026-08-20
184 + ProductMetaMigrator::addObjectMetaIndex();
185 +
165 186 // let's check the orders table sequence number
166 187 global $wpdb;
167 188
168 189 // Product Meta unique index removal
@@ -464,9 +485,15 @@
464 485 \FluentCart\Database\Migrations\ShippingZonesMigrator::migrated();
465 486 \FluentCart\Database\Migrations\ShippingClassesMigrator::migrated();
466 487 \FluentCart\Database\Migrations\SubscriptionsMigrator::migrated();
467 488
489 + // 2026-08-06
490 + // fct_order_transactions subscription_id index — also run here so
491 + // in-place plugin updates deliver it; migrate() only covers the
492 + // activation path.
493 + \FluentCart\Database\Migrations\OrderTransactionsMigrator::migrated();
468 494
495 +
469 496 // 2026-05-06
470 497 // Backfill, dedup, then add unique index — must run in this order
471 498 // so the constraint can be applied without "Duplicate entry" errors.
472 499 TaxClassesMigrator::backfillNullSlugs();
@@ -500,8 +527,21 @@
500 527 }
501 528 update_option('_fluent_cart_price_suffix_migrated', '1', 'no');
502 529 }
503 530
531 + // 2026-07-08
532 + // One-time migration: rename the legacy tax-display value 'both'
533 + // (and the removed 'label'/'tooltip') to 'itemized'. Value-guarded —
534 + // once migrated the stored value is 'itemized' so this no-ops; no
535 + // separate flag option is written (nothing left behind when this
536 + // block is removed later). Safe to remove after ~2027-07.
537 + $fctTaxSettings = get_option('fluent_cart_tax_configuration_settings', []);
538 + if (isset($fctTaxSettings['checkout_tax_breakdown_display'])
539 + && in_array($fctTaxSettings['checkout_tax_breakdown_display'], ['both', 'label', 'tooltip'], true)) {
540 + $fctTaxSettings['checkout_tax_breakdown_display'] = 'itemized';
541 + update_option('fluent_cart_tax_configuration_settings', $fctTaxSettings, true);
542 + }
543 +
504 544 // 2026-05-18
505 545 // One-time migration: copy seller identity fields from the Pro seller_details fct_meta
506 546 // entry into fluent_cart_store_settings. Guarded by a sentinel so it runs exactly once.
507 547 if (!get_option('_fluent_cart_seller_details_migrated')) {
@@ -557,8 +597,40 @@
557 597 AttributeObjectRelationsMigrator::migrate();
558 598 AttributeTermsMigrator::migrate();
559 599 AttributeSeeder::seed();
560 600
601 + self::releaseMigrationLock();
602 + }
603 + }
604 +
605 + /** Upgrade active stores without running index DDL on customer requests. */
606 + public static function maybeMigrateCustomerRecoveryIndexes(): void
607 + {
608 + $option = '_fluent_cart_customer_recovery_indexes_version';
609 + if (get_option($option) === '1') {
610 + return;
611 + }
612 + if (!(defined('WP_CLI') && WP_CLI) && (!is_admin() || !current_user_can('manage_options'))) {
613 + return;
614 + }
615 + if (!self::acquireMigrationLock()) {
616 + return;
617 + }
618 + try {
619 + if (get_option($option) === '1') {
620 + return;
621 + }
622 + foreach ([SubscriptionsMigrator::class, OrderDownloadPermissionsMigrator::class, CartMigrator::class] as $migrator) {
623 + if (!Schema::hasTable($migrator::$tableName)) {
624 + return;
625 + }
626 + $migrator::addCustomerRecoveryIndex();
627 + if (!$migrator::hasCustomerRecoveryIndex()) {
628 + return; // Keep the upgrade pending if ALTER failed.
629 + }
630 + }
631 + update_option($option, '1', false);
632 + } finally {
561 633 self::releaseMigrationLock();
562 634 }
563 635 }
564 636