PluginProbe
Master Addons for Elementor – Elementor Addons, Widgets, Mega Menu Builder, Popup Builder, Widget Builder & Template Kits / 3.1.2
Master Addons for Elementor – Elementor Addons, Widgets, Mega Menu Builder, Popup Builder, Widget Builder & Template Kits v3.1.2
3.2.2 3.2.3 3.2.1 3.2.0 3.1.9 3.1.8 3.1.7 3.1.6 3.1.5 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.9 trunk 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.1.3 1.1.4 1.1.5 All 174 releases
master-addons / inc / classes / notifications / promo-pointer.php

promo-pointer.php in Master Addons for Elementor – Elementor Addons, Widgets, Mega Menu Builder, Popup Builder, Widget Builder & Template Kits 3.1.2, at inc/classes/notifications/promo-pointer.php

306 lines 6.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace MasterAddons\Inc\Classes\Notifications;
4
5 use MasterAddons\Inc\Classes\Helper;
6
7 // No, Direct access Sir !!!
8 if (!defined('ABSPATH')) {
9 exit;
10 }
11
12 /**
13 * Promo Pointer Notification
14 *
15 * WordPress Pointer-style promotional notification that appears
16 * attached to the Master Addons menu item.
17 *
18 * Jewel Theme <support@jeweltheme.com>
19 */
20 class Promo_Pointer
21 {
22 /**
23 * Pointer ID for tracking dismissal
24 *
25 * @var string
26 */
27 private $pointer_id = 'jltma_promo_pointer';
28
29 /**
30 * Transient key for dismissal tracking
31 *
32 * @var string
33 */
34 private $transient_key = 'jltma_promo_pointer_dismiss';
35
36 /**
37 * Campaign end date/time
38 *
39 * @var string
40 */
41 private $campaign_end_date = '11:59:59pm 31st January, 2026';
42
43 /**
44 * Menu selector for the pointer
45 *
46 * @var string
47 */
48 private $menu_selector = '#toplevel_page_master-addons-settings';
49
50 /**
51 * Allowed screen IDs where pointer should show
52 *
53 * @var array
54 */
55 private $allowed_screens = ['index.php', 'toplevel_page_master-addons-settings'];
56
57 /**
58 * Promo content configuration
59 *
60 * @var array
61 */
62 private $promo_config = [];
63
64 /**
65 * Constructor
66 */
67 public function __construct()
68 {
69 $this->set_promo_config();
70 $this->init_hooks();
71 }
72
73 /**
74 * Set promotional content configuration
75 *
76 * Override this method or use filter to customize content
77 *
78 * @return void
79 */
80 protected function set_promo_config()
81 {
82 $this->promo_config = apply_filters('jltma_promo_pointer_config', [
83 'title' => __('Master Addons: New Year Sale!', 'master-addons'),
84 'description' => __('Unlock the full power of Elementor with 70+ advanced widgets. Build faster, design smarter.', 'master-addons'),
85 'button_text' => __('Save Up to 50%', 'master-addons'),
86 'button_url' => 'https://master-addons.com/pricing/?utm_source=plugin&utm_medium=pointer&utm_campaign=newyear2026',
87 ]);
88 }
89
90 /**
91 * Initialize hooks
92 *
93 * @return void
94 */
95 private function init_hooks()
96 {
97 add_action('in_admin_header', [$this, 'render_pointer']);
98 add_action('admin_init', [$this, 'handle_dismiss']);
99 }
100
101 /**
102 * Check if pointer should be displayed
103 *
104 * @return bool
105 */
106 private function should_display()
107 {
108 // Only for free plan users
109 if (Helper::jltma_premium()) {
110 return false;
111 }
112
113 // Check if campaign has ended
114 if (time() > strtotime($this->campaign_end_date)) {
115 return false;
116 }
117
118 // Check allowed screens
119 $current_screen = get_current_screen();
120 $current_page = $GLOBALS['pagenow'] ?? '';
121
122 $is_allowed_screen = $current_page === 'index.php' ||
123 ($current_screen && in_array($current_screen->id, $this->allowed_screens, true));
124
125 if (!$is_allowed_screen) {
126 return false;
127 }
128
129 // Check if already dismissed
130 if (get_transient($this->transient_key)) {
131 return false;
132 }
133
134 return true;
135 }
136
137 /**
138 * Render the pointer notification
139 *
140 * @return void
141 */
142 public function render_pointer()
143 {
144 if (!$this->should_display()) {
145 return;
146 }
147
148 // Enqueue required scripts
149 wp_enqueue_script('jquery');
150 wp_enqueue_style('wp-pointer');
151 wp_enqueue_script('wp-pointer');
152
153 $pointer_content = $this->get_pointer_content();
154 $selector = esc_js($this->menu_selector);
155 $nonce = wp_create_nonce('jltma_promo_pointer_dismiss');
156 ?>
157 <script>
158 jQuery(function($) {
159 $('<?php echo $selector; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- $selector is already sanitized via esc_js() above ?>').pointer({
160 content: <?php echo wp_json_encode($pointer_content); ?>,
161 position: {
162 edge: 'left',
163 align: 'center'
164 },
165 pointerClass: 'wp-pointer jltma-promo-pointer',
166 close: function() {
167 $.post(ajaxurl, {
168 action: 'jltma_dismiss_promo_pointer',
169 _wpnonce: '<?php echo esc_js($nonce); ?>'
170 });
171 }
172 }).pointer('open');
173
174 // Add custom styles
175 $('.jltma-promo-pointer').css({
176 'max-width': '320px'
177 });
178
179 // Handle CTA button click
180 $(document).on('click', '.jltma-pointer-cta-btn', function() {
181 // Dismiss on CTA click as well
182 $.post(ajaxurl, {
183 action: 'jltma_dismiss_promo_pointer',
184 _wpnonce: '<?php echo esc_js($nonce); ?>'
185 });
186 });
187 });
188 </script>
189 <style>
190 .jltma-promo-pointer .wp-pointer-content h3 {
191 background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);
192 border-color: #6366f1;
193 font-weight: 600;
194 }
195
196 .jltma-promo-pointer .wp-pointer-content p {
197 margin: 1em 0;
198 line-height: 1.6;
199 }
200
201 .jltma-promo-pointer .jltma-pointer-cta-btn {
202 display: inline-block;
203 background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);
204 color: #fff !important;
205 padding: 8px 16px;
206 border-radius: 4px;
207 text-decoration: none;
208 font-weight: 600;
209 transition: all 0.3s ease;
210 }
211
212 .jltma-promo-pointer .jltma-pointer-cta-btn:hover {
213 transform: translateY(-1px);
214 box-shadow: 0 4px 12px rgba(99, 102, 241, 0.4);
215 }
216
217 .jltma-promo-pointer .wp-pointer-arrow-inner {
218 border-right-color: #6366f1;
219 }
220 </style>
221 <?php
222 }
223
224 /**
225 * Get pointer HTML content
226 *
227 * @return string
228 */
229 private function get_pointer_content()
230 {
231 $title = esc_html($this->promo_config['title']);
232 $description = esc_html($this->promo_config['description']);
233 $button_text = esc_html($this->promo_config['button_text']);
234 $button_url = esc_url($this->promo_config['button_url']);
235
236 return sprintf(
237 '<h3 style="font-weight: 600;">%s</h3><p style="margin: 1em 0;">%s</p><p><a class="jltma-pointer-cta-btn" href="%s" target="_blank">%s</a></p>',
238 $title,
239 $description,
240 $button_url,
241 $button_text
242 );
243 }
244
245 /**
246 * Handle pointer dismissal via AJAX
247 *
248 * @return void
249 */
250 public function handle_dismiss()
251 {
252 // Handle standard WP pointer dismiss
253 if (
254 isset($_POST['action']) &&
255 'dismiss-wp-pointer' === $_POST['action'] &&
256 isset($_POST['pointer']) &&
257 $this->pointer_id === $_POST['pointer']
258 ) {
259 set_transient($this->transient_key, true, DAY_IN_SECONDS * 30);
260 return;
261 }
262
263 // Handle custom dismiss action
264 if (isset($_POST['action']) && 'jltma_dismiss_promo_pointer' === $_POST['action']) {
265 if (!wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['_wpnonce'] ?? '' ) ), 'jltma_promo_pointer_dismiss')) {
266 return;
267 }
268 set_transient($this->transient_key, true, DAY_IN_SECONDS * 30);
269 wp_send_json_success();
270 }
271 }
272
273 /**
274 * Update campaign end date
275 *
276 * @param string $date Date string parseable by strtotime()
277 * @return void
278 */
279 public function set_campaign_end_date($date)
280 {
281 $this->campaign_end_date = $date;
282 }
283
284 /**
285 * Update promo configuration
286 *
287 * @param array $config Configuration array with title, description, button_text, button_url
288 * @return void
289 */
290 public function set_promo_config_values($config)
291 {
292 $this->promo_config = array_merge($this->promo_config, $config);
293 }
294
295 /**
296 * Add additional allowed screen
297 *
298 * @param string $screen_id Screen ID to allow
299 * @return void
300 */
301 public function add_allowed_screen($screen_id)
302 {
303 $this->allowed_screens[] = $screen_id;
304 }
305 }
306