PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.11.14
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.11.14
4.0.8 4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.2 3.1.3 3.10.0 3.10.1 3.10.10 3.10.11 3.10.12 3.10.13 3.10.14 3.10.15 3.10.2 3.10.3 All 149 releases
visualizer / vendor / codeinwp / themeisle-sdk / src / Modules / Announcements.php

Announcements.php in Visualizer – Tables & Charts Manager with Built-in AI Generator 3.11.14, at vendor/codeinwp/themeisle-sdk/src/Modules/Announcements.php

411 lines 10.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * File responsible for announcements.
4 *
5 * This is used to display information about limited events, such as Black Friday.
6 *
7 * @package ThemeIsleSDK
8 * @subpackage Modules
9 * @copyright Copyright (c) 2017, Marius Cristea
10 * @license http://opensource.org/licenses/gpl-3.0.php GNU Public License
11 * @since 3.3.0
12 */
13
14 namespace ThemeisleSDK\Modules;
15
16 use DateTime;
17 use ThemeisleSDK\Common\Abstract_Module;
18 use ThemeisleSDK\Loader;
19 use ThemeisleSDK\Product;
20
21 /**
22 * Announcement module for the ThemeIsle SDK.
23 */
24 class Announcements extends Abstract_Module {
25
26 const SALE_DURATION_BLACK_FRIDAY = '+7 days'; // DateTime modifier. (Include Cyber Monday)
27
28 /**
29 * Mark if the notice was already loaded.
30 *
31 * @var boolean
32 */
33 private static $notice_loaded = false;
34
35 /**
36 * The product to be used.
37 *
38 * @var string
39 */
40 private static $current_product = '';
41
42 /**
43 * Check if the module can be loaded.
44 *
45 * @param Product $product Product data.
46 *
47 * @return bool
48 */
49 public function can_load( $product ) {
50 if ( $this->is_from_partner( $product ) ) {
51 return false;
52 }
53
54 return true;
55 }
56
57 /**
58 * Load the module for the selected product.
59 *
60 * @param Product $product Product data.
61 *
62 * @return void
63 */
64 public function load( $product ) {
65 $this->product = $product;
66
67 add_filter(
68 'themeisle_sdk_is_black_friday_sale',
69 function( $is_black_friday ) {
70 return $this->is_black_friday_sale( $this->get_current_date() );
71 }
72 );
73
74 add_action( 'admin_init', array( $this, 'load_announcements' ) );
75 }
76
77 /**
78 * Load all valid announcements.
79 *
80 * @return void
81 */
82 public function load_announcements() {
83 if ( ! $this->is_black_friday_sale( $this->get_current_date() ) ) {
84 return;
85 }
86
87 add_action( 'admin_notices', array( $this, 'black_friday_notice_render' ) );
88 add_action( 'wp_ajax_themeisle_sdk_dismiss_black_friday_notice', array( $this, 'disable_notification_ajax' ) );
89 add_action(
90 'themeisle_internal_page',
91 function( $plugin, $page_slug ) {
92 self::$current_product = $plugin;
93 },
94 10,
95 2
96 );
97 }
98
99
100
101 /**
102 * Get the remaining time for the event in a human-readable format.
103 *
104 * @param DateTime $end_date The end date for event.
105 *
106 * @return string Remaining time for the event.
107 */
108 public function get_remaining_time_for_event( $end_date ) {
109 return human_time_diff( $this->get_current_date()->getTimestamp(), $end_date->getTimestamp() );
110 }
111
112 /**
113 * Check if the announcement can be shown.
114 *
115 * @param DateTime $current_date The announcement to check.
116 * @param int $user_id The user id to show the notice.
117 *
118 * @return bool
119 */
120 public function can_show_notice( $current_date, $user_id ) {
121 $current_year = $current_date->format( 'Y' );
122 $user_notice_dismiss_timestamp = get_user_meta( $user_id, 'themeisle_sdk_dismissed_notice_black_friday', true );
123
124 if ( empty( $user_notice_dismiss_timestamp ) ) {
125 return true;
126 }
127
128 $dismissed_year = wp_date( 'Y', $user_notice_dismiss_timestamp );
129
130 return $current_year !== $dismissed_year;
131 }
132
133 /**
134 * Calculate the start date for Black Friday based on the year of the given date.
135 *
136 * Black Friday is the day after the Thanksgiving and the sale starts on the Monday of that week.
137 *
138 * @param DateTime $date The current date object, used to determine the year.
139 * @return DateTime The start date of Black Friday for the given year.
140 */
141 public function get_start_date( $date ) {
142 $year = $date->format( 'Y' );
143 $black_friday = new DateTime( "last friday of november {$year}" );
144
145 $sale_start = clone $black_friday;
146 $sale_start->modify( 'monday this week' );
147 $sale_start->setTime( 0, 0 );
148
149 return $sale_start;
150 }
151
152 /**
153 * Calculate the event end date.
154 *
155 * @param DateTime $start_date The start date.
156 * @return DateTime The end date.
157 */
158 public function get_end_date( $start_date ) {
159 $black_friday_end = clone $start_date;
160 $black_friday_end->modify( self::SALE_DURATION_BLACK_FRIDAY );
161 $black_friday_end->setTime( 23, 59, 59 );
162 return $black_friday_end;
163 }
164
165 /**
166 * Check if the current date falls within the Black Friday sale period.
167 *
168 * @param DateTime $current_date The date to check.
169 * @return bool True if the date is within the Black Friday sale period, false otherwise.
170 */
171 public function is_black_friday_sale( $current_date ) {
172 $black_friday_start_date = $this->get_start_date( $current_date );
173 $black_friday_end = $this->get_end_date( $black_friday_start_date );
174 return $black_friday_start_date <= $current_date && $current_date <= $black_friday_end;
175 }
176
177 /**
178 * Get the notice data.
179 *
180 * @return array The notice data.
181 */
182 public function get_notice_data() {
183 $time_left_label = $this->get_remaining_time_for_event( $this->get_end_date( $this->get_start_date( $this->get_current_date() ) ) );
184 $time_left_label = sprintf( Loader::$labels['announcements']['time_left'], $time_left_label );
185
186 $utm_location = 'globalnotice';
187 if ( ! empty( $this->product ) ) {
188 $utm_location = $this->product->get_friendly_name();
189 }
190
191 $sale_title = Loader::$labels['announcements']['black_friday'];
192 $sale_url = tsdk_translate_link( tsdk_utmify( 'https://themeisle.com/blackfriday/', 'bfcm25', $utm_location ) );
193 $sale_message = sprintf( Loader::$labels['announcements']['max_savings'], '50%' );
194
195 return array(
196 'title' => $sale_title,
197 'sale_url' => $sale_url,
198 'message' => $sale_message,
199 'time_left' => $time_left_label,
200 );
201 }
202
203 /**
204 * Render the Black Friday notice.
205 *
206 * @return void
207 */
208 public function black_friday_notice_render() {
209
210 // Prevent the notice from being rendered twice.
211 if ( self::$notice_loaded ) {
212 return;
213 }
214 self::$notice_loaded = true;
215
216 $all_configs = apply_filters( 'themeisle_sdk_blackfriday_data', array( 'default' => $this->get_notice_data() ) );
217
218 if ( empty( $all_configs ) ) {
219 return;
220 }
221
222 $data = end( $all_configs );
223
224 if ( ! empty( self::$current_product ) && isset( $all_configs[ self::$current_product ] ) ) {
225 $data = $all_configs[ self::$current_product ];
226 }
227
228 if ( empty( $data ) || ! is_array( $data ) ) {
229 return;
230 }
231
232 $current_user_id = get_current_user_id();
233 $can_dismiss = true;
234
235 if ( ! empty( $data['dismiss'] ) ) {
236 $can_dismiss = $data['dismiss'];
237 } else {
238 // Disable by default if we are on a product page.
239 if ( 0 < did_action( 'themeisle_internal_page' ) ) {
240 $can_dismiss = false;
241 }
242 }
243
244 if ( $can_dismiss && ! $this->can_show_notice( $this->get_current_date(), $current_user_id ) ) {
245 return;
246 }
247
248 $sale_url = ! empty( $data['sale_url'] ) ? $data['sale_url'] : '';
249 $hide_other_notices = ! empty( $data['hide_other_notices'] ) ? $data['hide_other_notices'] : ! $can_dismiss;
250 $dismiss_notice_url = wp_nonce_url(
251 add_query_arg(
252 array( 'action' => 'themeisle_sdk_dismiss_black_friday_notice' ),
253 admin_url( 'admin-ajax.php' )
254 ),
255 'dismiss_themeisle_event_notice'
256 );
257
258 if ( empty( $sale_url ) ) {
259 return;
260 }
261
262 if ( ! current_user_can( 'install_plugins' ) ) {
263 $sale_url = remove_query_arg( 'lkey', $sale_url );
264 }
265
266 ?>
267 <style>
268 .themeisle-sale {
269 border-left-color: #0466CB;
270 }
271 .themeisle-sale :is(.themeisle-sale-title, p) {
272 margin: 0;
273 }
274 .themeisle-sale-container {
275 display: flex;
276 align-items: center;
277 padding: 0.5rem 0;
278 gap: 0.5rem;
279 padding-right: 10px;
280 }
281 .themeisle-sale-content {
282 display: flex;
283 flex-direction: column;
284 gap: 0.2rem;
285 }
286 .themeisle-sale a {
287 text-decoration: none;
288 }
289 .themeisle-sale p a {
290 margin-left: 1rem;
291 padding: 7px 12px;
292 border-radius: 4px;
293 background: #0466CB;
294 color: white;
295 font-weight: 700;
296 }
297 .themeisle-sale-dismiss {
298 padding-top: 5px;
299 }
300 .themeisle-sale-dismiss span {
301 color: #787c82;
302 font-size: 16px;
303 }
304 .notice.themeisle-sale {
305 padding: 0;
306 }
307 .themeisle-sale-logo {
308 display: flex;
309 justify-content: center;
310 align-items: center;
311 margin-left: 5px;
312 }
313 .themeisle-sale-time-left {
314 margin-left: 5px;
315 padding: 3px 5px;
316 border-radius: 4px;
317 background-color: #dfdfdf;
318 font-weight: 600;
319 font-size: x-small;
320 line-height: 1;
321 }
322 .themeisle-sale-title {
323 font-size: 14px;
324 display: flex;
325 align-items: center;
326 }
327 .themeisle-sale-action {
328 flex-grow: 1;
329 display: flex;
330 justify-content: flex-end;
331 }
332 <?php if ( $hide_other_notices ) : ?>
333 .notice:not(.themeisle-sale) {
334 display: none;
335 }
336 <?php endif; ?>
337 </style>
338 <div class="themeisle-sale notice notice-info" data-event-slug="black_friday">
339 <div class="themeisle-sale-container">
340 <div class="themeisle-sale-logo">
341 <img
342 width="45"
343 src="<?php echo esc_url( $this->get_sdk_uri() . 'assets/images/themeisle-logo.png' ); ?>"
344 />
345 </div>
346 <div class="themeisle-sale-content">
347 <h4 class="themeisle-sale-title">
348 <?php echo esc_html( $data['title'] ); ?>
349 <span class="themeisle-sale-time-left">
350 <?php echo esc_html( $data['time_left'] ); ?>
351 </span>
352 </h4>
353 <p>
354 <?php echo wp_kses_post( $data['message'] ); ?>
355 </p>
356 </div>
357 <div class="themeisle-sale-action">
358 <a
359 href="<?php echo esc_url( $sale_url ); ?>"
360 target="_blank"
361 class="button button-primary themeisle-sale-button"
362 >
363 <?php echo esc_html( Loader::$labels['announcements']['notice_link_label'] ); ?>
364 </a>
365 </div>
366 <?php if ( $can_dismiss ) : ?>
367 <a href="<?php echo esc_url( $dismiss_notice_url ); ?>" class="themeisle-sale-dismiss">
368 <span class="dashicons dashicons-dismiss"></span>
369 </a>
370 <?php endif; ?>
371 </div>
372 </div>
373 <script>
374 // Note: Some plugins use React and the content is ready after the `DOMContentLoaded` event. Use this function to reposition the notice after components have rendered.
375 window.tsdk_reposition_notice = function() {
376 const bannerRoot = document.getElementById('tsdk_banner');
377 const saleNotice = document.querySelector('.themeisle-sale');
378 if ( ! bannerRoot || ! saleNotice ) {
379 return;
380 }
381
382 bannerRoot.appendChild(saleNotice);
383 };
384
385 document.addEventListener( 'DOMContentLoaded', function() {
386 window.tsdk_reposition_notice();
387 } );
388 </script>
389 <?php
390 }
391
392 /**
393 * Disable the notification via ajax.
394 *
395 * @return void
396 */
397 public function disable_notification_ajax() {
398 check_ajax_referer( 'dismiss_themeisle_event_notice' );
399
400 update_user_meta( get_current_user_id(), 'themeisle_sdk_dismissed_notice_black_friday', $this->get_current_date()->getTimestamp() );
401
402 $return_page_url = wp_get_referer();
403 if ( empty( $return_page_url ) ) {
404 $return_page_url = admin_url();
405 }
406
407 wp_safe_redirect( $return_page_url );
408 exit;
409 }
410 }
411