| @@ -1,192 +1,307 @@ | ||
| 1 | -<?php | |
| 2 | - | |
| 3 | -namespace Booktics; | |
| 4 | - | |
| 5 | -use Booktics\Dummy_Data\Dummy_Data_Manager; | |
| 6 | - | |
| 7 | -class Installer { | |
| 8 | - /** | |
| 9 | - * Initializes the Booktics plugin by performing necessary setup tasks. | |
| 10 | - * | |
| 11 | - * This method performs the following setup operations: | |
| 12 | - * - Creates or updates required database tables | |
| 13 | - * - Initializes user roles and capabilities | |
| 14 | - * - Generates initial onboarding data using dummy data manager | |
| 15 | - */ | |
| 16 | - public static function run(): void { | |
| 17 | - self::create_tables(); | |
| 18 | - ( new Role() )->init(); | |
| 19 | - ( new Dummy_Data_Manager() )->generate_onboarding_data(); | |
| 20 | - } | |
| 21 | - | |
| 22 | - /** | |
| 23 | - * Creates and updates database tables required for the Booktics plugin. | |
| 24 | - * | |
| 25 | - * Creates the following tables if they don't exist: | |
| 26 | - * - booktics_schedules: Stores scheduling information for team members and services | |
| 27 | - * - booktics_carts: Stores shopping cart information | |
| 28 | - * - booktics_cart_items: Stores individual items in shopping carts | |
| 29 | - * - booktics_orders: Stores order information and payment details | |
| 30 | - * - booktics_payments: Stores payment transaction records | |
| 31 | - * | |
| 32 | - * Also handles table structure updates by adding missing columns to existing tables | |
| 33 | - * and performing necessary column modifications. | |
| 34 | - */ | |
| 35 | - private static function create_tables(): void { | |
| 36 | - require_once ABSPATH . 'wp-admin/includes/upgrade.php'; | |
| 37 | - | |
| 38 | - global $wpdb; | |
| 39 | - $charset_collate = $wpdb->get_charset_collate(); | |
| 40 | - | |
| 41 | - $table_schema = array( | |
| 42 | - "CREATE TABLE IF NOT EXISTS {$wpdb->prefix}booktics_schedules ( | |
| 43 | - id mediumint(9) NOT NULL AUTO_INCREMENT, | |
| 44 | - team_member_id int(11) NOT NULL, | |
| 45 | - service_id int(11) NOT NULL, | |
| 46 | - location_id int(11) NOT NULL, | |
| 47 | - start_time varchar(100) NOT NULL, | |
| 48 | - end_time varchar(100) NOT NULL, | |
| 49 | - week_day varchar(100) NOT NULL, | |
| 50 | - custom_date varchar(100) NOT NULL, | |
| 51 | - created_at datetime DEFAULT NULL, | |
| 52 | - updated_at datetime DEFAULT NULL, | |
| 53 | - PRIMARY KEY (id) | |
| 54 | - ) $charset_collate;", | |
| 55 | - | |
| 56 | - "CREATE TABLE IF NOT EXISTS {$wpdb->prefix}booktics_carts ( | |
| 57 | - id mediumint(9) NOT NULL AUTO_INCREMENT, | |
| 58 | - uuid varchar(36) NOT NULL, | |
| 59 | - user_id int(11) NOT NULL, | |
| 60 | - coupon_code varchar(100) DEFAULT NULL, | |
| 61 | - total decimal(10,2) DEFAULT NULL, | |
| 62 | - created_at datetime DEFAULT NULL, | |
| 63 | - updated_at datetime DEFAULT NULL, | |
| 64 | - PRIMARY KEY (id) | |
| 65 | - ) $charset_collate;", | |
| 66 | - | |
| 67 | - "CREATE TABLE IF NOT EXISTS {$wpdb->prefix}booktics_cart_items ( | |
| 68 | - id mediumint(9) NOT NULL AUTO_INCREMENT, | |
| 69 | - uuid varchar(36) NOT NULL, | |
| 70 | - cart_id mediumint(9) NOT NULL, | |
| 71 | - team_member_id int(11) DEFAULT NULL, | |
| 72 | - service_id int(11) DEFAULT NULL, | |
| 73 | - date date DEFAULT NULL, | |
| 74 | - start_time varchar(100) DEFAULT NULL, | |
| 75 | - end_time varchar(100) DEFAULT NULL, | |
| 76 | - price VARCHAR(100) DEFAULT NULL, | |
| 77 | - created_at datetime DEFAULT NULL, | |
| 78 | - updated_at datetime DEFAULT NULL, | |
| 79 | - PRIMARY KEY (id) | |
| 80 | - ) $charset_collate;", | |
| 81 | - | |
| 82 | - "CREATE TABLE IF NOT EXISTS {$wpdb->prefix}booktics_orders ( | |
| 83 | - id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, | |
| 84 | - order_no VARCHAR(100) NOT NULL, | |
| 85 | - customer_id BIGINT UNSIGNED NOT NULL, | |
| 86 | - customer_note VARCHAR(100) DEFAULT NULL, | |
| 87 | - status VARCHAR(50) DEFAULT 'pending', | |
| 88 | - payment_status VARCHAR(50) DEFAULT NULL, | |
| 89 | - timezone VARCHAR(50) DEFAULT 'UTC', | |
| 90 | - price_breakdown JSON DEFAULT NULL, | |
| 91 | - tax_total VARCHAR(100) DEFAULT NULL, | |
| 92 | - coupon_code VARCHAR(100) DEFAULT NULL, | |
| 93 | - coupon_discount VARCHAR(100) DEFAULT NULL, | |
| 94 | - subtotal VARCHAR(100) DEFAULT 0, | |
| 95 | - total VARCHAR(100) DEFAULT 0, | |
| 96 | - payment_method VARCHAR(50) DEFAULT NULL, | |
| 97 | - payment_intent_id VARCHAR(250) DEFAULT NULL, | |
| 98 | - payment_transaction_id VARCHAR(250) DEFAULT NULL, | |
| 99 | - created_at DATETIME DEFAULT CURRENT_TIMESTAMP, | |
| 100 | - updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, | |
| 101 | - PRIMARY KEY (id), | |
| 102 | - INDEX (order_no) | |
| 103 | - ) $charset_collate;", | |
| 104 | - | |
| 105 | - "CREATE TABLE IF NOT EXISTS {$wpdb->prefix}booktics_payments ( | |
| 106 | - id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, | |
| 107 | - order_id BIGINT UNSIGNED NOT NULL, | |
| 108 | - customer_id BIGINT UNSIGNED NOT NULL, | |
| 109 | - amount VARCHAR(20) NOT NULL, | |
| 110 | - currency VARCHAR(10) DEFAULT 'usd', | |
| 111 | - intent_id VARCHAR(255), | |
| 112 | - transaction_id VARCHAR(255), | |
| 113 | - status varchar(100) NOT NULL DEFAULT 'pending', | |
| 114 | - payment_method VARCHAR(50) NOT NULL, | |
| 115 | - refunded_amount VARCHAR(20) DEFAULT '0.00', | |
| 116 | - failure_reason TEXT, | |
| 117 | - date DATE NOT NULL, | |
| 118 | - date_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
| 119 | - INDEX (order_id), | |
| 120 | - INDEX (customer_id), | |
| 121 | - INDEX (intent_id), | |
| 122 | - INDEX (transaction_id) | |
| 123 | - ) $charset_collate;", | |
| 124 | - ); | |
| 125 | - | |
| 126 | - foreach ( $table_schema as $table_sql ) { | |
| 127 | - dbDelta( $table_sql ); | |
| 128 | - } | |
| 129 | - | |
| 130 | - // Add missing columns to booktics_orders table | |
| 131 | - $orders_table = "{$wpdb->prefix}booktics_orders"; | |
| 132 | - $orders_columns = $wpdb->get_col( 'DESC `' . esc_sql( $orders_table ) . '`', 0 ); | |
| 133 | - | |
| 134 | - $orders_columns_to_add = array( | |
| 135 | - 'payment_method' => 'VARCHAR(50) DEFAULT NULL', | |
| 136 | - 'payment_intent_id' => 'VARCHAR(250) DEFAULT NULL', | |
| 137 | - 'payment_transaction_id' => 'VARCHAR(250) DEFAULT NULL', | |
| 138 | - ); | |
| 139 | - | |
| 140 | - foreach ( $orders_columns_to_add as $column => $definition ) { | |
| 141 | - if ( ! in_array( $column, $orders_columns, true ) ) { | |
| 142 | - $query = sprintf( | |
| 143 | - 'ALTER TABLE `%s` ADD COLUMN `%s` %s', | |
| 144 | - esc_sql( $orders_table ), | |
| 145 | - esc_sql( $column ), | |
| 146 | - $definition | |
| 147 | - ); | |
| 148 | - $wpdb->query( $query ); | |
| 149 | - } | |
| 150 | - } | |
| 151 | - | |
| 152 | - // Handle booktics_cart_items table | |
| 153 | - $cart_items_table = "{$wpdb->prefix}booktics_cart_items"; | |
| 154 | - $cart_items_columns = $wpdb->get_col( 'DESC `' . esc_sql( $cart_items_table ) . '`', 0 ); | |
| 155 | - | |
| 156 | - // Rename sub_total to subtotal if exists | |
| 157 | - if ( in_array( 'sub_total', $cart_items_columns, true ) ) { | |
| 158 | - $wpdb->query( | |
| 159 | - sprintf( | |
| 160 | - 'ALTER TABLE `%s` CHANGE COLUMN `sub_total` `subtotal` VARCHAR(20) NOT NULL', | |
| 161 | - esc_sql( $cart_items_table ) | |
| 162 | - ) | |
| 163 | - ); | |
| 164 | - } elseif ( ! in_array( 'subtotal', $cart_items_columns, true ) ) { | |
| 165 | - $wpdb->query( | |
| 166 | - sprintf( | |
| 167 | - 'ALTER TABLE `%s` ADD COLUMN `subtotal` VARCHAR(20) NOT NULL', | |
| 168 | - esc_sql( $cart_items_table ) | |
| 169 | - ) | |
| 170 | - ); | |
| 171 | - } | |
| 172 | - | |
| 173 | - $cart_items_columns_to_add = array( | |
| 174 | - 'extra_services' => 'TEXT DEFAULT NULL', | |
| 175 | - 'total' => 'VARCHAR(20) NOT NULL', | |
| 176 | - 'additional_duration_id' => 'VARCHAR(100) NOT NULL', | |
| 177 | - 'group_booking' => 'TEXT DEFAULT NULL', | |
| 178 | - ); | |
| 179 | - | |
| 180 | - foreach ( $cart_items_columns_to_add as $column => $definition ) { | |
| 181 | - if ( ! in_array( $column, $cart_items_columns, true ) ) { | |
| 182 | - $query = sprintf( | |
| 183 | - 'ALTER TABLE `%s` ADD COLUMN `%s` %s', | |
| 184 | - esc_sql( $cart_items_table ), | |
| 185 | - esc_sql( $column ), | |
| 186 | - $definition | |
| 187 | - ); | |
| 188 | - $wpdb->query( $query ); | |
| 189 | - } | |
| 190 | - } | |
| 191 | - } | |
| 192 | -} | |
| 1 | +<?php | |
| 2 | + | |
| 3 | +namespace Booktics; | |
| 4 | + | |
| 5 | +if ( ! defined( 'ABSPATH' ) ) { | |
| 6 | + exit; | |
| 7 | +} | |
| 8 | + | |
| 9 | +use Booktics\Dummy_Data\Dummy_Data_Manager; | |
| 10 | + | |
| 11 | +class Installer { | |
| 12 | + /** | |
| 13 | + * Initializes the Booktics plugin by performing necessary setup tasks. | |
| 14 | + * | |
| 15 | + * This method performs the following setup operations: | |
| 16 | + * - Creates or updates required database tables | |
| 17 | + * - Initializes user roles and capabilities | |
| 18 | + * - Generates initial onboarding data using dummy data manager | |
| 19 | + */ | |
| 20 | + public static function run(): void { | |
| 21 | + self::create_tables(); | |
| 22 | + ( new Role() )->init(); | |
| 23 | + ( new Dummy_Data_Manager() )->generate_onboarding_data(); | |
| 24 | + } | |
| 25 | + | |
| 26 | + /** | |
| 27 | + * Creates and updates database tables required for the Booktics plugin. | |
| 28 | + * | |
| 29 | + * Creates the following tables if they don't exist: | |
| 30 | + * - booktics_schedules: Stores scheduling information for team members and services | |
| 31 | + * - booktics_carts: Stores shopping cart information | |
| 32 | + * - booktics_cart_items: Stores individual items in shopping carts | |
| 33 | + * - booktics_orders: Stores order information and payment details | |
| 34 | + * - booktics_payments: Stores payment transaction records | |
| 35 | + * | |
| 36 | + * Also handles table structure updates by adding missing columns to existing tables | |
| 37 | + * and performing necessary column modifications. | |
| 38 | + */ | |
| 39 | + public static function create_tables(): void { | |
| 40 | + require_once ABSPATH . 'wp-admin/includes/upgrade.php'; | |
| 41 | + | |
| 42 | + global $wpdb; | |
| 43 | + $charset_collate = $wpdb->get_charset_collate(); | |
| 44 | + | |
| 45 | + $table_prefix = $wpdb->prefix; | |
| 46 | + $table_schema = array( | |
| 47 | + "CREATE TABLE IF NOT EXISTS {$table_prefix}booktics_schedules ( | |
| 48 | + id mediumint(9) NOT NULL AUTO_INCREMENT, | |
| 49 | + team_member_id int(11) NOT NULL, | |
| 50 | + service_id int(11) NOT NULL, | |
| 51 | + location_id int(11) NOT NULL, | |
| 52 | + start_time varchar(100) NOT NULL, | |
| 53 | + end_time varchar(100) NOT NULL, | |
| 54 | + week_day varchar(100) NOT NULL, | |
| 55 | + custom_date varchar(100) NOT NULL, | |
| 56 | + created_at datetime DEFAULT NULL, | |
| 57 | + updated_at datetime DEFAULT NULL, | |
| 58 | + PRIMARY KEY (id) | |
| 59 | + ) $charset_collate;", | |
| 60 | + | |
| 61 | + "CREATE TABLE IF NOT EXISTS {$table_prefix}booktics_carts ( | |
| 62 | + id mediumint(9) NOT NULL AUTO_INCREMENT, | |
| 63 | + uuid varchar(36) NOT NULL, | |
| 64 | + user_id int(11) NOT NULL, | |
| 65 | + coupon_code varchar(100) DEFAULT NULL, | |
| 66 | + total decimal(10,2) DEFAULT NULL, | |
| 67 | + created_at datetime DEFAULT NULL, | |
| 68 | + updated_at datetime DEFAULT NULL, | |
| 69 | + PRIMARY KEY (id) | |
| 70 | + ) $charset_collate;", | |
| 71 | + | |
| 72 | + "CREATE TABLE IF NOT EXISTS {$table_prefix}booktics_cart_items ( | |
| 73 | + id mediumint(9) NOT NULL AUTO_INCREMENT, | |
| 74 | + uuid varchar(36) NOT NULL, | |
| 75 | + cart_id mediumint(9) NOT NULL, | |
| 76 | + team_member_id int(11) DEFAULT NULL, | |
| 77 | + service_id int(11) DEFAULT NULL, | |
| 78 | + location_id int(11) DEFAULT NULL, | |
| 79 | + date date DEFAULT NULL, | |
| 80 | + start_time varchar(100) DEFAULT NULL, | |
| 81 | + end_time varchar(100) DEFAULT NULL, | |
| 82 | + price VARCHAR(100) DEFAULT NULL, | |
| 83 | + created_at datetime DEFAULT NULL, | |
| 84 | + updated_at datetime DEFAULT NULL, | |
| 85 | + PRIMARY KEY (id) | |
| 86 | + ) $charset_collate;", | |
| 87 | + | |
| 88 | + "CREATE TABLE IF NOT EXISTS {$table_prefix}booktics_orders ( | |
| 89 | + id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, | |
| 90 | + order_no VARCHAR(100) NOT NULL, | |
| 91 | + customer_id BIGINT UNSIGNED NOT NULL, | |
| 92 | + customer_note VARCHAR(100) DEFAULT NULL, | |
| 93 | + status VARCHAR(50) DEFAULT 'pending', | |
| 94 | + payment_status VARCHAR(50) DEFAULT NULL, | |
| 95 | + timezone VARCHAR(50) DEFAULT 'UTC', | |
| 96 | + currency VARCHAR(10) DEFAULT NULL, | |
| 97 | + price_breakdown JSON DEFAULT NULL, | |
| 98 | + tax_total VARCHAR(100) DEFAULT NULL, | |
| 99 | + coupon_code VARCHAR(100) DEFAULT NULL, | |
| 100 | + coupon_discount VARCHAR(100) DEFAULT NULL, | |
| 101 | + subtotal VARCHAR(100) DEFAULT 0, | |
| 102 | + total VARCHAR(100) DEFAULT 0, | |
| 103 | + payment_method VARCHAR(50) DEFAULT NULL, | |
| 104 | + payment_intent_id VARCHAR(250) DEFAULT NULL, | |
| 105 | + payment_transaction_id VARCHAR(250) DEFAULT NULL, | |
| 106 | + directorist_id BIGINT UNSIGNED DEFAULT NULL, | |
| 107 | + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, | |
| 108 | + updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, | |
| 109 | + PRIMARY KEY (id), | |
| 110 | + INDEX (order_no), | |
| 111 | + INDEX (directorist_id) | |
| 112 | + ) $charset_collate;", | |
| 113 | + | |
| 114 | + "CREATE TABLE IF NOT EXISTS {$table_prefix}booktics_payments ( | |
| 115 | + id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, | |
| 116 | + order_id BIGINT UNSIGNED NOT NULL, | |
| 117 | + customer_id BIGINT UNSIGNED NOT NULL, | |
| 118 | + amount VARCHAR(20) NOT NULL, | |
| 119 | + currency VARCHAR(10) DEFAULT 'usd', | |
| 120 | + intent_id VARCHAR(255), | |
| 121 | + transaction_id VARCHAR(255), | |
| 122 | + status varchar(100) NOT NULL DEFAULT 'pending', | |
| 123 | + payment_method VARCHAR(50) NOT NULL, | |
| 124 | + refunded_amount VARCHAR(20) DEFAULT '0.00', | |
| 125 | + failure_reason TEXT, | |
| 126 | + date DATE NOT NULL, | |
| 127 | + date_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
| 128 | + INDEX (order_id), | |
| 129 | + INDEX (customer_id), | |
| 130 | + INDEX (intent_id), | |
| 131 | + INDEX (transaction_id) | |
| 132 | + ) $charset_collate;", | |
| 133 | + | |
| 134 | + "CREATE TABLE IF NOT EXISTS {$table_prefix}booktics_guests ( | |
| 135 | + id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, | |
| 136 | + wp_user_id BIGINT UNSIGNED DEFAULT NULL, | |
| 137 | + first_name VARCHAR(100) DEFAULT NULL, | |
| 138 | + last_name VARCHAR(100) DEFAULT NULL, | |
| 139 | + user_login VARCHAR(100) DEFAULT NULL, | |
| 140 | + email VARCHAR(100) DEFAULT NULL, | |
| 141 | + phone VARCHAR(10) DEFAULT NULL, | |
| 142 | + description VARCHAR(250) DEFAULT NULL, | |
| 143 | + image VARCHAR(250) DEFAULT NULL, | |
| 144 | + status INT DEFAULT 0, | |
| 145 | + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, | |
| 146 | + updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, | |
| 147 | + INDEX (wp_user_id), | |
| 148 | + INDEX (email), | |
| 149 | + INDEX (first_name) | |
| 150 | + ) $charset_collate;", | |
| 151 | + ); | |
| 152 | + foreach ( $table_schema as $table_sql ) { | |
| 153 | + dbDelta( $table_sql ); | |
| 154 | + } | |
| 155 | + | |
| 156 | + // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.PreparedSQL.NotPrepared -- Schema migration; direct DB access required, caching inappropriate for DDL, identifiers sanitized via esc_sql(). | |
| 157 | + | |
| 158 | + // Add currency column to existing orders table if it doesn't exist | |
| 159 | + $orders_table = "{$table_prefix}booktics_orders"; | |
| 160 | + $column_exists = $wpdb->get_results( | |
| 161 | + "SHOW COLUMNS FROM `" . \esc_sql( $orders_table ) . "` LIKE 'currency'" | |
| 162 | + ); | |
| 163 | + if ( empty( $column_exists ) ) { | |
| 164 | + $wpdb->query( | |
| 165 | + "ALTER TABLE `" . \esc_sql( $orders_table ) . "` ADD COLUMN currency VARCHAR(10) DEFAULT NULL AFTER timezone" | |
| 166 | + ); | |
| 167 | + } | |
| 168 | + | |
| 169 | + // Handle booktics_guests table | |
| 170 | + $guests_table = "{$table_prefix}booktics_guests"; | |
| 171 | + $guests_columns = $wpdb->get_col( 'DESC `' . \esc_sql( $guests_table ) . '`', 0 ); | |
| 172 | + | |
| 173 | + // Drop index on first_name if it exists | |
| 174 | + $indexes = $wpdb->get_results( "SHOW INDEX FROM `" . \esc_sql( $guests_table ) . "` WHERE Key_name = 'first_name'", ARRAY_A ); | |
| 175 | + if ( ! empty( $indexes ) ) { | |
| 176 | + $wpdb->query( | |
| 177 | + sprintf( | |
| 178 | + 'ALTER TABLE `%s` DROP INDEX `first_name`', | |
| 179 | + \esc_sql( $guests_table ) | |
| 180 | + ) | |
| 181 | + ); | |
| 182 | + } | |
| 183 | + | |
| 184 | + // Rename first_name to name if first_name exists and name does not | |
| 185 | + if ( in_array( 'first_name', $guests_columns, true ) && ! in_array( 'name', $guests_columns, true ) ) { | |
| 186 | + $wpdb->query( | |
| 187 | + sprintf( | |
| 188 | + 'ALTER TABLE `%s` CHANGE COLUMN `first_name` `name` VARCHAR(100) DEFAULT NULL', | |
| 189 | + \esc_sql( $guests_table ) | |
| 190 | + ) | |
| 191 | + ); | |
| 192 | + } | |
| 193 | + | |
| 194 | + // Remove last_name column if it exists | |
| 195 | + if ( in_array( 'last_name', $guests_columns, true ) ) { | |
| 196 | + $wpdb->query( | |
| 197 | + sprintf( | |
| 198 | + 'ALTER TABLE `%s` DROP COLUMN `last_name`', | |
| 199 | + \esc_sql( $guests_table ) | |
| 200 | + ) | |
| 201 | + ); | |
| 202 | + } | |
| 203 | + | |
| 204 | + // Add index on name if it does not exist | |
| 205 | + $indexes_name = $wpdb->get_results( "SHOW INDEX FROM `" . \esc_sql( $guests_table ) . "` WHERE Key_name = 'name'", ARRAY_A ); | |
| 206 | + if ( empty( $indexes_name ) && in_array( 'name', $guests_columns, true ) ) { | |
| 207 | + $wpdb->query( | |
| 208 | + sprintf( | |
| 209 | + 'ALTER TABLE `%s` ADD INDEX (`name`)', | |
| 210 | + \esc_sql( $guests_table ) | |
| 211 | + ) | |
| 212 | + ); | |
| 213 | + } | |
| 214 | + | |
| 215 | + // Alter first_name column if it exists | |
| 216 | + if ( in_array( 'first_name', $guests_columns, true ) ) { | |
| 217 | + $wpdb->query( | |
| 218 | + sprintf( | |
| 219 | + 'ALTER TABLE `%s` MODIFY COLUMN `first_name` VARCHAR(100) DEFAULT NULL', | |
| 220 | + \esc_sql( $guests_table ) | |
| 221 | + ) | |
| 222 | + ); | |
| 223 | + } | |
| 224 | + | |
| 225 | + // Add missing columns to booktics_orders table | |
| 226 | + $orders_table = "{$table_prefix}booktics_orders"; | |
| 227 | + $orders_columns = $wpdb->get_col( 'DESC `' . esc_sql( $orders_table ) . '`', 0 ); | |
| 228 | + | |
| 229 | + $orders_columns_to_add = array( | |
| 230 | + 'payment_method' => 'VARCHAR(50) DEFAULT NULL', | |
| 231 | + 'payment_intent_id' => 'VARCHAR(250) DEFAULT NULL', | |
| 232 | + 'payment_transaction_id' => 'VARCHAR(250) DEFAULT NULL', | |
| 233 | + 'custom_fields' => 'TEXT DEFAULT NULL', | |
| 234 | + 'directorist_id' => 'BIGINT UNSIGNED DEFAULT NULL', | |
| 235 | + ); | |
| 236 | + | |
| 237 | + foreach ( $orders_columns_to_add as $column => $definition ) { | |
| 238 | + if ( ! in_array( $column, $orders_columns, true ) ) { | |
| 239 | + // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.PreparedSQL.NotPrepared -- Schema migration; identifiers sanitized via esc_sql(). | |
| 240 | + $wpdb->query( | |
| 241 | + sprintf( | |
| 242 | + 'ALTER TABLE `%s` ADD COLUMN `%s` %s', | |
| 243 | + esc_sql( $orders_table ), | |
| 244 | + esc_sql( $column ), | |
| 245 | + $definition | |
| 246 | + ) | |
| 247 | + ); | |
| 248 | + } | |
| 249 | + } | |
| 250 | + | |
| 251 | + // Add index for directorist_id if it doesn't exist | |
| 252 | + $indexes = $wpdb->get_results( "SHOW INDEX FROM `" . esc_sql( $orders_table ) . "` WHERE Key_name = 'directorist_id'", ARRAY_A ); | |
| 253 | + if ( empty( $indexes ) && in_array( 'directorist_id', $orders_columns, true ) ) { | |
| 254 | + $wpdb->query( | |
| 255 | + sprintf( | |
| 256 | + 'ALTER TABLE `%s` ADD INDEX (`directorist_id`)', | |
| 257 | + esc_sql( $orders_table ) | |
| 258 | + ) | |
| 259 | + ); | |
| 260 | + } | |
| 261 | + | |
| 262 | + // Handle booktics_cart_items table | |
| 263 | + $cart_items_table = "{$table_prefix}booktics_cart_items"; | |
| 264 | + $cart_items_columns = $wpdb->get_col( 'DESC `' . esc_sql( $cart_items_table ) . '`', 0 ); | |
| 265 | + | |
| 266 | + // Rename sub_total to subtotal if exists | |
| 267 | + if ( in_array( 'sub_total', $cart_items_columns, true ) ) { | |
| 268 | + $wpdb->query( | |
| 269 | + sprintf( | |
| 270 | + 'ALTER TABLE `%s` CHANGE COLUMN `sub_total` `subtotal` VARCHAR(20) NOT NULL', | |
| 271 | + esc_sql( $cart_items_table ) | |
| 272 | + ) | |
| 273 | + ); | |
| 274 | + } elseif ( ! in_array( 'subtotal', $cart_items_columns, true ) ) { | |
| 275 | + $wpdb->query( | |
| 276 | + sprintf( | |
| 277 | + 'ALTER TABLE `%s` ADD COLUMN `subtotal` VARCHAR(20) NOT NULL', | |
| 278 | + esc_sql( $cart_items_table ) | |
| 279 | + ) | |
| 280 | + ); | |
| 281 | + } | |
| 282 | + | |
| 283 | + $cart_items_columns_to_add = array( | |
| 284 | + 'extra_services' => 'TEXT DEFAULT NULL', | |
| 285 | + 'total' => 'VARCHAR(20) NOT NULL', | |
| 286 | + 'additional_duration_id' => 'VARCHAR(100) NOT NULL', | |
| 287 | + 'group_booking' => 'TEXT DEFAULT NULL', | |
| 288 | + 'time_format' => 'VARCHAR(10) DEFAULT NULL', | |
| 289 | + ); | |
| 290 | + | |
| 291 | + foreach ( $cart_items_columns_to_add as $column => $definition ) { | |
| 292 | + if ( ! in_array( $column, $cart_items_columns, true ) ) { | |
| 293 | + // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.PreparedSQL.NotPrepared -- Schema migration; identifiers sanitized via esc_sql(). | |
| 294 | + $wpdb->query( | |
| 295 | + sprintf( | |
| 296 | + 'ALTER TABLE `%s` ADD COLUMN `%s` %s', | |
| 297 | + esc_sql( $cart_items_table ), | |
| 298 | + esc_sql( $column ), | |
| 299 | + $definition | |
| 300 | + ) | |
| 301 | + ); | |
| 302 | + } | |
| 303 | + } | |
| 304 | + | |
| 305 | + // phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.PreparedSQL.NotPrepared | |
| 306 | + } | |
| 307 | +} | |