PluginProbe
Post Grid Gutenberg Blocks – PostX / 5.0.30
Post Grid Gutenberg Blocks – PostX v5.0.30
5.0.39 5.0.38 5.0.37 5.0.36 5.0.35 5.0.34 5.0.33 5.0.32 5.0.31 5.0.30 5.0.29 5.0.28 5.0.27 5.0.26 5.0.25 5.0.23 5.0.24 5.0.22 5.0.21 5.0.20 5.0.19 5.0.18 5.0.17 2.1.1 2.1.2 All 237 releases
ultimate-post / includes / notice / class-notice.php

class-notice.php in Post Grid Gutenberg Blocks – PostX 5.0.30, at includes/notice/class-notice.php

1,062 lines 32.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php //phpcs:ignore
2 namespace ULTP\Includes\Notice;
3
4 defined( 'ABSPATH' ) || exit;
5
6 use ULTP\Includes\Durbin\Xpo;
7 use ULTP\Includes\Durbin\DurbinClient;
8
9 /**
10 * Plugin Notice
11 */
12 class Notice {
13
14
15 /**
16 * Notice version
17 *
18 * @var string
19 */
20 private $notice_version = 'v5132';
21
22 /**
23 * Notice JS/CSS applied
24 *
25 * @var boolean
26 */
27 private $notice_js_css_applied = false;
28
29 /**
30 * Notice Priority
31 *
32 * @var string $plugin_notice_priority
33 */
34 private $plugin_notice_priority = 1;
35
36 /**
37 * Notice Priority
38 *
39 * @var string $plugin_notice_priority
40 */
41 private $plugin_notice_priority_key = 'postx';
42
43 /**
44 * Notice Constructor
45 */
46 public function __construct() {
47 add_action( 'admin_notices', array( $this, 'admin_notices_callback' ) );
48 add_action( 'admin_init', array( $this, 'set_dismiss_notice_callback' ) );
49
50 // REST API routes.
51 add_action( 'rest_api_init', array( $this, 'register_rest_route' ) );
52
53 // Woocommerce Install Action
54 // add_action( 'wp_ajax_ultp_install', array( $this, 'install_activate_plugin' ) ); // this ajax not called anywhere in future need to removed, that is arise patchstack security issue
55 add_filter( 'xpo_active_notice_lists', array( $this, 'handle_xpo_active_notice_lists' ), 99, 1 );
56 }
57
58 /**
59 * Registers REST API endpoints.
60 *
61 * @return void
62 */
63 public function register_rest_route() {
64 $routes = array(
65 // Hello Bar.
66 array(
67 'endpoint' => 'hello_bar',
68 'methods' => 'POST',
69 'callback' => array( $this, 'hello_bar_callback' ),
70 'permission_callback' => function () {
71 return current_user_can( 'manage_options' );
72 },
73 ),
74 );
75
76 foreach ( $routes as $route ) {
77 register_rest_route(
78 'ultp',
79 $route['endpoint'],
80 array(
81 array(
82 'methods' => $route['methods'],
83 'callback' => $route['callback'],
84 'permission_callback' => $route['permission_callback'],
85 ),
86 )
87 );
88 }
89 }
90
91 /**
92 * Hellobar config
93 *
94 * @return array
95 */
96 public static function get_hellobar_config() {
97 return array(
98 // Flash sale.
99 'ultp_helloBar_flash_sale_2026_4' => Xpo::get_transient_without_cache( 'ultp_helloBar_flash_sale_2026_4' ),
100 // Surprise sale.
101 'ultp_helloBar_surprise_sale_2026_5' => Xpo::get_transient_without_cache( 'ultp_helloBar_surprise_sale_2026_5' ),
102 // Massive sale.
103 'ultp_helloBar_massive_sale_2026_6' => Xpo::get_transient_without_cache( 'ultp_helloBar_massive_sale_2026_6' ),
104 // Final hours sale.
105 'ultp_helloBar_final_hours_sale_2026_7' => Xpo::get_transient_without_cache( 'ultp_helloBar_final_hours_sale_2026_7' ),
106 );
107 }
108
109 /**
110 * Handles Hello Bar dismissal action via REST API .
111 *
112 * @param \WP_REST_Request $request REST request object .
113 * @return \WP_REST_Response
114 */
115 public function hello_bar_callback( \WP_REST_Request $request ) {
116 $request_params = $request->get_params();
117 $type = isset( $request_params['type'] ) ? $request_params['type'] : '';
118 $id = isset( $request_params['id'] ) ? $request_params['id'] : '';
119
120 if ( 'hello_bar' === $type && ! empty( $id ) ) {
121 Xpo::set_transient_without_cache( $id, 'hide', 1296000 );
122 }
123
124 return new \WP_REST_Response(
125 array(
126 'success' => true,
127 'message' => __( 'Hello Bar Action performed', 'ultimate-post' ),
128 ),
129 200
130 );
131 }
132
133 /**
134 * Set Notice Dismiss Callback
135 *
136 * @return void
137 */
138 public function set_dismiss_notice_callback() {
139
140 if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['wpnonce'] ?? '' ) ), 'ultp-nonce' ) ) {
141 return;
142 }
143
144 $durbin_key = sanitize_text_field( wp_unslash( $_GET['ultp_durbin_key'] ?? '' ) );
145
146 // Durbin notice dismiss.
147 if ( ! empty( $durbin_key ) ) {
148 Xpo::set_transient_without_cache( 'ultp_durbin_notice_' . $durbin_key, 'off' );
149
150 if ( 'get' === sanitize_text_field( wp_unslash( $_GET['ultp_get_durbin'] ?? '' ) ) ) {
151 DurbinClient::send( DurbinClient::ACTIVATE_ACTION );
152 }
153 }
154
155 // Install notice dismiss.
156 $install_key = sanitize_text_field( wp_unslash( $_GET['ultp_install_key'] ?? '' ) );
157 if ( ! empty( $install_key ) ) {
158 Xpo::set_transient_without_cache( 'ultp_install_notice_' . $install_key, 'off' );
159 }
160 $notice_key = sanitize_text_field( wp_unslash( $_GET['ultp_notice'] ?? '' ) );
161 if ( ! empty( $notice_key ) ) {
162 $interval = (int) sanitize_text_field( wp_unslash( $_GET['ultp_interval'] ?? '' ) );
163 if ( ! empty( $interval ) ) {
164 Xpo::set_transient_without_cache( 'ultp_get_pro_notice_' . $notice_key, 'off', $interval );
165 } else {
166 Xpo::set_transient_without_cache( 'ultp_get_pro_notice_' . $notice_key, 'off' );
167 }
168 }
169 }
170
171 /**
172 * Admin Notices Callback
173 *
174 * @return void
175 */
176 public function admin_notices_callback() {
177 $this->ultp_dashboard_notice_callback();
178 $this->ultp_dashboard_durbin_notice_callback();
179 }
180
181 /**
182 * Admin Dashboard Notice Callback
183 *
184 * @return void
185 */
186 public function ultp_dashboard_notice_callback() {
187 if ( $this->is_available_for_notice() ) {
188 $this->ultp_dashboard_banner_notice();
189 $this->ultp_dashboard_content_notice();
190 }
191 }
192
193 /**
194 * Dashboard Banner Notice
195 *
196 * @return void
197 */
198 public function ultp_dashboard_banner_notice( $return_bool = false ) {
199 $ultp_db_nonce = wp_create_nonce( 'ultp-nonce' );
200 $banner_notices = array(
201 // FLash sale.
202 array(
203 'key' => 'ultp_banner_flash_sale_2026_1',
204 'start' => '2026-05-18 00:00 Asia/Dhaka',
205 'end' => '2026-05-21 23:59 Asia/Dhaka', // format YY-MM-DD always set time 23:59 and zone Asia/Dhaka.
206
207 'brand_color' => '#0322ff',
208
209 'left_image' => ULTP_URL . 'assets/img/dashboard_banner/flash_sale/offer.png',
210 'right_image' => ULTP_URL . 'assets/img/dashboard_banner/flash_sale/btn.png',
211 'bg_image' => ULTP_URL . 'assets/img/dashboard_banner/flash_sale/bg.png',
212 'text' => 'Deal ending soon',
213 'countdown_duration' => 259200, // Duration in seconds.
214 // 'countdown_color' => '#0322ff',
215 'countdown_color' => '#3CF357',
216 'url' => Xpo::generate_utm_link(
217 array(
218 'utmKey' => 'flash_sale_content',
219 )
220 ),
221
222 'visibility' => ! Xpo::is_lc_active(),
223 ),
224 // surprise sale
225 array(
226 'key' => 'ultp_banner_surprise_sale_2026_1',
227 'start' => '2026-05-29 00:00 Asia/Dhaka',
228 'end' => '2026-06-01 23:59 Asia/Dhaka', // format YY-MM-DD always set time 23:59 and zone Asia/Dhaka.
229
230 'brand_color' => '#0322ff',
231
232 'left_image' => ULTP_URL . 'assets/img/dashboard_banner/surprise_sale/offer.png',
233 'right_image' => ULTP_URL . 'assets/img/dashboard_banner/surprise_sale/btn.png',
234 'bg_image' => ULTP_URL . 'assets/img/dashboard_banner/surprise_sale/bg.png',
235 'text' => 'Limited Time Offer',
236 'countdown_duration' => 259200, // Duration in seconds.
237 // 'countdown_color' => '#0322ff',
238 'countdown_color' => '#3CF357',
239 'url' => Xpo::generate_utm_link(
240 array(
241 'utmKey' => 'surprise_sale_content',
242 )
243 ),
244
245 'visibility' => ! Xpo::is_lc_active(),
246 ),
247 // massive sale
248 array(
249 'key' => 'ultp_banner_massive_sale_2026_1',
250 'start' => '2026-06-17 00:00 Asia/Dhaka',
251 'end' => '2026-06-20 23:59 Asia/Dhaka', // format YY-MM-DD always set time 23:59 and zone Asia/Dhaka.
252
253 'brand_color' => '#0322ff',
254
255 'left_image' => ULTP_URL . 'assets/img/dashboard_banner/massive_sale/offer.png',
256 'right_image' => ULTP_URL . 'assets/img/dashboard_banner/massive_sale/btn.png',
257 'bg_image' => ULTP_URL . 'assets/img/dashboard_banner/massive_sale/bg.png',
258 'text' => 'Deal ending soon',
259 'countdown_duration' => 259200, // Duration in seconds.
260 // 'countdown_color' => '#0322ff',
261 'countdown_color' => '#3CF357',
262 'url' => Xpo::generate_utm_link(
263 array(
264 'utmKey' => 'massive_sale_content',
265 )
266 ),
267
268 'visibility' => ! Xpo::is_lc_active(),
269 ),
270 // Final hours sale
271 array(
272 'key' => 'ultp_banner_final_hours_sale_2026_1',
273 'start' => '2026-06-28 00:00 Asia/Dhaka',
274 'end' => '2026-06-30 23:59 Asia/Dhaka', // format YY-MM-DD always set time 23:59 and zone Asia/Dhaka.
275
276 'brand_color' => '#0322ff',
277
278 'left_image' => ULTP_URL . 'assets/img/dashboard_banner/final_hours_sale/offer.png',
279 'right_image' => ULTP_URL . 'assets/img/dashboard_banner/final_hours_sale/btn.png',
280 'bg_image' => ULTP_URL . 'assets/img/dashboard_banner/final_hours_sale/bg.png',
281 'text' => 'Hurry Before It Ends!',
282 'countdown_duration' => 259200, // Duration in seconds.
283 // 'countdown_color' => '#0322ff',
284 'countdown_color' => '#3CF357',
285 'url' => Xpo::generate_utm_link(
286 array(
287 'utmKey' => 'final_hours_content',
288 )
289 ),
290 'visibility' => ! Xpo::is_lc_active(),
291 ),
292 );
293 foreach ( $banner_notices as $notice ) {
294 $notice_key = isset( $notice['key'] ) ? $notice['key'] : $this->notice_version;
295
296 if ( isset( $_GET['ultp_notice'] ) && $notice_key === sanitize_text_field(wp_unslash($_GET['ultp_notice'])) ) { // phpcs:ignore
297 continue;
298 }
299
300 $current_time = gmdate( 'U' );
301 $notice_start = gmdate( 'U', strtotime( $notice['start'] ) );
302 $notice_end = gmdate( 'U', strtotime( $notice['end'] ) );
303 if ( $current_time >= $notice_start && $current_time <= $notice_end && $notice['visibility'] ) {
304
305 $notice_transient = Xpo::get_transient_without_cache( 'ultp_get_pro_notice_' . $notice_key );
306
307 if ( 'off' === $notice_transient ) {
308 continue;
309 }
310 if ( $return_bool ) { // Early return for Other plugin notice.
311 return true;
312 }
313 if ( ! $this->notice_js_css_applied ) {
314 $this->ultp_banner_notice_js();
315 $this->notice_js_css_applied = true;
316 }
317 $query_args = array(
318 'ultp_notice' => $notice_key,
319 'wpnonce' => $ultp_db_nonce,
320 );
321 if ( isset( $notice['repeat_interval'] ) && $notice['repeat_interval'] ) {
322 $query_args['ultp_interval'] = $notice['repeat_interval'];
323 }
324 ?>
325 <style type="text/css">
326 .ultp-notice-wrapper.ultp-banner-notice {
327 height: auto !important;
328 padding: 0 !important;
329 position: relative;
330 box-sizing: border-box;
331 background-repeat: no-repeat;
332 background-size: cover;
333 background-position: center;
334 }
335 .ultp-notice-wrapper.ultp-banner-notice .ultp-banner-link {
336 width: 100%;
337 text-decoration: none;
338 display: block;
339 }
340 .ultp-notice-wrapper.ultp-banner-notice .ultp-banner-content {
341 display: flex;
342 justify-content: space-between;
343 align-items: center;
344 max-width: 700px;
345 margin: 0 auto;
346 padding: 10px 16px;
347 gap: 16px;
348 }
349 .ultp-notice-wrapper.ultp-banner-notice .ultp-banner-side-image {
350 display: block;
351 max-width: 100%;
352 height: auto;
353 max-height: 32px;
354 }
355 .ultp-notice-wrapper.ultp-banner-notice .ultp-banner-main .ultp-banner-main-text {
356 color: #ffffff;
357 }
358 .ultp-notice-wrapper.ultp-banner-notice .ultp-banner-main {
359 display: flex;
360 flex-direction: column;
361 gap: 4px;
362 align-items: center;
363 justify-content: center;
364 font-weight: 700;
365 font-size: 18px;
366 color: #333333;
367 line-height: 1.2;
368 text-align: center;
369 }
370
371 @media screen and (max-width: 1100px) {
372 /* .ultp-notice-wrapper.ultp-banner-notice .ultp-banner-content {
373 flex-direction: column;
374 } */
375 .ultp-notice-wrapper.ultp-banner-notice .ultp-banner-content .ultp-banner-main-text {
376 display: none;
377 }
378 }
379 @media screen and (max-width: 490px) {
380 .ultp-notice-wrapper.ultp-banner-notice {
381 display: none;
382 }
383 }
384 @media screen and (max-width: 782px) {
385 .ultp-notice-wrapper.ultp-banner-notice .ultp-banner-content {
386 justify-content: center;
387 padding: 12px 32px 12px 12px;
388 }
389 .ultp-notice-wrapper.ultp-banner-notice .ultp-banner-main {
390 font-size: 22px;
391 line-height: 28px;
392 }
393 }
394 @media screen and (max-width: 480px) {
395 .ultp-notice-wrapper.ultp-banner-notice .ultp-banner-content {
396 padding: 10px 32px 10px 10px;
397 }
398 .ultp-notice-wrapper.ultp-banner-notice .ultp-banner-main {
399 font-size: 18px;
400 line-height: 24px;
401 }
402 }
403 </style>
404 <div
405 class="ultp-notice-wrapper ultp-banner-notice notice"
406 style="
407 border-left: 3px solid <?php echo esc_attr( $notice['brand_color'] ); ?>;
408 background-image: url('<?php echo esc_attr( $notice['bg_image'] ); ?>');
409 ">
410 <a
411 class="wc-dismiss-notice dashicons dashicons-no-alt"
412 style="
413 position: absolute;
414 top: 1px;
415 right: 1px;
416 border-radius: 50%;
417 background-color: black;
418 color: white;
419 font-size: 14px;
420 display: flex;
421 align-items: center;
422 justify-content: center;
423 "
424 aria-label="<?php esc_html_e( 'Close Banner', 'product-addons' ); ?>"
425 href="<?php echo esc_url( add_query_arg( $query_args ) ); ?>">
426 </a>
427
428 <a class="ultp-banner-link" target="_blank" href="<?php echo esc_url( $notice['url'] ); ?>">
429 <div class="ultp-banner-content">
430 <img class="ultp-banner-side-image" loading="lazy" src="<?php echo esc_url( $notice['left_image'] ); ?>" />
431 <div class="ultp-banner-main">
432 <span class="ultp-banner-main-text">
433 <?php echo esc_html( $notice['text'] ); ?>
434 </span>
435 <div
436 class="ultp-notice-countdown"
437 style="
438 color: <?php echo esc_attr( $notice['countdown_color'] ); ?>;
439 "
440 data-notice-key="<?php echo esc_attr( $notice_key . '-countdown' ); ?>"
441 data-duration="<?php echo esc_attr( $notice['countdown_duration'] ); ?>">
442 00:00:00:00
443 </div>
444 </div>
445 <img class="ultp-banner-side-image" loading="lazy" src="<?php echo esc_url( $notice['right_image'] ); ?>" />
446 </div>
447 </a>
448 </div>
449 <?php
450 }
451 }
452 }
453
454 /**
455 * Banner JS
456 *
457 * @return void
458 */
459 public function ultp_banner_notice_js() {
460 ?>
461 <script type="text/javascript">
462 jQuery(function($) {
463 'use strict';
464
465 const storagePrefix = 'ultp_notice_countdown_';
466
467 const formatCountdown = function(seconds) {
468 const days = Math.floor(seconds / 86400);
469 const hours = Math.floor((seconds % 86400) / 3600);
470 const minutes = Math.floor((seconds % 3600) / 60);
471 const secs = seconds % 60;
472
473 return String(days).padStart(2, '0') + ':' + String(hours).padStart(2, '0') + ':' + String(minutes).padStart(2, '0') + ':' + String(secs).padStart(2, '0');
474 };
475
476 const parseDurationToSeconds = function(duration) {
477 if (typeof duration === 'number' && Number.isFinite(duration) && duration > 0) {
478 return Math.floor(duration);
479 }
480
481 const durationString = String(duration || '').trim();
482 if (/^\d+$/.test(durationString)) {
483 return parseInt(durationString, 10);
484 }
485
486 return 0;
487 };
488
489 const nowInSeconds = function() {
490 return Math.floor(Date.now() / 1000);
491 };
492
493 $('.ultp-notice-countdown').each(function() {
494 const countdownElement = $(this);
495 const noticeKey = String(countdownElement.data('noticeKey') || '');
496 const duration = parseDurationToSeconds(countdownElement.data('duration'));
497
498 if (!noticeKey || duration <= 0) {
499 return;
500 }
501
502 const storageKey = storagePrefix + noticeKey;
503 let endAt = 0;
504
505 try {
506 const storedDataRaw = window.localStorage.getItem(storageKey);
507 if (storedDataRaw) {
508 const storedData = JSON.parse(storedDataRaw);
509 if (storedData && parseInt(storedData.duration, 10) === duration) {
510 endAt = parseInt(storedData.endAt, 10) || 0;
511 }
512 }
513 } catch (error) {
514 endAt = 0;
515 }
516
517 const saveTimerState = function(nextEndAt) {
518 try {
519 window.localStorage.setItem(
520 storageKey,
521 JSON.stringify({
522 endAt: nextEndAt,
523 duration: duration,
524 })
525 );
526 } catch (error) {
527 // No-op.
528 }
529 };
530
531 const resetTimer = function(currentTime) {
532 endAt = currentTime + duration;
533 saveTimerState(endAt);
534 };
535
536 const tick = function() {
537 const currentTime = nowInSeconds();
538
539 if (endAt <= currentTime) {
540 resetTimer(currentTime);
541 }
542
543 const remaining = Math.max(endAt - currentTime, 0);
544 countdownElement.text(formatCountdown(remaining));
545 };
546
547 if (endAt <= nowInSeconds()) {
548 resetTimer(nowInSeconds());
549 }
550
551 tick();
552 window.setInterval(tick, 1000);
553 });
554 });
555 </script>
556 <?php
557 }
558
559
560 /**
561 * The Durbin Html
562 *
563 * @return void
564 */
565 public function ultp_dashboard_durbin_notice_callback() {
566 $durbin_key = 'ultp_durbin_dc1';
567
568 if (
569 isset( $_GET['ultp_durbin_key'] ) || // phpcs:ignore
570 'off' === Xpo::get_transient_without_cache( 'ultp_durbin_notice_' . $durbin_key )
571 ) {
572 return;
573 }
574
575 if ( ! $this->notice_js_css_applied ) {
576 $this->notice_js_css_applied = true;
577 }
578
579 $ultp_db_nonce = wp_create_nonce( 'ultp-nonce' );
580
581 ?>
582 <style>
583 .ultp-consent-box {
584 width: 656px;
585 padding: 16px !important;
586 border: 1px solid #070707;
587 border-left-width: 4px;
588 border-radius: 4px;
589 background-color: #fff;
590 position: relative;
591 width: 100%;
592 box-sizing: border-box;
593 }
594 .ultp-consent-content {
595 display: flex;
596 justify-content: flex-start;
597 align-items: flex-end;
598 gap: 26px;
599 }
600
601 .ultp-consent-text-first {
602 font-size: 14px;
603 font-weight: 600;
604 color: #070707;
605 }
606 .ultp-consent-text-last {
607 margin: 4px 0 0;
608 font-size: 14px;
609 color: #070707;
610 }
611
612 .ultp-consent-accept {
613 background-color: #070707;
614 color: #fff !important;
615 border: none;
616 padding: 6px 10px;
617 border-radius: 4px;
618 cursor: pointer;
619 font-size: 12px;
620 font-weight: 600;
621 text-decoration: none;
622 }
623 .ultp-consent-accept:hover {
624 background-color:rgb(38, 38, 38);
625 color: #fff;
626 }
627 </style>
628 <div class="ultp-consent-box ultp-notice-wrapper notice data_collection_notice">
629 <div class="ultp-consent-content">
630 <div class="ultp-consent-text">
631 <div class="ultp-consent-text-first"><?php esc_html_e( 'Want to help make PostX even more awesome?', 'ultimate-post' ); ?></div>
632 <div class="ultp-consent-text-last">
633 <?php esc_html_e( 'Allow us to collect diagnostic data and usage information. see ', 'ultimate-post' ); ?>
634 <a href="https://www.wpxpo.com/data-collection-policy/" target="_blank" ><?php esc_html_e( 'what we collect.', 'ultimate-post' ); ?></a>
635 </div>
636 </div>
637 <a
638 class="ultp-consent-accept"
639 href=
640 <?php
641 echo esc_url(
642 add_query_arg(
643 array(
644 'ultp_durbin_key' => $durbin_key,
645 'ultp_get_durbin' => 'get',
646 'wpnonce' => $ultp_db_nonce,
647 )
648 )
649 );
650 ?>
651 class="ultp-notice-close"
652 ><?php esc_html_e( 'Accept & Close', 'ultimate-post' ); ?></a>
653 </div>
654 <a href=
655 <?php
656 echo esc_url(
657 add_query_arg(
658 array(
659 'ultp_durbin_key' => $durbin_key,
660 'wpnonce' => $ultp_db_nonce,
661 )
662 )
663 );
664 ?>
665 class="ultp-notice-close"
666 style="
667 position: absolute;
668 right: 2px;
669 top: 5px;
670 text-decoration: unset;
671 color: #b6b6b6;
672 font-family: dashicons;
673 font-size: 16px;
674 font-style: normal;
675 font-weight: 400;
676 line-height: 20px;
677 "
678 >
679 <span
680 style="font-size: 14px;"
681 class="ultp-notice-close-icon dashicons dashicons-dismiss"> </span></a>
682 </div>
683 <?php
684 }
685 /**
686 * Dashboard Content Notice
687 *
688 * @return void
689 */
690 public function ultp_dashboard_content_notice( $return_bool = false ) {
691 $content_notices = array(
692 // Flash sale
693 array(
694 'key' => 'ultp_dashboard_content_notice_flash_sale_brand_logos',
695 'start' => '2026-05-07 00:00 Asia/Dhaka',
696 'end' => '2026-05-12 23:59 Asia/Dhaka',
697 'url' => Xpo::generate_utm_link(
698 array(
699 'utmKey' => 'flash_sale',
700 )
701 ),
702 'visibility' => ! Xpo::is_lc_active(),
703 'content_heading' => __( 'Flash Sale:', 'ultimate-post' ),
704 'content_subheading' => __( 'Enjoy %s on PostX Pro.', 'ultimate-post' ),
705 'discount_content' => ' up to 45% Off',
706 'brand_color' => '#0322ff',
707 'icon' => ULTP_URL . 'assets/img/dashboard_banner/brand_logo_round.svg',
708 'button_text' => __( 'Claim Your Discount!', 'ultimate-post' ),
709 'is_discount_logo' => true,
710 'border_color' => '#0322ff',
711 ),
712 array(
713 'key' => 'ultp_dashboard_content_notice_flash_sale_discount_logo',
714 'start' => '2026-05-13 00:00 Asia/Dhaka',
715 'end' => '2026-05-17 23:59 Asia/Dhaka',
716 'url' => Xpo::generate_utm_link(
717 array(
718 'utmKey' => 'flash_sale',
719 )
720 ),
721 'visibility' => ! Xpo::is_lc_active(),
722 'content_heading' => __( 'Flash Sale:', 'ultimate-post' ),
723 'content_subheading' => __( 'Enjoy %s on PostX Pro.', 'ultimate-post' ),
724 'discount_content' => ' up to 45% Off',
725 'brand_color' => '#0322ff',
726 'icon' => ULTP_URL . 'assets/img/dashboard_banner/flash_sale_45_discount_logo.png',
727 'button_text' => __( 'Upgrade Now!', 'ultimate-post' ),
728 'is_discount_logo' => true,
729 'border_color' => '#0322ff',
730 ),
731
732 // Surprise Sale
733 array(
734 'key' => 'ultp_dashboard_content_notice_surprise_sale_brand_logo',
735 'start' => '2026-05-22 00:00 Asia/Dhaka',
736 'end' => '2026-05-25 23:59 Asia/Dhaka',
737 'url' => Xpo::generate_utm_link(
738 array(
739 'utmKey' => 'surprise_sale',
740 )
741 ),
742 'visibility' => ! Xpo::is_lc_active(),
743 'content_heading' => __( 'Surprise Sale:', 'ultimate-post' ),
744 'content_subheading' => __( 'Enjoy %s on PostX Pro.', 'ultimate-post' ),
745 'discount_content' => ' up to 50% Off',
746 'brand_color' => '#0322ff',
747 'icon' => ULTP_URL . 'assets/img/dashboard_banner/brand_logo_round.svg',
748 'button_text' => __( 'Claim Your Discount!', 'ultimate-post' ),
749 'is_discount_logo' => true,
750 'border_color' => '#0322ff',
751 ),
752 array(
753 'key' => 'ultp_dashboard_content_notice_surprise_sale_discount_logo',
754 'start' => '2026-05-26 00:00 Asia/Dhaka',
755 'end' => '2026-05-28 23:59 Asia/Dhaka',
756 'url' => Xpo::generate_utm_link(
757 array(
758 'utmKey' => 'surprise_sale',
759 )
760 ),
761 'visibility' => ! Xpo::is_lc_active(),
762 'content_heading' => __( 'Surprise Sale:', 'ultimate-post' ),
763 'content_subheading' => __( 'Enjoy %s on PostX Pro.', 'ultimate-post' ),
764 'discount_content' => ' up to 50% Off',
765 'brand_color' => '#0322ff',
766 'icon' => ULTP_URL . 'assets/img/dashboard_banner/flash_sale_50_discount_logo.png',
767 'button_text' => __( 'Upgrade Now!', 'ultimate-post' ),
768 'is_discount_logo' => true,
769 'border_color' => '#0322ff',
770 ),
771
772 // Massive Sale
773 array(
774 'key' => 'ultp_dashboard_content_notice_massive_sale_brand_logo',
775 'start' => '2026-06-02 00:00 Asia/Dhaka',
776 'end' => '2026-06-10 23:59 Asia/Dhaka',
777 'url' => Xpo::generate_utm_link(
778 array(
779 'utmKey' => 'massive_sale',
780 )
781 ),
782 'visibility' => ! Xpo::is_lc_active(),
783 'content_heading' => __( 'Massive Sale:', 'ultimate-post' ),
784 'content_subheading' => __( 'Enjoy %s on PostX Pro.', 'ultimate-post' ),
785 'discount_content' => ' up to 50% Off',
786 'brand_color' => '#0322ff',
787 'icon' => ULTP_URL . 'assets/img/dashboard_banner/brand_logo_round.svg',
788 'button_text' => __( 'Claim Your Discount!', 'ultimate-post' ),
789 'is_discount_logo' => true,
790 'border_color' => '#0322ff',
791 ),
792 array(
793 'key' => 'ultp_dashboard_content_notice_massive_sale_discount_logo',
794 'start' => '2026-06-11 00:00 Asia/Dhaka',
795 'end' => '2026-06-16 23:59 Asia/Dhaka',
796 'url' => Xpo::generate_utm_link(
797 array(
798 'utmKey' => 'massive_sale',
799 )
800 ),
801 'visibility' => ! Xpo::is_lc_active(),
802 'content_heading' => __( 'Massive Sale:', 'ultimate-post' ),
803 'content_subheading' => __( 'Enjoy %s on PostX Pro.', 'ultimate-post' ),
804 'discount_content' => ' up to 50% Off',
805 'brand_color' => '#0322ff',
806 'icon' => ULTP_URL . 'assets/img/dashboard_banner/flash_sale_50_discount_logo.png',
807 'button_text' => __( 'Upgrade Now!', 'ultimate-post' ),
808 'is_discount_logo' => true,
809 'border_color' => '#0322ff',
810 ),
811
812 // Final Hours Sale
813 array(
814 'key' => 'ultp_dashboard_content_notice_final_hours_sale_brand_logo',
815 'start' => '2026-06-21 00:00 Asia/Dhaka',
816 'end' => '2026-06-24 23:59 Asia/Dhaka',
817 'url' => Xpo::generate_utm_link(
818 array(
819 'utmKey' => 'final_hour',
820 )
821 ),
822 'visibility' => ! Xpo::is_lc_active(),
823 'content_heading' => __( 'Final Hours Sale:', 'ultimate-post' ),
824 'content_subheading' => __( 'Enjoy %s on PostX Pro.', 'ultimate-post' ),
825 'discount_content' => ' up to 50% Off',
826 'brand_color' => '#0322ff',
827 'icon' => ULTP_URL . 'assets/img/dashboard_banner/brand_logo_round.svg',
828 'button_text' => __( 'Claim Your Discount!', 'ultimate-post' ),
829 'is_discount_logo' => true,
830 'border_color' => '#0322ff',
831 ),
832 array(
833 'key' => 'ultp_dashboard_content_notice_final_hours_sale_discount_logo',
834 'start' => '2026-06-25 00:00 Asia/Dhaka',
835 'end' => '2026-06-27 23:59 Asia/Dhaka',
836 'url' => Xpo::generate_utm_link(
837 array(
838 'utmKey' => 'final_hour',
839 )
840 ),
841 'visibility' => ! Xpo::is_lc_active(),
842 'content_heading' => __( 'Final Hours Sale:', 'ultimate-post' ),
843 'content_subheading' => __( 'Enjoy %s on PostX Pro.', 'ultimate-post' ),
844 'discount_content' => ' up to 50% Off',
845 'brand_color' => '#0322ff',
846 'icon' => ULTP_URL . 'assets/img/dashboard_banner/flash_sale_50_discount_logo.png',
847 'button_text' => __( 'Upgrade Now!', 'ultimate-post' ),
848 'is_discount_logo' => true,
849 'border_color' => '#0322ff',
850 ),
851
852 );
853
854 $ultp_db_nonce = wp_create_nonce( 'ultp-nonce' );
855
856 foreach ( $content_notices as $key => $notice ) {
857 $notice_key = isset( $notice['key'] ) ? $notice['key'] : $this->notice_version;
858 if ( isset( $_GET['ultp_notice'] ) && $notice_key === $_GET['ultp_notice'] ) {
859 continue;
860 } else {
861 $border_color = $notice['border_color'];
862
863 $current_time = gmdate( 'U' );
864 $notice_start = gmdate( 'U', strtotime( $notice['start'] ) );
865 $notice_end = gmdate( 'U', strtotime( $notice['end'] ) );
866 if ( $current_time >= $notice_start && $current_time <= $notice_end && $notice['visibility'] ) {
867 $notice_transient = Xpo::get_transient_without_cache( 'ultp_get_pro_notice_' . $notice_key );
868
869 if ( 'off' !== $notice_transient ) {
870 if ( $return_bool ) { // Early return for Other plugin notice.
871 return true;
872 }
873 $query_args = array(
874 'ultp_notice' => $notice_key,
875 'wpnonce' => $ultp_db_nonce,
876 );
877 if ( isset( $notice['repeat_interval'] ) && $notice['repeat_interval'] ) {
878 $query_args['ultp_interval'] = $notice['repeat_interval'];
879 }
880
881 $url = isset( $notice['url'] ) ? $notice['url'] : Xpo::generate_utm_link(
882 array(
883 'utmKey' => 'content_notice',
884 )
885 );
886
887 ?>
888
889 <style id="ultp-notice-css" type="text/css">
890 .ultp-content-notice-wrapper {
891 border: 1px solid #c3c4c7;
892 border-left: 3px solid #037fff;
893 margin: 15px 0 !important;
894 display: flex;
895 align-items: center;
896 background-color: #eef0f4;
897 width: 100%;
898 padding: 10px 0;
899 position: relative;
900 box-sizing: border-box;
901 }
902
903 .ultp-content-notice-wrapper.notice {
904 margin: 10px 0;
905 width: calc(100% - 20px);
906 }
907
908 .wrap .ultp-content-notice-wrapper.notice {
909 width: 100%;
910 }
911
912 .ultp-content-notice-icon {
913 margin-left: 15px;
914 }
915
916 .ultp-content-notice-discout-icon {
917 margin-left: 10px;
918 }
919
920 .ultp-content-notice-icon img {
921 max-width: 42px;
922 height: 70px;
923 }
924
925 .ultp-content-notice-discout-icon img {
926 height: 70px;
927 width: 70px;
928 object-fit: contain;
929 }
930
931 .ultp-notice-content-wrapper {
932 display: flex;
933 flex-direction: column;
934 gap: 8px;
935 font-size: 14px;
936 line-height: 20px;
937 margin-left: 15px;
938 }
939
940 .ultp-content-notice-buttons {
941 display: flex;
942 align-items: center;
943 gap: 15px;
944 }
945
946 .ultp-content-notice-btn {
947 font-weight: 600;
948 text-transform: uppercase !important;
949 padding: 2px 10px !important;
950 background-color: #0322ff;
951 border: none !important;
952 }
953
954 .ultp-content-discount_btn {
955 background-color: #ffffff;
956 text-decoration: none;
957 border: 1px solid #0322ff;
958 padding: 5px 10px;
959 border-radius: 5px;
960 font-weight: 500;
961 text-transform: uppercase;
962 color: #0322ff !important;
963 }
964
965 .ultp-content-notice-close {
966 position: absolute;
967 right: 2px;
968 top: 5px;
969 text-decoration: none;
970 color: #b6b6b6;
971 font-family: dashicons;
972 font-size: 16px;
973 line-height: 20px;
974 }
975
976 .ultp-content-notice-close-icon {
977 font-size: 14px;
978 }
979 </style>
980 <div class="ultp-content-notice-wrapper notice data_collection_notice"
981 style="border-left: 3px solid <?php echo esc_attr( $border_color ); ?>;"
982 >
983 <?php
984 if ( $notice['is_discount_logo'] ) {
985 ?>
986 <div class="ultp-content-notice-discout-icon"> <img src="<?php echo esc_url( $notice['icon'] ); ?>"/> </div>
987 <?php
988 } else {
989 ?>
990 <div class="ultp-content-notice-icon"> <img src="<?php echo esc_url( $notice['icon'] ); ?>"/> </div>
991 <?php
992 }
993 ?>
994
995 <div class="ultp-notice-content-wrapper">
996 <div class="">
997 <strong><?php printf( esc_html( $notice['content_heading'] ) ); ?> </strong>
998 <?php
999 printf(
1000 wp_kses_post( $notice['content_subheading'] ),
1001 '<strong>' . esc_html( $notice['discount_content'] ) . '</strong>'
1002 );
1003 ?>
1004 </div>
1005 <div class="ultp-content-notice-buttons">
1006 <?php if ( isset( $notice['is_discount_logo'] ) && $notice['is_discount_logo'] ) : ?>
1007 <a class="ultp-content-discount_btn" href="<?php echo esc_url( $url ); ?>" target="_blank">
1008 <?php echo esc_html( $notice['button_text'] ); ?>
1009 </a>
1010 <?php else : ?>
1011 <a class="ultp-content-notice-btn button button-primary" href="<?php echo esc_url( $url ); ?>" target="_blank" style="background-color: <?php echo ! empty( $notice['background_color'] ) ? esc_attr( $notice['background_color'] ) : '#86a62c'; ?>;">
1012 <?php echo esc_html( $notice['button_text'] ); ?>
1013
1014 </a>
1015 <?php endif; ?>
1016 </div>
1017 </div>
1018 <a href=
1019 <?php
1020 echo esc_url(
1021 add_query_arg(
1022 $query_args
1023 )
1024 );
1025 ?>
1026 class="ultp-content-notice-close"><span class="ultp-content-notice-close-icon dashicons dashicons-dismiss"> </span></a>
1027 </div>
1028 <?php
1029 }
1030 }
1031 }
1032 }
1033 }
1034
1035 /**
1036 * Handle Plugin Notice for all plugins
1037 *
1038 * @param array $active_lists Lists of all active plugin notice.
1039 * @return array
1040 */
1041 public function handle_xpo_active_notice_lists( $active_lists ) {
1042 if ( $this->ultp_dashboard_banner_notice( true ) || $this->ultp_dashboard_content_notice( true ) ) {
1043 $active_lists[ $this->plugin_notice_priority_key ] = $this->plugin_notice_priority;
1044 }
1045 return $active_lists;
1046 }
1047
1048 /**
1049 * Handle Plugin Notice for all plugins
1050 *
1051 * @return bool
1052 */
1053 public function is_available_for_notice() {
1054 $active_notices = apply_filters( 'xpo_active_notice_lists', array() );
1055 if ( empty( $active_notices ) ) {
1056 return true;
1057 }
1058 asort( $active_notices );
1059 return array_key_first( $active_notices ) === $this->plugin_notice_priority_key;
1060 }
1061 }
1062