wpr-conditions-manager.php
5 days ago
wpr-editor-hooks.php
5 days ago
wpr-render-templates.php
5 days ago
wpr-templates-actions.php
5 days ago
wpr-templates-category-filter.php
5 days ago
wpr-templates-library.php
5 days ago
wpr-templates-loop.php
5 days ago
wpr-templates-modal-popups.php
5 days ago
wpr-templates-shortcode.php
5 days ago
wpr-editor-hooks.php
196 lines
| 1 | <?php |
| 2 | namespace WprAddons\Admin\Includes; |
| 3 | |
| 4 | if ( ! defined( 'ABSPATH' ) ) { |
| 5 | exit; // Exit if accessed directly. |
| 6 | } |
| 7 | |
| 8 | /** |
| 9 | * WPR_Editor_Hooks |
| 10 | * |
| 11 | * Handles Elementor editor hooks and modifications |
| 12 | * Including removal of Elementor Pro promotion widgets |
| 13 | */ |
| 14 | class WPR_Editor_Hooks { |
| 15 | |
| 16 | /** |
| 17 | * Instance of this class |
| 18 | * |
| 19 | * @var WPR_Editor_Hooks |
| 20 | */ |
| 21 | private static $_instance = null; |
| 22 | |
| 23 | /** |
| 24 | * Get instance |
| 25 | * |
| 26 | * @return WPR_Editor_Hooks |
| 27 | */ |
| 28 | public static function instance() { |
| 29 | if ( is_null( self::$_instance ) ) { |
| 30 | self::$_instance = new self(); |
| 31 | } |
| 32 | return self::$_instance; |
| 33 | } |
| 34 | |
| 35 | /** |
| 36 | * Constructor |
| 37 | */ |
| 38 | private function __construct() { |
| 39 | $this->add_hooks(); |
| 40 | } |
| 41 | |
| 42 | /** |
| 43 | * Register all hooks |
| 44 | */ |
| 45 | private function add_hooks() { |
| 46 | // Remove Elementor Pro Promotion Widgets - Only in editor (not during import) |
| 47 | if ( current_user_can('administrator') ) { |
| 48 | add_action('elementor/editor/before_enqueue_scripts', [$this, 'conditional_remove_elementor_pro_promotions'], 1); |
| 49 | // Detect widgets when page is saved |
| 50 | add_action('elementor/editor/after_save', [$this, 'detect_widgets_on_save'], 10, 2); |
| 51 | } |
| 52 | } |
| 53 | |
| 54 | /** |
| 55 | * Remove pro widgets from Elementor transient |
| 56 | * |
| 57 | * @param mixed $transient Transient data |
| 58 | * @return mixed Modified transient data |
| 59 | */ |
| 60 | public function remove_pro_widgets_from_transient($transient) { |
| 61 | // Remove pro_widgets from the Elementor API data |
| 62 | if ($transient && isset($transient['pro_widgets'])) { |
| 63 | $transient['pro_widgets'] = []; |
| 64 | } |
| 65 | return $transient; |
| 66 | } |
| 67 | |
| 68 | /** |
| 69 | * Conditionally remove Elementor Pro promotions |
| 70 | * Uses persistent flag for performance - once Royal widgets are used, always hide promotions |
| 71 | */ |
| 72 | public function conditional_remove_elementor_pro_promotions() { |
| 73 | // Check persistent flag first (most efficient) - works everywhere |
| 74 | $flag = get_option('wpr_has_used_royal_widgets'); |
| 75 | |
| 76 | if ($flag) { |
| 77 | $this->remove_elementor_promotions(); |
| 78 | return; |
| 79 | } |
| 80 | |
| 81 | // Only continue for first-time detection in actual Elementor editor (not during imports) |
| 82 | $is_editor = isset(\Elementor\Plugin::$instance->editor); |
| 83 | $is_edit_mode = $is_editor && \Elementor\Plugin::$instance->editor->is_edit_mode(); |
| 84 | |
| 85 | if (!$is_editor || !$is_edit_mode) { |
| 86 | return; |
| 87 | } |
| 88 | |
| 89 | // Fallback: Check current page for first-time detection |
| 90 | $post_id = get_the_ID(); |
| 91 | |
| 92 | if (!$post_id) { |
| 93 | return; |
| 94 | } |
| 95 | |
| 96 | // Check if this page uses Royal widgets |
| 97 | $has_widgets = $this->page_has_royal_widgets($post_id); |
| 98 | |
| 99 | if ($has_widgets) { |
| 100 | // Set persistent flag for future use |
| 101 | update_option('wpr_has_used_royal_widgets', time()); |
| 102 | |
| 103 | // Remove promotions |
| 104 | $this->remove_elementor_promotions(); |
| 105 | } |
| 106 | } |
| 107 | |
| 108 | /** |
| 109 | * Detect Royal widgets when page is saved and set persistent flag |
| 110 | * |
| 111 | * @param int $post_id Post ID that was saved |
| 112 | * @param array $data Elementor data being saved |
| 113 | */ |
| 114 | public function detect_widgets_on_save($post_id, $data) { |
| 115 | // Skip if flag already set |
| 116 | if (get_option('wpr_has_used_royal_widgets')) { |
| 117 | return; |
| 118 | } |
| 119 | |
| 120 | // Clear cache to force fresh detection |
| 121 | delete_transient('wpr_has_widgets_' . $post_id); |
| 122 | |
| 123 | // Check if this page has Royal widgets |
| 124 | if ($this->page_has_royal_widgets($post_id)) { |
| 125 | update_option('wpr_has_used_royal_widgets', time()); |
| 126 | } |
| 127 | } |
| 128 | |
| 129 | /** |
| 130 | * Apply filters to remove Elementor promotions |
| 131 | */ |
| 132 | private function remove_elementor_promotions() { |
| 133 | add_filter('pre_transient_elementor_remote_info_api_data_' . ELEMENTOR_VERSION, |
| 134 | [$this, 'remove_pro_widgets_from_transient'], 999); |
| 135 | add_filter('transient_elementor_remote_info_api_data_' . ELEMENTOR_VERSION, |
| 136 | [$this, 'remove_pro_widgets_from_transient'], 999); |
| 137 | } |
| 138 | |
| 139 | /** |
| 140 | * Check if a page has Royal Addons widgets |
| 141 | * |
| 142 | * @param int $post_id Post ID to check |
| 143 | * @return bool True if Royal widgets found |
| 144 | */ |
| 145 | private function page_has_royal_widgets($post_id) { |
| 146 | // Check cache first |
| 147 | $cache_key = 'wpr_has_widgets_' . $post_id; |
| 148 | $cached = get_transient($cache_key); |
| 149 | if (false !== $cached) { |
| 150 | return $cached === 'yes'; |
| 151 | } |
| 152 | |
| 153 | $has_widgets = false; |
| 154 | |
| 155 | // Method 1: Check _elementor_controls_usage (fastest and most reliable) |
| 156 | $controls_usage = get_post_meta($post_id, '_elementor_controls_usage', true); |
| 157 | |
| 158 | if (is_array($controls_usage)) { |
| 159 | foreach ($controls_usage as $widget_type => $data) { |
| 160 | if (is_string($widget_type) && strpos($widget_type, 'wpr-') === 0) { |
| 161 | $has_widgets = true; |
| 162 | break; |
| 163 | } |
| 164 | } |
| 165 | } |
| 166 | |
| 167 | // Method 2: Fallback to _elementor_data for unsaved pages |
| 168 | if (!$has_widgets) { |
| 169 | $elementor_data = get_post_meta($post_id, '_elementor_data', true); |
| 170 | |
| 171 | if (!empty($elementor_data)) { |
| 172 | // Handle both array (during import) and string (normal) cases |
| 173 | if (is_array($elementor_data)) { |
| 174 | $elementor_data = wp_json_encode($elementor_data); |
| 175 | } |
| 176 | |
| 177 | if (is_string($elementor_data)) { |
| 178 | if (strpos($elementor_data, '"widgetType":"wpr-') !== false) { |
| 179 | $has_widgets = true; |
| 180 | } |
| 181 | } |
| 182 | } |
| 183 | } |
| 184 | |
| 185 | // Cache result for 1 hour |
| 186 | $cache_value = $has_widgets ? 'yes' : 'no'; |
| 187 | set_transient($cache_key, $cache_value, HOUR_IN_SECONDS); |
| 188 | |
| 189 | return $has_widgets; |
| 190 | } |
| 191 | |
| 192 | } |
| 193 | |
| 194 | // Initialize |
| 195 | WPR_Editor_Hooks::instance(); |
| 196 |