PluginProbe
Booktics – Appointment Booking Calendar for Service Businesses / 1.0.28
Booktics – Appointment Booking Calendar for Service Businesses v1.0.28
1.0.29 1.0.28 1.0.27 1.0.26 1.0.25 1.0.24 1.0.23 1.0.22 1.0.21 1.0.20 1.0.19 trunk 1.0.0 1.0.1 1.0.10 1.0.11 1.0.12 1.0.13 1.0.14 1.0.15 1.0.16 1.0.17 1.0.18 1.0.2 1.0.3 All 31 releases
← All changes | base/installer.php +307 -192 1.0.1 → 1.0.28 View file →
@@ -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 +}