| 1 |
<?php |
| 2 |
|
| 3 |
namespace UltimateStoreKit; |
| 4 |
|
| 5 |
if (! defined('ABSPATH')) { |
| 6 |
exit; // Exit if accessed directly |
| 7 |
} |
| 8 |
|
| 9 |
// phpcs:disable WordPress.NamingConventions.PrefixAllGlobals -- BDTUSK_ / ultimate_store_kit_ / ultimate-store-kit- are this plugin's established public prefixes. |
| 10 |
|
| 11 |
use Elementor\Plugin; |
| 12 |
|
| 13 |
final class usk_Modal { |
| 14 |
|
| 15 |
/** |
| 16 |
* Quick-view modal Kit control ids that were unprefixed before 3.1.2. |
| 17 |
* |
| 18 |
* Elementor Kit controls all live in one flat namespace shared with every |
| 19 |
* other plugin that registers a Kit tab, so ids like "modal_width" and |
| 20 |
* "button_text" were collision-prone. They are now prefixed. The values are |
| 21 |
* stored user data, so the old ids are still recognised: read falls back to |
| 22 |
* the legacy id, and migrate_legacy_kit_settings() rewrites the stored keys |
| 23 |
* once so Elementor keeps generating the Kit CSS for the style controls. |
| 24 |
* |
| 25 |
* @var string[] legacy id => current id |
| 26 |
*/ |
| 27 |
const LEGACY_KIT_SETTING_IDS = [ |
| 28 |
'modal_layout' => 'ultimate_store_kit_modal_layout', |
| 29 |
'modal_width' => 'ultimate_store_kit_modal_width', |
| 30 |
'modal_height' => 'ultimate_store_kit_modal_height', |
| 31 |
'modal_animation' => 'ultimate_store_kit_modal_animation', |
| 32 |
'close_btn_heading' => 'ultimate_store_kit_modal_close_btn_heading', |
| 33 |
'show_close_btn' => 'ultimate_store_kit_modal_show_close_btn', |
| 34 |
'button_style' => 'ultimate_store_kit_modal_button_style', |
| 35 |
'button_text' => 'ultimate_store_kit_modal_button_text', |
| 36 |
'btn_place' => 'ultimate_store_kit_modal_btn_place', |
| 37 |
'modal_background' => 'ultimate_store_kit_modal_background', |
| 38 |
'modal_overlay' => 'ultimate_store_kit_modal_overlay', |
| 39 |
'modal_close_btn' => 'ultimate_store_kit_modal_close_btn', |
| 40 |
'close_btn_normal' => 'ultimate_store_kit_modal_close_btn_normal', |
| 41 |
'modal_close_btn_color' => 'ultimate_store_kit_modal_close_btn_color', |
| 42 |
'modal_close_btn_bg_color' => 'ultimate_store_kit_modal_close_btn_bg_color', |
| 43 |
'close_btn_hover' => 'ultimate_store_kit_modal_close_btn_hover', |
| 44 |
'modal_close_btn_hover_color' => 'ultimate_store_kit_modal_close_btn_hover_color', |
| 45 |
'modal_close_btn_hover_bg_color' => 'ultimate_store_kit_modal_close_btn_hover_bg_color', |
| 46 |
'modal_close_btn_tabs' => 'ultimate_store_kit_modal_close_btn_tabs', |
| 47 |
'modal_heading_title' => 'ultimate_store_kit_modal_heading_title', |
| 48 |
'title_tab_normal' => 'ultimate_store_kit_modal_title_tab_normal', |
| 49 |
'modal_title_color' => 'ultimate_store_kit_modal_title_color', |
| 50 |
'title_tab_hover' => 'ultimate_store_kit_modal_title_tab_hover', |
| 51 |
'modal_title_hover_color' => 'ultimate_store_kit_modal_title_hover_color', |
| 52 |
'modal_title_tabs' => 'ultimate_store_kit_modal_title_tabs', |
| 53 |
'modal_title_typography' => 'ultimate_store_kit_modal_title_typography', |
| 54 |
'modal_rating_star' => 'ultimate_store_kit_modal_rating_star', |
| 55 |
'modal_rating_normal' => 'ultimate_store_kit_modal_rating_normal', |
| 56 |
'rating_color' => 'ultimate_store_kit_modal_rating_color', |
| 57 |
'modal_rating_active' => 'ultimate_store_kit_modal_rating_active', |
| 58 |
'active_rating_color' => 'ultimate_store_kit_modal_active_rating_color', |
| 59 |
'modal_rating_tabs' => 'ultimate_store_kit_modal_rating_tabs', |
| 60 |
'modal_sale_price_heading' => 'ultimate_store_kit_modal_sale_price_heading', |
| 61 |
'price_regular_tab' => 'ultimate_store_kit_modal_price_regular_tab', |
| 62 |
'regular_price_color' => 'ultimate_store_kit_modal_regular_price_color', |
| 63 |
'price_sale_tab' => 'ultimate_store_kit_modal_price_sale_tab', |
| 64 |
'sale_price_color' => 'ultimate_store_kit_modal_sale_price_color', |
| 65 |
'sale_price_typography' => 'ultimate_store_kit_modal_sale_price_typography', |
| 66 |
'modal_price_tabs' => 'ultimate_store_kit_modal_price_tabs', |
| 67 |
'modal_heading_desc' => 'ultimate_store_kit_modal_heading_desc', |
| 68 |
'modal_desc_color' => 'ultimate_store_kit_modal_desc_color', |
| 69 |
'modal_desc_typography' => 'ultimate_store_kit_modal_desc_typography', |
| 70 |
'modal_heading_btn' => 'ultimate_store_kit_modal_heading_btn', |
| 71 |
'modal_tab_normal' => 'ultimate_store_kit_modal_tab_normal', |
| 72 |
'modal_btn_color' => 'ultimate_store_kit_modal_btn_color', |
| 73 |
'modal_btn_bg_color' => 'ultimate_store_kit_modal_btn_bg_color', |
| 74 |
'modal_btn_tab_hover' => 'ultimate_store_kit_modal_btn_tab_hover', |
| 75 |
'modal_btn_hover_color' => 'ultimate_store_kit_modal_btn_hover_color', |
| 76 |
'modal_btn_hover_bg_color' => 'ultimate_store_kit_modal_btn_hover_bg_color', |
| 77 |
'modal_btn_tabs' => 'ultimate_store_kit_modal_btn_tabs', |
| 78 |
'modal_heading_stock' => 'ultimate_store_kit_modal_heading_stock', |
| 79 |
'modal_stock_color' => 'ultimate_store_kit_modal_stock_color', |
| 80 |
'modal_stock_typography' => 'ultimate_store_kit_modal_stock_typography', |
| 81 |
'modal_heading_sku' => 'ultimate_store_kit_modal_heading_sku', |
| 82 |
'sku_tab_label' => 'ultimate_store_kit_modal_sku_tab_label', |
| 83 |
'modal_sku_label_color' => 'ultimate_store_kit_modal_sku_label_color', |
| 84 |
'modal_sku_label_typography' => 'ultimate_store_kit_modal_sku_label_typography', |
| 85 |
'sku_tab_value' => 'ultimate_store_kit_modal_sku_tab_value', |
| 86 |
'modal_sku_color' => 'ultimate_store_kit_modal_sku_color', |
| 87 |
'modal_sku_typography' => 'ultimate_store_kit_modal_sku_typography', |
| 88 |
'modal_sku_tabs' => 'ultimate_store_kit_modal_sku_tabs', |
| 89 |
'modal_heading_category' => 'ultimate_store_kit_modal_heading_category', |
| 90 |
'category_tab_label' => 'ultimate_store_kit_modal_category_tab_label', |
| 91 |
'modal_category_label_color' => 'ultimate_store_kit_modal_category_label_color', |
| 92 |
'modal_category_label_typography' => 'ultimate_store_kit_modal_category_label_typography', |
| 93 |
'category_tab_value' => 'ultimate_store_kit_modal_category_tab_value', |
| 94 |
'modal_category_color' => 'ultimate_store_kit_modal_category_color', |
| 95 |
'modal_category_typography' => 'ultimate_store_kit_modal_category_typography', |
| 96 |
'modal_category_tabs' => 'ultimate_store_kit_modal_category_tabs', |
| 97 |
]; |
| 98 |
|
| 99 |
const MIGRATED_OPTION = 'ultimate_store_kit_kit_modal_ids_migrated'; |
| 100 |
|
| 101 |
public function __construct() { |
| 102 |
add_action('wp_footer', [$this, 'usk_render_data']); |
| 103 |
add_action('elementor/init', [__CLASS__, 'migrate_legacy_kit_settings']); |
| 104 |
} |
| 105 |
|
| 106 |
/** |
| 107 |
* Rewrite the active Kit's stored quick-view control ids to the prefixed |
| 108 |
* names, once per site. |
| 109 |
* |
| 110 |
* Only the handful of controls read in PHP go through usk_get_kit_setting(); |
| 111 |
* the rest are style controls whose CSS Elementor generates from the stored |
| 112 |
* settings array, so a read-side fallback alone would silently drop every |
| 113 |
* saved colour and typography value. Group controls store derived keys |
| 114 |
* ("<id>_font_size", "<id>_typography_font_family") and responsive controls |
| 115 |
* store "<id>_tablet"/"<id>_mobile", so keys are matched by prefix. |
| 116 |
* |
| 117 |
* @return void |
| 118 |
*/ |
| 119 |
public static function migrate_legacy_kit_settings() { |
| 120 |
if (get_option(self::MIGRATED_OPTION)) { |
| 121 |
return; |
| 122 |
} |
| 123 |
|
| 124 |
if (! class_exists('\Elementor\Plugin') || ! isset(Plugin::$instance->kits_manager)) { |
| 125 |
return; |
| 126 |
} |
| 127 |
|
| 128 |
$kit_id = Plugin::$instance->kits_manager->get_active_id(); |
| 129 |
|
| 130 |
if (! $kit_id) { |
| 131 |
return; |
| 132 |
} |
| 133 |
|
| 134 |
$settings = get_post_meta($kit_id, '_elementor_page_settings', true); |
| 135 |
|
| 136 |
if (is_array($settings) && $settings) { |
| 137 |
$changed = false; |
| 138 |
|
| 139 |
// Longest legacy id first so "modal_close_btn" cannot swallow the |
| 140 |
// keys belonging to "modal_close_btn_hover_color". |
| 141 |
$legacy_ids = array_keys(self::LEGACY_KIT_SETTING_IDS); |
| 142 |
usort($legacy_ids, function ($a, $b) { |
| 143 |
return strlen($b) - strlen($a); |
| 144 |
}); |
| 145 |
|
| 146 |
foreach ($legacy_ids as $legacy_id) { |
| 147 |
$current_id = self::LEGACY_KIT_SETTING_IDS[$legacy_id]; |
| 148 |
|
| 149 |
foreach (array_keys($settings) as $key) { |
| 150 |
if ($key !== $legacy_id && strpos($key, $legacy_id . '_') !== 0) { |
| 151 |
continue; |
| 152 |
} |
| 153 |
|
| 154 |
$new_key = $current_id . substr($key, strlen($legacy_id)); |
| 155 |
|
| 156 |
if (! isset($settings[$new_key])) { |
| 157 |
$settings[$new_key] = $settings[$key]; |
| 158 |
unset($settings[$key]); |
| 159 |
$changed = true; |
| 160 |
} |
| 161 |
} |
| 162 |
} |
| 163 |
|
| 164 |
if ($changed) { |
| 165 |
update_post_meta($kit_id, '_elementor_page_settings', $settings); |
| 166 |
|
| 167 |
// The Kit's generated CSS still references the old ids. |
| 168 |
if (isset(Plugin::$instance->files_manager)) { |
| 169 |
Plugin::$instance->files_manager->clear_cache(); |
| 170 |
} |
| 171 |
} |
| 172 |
} |
| 173 |
|
| 174 |
update_option(self::MIGRATED_OPTION, 1); |
| 175 |
} |
| 176 |
|
| 177 |
public function usk_get_kit_setting($setting_id) { |
| 178 |
global $usk_modal_settings; |
| 179 |
$return = ''; |
| 180 |
if (!isset($usk_modal_settings['kit_settings'])) { |
| 181 |
$active_kit_id = Plugin::$instance->kits_manager->get_active_id(); |
| 182 |
$kit = Plugin::$instance->documents->get($active_kit_id, false); |
| 183 |
|
| 184 |
// Check if kit exists and is a valid object before getting settings |
| 185 |
if ($kit && !is_wp_error($kit)) { |
| 186 |
$usk_modal_settings['kit_settings'] = $kit->get_settings(); |
| 187 |
} else { |
| 188 |
// Fallback if kit is not available |
| 189 |
$usk_modal_settings['kit_settings'] = []; |
| 190 |
} |
| 191 |
} |
| 192 |
|
| 193 |
if (isset($usk_modal_settings['kit_settings'][$setting_id])) { |
| 194 |
$return = $usk_modal_settings['kit_settings'][$setting_id]; |
| 195 |
} else { |
| 196 |
// Safety net for a Kit saved before the ids were prefixed, in case the |
| 197 |
// one-time migration has not run yet on this request. |
| 198 |
$legacy_id = array_search($setting_id, self::LEGACY_KIT_SETTING_IDS, true); |
| 199 |
|
| 200 |
if (false !== $legacy_id && isset($usk_modal_settings['kit_settings'][$legacy_id])) { |
| 201 |
$return = $usk_modal_settings['kit_settings'][$legacy_id]; |
| 202 |
} |
| 203 |
} |
| 204 |
|
| 205 |
return apply_filters('ultimate_store_kit_modal_settings_' . $setting_id, $return); |
| 206 |
} |
| 207 |
public function usk_render_data() { |
| 208 |
$modal_width_desktop = $this->usk_get_kit_setting('ultimate_store_kit_modal_width'); |
| 209 |
$modal_height = $this->usk_get_kit_setting('ultimate_store_kit_modal_height'); |
| 210 |
$animation = $this->usk_get_kit_setting('ultimate_store_kit_modal_animation'); |
| 211 |
$close_btn = $this->usk_get_kit_setting('ultimate_store_kit_modal_show_close_btn'); |
| 212 |
$btn_style = $this->usk_get_kit_setting('ultimate_store_kit_modal_button_style'); |
| 213 |
$btn_place = $this->usk_get_kit_setting('ultimate_store_kit_modal_btn_place'); |
| 214 |
$button_text = $this->usk_get_kit_setting('ultimate_store_kit_modal_button_text'); |
| 215 |
$modal_background = $this->usk_get_kit_setting('ultimate_store_kit_modal_background'); |
| 216 |
$modal_overlay = $this->usk_get_kit_setting('ultimate_store_kit_modal_overlay'); |
| 217 |
?> |
| 218 |
<div class="product-quick-view" id="quick-view-id" data-modal-overlay="<?php echo esc_attr($modal_overlay); ?>" data-modal-bg="<?php echo esc_attr($modal_background); ?>" data-sm-init="true" data-modal-width="<?php echo esc_attr(is_array($modal_width_desktop) && isset($modal_width_desktop['size']) ? $modal_width_desktop['size'] : ''); ?>" data-modal-height="<?php echo esc_attr(is_array($modal_height) && isset($modal_height['size']) ? $modal_height['size'] : ''); ?>" data-btn-text="<?php echo esc_attr($button_text); ?>" data-btn-place="<?php echo esc_attr($btn_place); ?>" data-btn-style="<?php echo esc_attr($btn_style); ?>" data-close-btn="<?php echo esc_attr($close_btn); ?>" data-animation="<?php echo esc_attr($animation); ?>"> |
| 219 |
</div> |
| 220 |
<?php |
| 221 |
} |
| 222 |
} |
| 223 |
new usk_Modal(); |
| 224 |
|