PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.3.28
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.3.28
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 1.3.19 All 49 releases
fluent-cart / database / DBMigrator.php

DBMigrator.php in FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler 1.3.28, at database/DBMigrator.php

476 lines 25.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentCart\Database;
4
5 use FluentCart\App\CPT\FluentProducts;
6 use FluentCart\App\Models\Product;
7
8 require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
9
10 use FluentCart\Database\Migrations\AttributeGroupsMigrator;
11 use FluentCart\Database\Migrations\AttributeObjectRelationsMigrator;
12 use FluentCart\Database\Migrations\AttributeTermsMigrator;
13 use FluentCart\Database\Migrations\CartMigrator;
14 use FluentCart\Database\Migrations\CustomersMigrator;
15 use FluentCart\Database\Migrations\MetaMigrator;
16 use FluentCart\Database\Migrations\Migrator;
17 use FluentCart\Database\Migrations\OrderMetaMigrator;
18 use FluentCart\Database\Migrations\OrdersMigrator;
19 use FluentCart\Database\Migrations\OrdersItemsMigrator;
20 use FluentCart\Database\Migrations\OrderTransactionsMigrator;
21 use FluentCart\Database\Migrations\ProductDetailsMigrator;
22 use FluentCart\Database\Migrations\ProductDownloadsMigrator;
23 use FluentCart\Database\Migrations\ProductMetaMigrator;
24 use FluentCart\Database\Migrations\ProductVariationMigrator;
25 use FluentCart\Database\Migrations\ScheduledActionsMigrator;
26 use FluentCart\Database\Migrations\ShippingClassesMigrator;
27 use FluentCart\Database\Migrations\SubscriptionMetaMigrator;
28 use FluentCart\Database\Migrations\SubscriptionsMigrator;
29 use FluentCart\Database\Migrations\TaxClassesMigrator;
30 use FluentCart\Database\Migrations\TaxRatesMigrator;
31 use FluentCart\Database\Migrations\OrderTaxRateMigrator;
32 use FluentCart\Database\Migrations\CouponsMigrator;
33 use FluentCart\Database\Migrations\CustomerAddressesMigrator;
34 use FluentCart\Database\Migrations\CustomerMetaMigrator;
35 use FluentCart\Database\Migrations\OrderAddressesMigrator;
36 use FluentCart\Database\Migrations\OrderDownloadPermissionsMigrator;
37 use FluentCart\Database\Migrations\OrderOperationsMigrator;
38 use FluentCart\Database\Migrations\AppliedCouponsMigrator;
39 use FluentCart\Database\Migrations\LabelMigrator;
40 use FluentCart\Database\Migrations\LabelRelationshipsMigrator;
41 use FluentCart\Database\Migrations\ActivityMigrator;
42 use FluentCart\Database\Migrations\WebhookLogger;
43 use FluentCart\Framework\Database\Schema;
44 use FluentCartPro\App\Modules\Licensing\Models\License;
45 use FluentCartPro\App\Modules\Licensing\Models\LicenseActivation;
46 use FluentCartPro\App\Modules\Licensing\Models\LicenseMeta;
47 use FluentCartPro\App\Modules\Licensing\Models\LicenseSite;
48 use FluentCart\Database\Migrations\ShippingZonesMigrator;
49 use FluentCart\Database\Migrations\ShippingMethodsMigrator;
50 use FluentCart\Database\Migrations\RetentionSnapshotsMigrator;
51
52 class DBMigrator
53 {
54 private static array $migrators = [
55 MetaMigrator::class,
56 AttributeGroupsMigrator::class,
57 AttributeObjectRelationsMigrator::class,
58 AttributeTermsMigrator::class,
59 CartMigrator::class,
60 CouponsMigrator::class,
61 CustomerAddressesMigrator::class,
62 CustomerMetaMigrator::class,
63 CustomersMigrator::class,
64 OrderAddressesMigrator::class,
65 OrderDownloadPermissionsMigrator::class,
66 OrderMetaMigrator::class,
67 OrderOperationsMigrator::class,
68 OrdersItemsMigrator::class,
69 OrdersMigrator::class,
70 OrderTaxRateMigrator::class,
71 OrderTransactionsMigrator::class,
72 ProductDetailsMigrator::class,
73 ProductDownloadsMigrator::class,
74 ProductMetaMigrator::class,
75 SubscriptionMetaMigrator::class,
76 SubscriptionsMigrator::class,
77 TaxClassesMigrator::class,
78 TaxRatesMigrator::class,
79 ProductVariationMigrator::class,
80 AppliedCouponsMigrator::class,
81 LabelMigrator::class,
82 LabelRelationshipsMigrator::class,
83 ActivityMigrator::class,
84 WebhookLogger::class,
85 ShippingZonesMigrator::class,
86 ShippingMethodsMigrator::class,
87 ShippingClassesMigrator::class,
88 ScheduledActionsMigrator::class,
89 RetentionSnapshotsMigrator::class
90 ];
91
92 public static function migrateUp($network_wide = false)
93 {
94 global $wpdb;
95 if ($network_wide) {
96 // Retrieve all site IDs from this network (WordPress >= 4.6 provides easy to use functions for that).
97 if (function_exists('get_sites') && function_exists('get_current_network_id')) {
98 $site_ids = get_sites(array('fields' => 'ids', 'network_id' => get_current_network_id()));
99 } else {
100 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
101 $site_ids = $wpdb->get_col("SELECT blog_id FROM $wpdb->blogs WHERE site_id = $wpdb->siteid;");
102 }
103 // Install the plugin for all these sites.
104 foreach ($site_ids as $site_id) {
105 switch_to_blog($site_id);
106 self::run_migrate();
107 restore_current_blog();
108 }
109 } else {
110 self::run_migrate();
111 }
112 }
113
114 public static function run_migrate()
115 {
116 self::migrate();
117 self::maybeMigrateDBChanges();
118 update_option('_fluent_cart_db_version', FLUENTCART_DB_VERSION, 'no');
119 }
120
121 public static function migrate()
122 {
123 /**
124 * @var $migrator Migrator
125 */
126 foreach (self::$migrators as $migrator) {
127 $migrator::migrate();
128 }
129 }
130
131 public static function maybeMigrateDBChanges()
132 {
133 /*
134 * TODO We will remove this after final release
135 */
136 $currentDBVersion = get_option('_fluent_cart_db_version');
137
138 if (!$currentDBVersion || version_compare($currentDBVersion, FLUENTCART_DB_VERSION, '<')) {
139
140 update_option('_fluent_cart_db_version', FLUENTCART_DB_VERSION, 'no');
141
142 // 2026-05-10
143 AttributeGroupsMigrator::dropLegacyTitleUniqueIndexes();
144
145 // let's check the orders table sequence number
146 global $wpdb;
147
148 // Product Meta unique index removal
149 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
150 $hasProductMetaUnqIndex = $wpdb->get_col($wpdb->prepare("SELECT * FROM information_schema.STATISTICS WHERE TABLE_SCHEMA=DATABASE() AND INDEX_NAME='" . $wpdb->prefix . "fct_pm__comp_unq' AND TABLE_NAME=%s", $wpdb->prefix . 'fct_product_meta'));
151 if ($hasProductMetaUnqIndex) {
152
153 $table_name = $wpdb->prefix . 'fct_product_meta';
154 $index_name = 'fct_pm__comp_unq';
155
156 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
157 $wpdb->query(
158 $wpdb->prepare(
159 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
160 "ALTER TABLE %i DROP INDEX %i",
161 $table_name,
162 $index_name
163 ));
164
165 }
166
167 if (!Schema::hasColumn('tax_behavior', 'fct_orders')) {
168 $table_name = $wpdb->prefix . 'fct_orders';
169 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
170 $wpdb->query($wpdb->prepare(
171 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
172 "ALTER TABLE %i ADD COLUMN `tax_behavior` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '0 => no_tax, 1 => exclusive, 2 => inclusive' AFTER `rate`",
173 $table_name
174 ));
175 }
176
177 if (!Schema::hasColumn('slug', 'fct_tax_classes')) {
178 $table_name = $wpdb->prefix . 'fct_tax_classes';
179 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
180 $wpdb->query($wpdb->prepare(
181 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
182 "ALTER TABLE %i ADD COLUMN `slug` VARCHAR(100) NULL AFTER `title`",
183 $table_name
184 ));
185 }
186
187 $ordersTable = $wpdb->prefix . 'fct_orders';
188
189 if (!Schema::hasColumn('fee_total', 'fct_orders')) {
190 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
191 $wpdb->query($wpdb->prepare(
192 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
193 "ALTER TABLE %i ADD COLUMN `fee_total` BIGINT NOT NULL DEFAULT '0' AFTER `shipping_total`",
194 $ordersTable
195 ));
196 }
197
198 // check if scheduled_at is exist or not
199 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
200 $isReceiptNumberMigrated = $wpdb->get_col($wpdb->prepare("SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND COLUMN_NAME='receipt_number' AND TABLE_NAME=%s", $ordersTable));
201 if (!$isReceiptNumberMigrated) {
202 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
203 $wpdb->query($wpdb->prepare(
204 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
205 "ALTER TABLE %i ADD COLUMN `receipt_number` BIGINT NULL AFTER `parent_id`",
206 $ordersTable
207 ));
208 }
209
210 /**
211 * Changing fct_meta.key to fct_meta.meta_key
212 */
213 if (Schema::hasColumn('discount_total', 'fct_orders')) {
214 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
215 $wpdb->query($wpdb->prepare(
216 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
217 "ALTER TABLE %i CHANGE `discount_total` `manual_discount_total` BIGINT NOT NULL DEFAULT '0'",
218 $ordersTable
219 ));
220 }
221
222 /**
223 * Changing fct_meta.key to fct_meta.meta_key
224 */
225 if (Schema::hasColumn('key', 'fct_meta')) {
226 $table_name = $wpdb->prefix . 'fct_meta';
227 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
228 $wpdb->query($wpdb->prepare(
229 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
230 "ALTER TABLE %i CHANGE `key` `meta_key` VARCHAR(192)",
231 $table_name
232 ));
233 }
234
235 /**
236 * Changing fct_meta.value to fct_meta.meta_value
237 */
238 if (Schema::hasColumn('value', 'fct_meta')) {
239 $table_name = $wpdb->prefix . 'fct_meta';
240 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
241 $wpdb->query($wpdb->prepare(
242 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
243 "ALTER TABLE %i CHANGE `value` `meta_value` LONGTEXT",
244 $table_name
245 ));
246 }
247
248 /**
249 * Changing fct_order_meta.key to fct_order_meta.meta_key and fct_order_meta.value to fct_order_meta.meta_value
250 */
251 if (Schema::hasColumn('key', 'fct_order_meta')) {
252 $table_name = $wpdb->prefix . 'fct_order_meta';
253 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
254 $wpdb->query($wpdb->prepare(
255 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
256 "ALTER TABLE %i CHANGE `key` `meta_key` VARCHAR(192)",
257 $table_name
258 ));
259 }
260 /**
261 * Changing fct_meta.key to fct_meta.meta_key and fct_meta.value to fct_meta.meta_value
262 */
263 if (Schema::hasColumn('value', 'fct_order_meta')) {
264 $table_name = $wpdb->prefix . 'fct_order_meta';
265 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
266 $wpdb->query($wpdb->prepare(
267 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
268 "ALTER TABLE %i CHANGE `value` `meta_value` LONGTEXT",
269 $table_name
270 ));
271 }
272
273 /**
274 * adding ltv column to fct_customers table
275 */
276 if (!Schema::hasColumn('ltv', 'fct_customers')) {
277 $table_name = $wpdb->prefix . 'fct_customers';
278 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
279 $wpdb->query($wpdb->prepare(
280 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
281 "ALTER TABLE %i ADD COLUMN `ltv` BIGINT NOT NULL DEFAULT '0' AFTER `purchase_count`",
282 $table_name
283 ));
284 }
285
286 /**
287 * adding states column to fct_shipping_methods table
288 */
289 if (!Schema::hasColumn('states', 'fct_shipping_methods')) {
290 $table_name = $wpdb->prefix . 'fct_shipping_methods';
291 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
292 $wpdb->query($wpdb->prepare(
293 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
294 "ALTER TABLE %i ADD COLUMN `states` LONGTEXT NULL AFTER `is_enabled`",
295 $table_name
296 ));
297 }
298
299 /**
300 * modify states column to json in fct_shipping_methods table
301 */
302 if (Schema::hasColumn('states', 'fct_shipping_methods')) {
303 $table_name = $wpdb->prefix . 'fct_shipping_methods';
304 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
305 $wpdb->query($wpdb->prepare(
306 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
307 "ALTER TABLE %i MODIFY COLUMN `states` JSON NULL",
308 $table_name
309 ));
310 }
311
312 /**
313 * Changing fct_shipping_zones.regions to fct_shipping_zones.region
314 */
315 if (Schema::hasColumn('regions', 'fct_shipping_zones')) {
316 $table_name = $wpdb->prefix . 'fct_shipping_zones';
317 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
318 $wpdb->query($wpdb->prepare(
319 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
320 "ALTER TABLE %i CHANGE `regions` `region` VARCHAR(192) NOT NULL",
321 $table_name
322 ));
323 }
324
325 /**
326 * adding uuid column to fct_subscriptions table
327 */
328
329 if (!Schema::hasColumn('uuid', 'fct_subscriptions')) {
330 $table_name = $wpdb->prefix . 'fct_subscriptions';
331 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
332 $wpdb->query($wpdb->prepare(
333 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
334 "ALTER TABLE %i ADD COLUMN `uuid` VARCHAR(100) NOT NULL AFTER `id`",
335 $table_name
336 ));
337 }
338
339 if (Schema::hasColumn('initial_amount', 'fct_subscriptions')) {
340 $table_name = $wpdb->prefix . 'fct_subscriptions';
341 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
342 $wpdb->query($wpdb->prepare(
343 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
344 "ALTER TABLE %i CHANGE `initial_amount` `signup_fee` BIGINT UNSIGNED NOT NULL DEFAULT 0",
345 $table_name
346 ));
347 }
348
349 SubscriptionsMigrator::backfillEmptyUuids();
350
351 if (!Schema::hasColumn('meta', 'fct_order_addresses')) {
352 $table_name = $wpdb->prefix . 'fct_order_addresses';
353 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
354 $wpdb->query($wpdb->prepare(
355 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
356 "ALTER TABLE %i ADD COLUMN `meta` JSON DEFAULT NULL AFTER `country`",
357 $table_name
358 ));
359 }
360
361 if (!Schema::hasColumn('meta', 'fct_customer_addresses')) {
362 $table_name = $wpdb->prefix . 'fct_customer_addresses';
363 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
364 $wpdb->query($wpdb->prepare(
365 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
366 "ALTER TABLE %i ADD COLUMN `meta` JSON DEFAULT NULL AFTER `country`",
367 $table_name
368 ));
369 }
370
371 if (!Schema::hasColumn('meta', 'fct_order_tax_rate')) {
372 $table_name = $wpdb->prefix . 'fct_order_tax_rate';
373 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
374 $wpdb->query($wpdb->prepare(
375 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
376 "ALTER TABLE %i ADD COLUMN `meta` JSON",
377 $table_name
378 ));
379 }
380
381 if (!Schema::hasColumn('filed_at', 'fct_order_tax_rate')) {
382 $table_name = $wpdb->prefix . 'fct_order_tax_rate';
383 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
384 $wpdb->query($wpdb->prepare(
385 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
386 "ALTER TABLE %i ADD COLUMN `filed_at` DATETIME NULL AFTER `meta`",
387 $table_name
388 ));
389 }
390
391 if (Schema::hasColumn('categories', 'fct_tax_classes') && !Schema::hasColumn('meta', 'fct_tax_classes')) {
392 $table_name = $wpdb->prefix . 'fct_tax_classes';
393 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
394 $wpdb->query($wpdb->prepare(
395 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
396 "ALTER TABLE %i CHANGE `categories` `meta` JSON",
397 $table_name
398 ));
399 }
400
401 if (!Schema::hasColumn('meta', 'fct_tax_classes')) {
402 $table_name = $wpdb->prefix . 'fct_tax_classes';
403 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
404 $wpdb->query($wpdb->prepare(
405 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
406 "ALTER TABLE %i ADD COLUMN `meta` JSON",
407 $table_name
408 ));
409 }
410
411 if (!Schema::hasColumn('description', 'fct_tax_classes')) {
412 $table_name = $wpdb->prefix . 'fct_tax_classes';
413 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
414 $wpdb->query($wpdb->prepare(
415 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
416 "ALTER TABLE %i ADD COLUMN `description` LONGTEXT NULL AFTER `title`",
417 $table_name
418 ));
419 }
420
421 if (!Schema::hasColumn('group', 'fct_tax_rates')) {
422 $table_name = $wpdb->prefix . 'fct_tax_rates';
423 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
424 $wpdb->query($wpdb->prepare(
425 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
426 "ALTER TABLE %i ADD COLUMN `group` VARCHAR(45) NULL AFTER `name`",
427 $table_name
428 ));
429 }
430
431 if (!Schema::hasColumn('meta', 'fct_shipping_methods')) {
432 $table_name = $wpdb->prefix . 'fct_shipping_methods';
433 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
434 $wpdb->query($wpdb->prepare(
435 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
436 "ALTER TABLE %i ADD COLUMN `meta` JSON NULL AFTER `order`",
437 $table_name
438 ));
439
440 }
441
442 // Shipping schema upgrades — also run here so plugin updates
443 // without deactivation/reactivation still apply new columns
444 \FluentCart\Database\Migrations\ShippingZonesMigrator::migrated();
445 \FluentCart\Database\Migrations\ShippingClassesMigrator::migrated();
446
447 }
448 }
449
450 public static function migrateDown($network_wide = false)
451 {
452 /**
453 * @var $migrator Migrator
454 */
455 foreach (self::$migrators as $migrator) {
456 $migrator::dropTable();
457 }
458
459 Product::query()->where('post_type', '=', FluentProducts::CPT_NAME)->delete();
460
461 //Migrate Down The Licenses
462 if (class_exists(License::class)) {
463 License::query()->truncate();
464 LicenseActivation::query()->truncate();
465 LicenseSite::query()->truncate();
466 LicenseMeta::query()->truncate();
467 }
468 }
469
470 public static function refresh($network_wide = false)
471 {
472 static::migrateDown($network_wide);
473 static::migrateUp($network_wide);
474 }
475 }
476