PluginProbe
NotificationX – FOMO, Live Sales Notification, WooCommerce Sales Popup, GDPR, Social Proof, Announcement Banner & Floating Notification Bar / trunk
NotificationX – FOMO, Live Sales Notification, WooCommerce Sales Popup, GDPR, Social Proof, Announcement Banner & Floating Notification Bar vtrunk
3.3.1 3.3.0 3.2.14 3.2.13 3.2.12 3.2.11 3.2.10 3.2.9 3.2.8 3.2.7 trunk 0.2.5.5 0.2.5.6 0.2.5.7 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.2.0 1.2.1 All 156 releases
notificationx / includes / Extensions / PopupNotification / PopupNotification.php

PopupNotification.php in NotificationX – FOMO, Live Sales Notification, WooCommerce Sales Popup, GDPR, Social Proof, Announcement Banner & Floating Notification Bar trunk, at includes/Extensions/PopupNotification/PopupNotification.php

1,333 lines 63.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Popup Notification
5 *
6 * @package NotificationX\Extensions
7 */
8
9 namespace NotificationX\Extensions\Popup;
10
11 use NotificationX\Admin\InfoTooltipManager;
12 use NotificationX\Core\PostType;
13 use NotificationX\GetInstance;
14 use NotificationX\Core\Rules;
15 use NotificationX\Extensions\GlobalFields;
16 use NotificationX\Extensions\Extension;
17
18 /**
19 * Popup Extension
20 * @method static Popup get_instance($args = null)
21 */
22 class PopupNotification extends Extension {
23 /**
24 * Instance of Popup
25 *
26 * @var Popup
27 */
28 use GetInstance;
29
30 public $priority = 15;
31 public $id = 'popup_notification';
32 public $doc_link = 'https://notificationx.com/docs/how-to-show-announcement-using-notificationx/';
33 public $types = 'popup';
34 public $module = 'modules_popup';
35
36 /**
37 * Initially Invoked when initialized.
38 */
39 public function __construct(){
40 parent::__construct();
41 }
42
43 public function init() {
44 parent::init();
45 }
46
47 public function init_extension()
48 {
49 $this->title = __('Announcement', 'notificationx');
50 $this->module_title = __('Announcement', 'notificationx');
51 $this->themes = [
52 'theme-one' => [
53 'source' => NOTIFICATIONX_ADMIN_URL . 'images/extensions/themes/popup/popup-theme-one.png',
54 'defaults' => [
55 'popup_title' => __('Want to build credibility & boost sales?', 'notificationx'),
56 'popup_content' => __('We help you optimize conversions & drive sales', 'notificationx'),
57 'popup_button_text' => __('Get Started with Free Plan', 'notificationx'),
58 'position' => 'center',
59 ],
60 'column' => "5",
61 ],
62 'theme-two' => [
63 'source' => NOTIFICATIONX_ADMIN_URL . 'images/extensions/themes/popup/popup-theme-two.png',
64 'defaults' => [
65 'popup_title' => __('Boost your sales using SureCart', 'notificationx'),
66 'popup_content' => __('<iframe width="560" height="315" src="https://www.youtube.com/embed/dw176Jmk74M?si=3suUqkCkQuYQrh2G" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>', 'notificationx'),
67 'popup_button_text' => __('See How', 'notificationx'),
68 'position' => 'center',
69 ],
70 'column' => "5",
71 ],
72
73 'theme-four' => [
74 'source' => NOTIFICATIONX_ADMIN_URL . 'images/extensions/themes/popup/popup-theme-four.webp',
75 'defaults' => [
76 'popup_title' => __('Need Help?', 'notificationx'),
77 'popup_content' => __('Get the latest news and updates delivered to your inbox.', 'notificationx'),
78 'popup_button_text' => __('Submit', 'notificationx'),
79 'position' => 'center',
80 ],
81 'column' => "5",
82 ],
83 'theme-five' => [
84 'source' => NOTIFICATIONX_ADMIN_URL . 'images/extensions/themes/popup/popup-theme-five.webp',
85 'defaults' => [
86 'popup_title' => __('Need Help?', 'notificationx'),
87 'popup_content' => __('Subscribe to receive exclusive offers and updates directly in your inbox.', 'notificationx'),
88 'popup_email_placeholder' => __('Enter your email address', 'notificationx'),
89 'popup_button_text' => __('Submit', 'notificationx'),
90 'position' => 'center',
91 ],
92 'is_pro' => true,
93 'column' => "5",
94 ],
95 'theme-seven' => [
96 'source' => NOTIFICATIONX_ADMIN_URL . 'images/extensions/themes/popup/popup-theme-seven.webp',
97 'defaults' => [
98 'popup_title' => __('Want latest updates?', 'notificationx'),
99 'popup_subtitle' => __('Would like to get the lastes news & updates instantly?', 'notificationx'),
100 'popup_email_placeholder' => __('Enter email address', 'notificationx'),
101 'popup_button_text' => __('Get In Touch', 'notificationx'),
102 'popup_icon' => 'mail_icon.svg',
103 'popup_button_icon' => 'mail_icon.svg',
104 'position' => 'center',
105 ],
106 'is_pro' => true,
107 'column' => "5",
108 ],
109 'theme-six' => [
110 'source' => NOTIFICATIONX_ADMIN_URL . 'images/extensions/themes/popup/popup-theme-six.webp',
111 'defaults' => [
112 'popup_title' => __('Get latest news & updates', 'notificationx'),
113 'popup_email_placeholder' => __('Your email address', 'notificationx'),
114 'popup_button_text' => __('Submit Now', 'notificationx'),
115 'position' => 'center',
116 ],
117 'is_pro' => true,
118 'column' => "5",
119 ],
120 'theme-three' => [
121 'source' => NOTIFICATIONX_ADMIN_URL . 'images/extensions/themes/popup/popup-theme-three.png',
122 'defaults' => [
123 'popup_title' => __('All Offers', 'notificationx'),
124 'popup_button_text' => __('Latest Offers', 'notificationx'),
125 'popup_button_icon' => 'latest_offer.svg',
126 'position' => 'center',
127 ],
128 'column' => "5",
129 ],
130 // Coupon Popup card (light) — headline + description + copyable
131 // coupon code + "Get Coupon" CTA + dismiss link.
132 'theme-eight' => [
133 'source' => NOTIFICATIONX_ADMIN_URL . 'images/extensions/themes/popup/popup-theme-eight.png',
134 'defaults' => [
135 'popup_title' => __('35% OFF NOW', 'notificationx'),
136 'popup_content' => __('Get an extra 35% off on all products!', 'notificationx'),
137 'popup_coupon_code' => __('GET35OFF', 'notificationx'),
138 'popup_button_text' => __('Get Coupon', 'notificationx'),
139 'popup_button_url' => '#',
140 'position' => 'center',
141 ],
142 'column' => "5",
143 ],
144 // Festive/seasonal coupon popup — doodle-textured colored header
145 // with a wavy divider, big discount headline, an eyebrow tagline,
146 // a headline + copyable coupon code + soft dismiss link (no CTA).
147 'theme-eleven' => [
148 'source' => NOTIFICATIONX_ADMIN_URL . 'images/extensions/themes/popup/popup-theme-eleven.png?v=2',
149 'defaults' => [
150 'popup_subtitle' => __('Back to School Deal', 'notificationx'),
151 'popup_title' => __('25% OFF!', 'notificationx'),
152 'popup_content' => __('Get a ready-to-go healthy lunchbox kit', 'notificationx'),
153 'popup_coupon_code' => __('BTS2025', 'notificationx'),
154 'position' => 'center',
155 ],
156 'column' => "5",
157 ],
158 // High-impact electronics flash-sale coupon popup — bold yellow
159 // card, a rotated "%OFF" sticker badge (subtitle = the big number),
160 // headline + subtext + copyable coupon code (no CTA / dismiss).
161 'theme-twelve' => [
162 'source' => NOTIFICATIONX_ADMIN_URL . 'images/extensions/themes/popup/popup-theme-twelve.png',
163 'defaults' => [
164 'popup_subtitle' => __('64%', 'notificationx'),
165 'popup_title' => __('Enjoy 64% Electronics Sale', 'notificationx'),
166 'popup_content' => __('Upgrade your gadgets at unbeatable prices.', 'notificationx'),
167 'popup_coupon_code' => __('ELEC 4512658', 'notificationx'),
168 'position' => 'center',
169 ],
170 'column' => "5",
171 ],
172 // Multi-tier discount popup — gift hero, two-tone heading, a list of
173 // coupon "tickets" (percent + code + validity) and a "Claim Now" CTA.
174 'theme-thirteen' => [
175 'source' => NOTIFICATIONX_ADMIN_URL . 'images/extensions/themes/popup/popup-theme-thirteen.png',
176 'defaults' => [
177 'popup_title' => __('Buy Upto $500', 'notificationx'),
178 'popup_subtitle' => __('And Get Discount Now', 'notificationx'),
179 'popup_content' => __('Take discount in your next order', 'notificationx'),
180 'popup_button_text' => __('Claim Now', 'notificationx'),
181 'popup_button_url' => '#',
182 'popup_coupon_repeater' => [
183 [
184 'coupon_percent' => __('20%', 'notificationx'),
185 'coupon_code' => __('#SAVE20', 'notificationx'),
186 'coupon_validity' => __('Valid for 7 Days', 'notificationx'),
187 ],
188 ],
189 'position' => 'center',
190 ],
191 'column' => "5",
192 ],
193
194 ];
195 }
196
197 public function init_fields() {
198 parent::init_fields();
199 add_filter('nx_design_tab_fields', [$this, 'design_fields'], 99);
200 add_filter('nx_content_fields', [$this, 'content_fields'], 999);
201 add_filter('nx_customize_fields', [$this, 'customize_fields'], 999);
202 add_filter('nx_display_fields', [$this, 'display_fields'], 999);
203 }
204
205 public function display_fields($fields) {
206 // Hide image selection
207 if (isset($fields['image-section'])) {
208 $fields['image-section'] = Rules::is('source', $this->id, true, $fields['image-section']);
209 }
210 return $fields;
211 }
212
213 public function design_fields( $fields ) {
214 if (isset($fields['advance_design_section']['fields']['design'])) {
215 $fields['advance_design_section']['fields']['design'] = Rules::is('source', $this->id, true, $fields['advance_design_section']['fields']['design']);
216 }
217 if (isset($fields['advance_design_section']['fields']['typography'])) {
218 $fields['advance_design_section']['fields']['typography'] = Rules::is('source', $this->id, true, $fields['advance_design_section']['fields']['typography']);
219 }
220 if (isset($fields['advance_design_section']['fields']['image-appearance'])) {
221 $fields['advance_design_section']['fields']['image-appearance'] = Rules::is('source', $this->id, true, $fields['advance_design_section']['fields']['image-appearance']);
222 }
223 if (isset($fields['advance_design_section']['fields']['link_button_design'])) {
224 $fields['advance_design_section']['fields']['link_button_design'] = Rules::is('source', $this->id, true, $fields['advance_design_section']['fields']['link_button_design']);
225 }
226
227 // Popup Container Design Section
228 $fields['advance_design_section']['fields']['popup_design'] = [
229 'label' => __("Popup Design", 'notificationx'),
230 'name' => "popup_design",
231 'type' => "section",
232 'priority' => 5,
233 'rules' => Rules::logicalRule([
234 Rules::is('source', $this->id, false),
235 Rules::is('advance_edit', true),
236 ]),
237 'fields' => [
238 [
239 'label' => __("Background Color", 'notificationx'),
240 'name' => "popup_bg_color",
241 'type' => "colorpicker",
242 ],
243 [
244 'label' => __("Overlay Background Color", 'notificationx'),
245 'name' => "overlay_color",
246 'type' => "colorpicker",
247 'help' => __('Background color of the overlay behind the popup', 'notificationx'),
248 ],
249 [
250 'label' => __('Popup Width', 'notificationx'),
251 'name' => "popup_width",
252 'type' => "number",
253 'description' => 'px',
254 'help' => __('Maximum width of the popup container', 'notificationx'),
255 ],
256 [
257 'label' => __('Border Radius', 'notificationx'),
258 'name' => "popup_border_radius",
259 'type' => "number",
260 'description' => 'px',
261 'help' => __('Rounded corners for the popup container', 'notificationx'),
262 ],
263 [
264 'label' => __('Popup Padding', 'notificationx'),
265 'name' => "popup_padding",
266 'type' => "text",
267 'help' => __('Internal spacing of popup content (e.g., 30px or 20px 30px)', 'notificationx'),
268 ],
269 [
270 'label' => __("Close Button Color", 'notificationx'),
271 'name' => "close_btn_color",
272 'type' => "colorpicker",
273 ],
274 [
275 'label' => __('Close Button Size', 'notificationx'),
276 'name' => "close_btn_size",
277 'type' => "number",
278 'description' => 'px',
279 ],
280 ]
281 ];
282
283 // Typography Section
284 $fields['advance_design_section']['fields']['popup_typography'] = [
285 'label' => __("Typography", 'notificationx'),
286 'name' => "popup_typography",
287 'type' => "section",
288 'priority' => 6,
289 'rules' => Rules::logicalRule([
290 Rules::is('source', $this->id, false),
291 Rules::is('advance_edit', true),
292 ]),
293 'fields' => [
294 [
295 'label' => __("Title Color", 'notificationx'),
296 'name' => "popup_title_color",
297 'type' => "colorpicker",
298 ],
299 [
300 'label' => __('Title Font Size', 'notificationx'),
301 'name' => "popup_title_font_size",
302 'type' => "number",
303 'description' => 'px',
304 'help' => __('Font size for the popup title', 'notificationx'),
305 ],
306 [
307 'label' => __('Title Font Weight', 'notificationx'),
308 'name' => "popup_title_font_weight",
309 'type' => "select",
310 'options' => GlobalFields::get_instance()->normalize_fields([
311 '300' => __('Light (300)', 'notificationx'),
312 '400' => __('Normal (400)', 'notificationx'),
313 '500' => __('Medium (500)', 'notificationx'),
314 '600' => __('Semi Bold (600)', 'notificationx'),
315 '700' => __('Bold (700)', 'notificationx'),
316 '800' => __('Extra Bold (800)', 'notificationx'),
317 ]),
318 ],
319 [
320 'label' => __("Subtitle Color", 'notificationx'),
321 'name' => "popup_subtitle_color",
322 'type' => "colorpicker",
323 'rules' => Rules::is('themes', 'popup_notification_theme-seven'),
324 ],
325 [
326 'label' => __('Subtitle Font Size', 'notificationx'),
327 'name' => "popup_subtitle_font_size",
328 'type' => "number",
329 'description' => 'px',
330 'help' => __('Font size for the popup subtitle', 'notificationx'),
331 'rules' => Rules::is('themes', 'popup_notification_theme-seven'),
332 ],
333 [
334 'label' => __("Content/Message Color", 'notificationx'),
335 'name' => "popup_content_color",
336 'type' => "colorpicker",
337 'rules' => Rules::logicalRule([
338 Rules::is('themes', 'popup_notification_theme-one'),
339 Rules::is('themes', 'popup_notification_theme-two'),
340 Rules::is('themes', 'popup_notification_theme-three'),
341 Rules::is('themes', 'popup_notification_theme-four'),
342 Rules::is('themes', 'popup_notification_theme-five'),
343 ], 'or'),
344 ],
345 [
346 'label' => __('Content/Message Font Size', 'notificationx'),
347 'name' => "popup_content_font_size",
348 'type' => "number",
349 'description' => 'px',
350 'help' => __('Font size for the popup content/message text', 'notificationx'),
351 'rules' => Rules::logicalRule([
352 Rules::is('themes', 'popup_notification_theme-one'),
353 Rules::is('themes', 'popup_notification_theme-two'),
354 Rules::is('themes', 'popup_notification_theme-three'),
355 Rules::is('themes', 'popup_notification_theme-four'),
356 Rules::is('themes', 'popup_notification_theme-five'),
357 ], 'or'),
358 ],
359 ]
360 ];
361
362 // Button Design Section
363 $fields['advance_design_section']['fields']['popup_button_design'] = [
364 'label' => __("Button Design", 'notificationx'),
365 'name' => "popup_button_design",
366 'type' => "section",
367 'priority' => 7,
368 'rules' => Rules::logicalRule([
369 Rules::is('source', $this->id, false),
370 Rules::is('advance_edit', true),
371 ]),
372 'fields' => [
373 [
374 'label' => __("Background Color", 'notificationx'),
375 'name' => "popup_button_bg_color",
376 'type' => "colorpicker",
377 ],
378 [
379 'label' => __("Hover Background Color", 'notificationx'),
380 'name' => "popup_button_hover_bg_color",
381 'type' => "colorpicker",
382 'help' => __('Background color when button is hovered', 'notificationx'),
383 ],
384 [
385 'label' => __("Text Color", 'notificationx'),
386 'name' => "popup_button_text_color",
387 'type' => "colorpicker",
388 ],
389 [
390 'label' => __("Hover Text Color", 'notificationx'),
391 'name' => "popup_button_hover_text_color",
392 'type' => "colorpicker",
393 'help' => __('Text color when button is hovered', 'notificationx'),
394 ],
395 [
396 'label' => __("Border Color", 'notificationx'),
397 'name' => "popup_button_border_color",
398 'type' => "colorpicker",
399 ],
400 [
401 'label' => __("Hover Border Color", 'notificationx'),
402 'name' => "popup_button_border_hover_color",
403 'type' => "colorpicker",
404 ],
405 [
406 'label' => __('Border Width', 'notificationx'),
407 'name' => "popup_button_border_width",
408 'type' => "number",
409 'description' => 'px',
410 'help' => __('Width of the button border', 'notificationx'),
411 ],
412 [
413 'label' => __('Font Size', 'notificationx'),
414 'name' => "popup_button_font_size",
415 'type' => "number",
416 'description' => 'px',
417 ],
418 [
419 'label' => __('Font Weight', 'notificationx'),
420 'name' => "popup_button_font_weight",
421 'type' => "select",
422 'options' => GlobalFields::get_instance()->normalize_fields([
423 '300' => __('Light (300)', 'notificationx'),
424 '400' => __('Normal (400)', 'notificationx'),
425 '500' => __('Medium (500)', 'notificationx'),
426 '600' => __('Semi Bold (600)', 'notificationx'),
427 '700' => __('Bold (700)', 'notificationx'),
428 ]),
429 ],
430 [
431 'label' => __('Border Radius', 'notificationx'),
432 'name' => "popup_button_border_radius",
433 'type' => "number",
434 'description' => 'px',
435 'help' => __('Rounded corners for the button', 'notificationx'),
436 ],
437 [
438 'label' => __('Padding', 'notificationx'),
439 'name' => "popup_button_padding",
440 'type' => "text",
441 'help' => __('Button spacing in CSS format (e.g., 12px 24px)', 'notificationx'),
442 ],
443 [
444 'label' => __('Button Width', 'notificationx'),
445 'name' => "popup_button_width",
446 'type' => "select",
447 'default' => 'auto',
448 'options' => GlobalFields::get_instance()->normalize_fields([
449 'auto' => __('Auto Width', 'notificationx'),
450 '100%' => __('Full Width', 'notificationx'),
451 'custom' => __('Custom Width', 'notificationx'),
452 ]),
453 ],
454 [
455 'label' => __('Custom Button Width', 'notificationx'),
456 'name' => "popup_button_custom_width",
457 'type' => "number",
458 'description' => 'px',
459 'rules' => Rules::is('popup_button_width', 'custom'),
460 ],
461 ]
462 ];
463
464 // Email Input Design Section (for email collection themes)
465 $fields['advance_design_section']['fields']['popup_email_design'] = [
466 'label' => __("Email Input Design", 'notificationx'),
467 'name' => "popup_email_design",
468 'type' => "section",
469 'priority' => 8,
470 'rules' => Rules::logicalRule([
471 Rules::is('source', $this->id, false),
472 Rules::is('advance_edit', true),
473 Rules::logicalRule([
474 Rules::is('themes', 'popup_notification_theme-five'),
475 Rules::is('themes', 'popup_notification_theme-six'),
476 Rules::is('themes', 'popup_notification_theme-seven'),
477 ], 'or'),
478 ]),
479 'fields' => [
480 [
481 'label' => __("Input Background Color", 'notificationx'),
482 'name' => "popup_email_bg_color",
483 'type' => "colorpicker",
484 ],
485 [
486 'label' => __("Input Text Color", 'notificationx'),
487 'name' => "popup_email_text_color",
488 'type' => "colorpicker",
489 ],
490 [
491 'label' => __("Input Border Color", 'notificationx'),
492 'name' => "popup_email_border_color",
493 'type' => "colorpicker",
494 ],
495 [
496 'label' => __("Input Focus Border Color", 'notificationx'),
497 'name' => "popup_email_focus_border_color",
498 'type' => "colorpicker",
499 'help' => __('Border color when input is focused', 'notificationx'),
500 ],
501 [
502 'label' => __("Placeholder Text Color", 'notificationx'),
503 'name' => "popup_email_placeholder_color",
504 'type' => "colorpicker",
505 ],
506 [
507 'label' => __('Input Font Size', 'notificationx'),
508 'name' => "popup_email_font_size",
509 'type' => "number",
510 'description' => 'px',
511 ],
512 [
513 'label' => __('Input Border Width', 'notificationx'),
514 'name' => "popup_email_border_width",
515 'type' => "number",
516 'description' => 'px',
517 ],
518 [
519 'label' => __('Input Border Radius', 'notificationx'),
520 'name' => "popup_email_border_radius",
521 'type' => "number",
522 'description' => 'px',
523 ],
524 [
525 'label' => __('Input Padding', 'notificationx'),
526 'name' => "popup_email_padding",
527 'type' => "text",
528 'help' => __('Input field spacing in CSS format (e.g., 12px 16px)', 'notificationx'),
529 ],
530 [
531 'label' => __('Input Height', 'notificationx'),
532 'name' => "popup_email_height",
533 'type' => "number",
534 'description' => 'px',
535 'help' => __('Height of the email input field', 'notificationx'),
536 ],
537 ]
538 ];
539
540 // Repeater Items Design Section (for theme-three only)
541 $fields['advance_design_section']['fields']['popup_repeater_design'] = [
542 'label' => __("Content Items Design", 'notificationx'),
543 'name' => "popup_repeater_design",
544 'type' => "section",
545 'priority' => 9,
546 'rules' => Rules::logicalRule([
547 Rules::is('source', $this->id, false),
548 Rules::is('advance_edit', true),
549 Rules::is('themes', 'popup_notification_theme-three'),
550 ]),
551 'fields' => [
552 [
553 'label' => __("Item Background Color", 'notificationx'),
554 'name' => "popup_repeater_item_bg_color",
555 'type' => "colorpicker",
556 'help' => __('Background color for each content item', 'notificationx'),
557 ],
558 [
559 'label' => __("Highlight Text Color", 'notificationx'),
560 'name' => "popup_repeater_highlight_color",
561 'type' => "colorpicker",
562 'help' => __('Color for the highlight text (e.g., "30% OFF")', 'notificationx'),
563 ],
564 [
565 'label' => __("Item Title Color", 'notificationx'),
566 'name' => "popup_repeater_title_color",
567 'type' => "colorpicker",
568 ],
569 [
570 'label' => __('Item Title Font Size', 'notificationx'),
571 'name' => "popup_repeater_title_font_size",
572 'type' => "number",
573 'description' => 'px',
574 ],
575 [
576 'label' => __('Item Title Font Weight', 'notificationx'),
577 'name' => "popup_repeater_title_font_weight",
578 'type' => "select",
579 'options' => GlobalFields::get_instance()->normalize_fields([
580 '400' => __('Normal (400)', 'notificationx'),
581 '500' => __('Medium (500)', 'notificationx'),
582 '600' => __('Semi Bold (600)', 'notificationx'),
583 '700' => __('Bold (700)', 'notificationx'),
584 ]),
585 ],
586 [
587 'label' => __("Item Subtitle Color", 'notificationx'),
588 'name' => "popup_repeater_subtitle_color",
589 'type' => "colorpicker",
590 ],
591 [
592 'label' => __('Item Subtitle Font Size', 'notificationx'),
593 'name' => "popup_repeater_subtitle_font_size",
594 'type' => "number",
595 'description' => 'px',
596 ],
597 [
598 'label' => __('Item Border Radius', 'notificationx'),
599 'name' => "popup_repeater_item_border_radius",
600 'type' => "number",
601 'description' => 'px',
602 'help' => __('Rounded corners for each content item', 'notificationx'),
603 ],
604 [
605 'label' => __('Item Padding', 'notificationx'),
606 'name' => "popup_repeater_item_padding",
607 'type' => "text",
608 'help' => __('Internal spacing for each content item (e.g., 16px)', 'notificationx'),
609 ],
610 [
611 'label' => __('Item Spacing', 'notificationx'),
612 'name' => "popup_repeater_item_spacing",
613 'type' => "number",
614 'description' => 'px',
615 'help' => __('Space between content items', 'notificationx'),
616 ],
617 ]
618 ];
619
620 return $fields;
621 }
622
623 public function content_fields( $fields ) {
624 if (isset($fields['utm_options'])) {
625 $fields['utm_options'] = Rules::is('source', $this->id, true, $fields['utm_options']);
626 }
627 if (isset($fields['content'])) {
628 $fields['content'] = Rules::is('source', $this->id, true, $fields['content']);
629 }
630
631 $fields['popup_content'] = [
632 'label' => __('Popup Content', 'notificationx'),
633 'name' => 'popup_content',
634 'type' => 'section',
635 'priority' => 5,
636 'rules' => Rules::is('source', $this->id),
637 'fields' => [
638 [
639 'label' => __('Title', 'notificationx'),
640 'name' => 'popup_title',
641 'type' => 'text',
642 'priority' => 10,
643 'default' => __('Special Offer!', 'notificationx'),
644 ],
645 [
646 'label' => __('Subtitle', 'notificationx'),
647 'name' => 'popup_subtitle',
648 'type' => 'text',
649 'priority' => 12,
650 // No global field-level default: a hardcoded value here pre-fills the
651 // field and blocks each theme's own `defaults` (subtitle) from applying
652 // on selection, so coupon themes (eleven/twelve/thirteen) inherited the
653 // wrong subtitle. Leave empty so the selected theme's default fills it.
654 'default' => '',
655 'rules' => Rules::logicalRule([
656 Rules::is('themes', 'popup_notification_theme-seven'),
657 Rules::is('themes', 'popup_notification_theme-eleven'),
658 Rules::is('themes', 'popup_notification_theme-twelve'),
659 Rules::is('themes', 'popup_notification_theme-thirteen'),
660 ], 'or'),
661 ],
662 [
663 'label' => __('Popup Icon', 'notificationx'),
664 'name' => 'popup_icon',
665 'type' => 'icon-picker',
666 'priority' => 15,
667 'iconPrefix' => NOTIFICATIONX_ADMIN_URL . 'images/icons/',
668 'default' => 'mail_icon.svg',
669 'rules' => Rules::is('themes', 'popup_notification_theme-seven'),
670 'options' => [
671 [
672 'icon' => 'mail_icon.svg',
673 'label' => __('Mail Icon', 'notificationx')
674 ],
675 ],
676 ],
677 [
678 'label' => __('Content', 'notificationx'),
679 'name' => 'popup_content',
680 'type' => 'textarea',
681 'priority' => 20,
682 'default' => __('Don\'t miss out on this amazing deal!', 'notificationx'),
683 'rules' => Rules::logicalRule([
684 Rules::is('themes', 'popup_notification_theme-one'),
685 Rules::is('themes', 'popup_notification_theme-two'),
686 Rules::is('themes', 'popup_notification_theme-seven'),
687 Rules::is('themes', 'popup_notification_theme-eight'),
688 Rules::is('themes', 'popup_notification_theme-eleven'),
689 Rules::is('themes', 'popup_notification_theme-twelve'),
690 Rules::is('themes', 'popup_notification_theme-thirteen'),
691 ], 'or'),
692 ],
693 // Coupon code (with copy-to-clipboard) for the coupon-popup card
694 // themes (theme-eight / -eleven / -twelve).
695 [
696 'label' => __('Coupon Code', 'notificationx'),
697 'name' => 'popup_coupon_code',
698 'type' => 'text',
699 'priority' => 22,
700 // No global field-level default: it pre-filled the field with theme-eight's
701 // code and blocked theme-eleven/-twelve's own coupon-code defaults from
702 // applying on selection. Leave empty so the selected theme's default fills it.
703 'default' => '',
704 'placeholder' => __('GET35OFF', 'notificationx'),
705 'rules' => Rules::logicalRule([
706 Rules::is('themes', 'popup_notification_theme-eight'),
707 Rules::is('themes', 'popup_notification_theme-eleven'),
708 Rules::is('themes', 'popup_notification_theme-twelve'),
709 ], 'or'),
710 ],
711 // Multi-tier coupon "tickets" (percent + code + validity) for the
712 // multi-tier discount popup (theme-thirteen).
713 [
714 'label' => __('Coupon Tickets', 'notificationx'),
715 'name' => 'popup_coupon_repeater',
716 'type' => 'repeater',
717 'priority' => 23,
718 'rules' => Rules::is('themes', 'popup_notification_theme-thirteen'),
719 'button' => [
720 'label' => __('Add Coupon', 'notificationx'),
721 ],
722 'fields' => [
723 [
724 'label' => __('Discount', 'notificationx'),
725 'name' => 'coupon_percent',
726 'type' => 'text',
727 'placeholder' => __('e.g. 20%', 'notificationx'),
728 'help' => __('Big discount value shown on the left (e.g. "20%").', 'notificationx'),
729 ],
730 [
731 'label' => __('Coupon Code', 'notificationx'),
732 'name' => 'coupon_code',
733 'type' => 'text',
734 'placeholder' => __('e.g. #SAVE20', 'notificationx'),
735 ],
736 [
737 'label' => __('Validity', 'notificationx'),
738 'name' => 'coupon_validity',
739 'type' => 'text',
740 'placeholder' => __('e.g. Valid for 7 Days', 'notificationx'),
741 ],
742 ],
743 // One starter coupon by default. The QuickBuilder repeater always
744 // renders a single row for an unsaved field, so a one-row default
745 // keeps the editor, the saved data and the front end consistent
746 // (all show one coupon); users add more with the Add Coupon button.
747 'default' => [
748 [
749 'coupon_percent' => __('20%', 'notificationx'),
750 'coupon_code' => __('#SAVE20', 'notificationx'),
751 'coupon_validity' => __('Valid for 7 Days', 'notificationx'),
752 ],
753 ],
754 ],
755 // Form Field Toggles - only for form submission themes (4-7)
756 [
757 'label' => __('Show Name Field', 'notificationx'),
758 'name' => 'popup_show_name_field',
759 'type' => 'toggle',
760 'priority' => 25,
761 'default' => false,
762 'rules' => Rules::logicalRule([
763 Rules::is('themes', 'popup_notification_theme-four'),
764 Rules::is('themes', 'popup_notification_theme-five'),
765 Rules::is('themes', 'popup_notification_theme-six'),
766 Rules::is('themes', 'popup_notification_theme-seven'),
767 ], 'or'),
768 'is_pro' => true,
769 ],
770 [
771 'label' => __('Name Field Text', 'notificationx'),
772 'name' => 'popup_name_placeholder',
773 'type' => 'text',
774 'priority' => 30,
775 'default' => __('Enter your name', 'notificationx'),
776 'rules' => Rules::logicalRule([
777 Rules::logicalRule([
778 Rules::is('themes', 'popup_notification_theme-four'),
779 Rules::is('themes', 'popup_notification_theme-five'),
780 Rules::is('themes', 'popup_notification_theme-six'),
781 Rules::is('themes', 'popup_notification_theme-seven'),
782 ], 'or'),
783 Rules::is('popup_show_name_field', true),
784 ]),
785 ],
786 [
787 'label' => __('Show Email Field', 'notificationx'),
788 'name' => 'popup_show_email_field',
789 'type' => 'toggle',
790 'priority' => 35,
791 'info' => InfoTooltipManager::get_instance()->render('popup_notification_email_field'),
792 'rules' => Rules::logicalRule([
793 Rules::is('themes', 'popup_notification_theme-four'),
794 Rules::is('themes', 'popup_notification_theme-five'),
795 Rules::is('themes', 'popup_notification_theme-six'),
796 Rules::is('themes', 'popup_notification_theme-seven'),
797 ], 'or'),
798 'is_pro' => true,
799 ],
800 [
801 'label' => __('Email Field Text', 'notificationx'),
802 'name' => 'popup_email_placeholder',
803 'type' => 'text',
804 'priority' => 40,
805 'default' => __('Enter your email', 'notificationx'),
806 'rules' => Rules::logicalRule([
807 Rules::logicalRule([
808 Rules::is('themes', 'popup_notification_theme-four'),
809 Rules::is('themes', 'popup_notification_theme-five'),
810 Rules::is('themes', 'popup_notification_theme-six'),
811 Rules::is('themes', 'popup_notification_theme-seven'),
812 ], 'or'),
813 Rules::is('popup_show_email_field', true),
814 ]),
815 ],
816 [
817 'label' => __('Show Message Field', 'notificationx'),
818 'name' => 'popup_show_message_field',
819 'type' => 'toggle',
820 'priority' => 45,
821 'info' => InfoTooltipManager::get_instance()->render('popup_notification_message_field'),
822 'rules' => Rules::logicalRule([
823 Rules::is('themes', 'popup_notification_theme-four'),
824 Rules::is('themes', 'popup_notification_theme-five'),
825 Rules::is('themes', 'popup_notification_theme-six'),
826 Rules::is('themes', 'popup_notification_theme-seven'),
827 ], 'or'),
828 'default' => true,
829 ],
830 [
831 'label' => __('Message Field Text', 'notificationx'),
832 'name' => 'popup_message_placeholder',
833 'type' => 'text',
834 'priority' => 50,
835 'default' => __('Enter your message...', 'notificationx'),
836 'rules' => Rules::logicalRule([
837 Rules::logicalRule([
838 Rules::is('themes', 'popup_notification_theme-four'),
839 Rules::is('themes', 'popup_notification_theme-five'),
840 Rules::is('themes', 'popup_notification_theme-six'),
841 Rules::is('themes', 'popup_notification_theme-seven'),
842 ], 'or'),
843 Rules::is('popup_show_message_field', true),
844 ]),
845 ],
846
847 // Common Button Text field for all themes (theme-eleven and
848 // theme-twelve have no CTA — the copyable coupon code is the CTA).
849 [
850 'label' => __('Button Text', 'notificationx'),
851 'name' => 'popup_button_text',
852 'type' => 'text',
853 'priority' => 55,
854 'default' => __('Get Offer', 'notificationx'),
855 'rules' => Rules::logicalRule([
856 Rules::is('themes', 'popup_notification_theme-eleven', true),
857 Rules::is('themes', 'popup_notification_theme-twelve', true),
858 ], 'and'),
859 ],
860 // Button URL field - only for themes 1-3 (promotional themes with external links)
861 [
862 'label' => __('Button URL', 'notificationx'),
863 'name' => 'popup_button_url',
864 'type' => 'text',
865 'priority' => 60,
866 'default' => '#',
867 'rules' => Rules::logicalRule([
868 Rules::is('themes', 'popup_notification_theme-one'),
869 Rules::is('themes', 'popup_notification_theme-two'),
870 Rules::is('themes', 'popup_notification_theme-three'),
871 Rules::is('themes', 'popup_notification_theme-eight'),
872 Rules::is('themes', 'popup_notification_theme-thirteen'),
873 ], 'or'),
874 ],
875
876 // Button Icon field - only for theme-three and theme-seven
877 [
878 'label' => __('Button Icon', 'notificationx'),
879 'name' => 'popup_button_icon',
880 'type' => 'icon-picker',
881 'priority' => 62,
882 'iconPrefix' => NOTIFICATIONX_ADMIN_URL . 'images/icons/',
883 'default' => 'mail_icon.svg',
884 'options' => [
885 [
886 'icon' => 'mail_icon.svg',
887 'label' => __('Mail Icon', 'notificationx')
888 ],
889 [
890 'icon' => 'latest_offer.svg',
891 'label' => __('Latest OFfer', 'notificationx')
892 ],
893 [
894 'icon' => 'shop_now.svg',
895 'label' => __('Shop Now', 'notificationx')
896 ],
897 [
898 'icon' => 'shop_now_white.svg',
899 'label' => __('Shop Now White', 'notificationx')
900 ],
901 ],
902 'description' => __('Select an icon to display with the button text', 'notificationx'),
903 'rules' => Rules::logicalRule([
904 Rules::is('themes', 'popup_notification_theme-three'),
905 Rules::is('themes', 'popup_notification_theme-seven'),
906 ], 'or'),
907 ],
908 'open_in_new_tab' => [
909 'label' => __('Open URL in New Tab', 'notificationx'),
910 'name' => 'open_in_new_tab',
911 'type' => 'toggle',
912 'default' => false,
913 'rules' => Rules::logicalRule([
914 Rules::is('themes', 'popup_notification_theme-one'),
915 Rules::is('themes', 'popup_notification_theme-two'),
916 Rules::is('themes', 'popup_notification_theme-three'),
917 Rules::is('themes', 'popup_notification_theme-eight'),
918 Rules::is('themes', 'popup_notification_theme-thirteen'),
919 ], 'or'),
920 ],
921 // Repeater fields - only for theme-three
922 [
923 'label' => __('Content Items', 'notificationx'),
924 'name' => 'popup_content_repeater',
925 'type' => 'repeater',
926 'priority' => 65,
927 'rules' => Rules::is('themes', 'popup_notification_theme-three'),
928 'button' => [
929 'label' => __('Add New', 'notificationx')
930 ],
931 'fields' => [
932 [
933 'label' => __('Highlight Text', 'notificationx'),
934 'name' => 'repeater_highlight_text',
935 'type' => 'text',
936 'default' => __('30% OFF', 'notificationx'),
937 'help' => __('Text that will be highlighted in a different color (e.g., "30% OFF")', 'notificationx'),
938 ],
939 [
940 'label' => __('Title', 'notificationx'),
941 'name' => 'repeater_title',
942 'type' => 'text',
943 'default' => __('Feature Title', 'notificationx'),
944 ],
945 [
946 'label' => __('Subtitle', 'notificationx'),
947 'name' => 'repeater_subtitle',
948 'type' => 'text',
949 'default' => __('Feature description', 'notificationx'),
950 ],
951 ],
952 'default' => [
953 [
954 'repeater_highlight_text' => __('30% OFF', 'notificationx'),
955 'repeater_title' => __('Boost Sales', 'notificationx'),
956 'repeater_subtitle' => __('Increase conversions with social proof', 'notificationx'),
957 ],
958 [
959 'repeater_highlight_text' => __('50% OFF', 'notificationx'),
960 'repeater_title' => __('Build Trust', 'notificationx'),
961 'repeater_subtitle' => __('Show real customer activity', 'notificationx'),
962 ],
963 [
964 'repeater_highlight_text' => __('LIMITED', 'notificationx'),
965 'repeater_title' => __('Drive Action', 'notificationx'),
966 'repeater_subtitle' => __('Create urgency and FOMO', 'notificationx'),
967 ],
968 ],
969 ],
970 ]
971 ];
972
973 return $fields;
974 }
975
976 /**
977 * Fill EMPTY theme-specific fields from the selected theme's `defaults`.
978 *
979 * Why this is needed: the builder applies a theme's `defaults` on selection, but
980 * fields that are rules-gated OUT of the initial theme (e.g. popup_subtitle,
981 * popup_coupon_code, popup_coupon_repeater) get re-initialized to their own
982 * field-level default when they mount, clobbering the theme default. As a result
983 * the coupon themes (eleven/twelve/thirteen) ended up with the wrong/empty
984 * subtitle, coupon code and coupon tickets on a default (untouched) publish — so
985 * both the live Preview and the front end didn't match the design.
986 *
987 * This safety net fills only EMPTY values, so anything the user actually typed is
988 * preserved. A repeater row that holds only framework metadata (index/chosen/
989 * selected) with no real content counts as empty.
990 *
991 * @param array $data Flat settings array (content fields at top level).
992 * @param string $theme_full Selected theme key, e.g. "popup_notification_theme-twelve".
993 * @return array
994 */
995 private function fill_theme_defaults( $data, $theme_full ) {
996 if ( empty( $theme_full ) || empty( $this->themes ) || ! is_array( $data ) ) {
997 return $data;
998 }
999 // Strip the source-id prefix ("popup_notification_") to get the raw theme key.
1000 $prefix = $this->id . '_';
1001 $theme_key = ( strpos( $theme_full, $prefix ) === 0 ) ? substr( $theme_full, strlen( $prefix ) ) : $theme_full;
1002
1003 if ( empty( $this->themes[ $theme_key ]['defaults'] ) || ! is_array( $this->themes[ $theme_key ]['defaults'] ) ) {
1004 return $data;
1005 }
1006 // Keys the repeater/field framework injects into each row that carry no
1007 // user content — a row made up only of these is effectively empty.
1008 $meta_keys = array( 'index', 'chosen', 'selected' );
1009 foreach ( $this->themes[ $theme_key ]['defaults'] as $key => $value ) {
1010 $current = isset( $data[ $key ] ) ? $data[ $key ] : null;
1011 $is_empty = ( null === $current || '' === $current );
1012 if ( is_array( $current ) ) {
1013 // Empty array, or an array whose rows only hold framework metadata
1014 // (e.g. a clobbered repeater like [{index, chosen, selected}]).
1015 $has_real = false;
1016 foreach ( $current as $item ) {
1017 if ( is_array( $item ) ) {
1018 foreach ( $item as $ik => $iv ) {
1019 if ( ! in_array( $ik, $meta_keys, true ) && '' !== $iv && null !== $iv ) {
1020 $has_real = true;
1021 break 2;
1022 }
1023 }
1024 } elseif ( '' !== $item && null !== $item ) {
1025 $has_real = true;
1026 break;
1027 }
1028 }
1029 $is_empty = ! $has_real;
1030 }
1031 if ( $is_empty ) {
1032 $data[ $key ] = $value;
1033 }
1034 }
1035 return $data;
1036 }
1037
1038 /**
1039 * Apply theme defaults to empty fields at save time (persisted + front end).
1040 * Hooked automatically via nx_save_post_{$this->id} (see Extension::init()).
1041 *
1042 * @param array $post Post row about to be persisted; settings live in $post['data'].
1043 * @param array $data Full submitted settings.
1044 * @param int $nx_id Notification id (0 on create).
1045 * @return array
1046 */
1047 public function save_post( $post, $data, $nx_id ) {
1048 if ( isset( $post['data'] ) && is_array( $post['data'] ) ) {
1049 $theme_full = ! empty( $data['themes'] ) ? $data['themes'] : ( ! empty( $post['theme'] ) ? $post['theme'] : '' );
1050 $post['data'] = $this->fill_theme_defaults( $post['data'], $theme_full );
1051 $post['data'] = $this->strip_empty_repeater_rows( $post['data'] );
1052 }
1053 return $post;
1054 }
1055
1056 /**
1057 * Drop repeater rows that hold only framework metadata (index/chosen/selected)
1058 * and no real content. The QuickBuilder repeater commits a freshly "Add"ed row
1059 * with just an "index" until its inputs are edited, so an untouched extra coupon
1060 * would otherwise persist as an empty ticket that renders as a broken blank
1061 * ticket on the front end. Only the known coupon repeater is cleaned, so no other
1062 * data is affected.
1063 *
1064 * @param array $data Flat settings array.
1065 * @return array
1066 */
1067 private function strip_empty_repeater_rows( $data ) {
1068 $meta_keys = array( 'index', 'chosen', 'selected' );
1069 $repeater_fields = array( 'popup_coupon_repeater' );
1070 foreach ( $repeater_fields as $field ) {
1071 if ( empty( $data[ $field ] ) || ! is_array( $data[ $field ] ) ) {
1072 continue;
1073 }
1074 $data[ $field ] = array_values( array_filter( $data[ $field ], function ( $row ) use ( $meta_keys ) {
1075 if ( ! is_array( $row ) ) {
1076 return '' !== $row && null !== $row;
1077 }
1078 foreach ( $row as $k => $v ) {
1079 if ( ! in_array( $k, $meta_keys, true ) && '' !== $v && null !== $v ) {
1080 return true;
1081 }
1082 }
1083 return false;
1084 } ) );
1085 }
1086 return $data;
1087 }
1088
1089 /**
1090 * Apply theme defaults to empty fields for the live builder Preview, so the
1091 * preview matches the design even before anything is saved.
1092 * Hooked automatically via nx_preview_settings_{$this->id} (see Extension::init()).
1093 *
1094 * @param array $settings Flat preview settings.
1095 * @return array
1096 */
1097 public function preview_settings( $settings ) {
1098 $theme_full = ! empty( $settings['themes'] ) ? $settings['themes'] : ( ! empty( $settings['theme'] ) ? $settings['theme'] : '' );
1099 return $this->fill_theme_defaults( $settings, $theme_full );
1100 }
1101
1102 /**
1103 * Generate entry key
1104 *
1105 * @param string $key
1106 * @return string
1107 */
1108 public function key($key = '') {
1109 return $this->id . '_' . $key;
1110 }
1111
1112
1113 /**
1114 * Handle popup form submission
1115 *
1116 * @param WP_REST_Request $request
1117 * @return WP_REST_Response
1118 */
1119 public function handle_popup_submission($request) {
1120 $params = $request->get_params();
1121
1122 $id = $params['nx_id'];
1123 $notificationx = PostType::get_instance()->get_post( $id );
1124 if( !$notificationx ) {
1125 return new \WP_REST_Response([
1126 'success' => false,
1127 'message' => __('Notification not found', 'notificationx'),
1128 ], 404);
1129 }
1130
1131 // Prepare entry data
1132 $data = [
1133 'title' => $params['title'] ?: __('Popup Submission', 'notificationx'),
1134 'timestamp' => time(),
1135 ];
1136
1137 // Add email if provided
1138 if (!empty($params['email'])) {
1139 $data['email'] = $params['email'];
1140 }
1141
1142 // Add message if provided
1143 if (!empty($params['message'])) {
1144 $data['message'] = $params['message'];
1145 }
1146
1147 if (!empty($params['name'])) {
1148 $data['name'] = $params['name'];
1149 }
1150
1151 // Add theme information
1152 if (!empty($params['theme'])) {
1153 $data['theme'] = $params['theme'];
1154 }
1155
1156 // Add IP address
1157 $data['ip'] = $this->get_user_ip();
1158
1159 // Use the post's own source so exit-intent submissions aren't mis-tagged as
1160 // popup_notification (the same /popup-submit endpoint serves both types).
1161 $source = ! empty( $notificationx['source'] ) ? $notificationx['source'] : $this->id;
1162 $entry_key = $source . '_' . $params['nx_id'];
1163 $entry = [
1164 'nx_id' => $params['nx_id'],
1165 'source' => $source,
1166 'entry_key' => $entry_key,
1167 'data' => $data,
1168 ];
1169
1170 // Save the entry
1171 $this->update_notification($entry);
1172
1173 return new \WP_REST_Response([
1174 'success' => true,
1175 'message' => __('Submission saved successfully', 'notificationx'),
1176 ], 200);
1177 }
1178
1179
1180 /**
1181 * Get user IP address
1182 *
1183 * @return string
1184 */
1185 private function get_user_ip() {
1186 if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
1187 return sanitize_text_field(wp_unslash($_SERVER['HTTP_CLIENT_IP']));
1188 } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
1189 return sanitize_text_field(wp_unslash($_SERVER['HTTP_X_FORWARDED_FOR']));
1190 } else {
1191 return isset($_SERVER['REMOTE_ADDR']) ? sanitize_text_field(wp_unslash($_SERVER['REMOTE_ADDR'])) : '';
1192 }
1193 }
1194
1195
1196 /**
1197 * This method is an implementable method for All Extension coming forward.
1198 *
1199 * @param array $args Settings arguments.
1200 * @return mixed
1201 */
1202 public function customize_fields($fields) {
1203 $fields["timing"]['fields']['delay_between'] = Rules::is('source', $this->id, true, $fields["timing"]['fields']['delay_between']);
1204 $fields["timing"]['fields']['display_for'] = Rules::is('source', $this->id, true, $fields["timing"]['fields']['display_for']);
1205
1206 if (isset($fields['behaviour'])) {
1207 $fields['behaviour'] = Rules::is('source', $this->id, true, $fields['behaviour']);
1208 }
1209 if (isset($fields['sound_section'])) {
1210 $fields['sound_section'] = Rules::is('source', $this->id, true, $fields['sound_section']);
1211 }
1212 if (isset($fields['queue_management'])) {
1213 $fields['queue_management'] = Rules::is('source', $this->id, true, $fields['queue_management']);
1214 }
1215
1216 $_fields = &$fields["appearance"]['fields'];
1217 $conversion_position = &$_fields['position']['options'];
1218
1219 $conversion_position['center'] = [
1220 'label' => __('Center', 'notificationx'),
1221 'value' => 'center',
1222 'rules' => Rules::is('source', $this->id),
1223 ];
1224 // Exit Intent Popup conversion (Announcement type).
1225 $fields['exit_intent_settings'] = [
1226 'label' => __('Exit Intent Popup', 'notificationx'),
1227 'name' => 'exit_intent_settings',
1228 'type' => 'section',
1229 'priority' => 14,
1230 'rules' => Rules::_is('source', $this->id),
1231 'fields' => [
1232 'convert_to_exit_intent' => [
1233 'label' => __('Convert to Exit Intent Popup', 'notificationx'),
1234 'name' => 'convert_to_exit_intent',
1235 'type' => 'checkbox',
1236 'default' => false,
1237 'priority' => 5,
1238 'description' => __('Show this Announcement as a centered popup when the visitor is about to leave the page.', 'notificationx'),
1239 ],
1240 'exit_intent_cookie_duration' => [
1241 'label' => __('Cookie Duration', 'notificationx'),
1242 'name' => 'exit_intent_cookie_duration',
1243 'type' => 'number',
1244 'default' => 7,
1245 'min' => 1,
1246 'max' => 365,
1247 'priority' => 10,
1248 'description' => __('Days', 'notificationx'),
1249 'help' => __('Suppress the popup for this many days after it has been shown to a visitor.', 'notificationx'),
1250 'rules' => Rules::_is('convert_to_exit_intent', true),
1251 ],
1252 ],
1253 ];
1254
1255 $hide_when_exit_intent = Rules::logicalRule([
1256 Rules::_is('source', $this->id, true),
1257 Rules::_is('convert_to_exit_intent', true, true),
1258 ], 'or');
1259
1260 if (isset($fields['timing']['fields']['display_for'])) {
1261 $fields['timing']['fields']['display_for'] = Rules::add(
1262 $hide_when_exit_intent,
1263 $fields['timing']['fields']['display_for']
1264 );
1265 }
1266 if (isset($fields['timing']['fields']['delay_between'])) {
1267 $fields['timing']['fields']['delay_between'] = Rules::add(
1268 $hide_when_exit_intent,
1269 $fields['timing']['fields']['delay_between']
1270 );
1271 }
1272 if (isset($_fields['position'])) {
1273 $_fields['position'] = Rules::add(
1274 $hide_when_exit_intent,
1275 $_fields['position']
1276 );
1277 }
1278
1279 // Popup specific settings
1280 $fields['popup_settings'] = [
1281 'label' => __('Popup Settings', 'notificationx'),
1282 'name' => 'popup_settings',
1283 'type' => 'section',
1284 'priority' => 15,
1285 'rules' => Rules::is('source', $this->id),
1286 'fields' => [
1287 'show_close_button' => [
1288 'label' => __('Show Close Button', 'notificationx'),
1289 'name' => 'show_close_button',
1290 'type' => 'toggle',
1291 'default' => true,
1292 ],
1293 'close_on_button_click' => [
1294 'label' => __('Close on Button Click', 'notificationx'),
1295 'name' => 'close_on_button_click',
1296 'type' => 'toggle',
1297 'default' => true,
1298 ],
1299 'close_button_position' => [
1300 'label' => __('Close Button Position', 'notificationx'),
1301 'name' => 'close_button_position',
1302 'type' => 'select',
1303 'default' => 'top-right',
1304 'options' => GlobalFields::get_instance()->normalize_fields([
1305 'top-right' => __('Top Right', 'notificationx'),
1306 'top-left' => __('Top Left', 'notificationx'),
1307 'bottom-right' => __('Bottom Right', 'notificationx'),
1308 'bottom-left' => __('Bottom Left', 'notificationx'),
1309 ]),
1310 'rules' => Rules::is('show_close_button', true),
1311 ],
1312 ]
1313 ];
1314
1315 return $fields;
1316 }
1317
1318 public function doc(){
1319 /* translators: %1$s: step-by-step guides link URL, %2$s: tutorial link URL, %3$s: URL */
1320 return sprintf(__('<p>Create compelling Announcements that capture visitor interest and help you generate more leads on your WordPress site. Need help? Check out our <a href="%1$s" target="_blank">step-by-step guides</a> to build impactful Announcements.</p>
1321 <p>🎦 Watch the quick video <a target="_blank" href="%2$s">tutorial</a> for an easy walk-through.</p>
1322 <p><strong>Recommended Blogs:</strong></p>
1323 <p>🔥 <a target="_blank" href="%3$s">How to Create High-Performing Announcements with NotificationX?</a></p>
1324 <p><strong>Pro Tips:</strong></p>
1325 <p>✨ Use attention-grabbing headlines and clear action prompts to encourage more sign-ups.</p>', 'notificationx'),
1326 'https://notificationx.com/docs/how-to-show-announcement-using-notificationx/',
1327 'https://www.youtube.com/playlist?list=PLWHp1xKHCfxAj4AAs3kmzmDZKvjv6eycK',
1328 'https://notificationx.com/blog/announcement-notifications-on-wordpress'
1329 );
1330 }
1331
1332 }
1333