PluginProbe
Master Addons for Elementor – Elementor Addons, Widgets, Mega Menu Builder, Popup Builder, Widget Builder & Template Kits / 3.1.9
Master Addons for Elementor – Elementor Addons, Widgets, Mega Menu Builder, Popup Builder, Widget Builder & Template Kits v3.1.9
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 / admin / popup-builder / class-popup-builder.php

class-popup-builder.php in Master Addons for Elementor – Elementor Addons, Widgets, Mega Menu Builder, Popup Builder, Widget Builder & Template Kits 3.1.9, at inc/admin/popup-builder/class-popup-builder.php

724 lines 37.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace MasterAddons\Inc\Admin\PopupBuilder;
3
4 use MasterAddons\Master_Elementor_Addons;
5
6 if (!defined('ABSPATH')) {
7 exit;
8 }
9
10 class Popup_Builder {
11
12 private static $instance = null;
13
14 public static function get_instance() {
15 if (self::$instance === null) {
16 self::$instance = new self();
17 }
18 return self::$instance;
19 }
20
21 public function __construct() {
22 $this->init_hooks();
23 $this->includes();
24 }
25
26 private function init_hooks() {
27 add_action('admin_menu', [$this, 'add_admin_menu'], 55);
28 add_action('admin_enqueue_scripts', [$this, 'enqueue_admin_assets']);
29 add_action('wp_ajax_jltma_popup_save', [$this, 'save_popup']);
30 add_action('wp_ajax_jltma_popup_delete', [$this, 'delete_popup']);
31 add_action('wp_ajax_jltma_popup_duplicate', [$this, 'duplicate_popup']);
32 add_action('wp_ajax_jltma_popup_toggle_status', [$this, 'toggle_popup_status']);
33 }
34
35 private function includes() {
36 // Classes are now autoloaded via the plugin autoloader
37 }
38
39 public function add_admin_menu() {
40 add_submenu_page(
41 'master-addons-settings',
42 __('Popup Builder', 'master-addons'),
43 __('Popup Builder', 'master-addons'),
44 'manage_options',
45 'jltma-popups',
46 [$this, 'render_popup_page']
47 );
48 }
49
50 public function render_popup_page() {
51 $action = isset($_GET['action']) ? sanitize_text_field( wp_unslash( $_GET['action'] ) ) : 'list'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only display routing, no state change
52
53 switch ($action) {
54 case 'new':
55 $this->render_new_popup_page();
56 break;
57 case 'edit':
58 $this->render_edit_popup_page();
59 break;
60 case 'templates':
61 $this->render_templates_page();
62 break;
63 default:
64 $this->render_list_page();
65 break;
66 }
67 }
68
69 private function render_list_page() {
70 $list_table = new Popup_List_Table();
71 $list_table->prepare_items();
72 ?>
73 <div class="wrap ma-popup-builder">
74 <h1 class="wp-heading-inline"><?php esc_html_e('Popups', 'master-addons'); ?></h1>
75 <a href="<?php echo esc_url( admin_url('admin.php?page=jltma-popups&action=new') ); ?>" class="page-title-action">
76 <?php esc_html_e('Add New', 'master-addons'); ?>
77 </a>
78 <a href="<?php echo esc_url( admin_url('admin.php?page=jltma-popups&action=templates') ); ?>" class="page-title-action">
79 <?php esc_html_e('Templates', 'master-addons'); ?>
80 </a>
81 <hr class="wp-header-end">
82
83 <form method="post">
84 <?php $list_table->display(); ?>
85 </form>
86 </div>
87 <?php
88 }
89
90 private function render_new_popup_page() {
91 ?>
92 <div class="wrap ma-popup-builder">
93 <h1><?php esc_html_e('Add New Popup', 'master-addons'); ?></h1>
94
95 <form id="ma-popup-form" method="post">
96 <div class="ma-popup-builder-container">
97 <div class="ma-popup-main-content">
98 <div class="postbox">
99 <h2 class="hndle"><?php esc_html_e('Popup Details', 'master-addons'); ?></h2>
100 <div class="inside">
101 <table class="form-table">
102 <tr>
103 <th scope="row">
104 <label for="popup-name"><?php esc_html_e('Popup Name', 'master-addons'); ?></label>
105 </th>
106 <td>
107 <input type="text" id="popup-name" name="popup_name" class="regular-text" required>
108 </td>
109 </tr>
110 <tr>
111 <th scope="row">
112 <label for="popup-type"><?php esc_html_e('Popup Type', 'master-addons'); ?></label>
113 </th>
114 <td>
115 <select id="popup-type" name="popup_type">
116 <option value="notification"><?php esc_html_e('Notification Bar', 'master-addons'); ?></option>
117 <option value="modal"><?php esc_html_e('Modal', 'master-addons'); ?></option>
118 <option value="slide-in"><?php esc_html_e('Slide-in', 'master-addons'); ?></option>
119 <option value="full-screen"><?php esc_html_e('Full Screen', 'master-addons'); ?></option>
120 <option value="corner"><?php esc_html_e('Corner Popup', 'master-addons'); ?></option>
121 </select>
122 </td>
123 </tr>
124 <tr>
125 <th scope="row">
126 <label for="popup-content"><?php esc_html_e('Content', 'master-addons'); ?></label>
127 </th>
128 <td>
129 <?php
130 $content = '';
131 $editor_id = 'popup-content';
132 $settings = array(
133 'textarea_name' => 'popup_content',
134 'media_buttons' => true,
135 'textarea_rows' => 10,
136 );
137 wp_editor($content, $editor_id, $settings);
138 ?>
139 </td>
140 </tr>
141 </table>
142 </div>
143 </div>
144
145 <?php $this->render_trigger_settings(); ?>
146 <?php $this->render_display_conditions(); ?>
147 <?php $this->render_design_settings(); ?>
148 </div>
149
150 <div class="ma-popup-sidebar">
151 <?php $this->render_sidebar_settings(); ?>
152 </div>
153 </div>
154
155 <?php wp_nonce_field('jltma_popup_save', 'jltma_popup_nonce'); ?>
156 <input type="hidden" name="action" value="jltma_popup_save">
157 </form>
158 </div>
159 <?php
160 }
161
162 private function render_edit_popup_page() {
163 $popup_id = isset($_GET['popup_id']) ? absint( $_GET['popup_id'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only display routing, no state change
164 $popup = $this->get_popup($popup_id);
165
166 if (!$popup) {
167 wp_die( esc_html__('Popup not found', 'master-addons') );
168 }
169
170 ?>
171 <div class="wrap ma-popup-builder">
172 <h1><?php esc_html_e('Edit Popup', 'master-addons'); ?></h1>
173
174 <form id="ma-popup-form" method="post">
175 <div class="ma-popup-builder-container">
176 <div class="ma-popup-main-content">
177 <div class="postbox">
178 <h2 class="hndle"><?php esc_html_e('Popup Details', 'master-addons'); ?></h2>
179 <div class="inside">
180 <table class="form-table">
181 <tr>
182 <th scope="row">
183 <label for="popup-name"><?php esc_html_e('Popup Name', 'master-addons'); ?></label>
184 </th>
185 <td>
186 <input type="text" id="popup-name" name="popup_name" class="regular-text"
187 value="<?php echo esc_attr($popup->name); ?>" required>
188 </td>
189 </tr>
190 <tr>
191 <th scope="row">
192 <label for="popup-type"><?php esc_html_e('Popup Type', 'master-addons'); ?></label>
193 </th>
194 <td>
195 <select id="popup-type" name="popup_type">
196 <option value="notification" <?php selected($popup->type, 'notification'); ?>><?php esc_html_e('Notification Bar', 'master-addons'); ?></option>
197 <option value="modal" <?php selected($popup->type, 'modal'); ?>><?php esc_html_e('Modal', 'master-addons'); ?></option>
198 <option value="slide-in" <?php selected($popup->type, 'slide-in'); ?>><?php esc_html_e('Slide-in', 'master-addons'); ?></option>
199 <option value="full-screen" <?php selected($popup->type, 'full-screen'); ?>><?php esc_html_e('Full Screen', 'master-addons'); ?></option>
200 <option value="corner" <?php selected($popup->type, 'corner'); ?>><?php esc_html_e('Corner Popup', 'master-addons'); ?></option>
201 </select>
202 </td>
203 </tr>
204 <tr>
205 <th scope="row">
206 <label for="popup-content"><?php esc_html_e('Content', 'master-addons'); ?></label>
207 </th>
208 <td>
209 <?php
210 $content = $popup->content;
211 $editor_id = 'popup-content';
212 $settings = array(
213 'textarea_name' => 'popup_content',
214 'media_buttons' => true,
215 'textarea_rows' => 10,
216 );
217 wp_editor($content, $editor_id, $settings);
218 ?>
219 </td>
220 </tr>
221 </table>
222 </div>
223 </div>
224
225 <?php $this->render_trigger_settings($popup); ?>
226 <?php $this->render_display_conditions($popup); ?>
227 <?php $this->render_design_settings($popup); ?>
228 </div>
229
230 <div class="ma-popup-sidebar">
231 <?php $this->render_sidebar_settings($popup); ?>
232 </div>
233 </div>
234
235 <?php wp_nonce_field('jltma_popup_save', 'jltma_popup_nonce'); ?>
236 <input type="hidden" name="action" value="jltma_popup_save">
237 <input type="hidden" name="popup_id" value="<?php echo absint( $popup_id ); ?>">
238 </form>
239 </div>
240 <?php
241 }
242
243 private function render_trigger_settings($popup = null) {
244 ?>
245 <div class="postbox">
246 <h2 class="hndle"><?php esc_html_e('Trigger Settings', 'master-addons'); ?></h2>
247 <div class="inside">
248 <input type="hidden" name="trigger_type" value="load">
249 <input type="hidden" name="trigger_delay" value="0">
250 <table class="form-table">
251 <tr class="trigger-scroll-row" style="display:none;">
252 <th scope="row">
253 <label for="trigger-scroll-percent"><?php esc_html_e('Scroll Percentage', 'master-addons'); ?></label>
254 </th>
255 <td>
256 <input type="number" id="trigger-scroll-percent" name="trigger_scroll_percent" min="0" max="100" value="50">
257 </td>
258 </tr>
259 <tr class="trigger-element-row" style="display:none;">
260 <th scope="row">
261 <label for="trigger-element"><?php esc_html_e('Element Selector', 'master-addons'); ?></label>
262 </th>
263 <td>
264 <input type="text" id="trigger-element" name="trigger_element" class="regular-text" placeholder="#element-id or .element-class">
265 </td>
266 </tr>
267 </table>
268 </div>
269 </div>
270 <?php
271 }
272
273 private function render_display_conditions($popup = null) {
274 ?>
275 <div class="postbox">
276 <h2 class="hndle"><?php esc_html_e('Display Conditions', 'master-addons'); ?></h2>
277 <div class="inside">
278 <table class="form-table">
279 <tr>
280 <th scope="row">
281 <label><?php esc_html_e('Show On', 'master-addons'); ?></label>
282 </th>
283 <td>
284 <label>
285 <input type="radio" name="display_on" value="all" checked>
286 <?php esc_html_e('All Pages', 'master-addons'); ?>
287 </label><br>
288 <label>
289 <input type="radio" name="display_on" value="specific">
290 <?php esc_html_e('Specific Pages', 'master-addons'); ?>
291 </label><br>
292 <label>
293 <input type="radio" name="display_on" value="exclude">
294 <?php esc_html_e('All Pages Except', 'master-addons'); ?>
295 </label>
296 </td>
297 </tr>
298 <tr class="specific-pages-row" style="display:none;">
299 <th scope="row">
300 <label for="specific-pages"><?php esc_html_e('Select Pages', 'master-addons'); ?></label>
301 </th>
302 <td>
303 <select id="specific-pages" name="specific_pages[]" multiple class="regular-text">
304 <?php
305 $pages = get_pages();
306 foreach ($pages as $page) {
307 echo '<option value="' . absint( $page->ID ) . '">' . esc_html( $page->post_title ) . '</option>';
308 }
309 ?>
310 </select>
311 </td>
312 </tr>
313 <tr>
314 <th scope="row">
315 <label><?php esc_html_e('User Conditions', 'master-addons'); ?></label>
316 </th>
317 <td>
318 <label>
319 <input type="checkbox" name="show_logged_in" value="1">
320 <?php esc_html_e('Show to Logged-in Users', 'master-addons'); ?>
321 </label><br>
322 <label>
323 <input type="checkbox" name="show_logged_out" value="1" checked>
324 <?php esc_html_e('Show to Logged-out Users', 'master-addons'); ?>
325 </label><br>
326 <label>
327 <input type="checkbox" name="show_first_time" value="1">
328 <?php esc_html_e('Show to First-time Visitors Only', 'master-addons'); ?>
329 </label>
330 </td>
331 </tr>
332 <tr>
333 <th scope="row">
334 <label for="show-frequency"><?php esc_html_e('Show Frequency', 'master-addons'); ?></label>
335 </th>
336 <td>
337 <select id="show-frequency" name="show_frequency">
338 <option value="always"><?php esc_html_e('Always', 'master-addons'); ?></option>
339 <option value="once_session"><?php esc_html_e('Once Per Session', 'master-addons'); ?></option>
340 <option value="once_day"><?php esc_html_e('Once Per Day', 'master-addons'); ?></option>
341 <option value="once_week"><?php esc_html_e('Once Per Week', 'master-addons'); ?></option>
342 <option value="once"><?php esc_html_e('Once Ever', 'master-addons'); ?></option>
343 </select>
344 </td>
345 </tr>
346 </table>
347 </div>
348 </div>
349 <?php
350 }
351
352 private function render_design_settings($popup = null) {
353 ?>
354 <div class="postbox">
355 <h2 class="hndle"><?php esc_html_e('Design Settings', 'master-addons'); ?></h2>
356 <div class="inside">
357 <table class="form-table">
358 <tr>
359 <th scope="row">
360 <label for="popup-position"><?php esc_html_e('Position', 'master-addons'); ?></label>
361 </th>
362 <td>
363 <select id="popup-position" name="popup_position">
364 <option value="center"><?php esc_html_e('Center', 'master-addons'); ?></option>
365 <option value="top-left"><?php esc_html_e('Top Left', 'master-addons'); ?></option>
366 <option value="top-center"><?php esc_html_e('Top Center', 'master-addons'); ?></option>
367 <option value="top-right"><?php esc_html_e('Top Right', 'master-addons'); ?></option>
368 <option value="bottom-left"><?php esc_html_e('Bottom Left', 'master-addons'); ?></option>
369 <option value="bottom-center"><?php esc_html_e('Bottom Center', 'master-addons'); ?></option>
370 <option value="bottom-right"><?php esc_html_e('Bottom Right', 'master-addons'); ?></option>
371 </select>
372 </td>
373 </tr>
374 <tr>
375 <th scope="row">
376 <label for="popup-width"><?php esc_html_e('Width', 'master-addons'); ?></label>
377 </th>
378 <td>
379 <input type="text" id="popup-width" name="popup_width" value="600px" class="small-text">
380 <p class="description"><?php esc_html_e('Enter value with unit (px, %, vw)', 'master-addons'); ?></p>
381 </td>
382 </tr>
383 <tr>
384 <th scope="row">
385 <label for="popup-animation"><?php esc_html_e('Animation', 'master-addons'); ?></label>
386 </th>
387 <td>
388 <select id="popup-animation" name="popup_animation">
389 <option value="fade"><?php esc_html_e('Fade', 'master-addons'); ?></option>
390 <option value="slide-down"><?php esc_html_e('Slide Down', 'master-addons'); ?></option>
391 <option value="slide-up"><?php esc_html_e('Slide Up', 'master-addons'); ?></option>
392 <option value="slide-left"><?php esc_html_e('Slide Left', 'master-addons'); ?></option>
393 <option value="slide-right"><?php esc_html_e('Slide Right', 'master-addons'); ?></option>
394 <option value="zoom"><?php esc_html_e('Zoom', 'master-addons'); ?></option>
395 </select>
396 </td>
397 </tr>
398 <tr>
399 <th scope="row">
400 <label><?php esc_html_e('Overlay', 'master-addons'); ?></label>
401 </th>
402 <td>
403 <label>
404 <input type="checkbox" name="show_overlay" value="1" checked>
405 <?php esc_html_e('Show Overlay', 'master-addons'); ?>
406 </label><br>
407 <label>
408 <input type="checkbox" name="close_on_overlay" value="1" checked>
409 <?php esc_html_e('Close on Overlay Click', 'master-addons'); ?>
410 </label>
411 </td>
412 </tr>
413 <tr>
414 <th scope="row">
415 <label><?php esc_html_e('Close Button', 'master-addons'); ?></label>
416 </th>
417 <td>
418 <label>
419 <input type="checkbox" name="show_close_button" value="1" checked>
420 <?php esc_html_e('Show Close Button', 'master-addons'); ?>
421 </label><br>
422 <label>
423 <input type="checkbox" name="close_on_esc" value="1" checked>
424 <?php esc_html_e('Close on ESC Key', 'master-addons'); ?>
425 </label>
426 </td>
427 </tr>
428 </table>
429 </div>
430 </div>
431 <?php
432 }
433
434 private function render_sidebar_settings($popup = null) {
435 ?>
436 <div class="postbox">
437 <h2 class="hndle"><?php esc_html_e('Publish', 'master-addons'); ?></h2>
438 <div class="inside">
439 <div class="submitbox">
440 <div id="minor-publishing">
441 <div class="misc-pub-section">
442 <label>
443 <input type="checkbox" name="popup_status" value="active" <?php echo (!$popup || $popup->status == 'active') ? 'checked' : ''; ?>>
444 <?php esc_html_e('Active', 'master-addons'); ?>
445 </label>
446 </div>
447 </div>
448 <div id="major-publishing-actions">
449 <div id="publishing-action">
450 <button type="submit" class="button button-primary button-large">
451 <?php echo $popup ? esc_html__('Update', 'master-addons') : esc_html__('Publish', 'master-addons'); ?>
452 </button>
453 </div>
454 <div class="clear"></div>
455 </div>
456 </div>
457 </div>
458 </div>
459
460 <div class="postbox">
461 <h2 class="hndle"><?php esc_html_e('Advanced Settings', 'master-addons'); ?></h2>
462 <div class="inside">
463 <p>
464 <label for="popup-priority"><?php esc_html_e('Priority', 'master-addons'); ?></label><br>
465 <input type="number" id="popup-priority" name="popup_priority" value="10" class="small-text">
466 <span class="description"><?php esc_html_e('Higher priority popups show first', 'master-addons'); ?></span>
467 </p>
468 <p>
469 <label for="popup-class"><?php esc_html_e('Custom CSS Class', 'master-addons'); ?></label><br>
470 <input type="text" id="popup-class" name="popup_class" class="regular-text">
471 </p>
472 <p>
473 <label for="popup-custom-css"><?php esc_html_e('Custom CSS', 'master-addons'); ?></label><br>
474 <textarea id="popup-custom-css" name="popup_custom_css" rows="5" class="large-text code"></textarea>
475 </p>
476 </div>
477 </div>
478 <?php
479 }
480
481 private function render_templates_page() {
482 $templates = new Popup_Templates();
483 $templates->render();
484 }
485
486 public function enqueue_admin_assets($hook) {
487 if (strpos($hook, 'jltma-popups') === false) {
488 return;
489 }
490
491 \MasterAddons\Inc\Classes\Assets_Manager::enqueue('popup-builder-admin');
492
493 wp_localize_script('jltma-popup-builder-admin', 'jltma_popup_builder', [
494 'ajax_url' => admin_url('admin-ajax.php'),
495 'nonce' => wp_create_nonce('jltma_popup_builder'),
496 'strings' => [
497 'confirm_delete' => __('Are you sure you want to delete this popup?', 'master-addons'),
498 'saving' => __('Saving...', 'master-addons'),
499 'saved' => __('Saved!', 'master-addons'),
500 'error' => __('An error occurred. Please try again.', 'master-addons'),
501 ]
502 ]);
503 }
504
505 public function save_popup() {
506 if (!check_ajax_referer('jltma_popup_save', 'jltma_popup_nonce', false)) {
507 wp_die( esc_html__('Security check failed', 'master-addons') );
508 }
509
510 if (!current_user_can('edit_posts')) {
511 wp_send_json_error(['message' => esc_html__('Invalid access', 'master-addons')]);
512 }
513
514 $popup_id = isset( $_POST['popup_id'] ) ? absint( $_POST['popup_id'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified above
515 $popup_data = [
516 'name' => isset( $_POST['popup_name'] ) ? sanitize_text_field( wp_unslash( $_POST['popup_name'] ) ) : '', // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified above
517 'type' => isset( $_POST['popup_type'] ) ? sanitize_text_field( wp_unslash( $_POST['popup_type'] ) ) : '', // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified above
518 'content' => isset( $_POST['popup_content'] ) ? wp_kses_post( wp_unslash( $_POST['popup_content'] ) ) : '', // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified above
519 'trigger_type' => isset( $_POST['trigger_type'] ) ? sanitize_text_field( wp_unslash( $_POST['trigger_type'] ) ) : '', // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified above
520 'trigger_delay' => isset( $_POST['trigger_delay'] ) ? absint( $_POST['trigger_delay'] ) : 0, // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified above
521 'display_on' => isset( $_POST['display_on'] ) ? sanitize_text_field( wp_unslash( $_POST['display_on'] ) ) : '', // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified above
522 'show_frequency' => isset( $_POST['show_frequency'] ) ? sanitize_text_field( wp_unslash( $_POST['show_frequency'] ) ) : '', // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified above
523 'popup_position' => isset( $_POST['popup_position'] ) ? sanitize_text_field( wp_unslash( $_POST['popup_position'] ) ) : '', // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified above
524 'popup_width' => isset( $_POST['popup_width'] ) ? sanitize_text_field( wp_unslash( $_POST['popup_width'] ) ) : '', // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified above
525 'popup_animation' => isset( $_POST['popup_animation'] ) ? sanitize_text_field( wp_unslash( $_POST['popup_animation'] ) ) : '', // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified above
526 'status' => isset($_POST['popup_status']) ? 'active' : 'inactive',
527 'settings' => [
528 'show_overlay' => isset($_POST['show_overlay']),
529 'close_on_overlay' => isset($_POST['close_on_overlay']),
530 'show_close_button' => isset($_POST['show_close_button']),
531 'close_on_esc' => isset($_POST['close_on_esc']),
532 'show_logged_in' => isset($_POST['show_logged_in']),
533 'show_logged_out' => isset($_POST['show_logged_out']),
534 'show_first_time' => isset($_POST['show_first_time']),
535 'popup_priority' => isset( $_POST['popup_priority'] ) ? absint( $_POST['popup_priority'] ) : 0, // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified above
536 'popup_class' => isset( $_POST['popup_class'] ) ? sanitize_text_field( wp_unslash( $_POST['popup_class'] ) ) : '', // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified above
537 'popup_custom_css' => isset( $_POST['popup_custom_css'] ) ? sanitize_textarea_field( wp_unslash( $_POST['popup_custom_css'] ) ) : '', // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified above
538 ]
539 ];
540
541 global $wpdb;
542 $table_name = $wpdb->prefix . 'jltma_popups';
543
544 if ($popup_id) {
545 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- direct update required for custom popup table, no WP core API equivalent
546 $result = $wpdb->update(
547 $table_name,
548 [
549 'name' => $popup_data['name'],
550 'type' => $popup_data['type'],
551 'content' => $popup_data['content'],
552 'settings' => json_encode($popup_data['settings']),
553 'status' => $popup_data['status'],
554 'updated_at' => current_time('mysql')
555 ],
556 ['id' => $popup_id]
557 );
558 } else {
559 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery -- direct insert required for custom popup table, no WP core API equivalent
560 $result = $wpdb->insert(
561 $table_name,
562 [
563 'name' => $popup_data['name'],
564 'type' => $popup_data['type'],
565 'content' => $popup_data['content'],
566 'settings' => json_encode($popup_data['settings']),
567 'status' => $popup_data['status'],
568 'created_at' => current_time('mysql'),
569 'updated_at' => current_time('mysql')
570 ]
571 );
572 $popup_id = $wpdb->insert_id;
573 }
574
575 if ($result !== false) {
576 wp_send_json_success([
577 'message' => __('Popup saved successfully', 'master-addons'),
578 'popup_id' => $popup_id
579 ]);
580 } else {
581 wp_send_json_error(['message' => __('Failed to save popup', 'master-addons')]);
582 }
583 }
584
585 public function delete_popup() {
586 if (!check_ajax_referer('jltma_popup_builder', 'nonce', false)) {
587 wp_die( esc_html__('Security check failed', 'master-addons') );
588 }
589
590 if (!current_user_can('edit_posts')) {
591 wp_send_json_error(['message' => esc_html__('Invalid access', 'master-addons')]);
592 }
593
594 $popup_id = isset( $_POST['popup_id'] ) ? absint( $_POST['popup_id'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified above
595
596 global $wpdb;
597 $table_name = $wpdb->prefix . 'jltma_popups';
598
599 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- direct delete required for custom popup table, no WP core API equivalent
600 $result = $wpdb->delete($table_name, ['id' => $popup_id]);
601
602 if ($result) {
603 wp_send_json_success(['message' => __('Popup deleted successfully', 'master-addons')]);
604 } else {
605 wp_send_json_error(['message' => __('Failed to delete popup', 'master-addons')]);
606 }
607 }
608
609 public function duplicate_popup() {
610 if (!check_ajax_referer('jltma_popup_builder', 'nonce', false)) {
611 wp_die( esc_html__('Security check failed', 'master-addons') );
612 }
613
614 if (!current_user_can('edit_posts')) {
615 wp_send_json_error(['message' => esc_html__('Invalid access', 'master-addons')]);
616 }
617
618 $popup_id = isset( $_POST['popup_id'] ) ? absint( $_POST['popup_id'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified above
619
620 global $wpdb;
621 $table_name = $wpdb->prefix . 'jltma_popups';
622
623 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.PreparedSQL.InterpolatedNotPrepared,PluginCheck.Security.DirectDB.UnescapedDBParameter -- $table_name is a safe prefixed table name, value is prepared with %d
624 $popup = $wpdb->get_row($wpdb->prepare("SELECT * FROM $table_name WHERE id = %d", $popup_id));
625
626 if ($popup) {
627 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery -- direct insert required for custom popup table, no WP core API equivalent
628 $result = $wpdb->insert(
629 $table_name,
630 [
631 'name' => $popup->name . ' - Copy',
632 'type' => $popup->type,
633 'content' => $popup->content,
634 'settings' => $popup->settings,
635 'status' => 'inactive',
636 'created_at' => current_time('mysql'),
637 'updated_at' => current_time('mysql')
638 ]
639 );
640
641 if ($result) {
642 wp_send_json_success(['message' => __('Popup duplicated successfully', 'master-addons')]);
643 }
644 }
645
646 wp_send_json_error(['message' => __('Failed to duplicate popup', 'master-addons')]);
647 }
648
649 public function toggle_popup_status() {
650 if (!check_ajax_referer('jltma_popup_builder', 'nonce', false)) {
651 wp_die( esc_html__('Security check failed', 'master-addons') );
652 }
653
654 if (!current_user_can('edit_posts')) {
655 wp_send_json_error(['message' => esc_html__('Invalid access', 'master-addons')]);
656 }
657
658 $popup_id = isset( $_POST['popup_id'] ) ? absint( $_POST['popup_id'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified above
659
660 global $wpdb;
661 $table_name = $wpdb->prefix . 'jltma_popups';
662
663 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.PreparedSQL.InterpolatedNotPrepared,PluginCheck.Security.DirectDB.UnescapedDBParameter -- $table_name is a safe prefixed table name, value is prepared with %d
664 $popup = $wpdb->get_row($wpdb->prepare("SELECT status FROM $table_name WHERE id = %d", $popup_id));
665
666 if ($popup) {
667 $new_status = $popup->status === 'active' ? 'inactive' : 'active';
668
669 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- direct update required for custom popup table, no WP core API equivalent
670 $result = $wpdb->update(
671 $table_name,
672 ['status' => $new_status],
673 ['id' => $popup_id]
674 );
675
676 if ($result !== false) {
677 wp_send_json_success([
678 'message' => __('Status updated successfully', 'master-addons'),
679 'new_status' => $new_status
680 ]);
681 }
682 }
683
684 wp_send_json_error(['message' => __('Failed to update status', 'master-addons')]);
685 }
686
687 private function get_popup($id) {
688 global $wpdb;
689 $table_name = $wpdb->prefix . 'jltma_popups';
690
691 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.PreparedSQL.InterpolatedNotPrepared,PluginCheck.Security.DirectDB.UnescapedDBParameter -- $table_name is a safe prefixed table name, value is prepared with %d
692 $popup = $wpdb->get_row($wpdb->prepare("SELECT * FROM $table_name WHERE id = %d", $id));
693
694 if ($popup && !empty($popup->settings)) {
695 $popup->settings = json_decode($popup->settings, true);
696 }
697
698 return $popup;
699 }
700
701 public static function create_database_table() {
702 global $wpdb;
703
704 $table_name = $wpdb->prefix . 'jltma_popups';
705 $charset_collate = $wpdb->get_charset_collate();
706
707 $sql = "CREATE TABLE IF NOT EXISTS $table_name (
708 id mediumint(9) NOT NULL AUTO_INCREMENT,
709 name varchar(255) NOT NULL,
710 type varchar(50) NOT NULL,
711 content longtext NOT NULL,
712 settings longtext,
713 status varchar(20) DEFAULT 'active',
714 views int DEFAULT 0,
715 conversions int DEFAULT 0,
716 created_at datetime DEFAULT CURRENT_TIMESTAMP,
717 updated_at datetime DEFAULT CURRENT_TIMESTAMP,
718 PRIMARY KEY (id)
719 ) $charset_collate;";
720
721 require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
722 dbDelta($sql);
723 }
724 }