PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.7.9
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.7.9
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 3.10.4 All 148 releases
visualizer / vendor / codeinwp / themeisle-sdk / src / Modules / Notification.php

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

493 lines 13.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * The notification model class for ThemeIsle SDK
4 *
5 * @package ThemeIsleSDK
6 * @subpackage Modules
7 * @copyright Copyright (c) 2017, Marius Cristea
8 * @license http://opensource.org/licenses/gpl-3.0.php GNU Public License
9 * @since 1.0.0
10 */
11
12 namespace ThemeisleSDK\Modules;
13
14 use ThemeisleSDK\Common\Abstract_Module;
15 use ThemeisleSDK\Product;
16
17 // Exit if accessed directly.
18 if ( ! defined( 'ABSPATH' ) ) {
19 exit;
20 }
21
22 /**
23 * Notification module for ThemeIsle SDK.
24 */
25 class Notification extends Abstract_Module {
26 /**
27 * Show notifications only after the user has the product installed after this amount of time, in hours.
28 */
29 const MIN_INSTALL_TIME = 100;
30 /**
31 * How much time should we show the notification, in days.
32 */
33 const MAX_TIME_TO_LIVE = 7;
34
35 /**
36 * Number of days between notifications.
37 */
38 const TIME_BETWEEN_NOTIFICATIONS = 5;
39
40 /**
41 * Holds a possible notification list.
42 *
43 * @var array Notifications list.
44 */
45 private static $notifications = [];
46
47 /**
48 * Show notification data.
49 */
50 public static function show_notification() {
51
52 $current_notification = self::get_last_notification();
53
54 $notification_details = [];
55 // Check if the saved notification is still present among the possible ones.
56 if ( ! empty( $current_notification ) ) {
57 $notification_details = self::get_notification_details( $current_notification );
58 if ( empty( $notification_details ) ) {
59 $current_notification = [];
60 }
61 }
62 // Check if the notificatin is expired.
63 if ( ! empty( $current_notification ) && self::is_notification_expired( $current_notification ) ) {
64 update_option( $current_notification['id'], 'no' );
65 self::set_last_active_notification_timestamp();
66 $current_notification = [];
67 }
68 // If we don't have any saved notification, get a new one.
69 if ( empty( $current_notification ) ) {
70 $notification_details = self::get_random_notification();
71 if ( empty( $notification_details ) ) {
72 return;
73 }
74 self::set_active_notification(
75 [
76 'id' => $notification_details['id'],
77 'display_at' => time(),
78 ]
79 );
80 }
81 if ( empty( $notification_details ) ) {
82 return;
83 }
84 $notification_html = self::get_notification_html( $notification_details );
85 do_action( $notification_details['id'] . '_before_render' );
86
87 echo $notification_html; //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, already escaped internally.
88
89 do_action( $notification_details['id'] . '_after_render' );
90 self::render_snippets();
91 }
92
93 /**
94 * Get last notification details.
95 *
96 * @return array Last notification details.
97 */
98 private static function get_last_notification() {
99 $notification = self::get_notifications_metadata();
100
101 return isset( $notification['last_notification'] ) ? $notification['last_notification'] : [];
102 }
103
104 /**
105 * Get notification center details.
106 *
107 * @return array Notification center details.
108 */
109 private static function get_notifications_metadata() {
110
111 $data = get_option(
112 'themeisle_sdk_notifications',
113 [
114 'last_notification' => [],
115 'last_notification_active' => 0,
116 ]
117 );
118
119 return $data;
120
121 }
122
123 /**
124 * Check if the notification is still possible.
125 *
126 * @param array $notification Notification to check.
127 *
128 * @return array Either is still active or not.
129 */
130 private static function get_notification_details( $notification ) {
131 $notifications = array_filter(
132 self::$notifications,
133 function ( $value ) use ( $notification ) {
134 if ( isset( $value['id'] ) && isset( $notification['id'] ) && $value['id'] === $notification['id'] ) {
135 return true;
136 }
137
138 return false;
139 }
140 );
141
142 return ! empty( $notifications ) ? reset( $notifications ) : [];
143 }
144
145 /**
146 * Check if the notification is expired.
147 *
148 * @param array $notification Notification to check.
149 *
150 * @return bool Either the notification is due.
151 */
152 private static function is_notification_expired( $notification ) {
153 if ( ! isset( $notification['display_at'] ) ) {
154 return true;
155 }
156
157 $notifications = array_filter(
158 self::$notifications,
159 function ( $value ) use ( $notification ) {
160 if ( isset( $value['id'] ) && isset( $notification['id'] ) && $value['id'] === $notification['id'] ) {
161 return true;
162 }
163
164 return false;
165 }
166 );
167
168 if ( empty( $notifications ) ) {
169 return true;
170 }
171 $notification_definition = reset( $notifications );
172
173 $when_to_expire = isset( $notification_definition['expires_at'] )
174 ? $notification_definition['expires_at'] :
175 ( isset( $notification_definition['expires'] )
176 ? ( $notification['display_at'] + $notification_definition['expires'] ) :
177 ( $notification['display_at'] + self::MAX_TIME_TO_LIVE * DAY_IN_SECONDS )
178 );
179
180 return ( $when_to_expire - time() ) < 0;
181 }
182
183 /**
184 * Set last notification details.
185 */
186 private static function set_last_active_notification_timestamp() {
187 $metadata = self::get_notifications_metadata();
188 $metadata['last_notification_active'] = time();
189 update_option( 'themeisle_sdk_notifications', $metadata );
190 }
191
192 /**
193 * Return notification to show.
194 *
195 * @return array Notification data.
196 */
197 public static function get_random_notification() {
198 if ( ( time() - self::get_last_active_notification_timestamp() ) < self::TIME_BETWEEN_NOTIFICATIONS * DAY_IN_SECONDS ) {
199 return [];
200 }
201
202 $notifications = self::$notifications;
203 $notifications = array_filter(
204 $notifications,
205 function ( $value ) {
206 if ( isset( $value['sticky'] ) && true === $value['sticky'] ) {
207 return true;
208 }
209
210 return false;
211 }
212 );
213 // No priority notifications, use all.
214 if ( empty( $notifications ) ) {
215 $notifications = self::$notifications;
216 }
217 if ( empty( $notifications ) ) {
218 return [];
219 }
220 $notifications = array_values( $notifications );
221
222 return $notifications[ array_rand( $notifications, 1 ) ];
223
224 }
225
226 /**
227 * Get last notification details.
228 *
229 * @return int Last notification details.
230 */
231 private static function get_last_active_notification_timestamp() {
232 $notification = self::get_notifications_metadata();
233
234 return isset( $notification['last_notification_active'] ) ? $notification['last_notification_active'] : 0;
235 }
236
237 /**
238 * Get last notification details.
239 *
240 * @param array $notification Notification data.
241 */
242 private static function set_active_notification( $notification ) {
243 $metadata = self::get_notifications_metadata();
244 $metadata['last_notification'] = $notification;
245 update_option( 'themeisle_sdk_notifications', $metadata );
246 }
247
248 /**
249 * Get notification html.
250 *
251 * @param array $notification_details Notification details.
252 *
253 * @return string Html for notice.
254 */
255 public static function get_notification_html( $notification_details ) {
256 $default = [
257 'id' => '',
258 'heading' => '',
259 'message' => '',
260 'ctas' => [
261 'confirm' => [
262 'link' => '#',
263 'text' => '',
264 ],
265 'cancel' => [
266 'link' => '#',
267 'text' => '',
268 ],
269 ],
270 ];
271 $notification_details = wp_parse_args( $notification_details, $default );
272 global $pagenow;
273 $notification_details['ctas']['cancel']['link'] = wp_nonce_url( add_query_arg( [ 'nid' => $notification_details['id'] ], admin_url( $pagenow ) ), $notification_details['id'], 'tsdk_dismiss_nonce' );
274 $notification_html = '<div class="notice notice-success is-dismissible themeisle-sdk-notice" data-notification-id="' . esc_attr( $notification_details['id'] ) . '" id="' . esc_attr( $notification_details['id'] ) . '-notification"> <div class="themeisle-sdk-notification-box">';
275
276 if ( ! empty( $notification_details['heading'] ) ) {
277 $notification_html .= sprintf( '<h4>%s</h4>', wp_kses_post( $notification_details['heading'] ) );
278 }
279 if ( ! empty( $notification_details['message'] ) ) {
280 $notification_html .= wp_kses_post( $notification_details['message'] );
281 }
282 $notification_html .= '<div class="actions">';
283
284 if ( ! empty( $notification_details['ctas']['confirm']['text'] ) ) {
285 $notification_html .= sprintf(
286 '<a href="%s" target="_blank" class=" button button-primary %s" data-confirm="yes" >%s</a>',
287 esc_url( $notification_details['ctas']['confirm']['link'] ),
288 esc_attr( $notification_details['id'] . '_confirm' ),
289 wp_kses_post( $notification_details['ctas']['confirm']['text'] )
290 );
291 }
292
293 if ( ! empty( $notification_details['ctas']['cancel']['text'] ) ) {
294 $notification_html .= sprintf(
295 '<a href="%s" class=" button %s" data-confirm="no">%s</a>',
296 esc_url( $notification_details['ctas']['cancel']['link'] ),
297 esc_attr( $notification_details['id'] ) . '_cancel',
298 wp_kses_post( $notification_details['ctas']['cancel']['text'] )
299 );
300 }
301
302 $notification_html .= '</div>';
303 $notification_html .= ' </div>';
304 $notification_html .= ' </div>';
305
306 return $notification_html;
307 }
308
309 /**
310 * Adds js snippet for hiding the notice.
311 */
312 public static function render_snippets() {
313
314 ?>
315 <style type="text/css">
316 .themeisle-sdk-notification-box {
317 padding: 3px;
318 }
319
320 .themeisle-sdk-notification-box .actions {
321 margin-top: 6px;
322 margin-bottom: 4px;
323 }
324
325 .themeisle-sdk-notification-box .button {
326 margin-right: 5px;
327 }
328 </style>
329 <script type="text/javascript">
330 (function ($) {
331 $(document).ready(function () {
332 $('#wpbody-content').on('click', ".themeisle-sdk-notice a.button, .themeisle-sdk-notice .notice-dismiss", function (e) {
333
334 var container = $('.themeisle-sdk-notice');
335 var link = $(this);
336 var notification_id = container.attr('data-notification-id');
337 var confirm = link.attr('data-confirm');
338 if (typeof confirm === "undefined") {
339 confirm = 'no';
340 }
341 $.post(
342 ajaxurl,
343 {
344 'nonce': '<?php echo esc_attr( wp_create_nonce( (string) __CLASS__ ) ); ?>',
345 'action': 'themeisle_sdk_dismiss_notice',
346 'id': notification_id,
347 'confirm': confirm,
348 },
349 ).fail(function() {
350 location.href = encodeURI(link.attr('href'));
351 });
352 if (confirm === 'yes') {
353 $(this).trigger('themeisle-sdk:confirmed');
354 } else {
355 $(this).trigger('themeisle-sdk:canceled');
356 }
357 container.hide();
358 if (confirm === 'no' || link.attr('href') === '#') {
359 return false;
360 }
361 });
362 });
363 })(jQuery);
364 </script>
365 <?php
366 }
367
368 /**
369 * Dismiss the notification.
370 */
371 public static function dismiss() {
372 check_ajax_referer( (string) __CLASS__, 'nonce' );
373
374 $id = isset( $_POST['id'] ) ? sanitize_text_field( $_POST['id'] ) : '';
375 $confirm = isset( $_POST['confirm'] ) ? sanitize_text_field( $_POST['confirm'] ) : 'no';
376
377 if ( empty( $id ) ) {
378 wp_send_json( [] );
379 }
380 $ids = wp_list_pluck( self::$notifications, 'id' );
381 if ( ! in_array( $id, $ids, true ) ) {
382 wp_send_json( [] );
383 }
384 self::set_last_active_notification_timestamp();
385 update_option( $id, $confirm );
386 do_action( $id . '_process_confirm', $confirm );
387 wp_send_json( [] );
388 }
389 /**
390 * Dismiss the notification.
391 */
392 public static function dismiss_get() {
393 $is_nonce_dismiss = sanitize_text_field( isset( $_GET['tsdk_dismiss_nonce'] ) ? $_GET['tsdk_dismiss_nonce'] : '' );
394 if ( strlen( $is_nonce_dismiss ) < 5 ) {
395 return;
396 }
397 $id = sanitize_text_field( isset( $_GET['nid'] ) ? $_GET['nid'] : '' );
398 if ( empty( $id ) ) {
399 return;
400 }
401 $nonce = wp_verify_nonce( sanitize_text_field( $_GET['tsdk_dismiss_nonce'] ), $id );
402 if ( $nonce !== 1 ) {
403 return;
404 }
405 $ids = wp_list_pluck( self::$notifications, 'id' );
406 if ( ! in_array( $id, $ids, true ) ) {
407 return;
408 }
409 $confirm = 'no';
410 self::set_last_active_notification_timestamp();
411 update_option( $id, $confirm );
412 do_action( $id . '_process_confirm', $confirm );
413 }
414
415 /**
416 * Check if we should load the notification module.
417 *
418 * @param Product $product Product to check.
419 *
420 * @return bool Should we load this?
421 */
422 public function can_load( $product ) {
423
424 if ( $this->is_from_partner( $product ) ) {
425 return false;
426 }
427 if ( ! current_user_can( 'manage_options' ) ) {
428 return false;
429 }
430 if ( ( time() - $product->get_install_time() ) < ( self::MIN_INSTALL_TIME * HOUR_IN_SECONDS ) ) {
431 return false;
432 }
433
434 return true;
435 }
436
437 /**
438 * Setup notifications queue.
439 */
440 public static function setup_notifications() {
441 $notifications = apply_filters( 'themeisle_sdk_registered_notifications', [] );
442 $notifications = array_filter(
443 $notifications,
444 function ( $value ) {
445 if ( ! isset( $value['id'] ) ) {
446 return false;
447 }
448 if ( get_option( $value['id'], '' ) !== '' ) {
449 return false;
450 }
451
452 return apply_filters( $value['id'] . '_should_show', true );
453 }
454 );
455 self::$notifications = $notifications;
456 }
457 /**
458 * Load the module logic.
459 *
460 * @param Product $product Product to load the module for.
461 *
462 * @return Notification Module instance.
463 */
464 public function load( $product ) {
465 if ( apply_filters( 'themeisle_sdk_hide_notifications', false ) ) {
466 return;
467 }
468 $this->product = $product;
469
470 $notifications = apply_filters( 'themeisle_sdk_registered_notifications', [] );
471 $notifications = array_filter(
472 $notifications,
473 function ( $value ) {
474 if ( ! isset( $value['id'] ) ) {
475 return false;
476 }
477 if ( get_option( $value['id'], '' ) !== '' ) {
478 return false;
479 }
480
481 return apply_filters( $value['id'] . '_should_show', true );
482 }
483 );
484 self::$notifications = $notifications;
485 add_action( 'admin_notices', array( __CLASS__, 'show_notification' ) );
486 add_action( 'wp_ajax_themeisle_sdk_dismiss_notice', array( __CLASS__, 'dismiss' ) );
487 add_action( 'admin_head', array( __CLASS__, 'dismiss_get' ) );
488 add_action( 'admin_head', array( __CLASS__, 'setup_notifications' ) );
489
490 return $this;
491 }
492 }
493