PluginProbe
StoreEngine — Complete eCommerce Solution with Memberships, Licensing, Affiliates & More / 2.1.0
StoreEngine — Complete eCommerce Solution with Memberships, Licensing, Affiliates & More v2.1.0
2.3.0 2.2.0 2.1.1 2.1.0 2.0.0 1.10.0 1.9.1 1.9.0 1.2.1 1.2.2 1.3.0 1.3.1 1.3.2 1.3.3 1.4.0 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.6.0 All 59 releases
storeengine / includes / migration.php

migration.php in StoreEngine — Complete eCommerce Solution with Memberships, Licensing, Affiliates & More 2.1.0, at includes/migration.php

370 lines 14.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * DB Migration
4 *
5 * @package StoreEngine
6 */
7
8 namespace StoreEngine;
9
10 use StoreEngine;
11 use StoreEngine\Admin\Settings\Base;
12 use StoreEngine\Database\CreateEmailLog;
13 use StoreEngine\Database\CreateShippingZoneLocations;
14 use StoreEngine\Utils\Fs;
15 use StoreEngine\Utils\Helper;
16 use StoreEngine\Admin\Settings;
17
18 if ( ! defined( 'ABSPATH' ) ) {
19 exit;
20 }
21
22 class Migration {
23
24 public static function init() {
25 $self = new self();
26 add_action( 'init', [ $self, 'run_migration' ] );
27 }
28
29 public function run_migration() {
30 // @TODO refactor this with:
31 // - Update the original schema and remove the alter queries as db-delta can
32 // generate alter query when needed.
33 // - Progressive data migration with background task queue.
34 // - Run migration on update from installer (not on every init).
35
36 $this->update_admin_role();
37
38 $storeengine_version = get_option( 'storeengine_version' );
39
40 if ( ! get_option( 'storeengine_db_version' ) ) {
41 Database::create_initial_custom_table();
42 Settings::save_settings();
43 update_option( 'storeengine_version', STOREENGINE_VERSION );
44
45 return;
46 }
47
48 // Force update existence templates with new shortcodes.
49 $this->migrate_1_beta_5_1( $storeengine_version );
50 $this->migrate_1_beta_6( $storeengine_version );
51 $this->migrate_stable_1( $storeengine_version );
52 $this->migrate_1_0_2( $storeengine_version );
53 $this->migrate_1_2_1( $storeengine_version );
54 $this->migrate_1_3_0( $storeengine_version );
55 $this->migrate_1_3_3( $storeengine_version );
56 $this->migrate_1_5_0( $storeengine_version );
57 $this->migrate_1_5_2( $storeengine_version );
58 $this->migrate_1_5_5( $storeengine_version );
59 $this->migrate_1_8_0( $storeengine_version );
60 $this->migrate_1_10_0( $storeengine_version );
61
62 if ( STOREENGINE_VERSION !== $storeengine_version ) {
63 Settings::save_settings();
64 update_option( 'storeengine_version', STOREENGINE_VERSION );
65 }
66 }
67
68 public function update_admin_role() {
69 // Current user have administrator role and not have storeengine_shop_manager role then assign storeengine_shop_manager role
70 if ( ! is_user_logged_in() || ! get_current_user_id() ) {
71 return;
72 }
73
74 $user = wp_get_current_user();
75
76 if ( in_array( 'administrator', $user->roles, true ) && ! in_array( 'storeengine_shop_manager', $user->roles, true ) ) {
77 $user->add_role( 'storeengine_shop_manager' );
78 }
79 }
80
81 public function migrate_1_beta_5_1( $storeengine_version ) {
82 if ( version_compare( $storeengine_version, '1.0.0-beta-5.1', '<' ) ) {
83 StoreEngine::init()->load_cart();
84 Helper::create_initial_pages();
85
86 $pages = [ 'cart_page', 'checkout_page', 'thankyou_page', 'dashboard_page' ];
87 foreach ( $pages as $page ) {
88 $page_id = Helper::get_settings( $page );
89 if ( $page_id ) {
90 $page_content_path = STOREENGINE_TEMPLATE_PATH . 'page-content/' . str_replace( '_page', '', $page ) . '.php';
91 if ( file_exists( $page_content_path ) ) {
92 wp_update_post( [
93 'ID' => $page_id,
94 'post_content' => Fs::render_template( $page_content_path ),
95 ] );
96 }
97 }
98 }
99 }
100 }
101
102 // phpcs:disable PluginCheck.Security.DirectDB.UnescapedDBParameter, WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.SlowDBQuery.slow_db_query_meta_value, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.SlowDBQuery.slow_db_query_meta_key
103
104 public function migrate_1_beta_6( $storeengine_version ) {
105 if ( version_compare( $storeengine_version, '1.0.0-beta-6', '<' ) ) {
106 global $wpdb;
107 $method_table = $wpdb->prefix . 'storeengine_shipping_zone_methods';
108 $zone_table = $wpdb->prefix . 'storeengine_shipping_zones';
109
110 $wpdb->query( "ALTER TABLE $method_table DROP COLUMN `type`, DROP COLUMN `cost`, DROP COLUMN `tax`" );
111 $wpdb->query( "ALTER TABLE $method_table
112 ADD COLUMN `method_id` varchar(200) NOT NULL AFTER `zone_id`,
113 ADD COLUMN `settings` longtext NULL AFTER `description`,
114 ADD COLUMN `method_order` bigint(20) UNSIGNED NOT NULL AFTER `method_id`" );
115 $wpdb->query( "ALTER TABLE $zone_table DROP COLUMN `region`" );
116 $wpdb->query( "ALTER TABLE $zone_table ADD COLUMN `zone_order` BIGINT(20) UNSIGNED NOT NULL AFTER `zone_name`" );
117
118 if ( ! function_exists( 'dbDelta' ) ) {
119 require_once ABSPATH . 'wp-admin/includes/upgrade.php';
120 }
121
122 CreateShippingZoneLocations::up( $wpdb->prefix, $wpdb->get_charset_collate() );
123
124 $page = 'thankyou_page';
125 $page_id = Helper::get_settings( $page );
126
127 if ( $page_id ) {
128 $page_content_path = STOREENGINE_TEMPLATE_PATH . 'page-content/' . str_replace( '_page', '', $page ) . '.php';
129 if ( file_exists( $page_content_path ) ) {
130 wp_update_post( [
131 'ID' => $page_id,
132 'post_content' => Fs::render_template( $page_content_path ),
133 ] );
134 }
135 }
136 }
137 }
138
139 public function migrate_stable_1( $storeengine_version ) {
140 if ( version_compare( $storeengine_version, '1.0.0', '<' ) ) {
141 $settings = get_option( STOREENGINE_SETTINGS_NAME );
142 $settings = json_decode( $settings, true );
143
144 if ( 'leftWithSpace' === $settings['store_currency_position'] ) {
145 $settings['store_currency_position'] = 'left_space';
146 }
147 if ( 'rightWithSpace' === $settings['store_currency_position'] ) {
148 $settings['store_currency_position'] = 'right_space';
149 }
150
151 if ( isset( $settings['store_zip'] ) ) {
152 unset( $settings['store_zip'] );
153 }
154
155 update_option( STOREENGINE_SETTINGS_NAME, wp_json_encode( $settings ) );
156 }
157 }
158
159 public function migrate_1_0_2( $storeengine_version ) {
160 if ( version_compare( $storeengine_version, '1.0.2', '<' ) ) {
161 global $wpdb;
162 $users_metadata = $wpdb->get_results( "SELECT * FROM $wpdb->usermeta WHERE meta_key = '_storeengine_purchased_membership_ids'" );
163
164 foreach ( $users_metadata as $user_meta ) {
165 $membership_ids = maybe_unserialize( $user_meta->meta_value );
166 if ( is_array( $membership_ids ) ) {
167 continue;
168 }
169 $membership_ids = maybe_unserialize( $membership_ids );
170 update_user_meta( $user_meta->user_id, '_storeengine_purchased_membership_ids', $membership_ids );
171 }
172
173 if ( ! Helper::get_settings( 'product_archive_filters' ) ) {
174 Settings::save_settings();
175 Base::save_settings( [
176 'product_archive_filters' => [
177 [
178 'slug' => 'search',
179 'status' => true,
180 'order' => 0,
181 ],
182 [
183 'slug' => 'category',
184 'status' => true,
185 'order' => 1,
186 ],
187 [
188 'slug' => 'tags',
189 'status' => true,
190 'order' => 2,
191 ],
192 ],
193 ] );
194 }
195 }
196 }
197
198 public function migrate_1_2_1( $storeengine_version ) {
199 if ( version_compare( $storeengine_version, '1.2.1', '<' ) ) {
200 Settings::save_settings();
201 Base::save_settings( [
202 'product_archive_filters' => [
203 'search' => [
204 'status' => true,
205 'order' => 0,
206 ],
207 'category' => [
208 'status' => true,
209 'order' => 1,
210 ],
211 'tags' => [
212 'status' => true,
213 'order' => 2,
214 ],
215 ],
216 'auth_redirect_type' => 'storeengine',
217 'auth_redirect_url' => '',
218 ] );
219 }
220 }
221
222 public function migrate_1_3_0( $storeengine_version ) {
223 if ( version_compare( $storeengine_version, '1.3.0', '<' ) ) {
224 global $wpdb;
225
226 // Update taxonomy terms for new attribute taxonomy prefix.
227 $wpdb->query( "UPDATE $wpdb->term_taxonomy SET `taxonomy` = REGEXP_REPLACE(`taxonomy`, '^storeengine_pa_', 'se_pa_') WHERE taxonomy LIKE 'storeengine_pa_%'" );
228
229 // Update attribute order data with new attribute taxonomy prefix.
230 $results = $wpdb->get_results( "SELECT meta_id, meta_value FROM $wpdb->postmeta WHERE meta_key = '_storeengine_product_attributes_order' AND meta_value LIKE '%storeengine_pa_%'" );
231
232 foreach ( $results as $meta ) {
233 $meta_value = maybe_unserialize( $meta->meta_value );
234 if ( ! is_array( $meta_value ) ) {
235 $meta_value = json_decode( $meta->meta_value, true );
236 }
237
238 foreach ( $meta_value as $k => $v ) {
239 /** @noinspection RegExpRedundantEscape */
240 $meta_value[ $k ] = Helper::get_attribute_taxonomy_name( preg_replace( '/^storeengine_pa\_/', '', $v ) );
241 }
242
243 $wpdb->update(
244 $wpdb->postmeta,
245 [ 'meta_value' => maybe_serialize( $meta_value ) ],
246 [ 'meta_id' => $meta->meta_id ]
247 );
248 }
249 }
250 }
251
252 public function migrate_1_3_3( $storeengine_version ) {
253 if ( version_compare( $storeengine_version, '1.3.3', '<' ) ) {
254 global $wpdb;
255 wp_cache_flush();
256
257 // Missing migration for PR#803
258 $orders_meta = "{$wpdb->prefix}storeengine_orders_meta";
259 $orders = "{$wpdb->prefix}storeengine_orders";
260 $wpdb->query( "ALTER TABLE $orders_meta DROP INDEX meta_key_value;" );
261 $wpdb->query( "ALTER TABLE $orders_meta ADD INDEX meta_key_value (meta_key(100), meta_value(73));" );
262 $wpdb->query( "ALTER TABLE $orders_meta ADD INDEX order_id_meta_key_meta_value (order_id, meta_key(100), meta_value(73));" );
263 $wpdb->query( "ALTER TABLE $orders DROP INDEX customer_id_billing_email;" );
264 $wpdb->query( "ALTER TABLE $orders ADD INDEX customer_id_billing_email (customer_id, billing_email(171));" );
265 $wpdb->query( "ALTER TABLE $orders DROP INDEX billing_email;" );
266 $wpdb->query( "ALTER TABLE $orders ADD INDEX INDEX billing_email (billing_email(191));" );
267 // End Missing migration for PR#803
268
269 // Alter meta key index length.
270 $wpdb->query( "ALTER TABLE $orders_meta DROP INDEX meta_key_index;" );
271 $wpdb->query( "ALTER TABLE $orders_meta ADD INDEX meta_key_index (meta_key_index(191));" );
272
273 // Add missing product-id index in price & variation table.
274 $wpdb->query( "ALTER TABLE {$wpdb->prefix}storeengine_product_price ADD INDEX product_id (product_id);" );
275 $wpdb->query( "ALTER TABLE {$wpdb->prefix}storeengine_product_variations ADD INDEX product_id (product_id);" );
276
277 // Rename variation_meta variation-id index.
278 $wpdb->query( "ALTER TABLE {$wpdb->prefix}storeengine_product_variation_meta DROP INDEX order_id_index;" );
279 $wpdb->query( "ALTER TABLE {$wpdb->prefix}storeengine_product_variation_meta ADD INDEX variation_id_index (variation_id);" );
280
281 // Update variation_meta index length
282 $wpdb->query( "ALTER TABLE {$wpdb->prefix}storeengine_product_variation_meta DROP INDEX meta_key_index;" );
283 $wpdb->query( "ALTER TABLE {$wpdb->prefix}storeengine_product_variation_meta ADD INDEX meta_key_index (meta_key(191));" );
284 $wpdb->query( "ALTER TABLE {$wpdb->prefix}storeengine_product_variation_meta DROP INDEX meta_value_index;" );
285 $wpdb->query( "ALTER TABLE {$wpdb->prefix}storeengine_product_variation_meta ADD INDEX meta_value_index (meta_value(191));" );
286
287 // Added missing zone_id & method_id key in variation_term_relations
288 $wpdb->query( "ALTER TABLE {$wpdb->prefix}storeengine_shipping_zone_methods ADD INDEX zone_id (zone_id);" );
289 $wpdb->query( "ALTER TABLE {$wpdb->prefix}storeengine_shipping_zone_methods ADD INDEX method_id (method_id);" );
290
291 // Added missing variation_id & term_id key in shipping_zone_methods
292 $wpdb->query( "ALTER TABLE {$wpdb->prefix}storeengine_shipping_zone_methods ADD INDEX term_id (term_id);" );
293 $wpdb->query( "ALTER TABLE {$wpdb->prefix}storeengine_shipping_zone_methods ADD INDEX variation_id (variation_id);" );
294
295 // Change api table last-access into timestamp & add created-at timestamp
296 $wpdb->query( "ALTER TABLE {$wpdb->prefix}storeengine_api_keys MODIFY `last_access` TIMESTAMP NULL DEFAULT NULL, ADD `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP;" );
297 }
298 }
299
300 public function migrate_1_5_0( $storeengine_version ) {
301 if ( version_compare( $storeengine_version, '1.5.0', '<' ) ) {
302 global $wpdb;
303 wp_cache_flush();
304 $wpdb->query( "DELETE FROM $wpdb->usermeta WHERE meta_key = '_storeengine_memberships'" );
305 }
306 }
307
308 public function migrate_1_5_2( $storeengine_version ) {
309 if ( version_compare( $storeengine_version, '1.5.2', '<' ) ) {
310 if ( ! Helper::get_settings( 'product_archive_multi_price_display' ) ) {
311 Settings::save_settings();
312 Base::save_settings( [ 'product_archive_multi_price_display' => 'dropdown' ] );
313 }
314
315 // update email settings
316 $email_settings = get_option( 'storeengine_email_settings' );
317 if ( ! $email_settings ) {
318 return;
319 }
320 $email_settings = json_decode( $email_settings, true );
321 if ( ! is_array( $email_settings ) || isset( $email_settings['new_user_notification'] ) ) {
322 return;
323 }
324
325 $email_settings['new_user_notification'] = StoreEngine\Addons\Email\Admin\Settings::get_settings_default_data()['new_user_notification'];
326 update_option( 'storeengine_email_settings', wp_json_encode( $email_settings ) );
327 }
328 }
329
330 public function migrate_1_5_5( $storeengine_version ) {
331 if ( version_compare( $storeengine_version, '1.5.5', '<' ) ) {
332 global $wpdb;
333 // Migrate old meta-key to new meta-key.
334 $wpdb->query( "UPDATE $wpdb->postmeta SET meta_key = '_storeengine_coupon_customer_usage_limit' WHERE meta_key = '_storeengine_coupon_total_usage_limit';" );
335
336 // Remove unused metadata.
337 $wpdb->delete( "$wpdb->postmeta", [ 'meta_key' => '_storeengine_coupon_is_one_usage_per_user' ] );
338 $wpdb->delete( "$wpdb->postmeta", [ 'meta_key' => '_storeengine_coupon_is_total_usage_limit' ] );
339 $wpdb->delete( "$wpdb->postmeta", [ 'meta_key' => '_storeengine_per_user_coupon_usage_limit' ] );
340 $wpdb->delete( "$wpdb->postmeta", [ 'meta_key' => '_storeengine_coupon_customer_usage_limit_type' ] );
341 }
342 }
343
344 public function migrate_1_8_0( $storeengine_version ) {
345 if ( version_compare( $storeengine_version, '1.8.0', '<' ) ) {
346 global $wpdb;
347 $wpdb->query("DROP TABLE IF EXISTS {$wpdb->prefix}storeengine_log");
348 }
349 }
350
351 /**
352 * Create the storeengine_email_log table that the customer-communication
353 * audit (EmailLogger) writes into. dbDelta is idempotent so re-running on
354 * an existing install is safe; the version gate keeps it from firing on
355 * every page load.
356 */
357 public function migrate_1_10_0( $storeengine_version ) {
358 if ( version_compare( $storeengine_version, '1.10.0', '<' ) ) {
359 global $wpdb;
360 if ( ! function_exists( 'dbDelta' ) ) {
361 require_once ABSPATH . 'wp-admin/includes/upgrade.php';
362 }
363
364 CreateEmailLog::up( $wpdb->prefix, $wpdb->get_charset_collate() );
365 }
366 }
367
368 // phpcs:enable PluginCheck.Security.DirectDB.UnescapedDBParameter, WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.SlowDBQuery.slow_db_query_meta_value, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.SlowDBQuery.slow_db_query_meta_key
369 }
370