diff --git a/app/Controllers/AdminController.php b/app/Controllers/AdminController.php index f753c16..a4d301b 100644 --- a/app/Controllers/AdminController.php +++ b/app/Controllers/AdminController.php @@ -606,6 +606,7 @@ class AdminController { ]; update_option('sodino_settings', $settings); + \Sodino\Core\Cache::getInstance()->clearAll(); $this->redirectWithNotice(add_query_arg('updated', 'true', admin_url('admin.php?page=sodino-settings')), __('تنظیمات با موفقیت ذخیره شد.', 'sodino'), 'success'); } diff --git a/database/migrations.php b/database/migrations.php index 4ba1201..188f8fb 100644 --- a/database/migrations.php +++ b/database/migrations.php @@ -128,7 +128,7 @@ function sodino_create_tables() { sodino_run_migrations($current_version); // Add version option - update_option('sodino_db_version', '2.0'); + update_option('sodino_db_version', defined('SODINO_DB_VERSION') ? SODINO_DB_VERSION : '2.0'); } /** @@ -139,25 +139,80 @@ function sodino_run_migrations($from_version) { // Migration from 1.x to 2.0 if (version_compare($from_version, '2.0', '<')) { - // Add usage_count column if not exists $rules_table = $wpdb->prefix . 'sodino_rules'; - $column_exists = $wpdb->get_results("SHOW COLUMNS FROM {$rules_table} LIKE 'usage_count'"); + + $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']] + ); + } + } - if (empty($column_exists)) { + // 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) { - $col_exists = $wpdb->get_results("SHOW COLUMNS FROM {$rules_table} LIKE '{$col}'"); - if (!empty($col_exists)) { + if ($has_column($rules_table, $col)) { $wpdb->query("ALTER TABLE {$rules_table} DROP COLUMN {$col}"); } } // Add indexes for better performance - $wpdb->query("ALTER TABLE {$rules_table} ADD INDEX enabled_priority (enabled, priority)"); - $wpdb->query("ALTER TABLE {$rules_table} ADD INDEX start_end_dates (start_date, end_date)"); + 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 = ''"); + } } } diff --git a/sodino.php b/sodino.php index d058a1d..cb7808b 100644 --- a/sodino.php +++ b/sodino.php @@ -21,6 +21,7 @@ if (!defined('ABSPATH')) { // Define plugin constants define('SODINO_VERSION', '2.0.0'); +define('SODINO_DB_VERSION', '2.0'); define('SODINO_PLUGIN_DIR', plugin_dir_path(__FILE__)); define('SODINO_PLUGIN_URL', plugin_dir_url(__FILE__)); define('SODINO_PLUGIN_BASENAME', plugin_basename(__FILE__)); @@ -74,6 +75,20 @@ function sodino_activate() { } } +/** + * Run database migrations after code updates, not only on activation. + */ +function sodino_maybe_run_migrations() { + $current_version = get_option('sodino_db_version', '0'); + + if (version_compare($current_version, SODINO_DB_VERSION, '>=')) { + return; + } + + require_once SODINO_PLUGIN_DIR . 'database/migrations.php'; + sodino_create_tables(); +} + // Deactivation hook register_deactivation_hook(__FILE__, 'sodino_deactivate'); function sodino_deactivate() { @@ -99,6 +114,8 @@ function sodino_init() { // Load text domain load_plugin_textdomain('sodino', false, dirname(SODINO_PLUGIN_BASENAME) . '/languages/'); + sodino_maybe_run_migrations(); + // Initialize admin if (is_admin()) { require_once SODINO_PLUGIN_DIR . 'admin/admin.php';