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 / 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.2, at inc/admin/popup-builder/class-popup-builder.php

708 lines 37.0 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_ma_popup_save', [$this, 'save_popup']);
30 add_action('wp_ajax_ma_popup_delete', [$this, 'delete_popup']);
31 add_action('wp_ajax_ma_popup_duplicate', [$this, 'duplicate_popup']);
32 add_action('wp_ajax_ma_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('ma_popup_save', 'ma_popup_nonce'); ?>
156 <input type="hidden" name="action" value="ma_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('ma_popup_save', 'ma_popup_nonce'); ?>
236 <input type="hidden" name="action" value="ma_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', 'ma_popup_builder', [
494 'ajax_url' => admin_url('admin-ajax.php'),
495 'nonce' => wp_create_nonce('ma_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('ma_popup_save', 'ma_popup_nonce', false)) {
507 wp_die( esc_html__('Security check failed', 'master-addons') );
508 }
509
510 $popup_id = isset( $_POST['popup_id'] ) ? absint( $_POST['popup_id'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified above
511 $popup_data = [
512 'name' => isset( $_POST['popup_name'] ) ? sanitize_text_field( wp_unslash( $_POST['popup_name'] ) ) : '', // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified above
513 'type' => isset( $_POST['popup_type'] ) ? sanitize_text_field( wp_unslash( $_POST['popup_type'] ) ) : '', // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified above
514 'content' => isset( $_POST['popup_content'] ) ? wp_kses_post( wp_unslash( $_POST['popup_content'] ) ) : '', // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified above
515 'trigger_type' => isset( $_POST['trigger_type'] ) ? sanitize_text_field( wp_unslash( $_POST['trigger_type'] ) ) : '', // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified above
516 'trigger_delay' => isset( $_POST['trigger_delay'] ) ? absint( $_POST['trigger_delay'] ) : 0, // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified above
517 'display_on' => isset( $_POST['display_on'] ) ? sanitize_text_field( wp_unslash( $_POST['display_on'] ) ) : '', // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified above
518 'show_frequency' => isset( $_POST['show_frequency'] ) ? sanitize_text_field( wp_unslash( $_POST['show_frequency'] ) ) : '', // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified above
519 'popup_position' => isset( $_POST['popup_position'] ) ? sanitize_text_field( wp_unslash( $_POST['popup_position'] ) ) : '', // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified above
520 'popup_width' => isset( $_POST['popup_width'] ) ? sanitize_text_field( wp_unslash( $_POST['popup_width'] ) ) : '', // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified above
521 'popup_animation' => isset( $_POST['popup_animation'] ) ? sanitize_text_field( wp_unslash( $_POST['popup_animation'] ) ) : '', // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified above
522 'status' => isset($_POST['popup_status']) ? 'active' : 'inactive',
523 'settings' => [
524 'show_overlay' => isset($_POST['show_overlay']),
525 'close_on_overlay' => isset($_POST['close_on_overlay']),
526 'show_close_button' => isset($_POST['show_close_button']),
527 'close_on_esc' => isset($_POST['close_on_esc']),
528 'show_logged_in' => isset($_POST['show_logged_in']),
529 'show_logged_out' => isset($_POST['show_logged_out']),
530 'show_first_time' => isset($_POST['show_first_time']),
531 'popup_priority' => isset( $_POST['popup_priority'] ) ? absint( $_POST['popup_priority'] ) : 0, // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified above
532 'popup_class' => isset( $_POST['popup_class'] ) ? sanitize_text_field( wp_unslash( $_POST['popup_class'] ) ) : '', // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified above
533 '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
534 ]
535 ];
536
537 global $wpdb;
538 $table_name = $wpdb->prefix . 'ma_popups';
539
540 if ($popup_id) {
541 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- direct update required for custom popup table, no WP core API equivalent
542 $result = $wpdb->update(
543 $table_name,
544 [
545 'name' => $popup_data['name'],
546 'type' => $popup_data['type'],
547 'content' => $popup_data['content'],
548 'settings' => json_encode($popup_data['settings']),
549 'status' => $popup_data['status'],
550 'updated_at' => current_time('mysql')
551 ],
552 ['id' => $popup_id]
553 );
554 } else {
555 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery -- direct insert required for custom popup table, no WP core API equivalent
556 $result = $wpdb->insert(
557 $table_name,
558 [
559 'name' => $popup_data['name'],
560 'type' => $popup_data['type'],
561 'content' => $popup_data['content'],
562 'settings' => json_encode($popup_data['settings']),
563 'status' => $popup_data['status'],
564 'created_at' => current_time('mysql'),
565 'updated_at' => current_time('mysql')
566 ]
567 );
568 $popup_id = $wpdb->insert_id;
569 }
570
571 if ($result !== false) {
572 wp_send_json_success([
573 'message' => __('Popup saved successfully', 'master-addons'),
574 'popup_id' => $popup_id
575 ]);
576 } else {
577 wp_send_json_error(['message' => __('Failed to save popup', 'master-addons')]);
578 }
579 }
580
581 public function delete_popup() {
582 if (!check_ajax_referer('ma_popup_builder', 'nonce', false)) {
583 wp_die( esc_html__('Security check failed', 'master-addons') );
584 }
585
586 $popup_id = isset( $_POST['popup_id'] ) ? absint( $_POST['popup_id'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified above
587
588 global $wpdb;
589 $table_name = $wpdb->prefix . 'ma_popups';
590
591 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- direct delete required for custom popup table, no WP core API equivalent
592 $result = $wpdb->delete($table_name, ['id' => $popup_id]);
593
594 if ($result) {
595 wp_send_json_success(['message' => __('Popup deleted successfully', 'master-addons')]);
596 } else {
597 wp_send_json_error(['message' => __('Failed to delete popup', 'master-addons')]);
598 }
599 }
600
601 public function duplicate_popup() {
602 if (!check_ajax_referer('ma_popup_builder', 'nonce', false)) {
603 wp_die( esc_html__('Security check failed', 'master-addons') );
604 }
605
606 $popup_id = isset( $_POST['popup_id'] ) ? absint( $_POST['popup_id'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified above
607
608 global $wpdb;
609 $table_name = $wpdb->prefix . 'ma_popups';
610
611 // 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
612 $popup = $wpdb->get_row($wpdb->prepare("SELECT * FROM $table_name WHERE id = %d", $popup_id));
613
614 if ($popup) {
615 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery -- direct insert required for custom popup table, no WP core API equivalent
616 $result = $wpdb->insert(
617 $table_name,
618 [
619 'name' => $popup->name . ' - Copy',
620 'type' => $popup->type,
621 'content' => $popup->content,
622 'settings' => $popup->settings,
623 'status' => 'inactive',
624 'created_at' => current_time('mysql'),
625 'updated_at' => current_time('mysql')
626 ]
627 );
628
629 if ($result) {
630 wp_send_json_success(['message' => __('Popup duplicated successfully', 'master-addons')]);
631 }
632 }
633
634 wp_send_json_error(['message' => __('Failed to duplicate popup', 'master-addons')]);
635 }
636
637 public function toggle_popup_status() {
638 if (!check_ajax_referer('ma_popup_builder', 'nonce', false)) {
639 wp_die( esc_html__('Security check failed', 'master-addons') );
640 }
641
642 $popup_id = isset( $_POST['popup_id'] ) ? absint( $_POST['popup_id'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified above
643
644 global $wpdb;
645 $table_name = $wpdb->prefix . 'ma_popups';
646
647 // 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
648 $popup = $wpdb->get_row($wpdb->prepare("SELECT status FROM $table_name WHERE id = %d", $popup_id));
649
650 if ($popup) {
651 $new_status = $popup->status === 'active' ? 'inactive' : 'active';
652
653 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- direct update required for custom popup table, no WP core API equivalent
654 $result = $wpdb->update(
655 $table_name,
656 ['status' => $new_status],
657 ['id' => $popup_id]
658 );
659
660 if ($result !== false) {
661 wp_send_json_success([
662 'message' => __('Status updated successfully', 'master-addons'),
663 'new_status' => $new_status
664 ]);
665 }
666 }
667
668 wp_send_json_error(['message' => __('Failed to update status', 'master-addons')]);
669 }
670
671 private function get_popup($id) {
672 global $wpdb;
673 $table_name = $wpdb->prefix . 'ma_popups';
674
675 // 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
676 $popup = $wpdb->get_row($wpdb->prepare("SELECT * FROM $table_name WHERE id = %d", $id));
677
678 if ($popup && !empty($popup->settings)) {
679 $popup->settings = json_decode($popup->settings, true);
680 }
681
682 return $popup;
683 }
684
685 public static function create_database_table() {
686 global $wpdb;
687
688 $table_name = $wpdb->prefix . 'ma_popups';
689 $charset_collate = $wpdb->get_charset_collate();
690
691 $sql = "CREATE TABLE IF NOT EXISTS $table_name (
692 id mediumint(9) NOT NULL AUTO_INCREMENT,
693 name varchar(255) NOT NULL,
694 type varchar(50) NOT NULL,
695 content longtext NOT NULL,
696 settings longtext,
697 status varchar(20) DEFAULT 'active',
698 views int DEFAULT 0,
699 conversions int DEFAULT 0,
700 created_at datetime DEFAULT CURRENT_TIMESTAMP,
701 updated_at datetime DEFAULT CURRENT_TIMESTAMP,
702 PRIMARY KEY (id)
703 ) $charset_collate;";
704
705 require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
706 dbDelta($sql);
707 }
708 }