230 lines
8.9 KiB
PHP
230 lines
8.9 KiB
PHP
<?php
|
|
// Prevent direct access
|
|
if (!defined('ABSPATH')) {
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* Database migrations for Sodino plugin
|
|
*/
|
|
function sodino_create_tables() {
|
|
global $wpdb;
|
|
|
|
$charset_collate = $wpdb->get_charset_collate();
|
|
$current_version = get_option('sodino_db_version', '0');
|
|
|
|
// Rules table
|
|
$rules_table = $wpdb->prefix . 'sodino_rules';
|
|
$rules_sql = "CREATE TABLE $rules_table (
|
|
id mediumint(9) NOT NULL AUTO_INCREMENT,
|
|
name varchar(255) NOT NULL,
|
|
conditions longtext NOT NULL,
|
|
actions longtext NOT NULL,
|
|
priority int(11) NOT NULL DEFAULT 10,
|
|
usage_limit int(11) NOT NULL DEFAULT 0,
|
|
usage_count int(11) NOT NULL DEFAULT 0,
|
|
user_roles varchar(255) DEFAULT '',
|
|
start_date datetime NULL,
|
|
end_date datetime NULL,
|
|
enabled tinyint(1) DEFAULT 1,
|
|
created_at datetime DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (id),
|
|
KEY enabled_priority (enabled, priority),
|
|
KEY start_end_dates (start_date, end_date)
|
|
) $charset_collate;";
|
|
|
|
// Events table
|
|
$events_table = $wpdb->prefix . 'sodino_events';
|
|
$events_sql = "CREATE TABLE $events_table (
|
|
id bigint(20) NOT NULL AUTO_INCREMENT,
|
|
event_type varchar(100) NOT NULL,
|
|
product_id mediumint(9) DEFAULT NULL,
|
|
variation_id mediumint(9) DEFAULT NULL,
|
|
user_id bigint(20) DEFAULT NULL,
|
|
session_id varchar(255) DEFAULT NULL,
|
|
rule_id mediumint(9) DEFAULT NULL,
|
|
value decimal(10,2) DEFAULT 0,
|
|
discount_value decimal(10,2) DEFAULT 0,
|
|
metadata longtext DEFAULT NULL,
|
|
created_at datetime DEFAULT CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (id),
|
|
KEY event_type_created (event_type, created_at),
|
|
KEY product_id (product_id),
|
|
KEY rule_id (rule_id),
|
|
KEY session_id (session_id),
|
|
KEY created_at (created_at)
|
|
) $charset_collate;";
|
|
|
|
// Upsell table
|
|
$upsell_table = $wpdb->prefix . 'sodino_upsells';
|
|
$upsell_sql = "CREATE TABLE $upsell_table (
|
|
id mediumint(9) NOT NULL AUTO_INCREMENT,
|
|
title varchar(255) NOT NULL,
|
|
trigger_type varchar(50) NOT NULL,
|
|
trigger_value varchar(255) NOT NULL,
|
|
target_product_id bigint(20) NOT NULL DEFAULT 0,
|
|
discount_type varchar(50) DEFAULT 'percentage',
|
|
discount_value decimal(10,2) DEFAULT 0,
|
|
status tinyint(1) DEFAULT 1,
|
|
priority int(11) NOT NULL DEFAULT 10,
|
|
impressions bigint(20) NOT NULL DEFAULT 0,
|
|
conversions bigint(20) NOT NULL DEFAULT 0,
|
|
created_at datetime DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (id),
|
|
KEY status_priority (status, priority),
|
|
KEY trigger_type (trigger_type)
|
|
) $charset_collate;";
|
|
|
|
// Banner table
|
|
$banner_table = $wpdb->prefix . 'sodino_banners';
|
|
$banner_sql = "CREATE TABLE $banner_table (
|
|
id mediumint(9) NOT NULL AUTO_INCREMENT,
|
|
title varchar(255) NOT NULL,
|
|
content_type varchar(50) NOT NULL DEFAULT 'image',
|
|
content_value longtext NOT NULL,
|
|
link_url varchar(255) DEFAULT NULL,
|
|
position varchar(50) NOT NULL DEFAULT 'top',
|
|
display_type varchar(50) NOT NULL DEFAULT 'inline',
|
|
start_time datetime DEFAULT NULL,
|
|
end_time datetime DEFAULT NULL,
|
|
user_target varchar(50) NOT NULL DEFAULT 'all',
|
|
device_target varchar(50) NOT NULL DEFAULT 'all',
|
|
priority int(11) NOT NULL DEFAULT 10,
|
|
status tinyint(1) NOT NULL DEFAULT 1,
|
|
impressions bigint(20) NOT NULL DEFAULT 0,
|
|
clicks bigint(20) NOT NULL DEFAULT 0,
|
|
created_at datetime DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (id),
|
|
KEY status_priority (status, priority),
|
|
KEY position (position),
|
|
KEY start_end_time (start_time, end_time)
|
|
) $charset_collate;";
|
|
|
|
// Analytics cache table
|
|
$analytics_table = $wpdb->prefix . 'sodino_analytics_cache';
|
|
$analytics_sql = "CREATE TABLE $analytics_table (
|
|
id bigint(20) NOT NULL AUTO_INCREMENT,
|
|
cache_key varchar(255) NOT NULL,
|
|
cache_value longtext NOT NULL,
|
|
cache_group varchar(100) NOT NULL DEFAULT 'general',
|
|
expires_at datetime NOT NULL,
|
|
created_at datetime DEFAULT CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (id),
|
|
UNIQUE KEY cache_key_group (cache_key, cache_group),
|
|
KEY expires_at (expires_at)
|
|
) $charset_collate;";
|
|
|
|
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
|
|
dbDelta($rules_sql);
|
|
dbDelta($events_sql);
|
|
dbDelta($upsell_sql);
|
|
dbDelta($banner_sql);
|
|
dbDelta($analytics_sql);
|
|
|
|
// Run migrations
|
|
sodino_run_migrations($current_version);
|
|
|
|
// Add version option
|
|
update_option('sodino_db_version', defined('SODINO_DB_VERSION') ? SODINO_DB_VERSION : '2.0');
|
|
}
|
|
|
|
/**
|
|
* Run incremental migrations
|
|
*/
|
|
function sodino_run_migrations($from_version) {
|
|
global $wpdb;
|
|
|
|
// Migration from 1.x to 2.0
|
|
if (version_compare($from_version, '2.0', '<')) {
|
|
$rules_table = $wpdb->prefix . 'sodino_rules';
|
|
|
|
$has_column = function($table, $column) use ($wpdb) {
|
|
return !empty($wpdb->get_results($wpdb->prepare("SHOW COLUMNS FROM {$table} LIKE %s", $column)));
|
|
};
|
|
$has_index = function($table, $index) use ($wpdb) {
|
|
return !empty($wpdb->get_results($wpdb->prepare("SHOW INDEX FROM {$table} WHERE Key_name = %s", $index)));
|
|
};
|
|
|
|
// Older Sodino versions stored one condition/action in flat columns.
|
|
// Copy that data into the JSON columns before removing the old columns.
|
|
if (
|
|
$has_column($rules_table, 'condition_type')
|
|
&& $has_column($rules_table, 'condition_value')
|
|
&& $has_column($rules_table, 'action_type')
|
|
&& $has_column($rules_table, 'action_value')
|
|
&& $has_column($rules_table, 'conditions')
|
|
&& $has_column($rules_table, 'actions')
|
|
) {
|
|
$legacy_rules = $wpdb->get_results(
|
|
"SELECT id, condition_type, condition_value, action_type, action_value FROM {$rules_table}",
|
|
ARRAY_A
|
|
);
|
|
|
|
foreach ($legacy_rules as $legacy_rule) {
|
|
$wpdb->update(
|
|
$rules_table,
|
|
[
|
|
'conditions' => wp_json_encode([
|
|
[
|
|
'type' => $legacy_rule['condition_type'],
|
|
'value' => $legacy_rule['condition_value'],
|
|
],
|
|
]),
|
|
'actions' => wp_json_encode([
|
|
[
|
|
'type' => $legacy_rule['action_type'],
|
|
'value' => $legacy_rule['action_value'],
|
|
],
|
|
]),
|
|
],
|
|
['id' => (int) $legacy_rule['id']]
|
|
);
|
|
}
|
|
}
|
|
|
|
// Add usage_count column if not exists
|
|
if (!$has_column($rules_table, 'usage_count')) {
|
|
$wpdb->query("ALTER TABLE {$rules_table} ADD COLUMN usage_count int(11) NOT NULL DEFAULT 0 AFTER usage_limit");
|
|
}
|
|
|
|
// Remove deprecated columns
|
|
$deprecated_columns = ['condition_type', 'condition_value', 'action_type', 'action_value'];
|
|
foreach ($deprecated_columns as $col) {
|
|
if ($has_column($rules_table, $col)) {
|
|
$wpdb->query("ALTER TABLE {$rules_table} DROP COLUMN {$col}");
|
|
}
|
|
}
|
|
|
|
// Add indexes for better performance
|
|
if (!$has_index($rules_table, 'enabled_priority')) {
|
|
$wpdb->query("ALTER TABLE {$rules_table} ADD INDEX enabled_priority (enabled, priority)");
|
|
}
|
|
|
|
if (!$has_index($rules_table, 'start_end_dates')) {
|
|
$wpdb->query("ALTER TABLE {$rules_table} ADD INDEX start_end_dates (start_date, end_date)");
|
|
}
|
|
|
|
if ($has_column($rules_table, 'conditions')) {
|
|
$wpdb->query("UPDATE {$rules_table} SET conditions = '[]' WHERE conditions IS NULL OR conditions = ''");
|
|
}
|
|
|
|
if ($has_column($rules_table, 'actions')) {
|
|
$wpdb->query("UPDATE {$rules_table} SET actions = '[]' WHERE actions IS NULL OR actions = ''");
|
|
}
|
|
|
|
$upsell_table = $wpdb->prefix . 'sodino_upsells';
|
|
if ($has_column($upsell_table, 'id')) {
|
|
if (!$has_column($upsell_table, 'impressions')) {
|
|
$wpdb->query("ALTER TABLE {$upsell_table} ADD COLUMN impressions bigint(20) NOT NULL DEFAULT 0 AFTER priority");
|
|
}
|
|
|
|
if (!$has_column($upsell_table, 'conversions')) {
|
|
$wpdb->query("ALTER TABLE {$upsell_table} ADD COLUMN conversions bigint(20) NOT NULL DEFAULT 0 AFTER impressions");
|
|
}
|
|
}
|
|
}
|
|
}
|