PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.7.0
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.7.0
1.7.0 1.6.6 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 All 50 releases
← All changes | database/DBMigrator.php +78 -0 1.5.0 → 1.7.0 View file →
@@ -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');
@@ -154,15 +158,38 @@
154 158 }
155 159
156 160 update_option('_fluent_cart_db_version', FLUENTCART_DB_VERSION, 'no');
157 161
162 + if (!$currentDBVersion) {
163 + // Brand-new store: default tax display to the simplified single line.
164 + // Existing stores fall through to the read-time default 'itemized'.
165 + $taxSettings = get_option('fluent_cart_tax_configuration_settings', []);
166 + if (!isset($taxSettings['checkout_tax_breakdown_display'])) {
167 + $taxSettings['checkout_tax_breakdown_display'] = 'simplified';
168 + update_option('fluent_cart_tax_configuration_settings', $taxSettings, true);
169 + }
170 + }
171 +
158 172 // 2026-04-25
159 173 TaxRatesMigrator::upgradeShippingOverridePrecision();
160 174
175 + // 2026-07-01
176 + OrderTaxRateMigrator::allowVirtualTaxRateIds();
177 +
161 178 // 2026-05-27
162 179 TaxRatesMigrator::fixPostcodeRangeSeparator();
163 180 OrdersMigrator::addFeeTotalColumn();
164 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 +
165 192 // let's check the orders table sequence number
166 193 global $wpdb;
167 194
168 195 // Product Meta unique index removal
@@ -464,9 +491,15 @@
464 491 \FluentCart\Database\Migrations\ShippingZonesMigrator::migrated();
465 492 \FluentCart\Database\Migrations\ShippingClassesMigrator::migrated();
466 493 \FluentCart\Database\Migrations\SubscriptionsMigrator::migrated();
467 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();
468 500
501 +
469 502 // 2026-05-06
470 503 // Backfill, dedup, then add unique index — must run in this order
471 504 // so the constraint can be applied without "Duplicate entry" errors.
472 505 TaxClassesMigrator::backfillNullSlugs();
@@ -500,8 +533,21 @@
500 533 }
501 534 update_option('_fluent_cart_price_suffix_migrated', '1', 'no');
502 535 }
503 536
537 + // 2026-07-08
538 + // One-time migration: rename the legacy tax-display value 'both'
539 + // (and the removed 'label'/'tooltip') to 'itemized'. Value-guarded —
540 + // once migrated the stored value is 'itemized' so this no-ops; no
541 + // separate flag option is written (nothing left behind when this
542 + // block is removed later). Safe to remove after ~2027-07.
543 + $fctTaxSettings = get_option('fluent_cart_tax_configuration_settings', []);
544 + if (isset($fctTaxSettings['checkout_tax_breakdown_display'])
545 + && in_array($fctTaxSettings['checkout_tax_breakdown_display'], ['both', 'label', 'tooltip'], true)) {
546 + $fctTaxSettings['checkout_tax_breakdown_display'] = 'itemized';
547 + update_option('fluent_cart_tax_configuration_settings', $fctTaxSettings, true);
548 + }
549 +
504 550 // 2026-05-18
505 551 // One-time migration: copy seller identity fields from the Pro seller_details fct_meta
506 552 // entry into fluent_cart_store_settings. Guarded by a sentinel so it runs exactly once.
507 553 if (!get_option('_fluent_cart_seller_details_migrated')) {
@@ -557,8 +603,40 @@
557 603 AttributeObjectRelationsMigrator::migrate();
558 604 AttributeTermsMigrator::migrate();
559 605 AttributeSeeder::seed();
560 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 {
561 639 self::releaseMigrationLock();
562 640 }
563 641 }
564 642