PluginProbe ʕ •ᴥ•ʔ
Blocks Animation: CSS Animations for Gutenberg Blocks / 3.2.0
Blocks Animation: CSS Animations for Gutenberg Blocks v3.2.0
3.2.0 3.1.11 3.1.10 2.2.5 2.2.6 2.2.7 2.3.0 2.3.1 2.3.2 2.3.3 2.3.4 2.4.0 2.4.1 2.5.0 2.5.1 2.5.2 2.6.0 2.6.1 2.6.10 2.6.11 2.6.12 2.6.13 2.6.2 2.6.3 2.6.4 2.6.5 2.6.6 2.6.7 2.6.8 2.6.9 3.0.0 3.0.1 3.0.10 3.0.11 3.0.12 3.0.2 3.0.3 3.0.4 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.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 trunk 1.0.0 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.1.0 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 2.0.0 2.0.1 2.0.10 2.0.11 2.0.12 2.0.13 2.0.14 2.0.15 2.0.16 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4
blocks-animation / vendor / codeinwp / themeisle-sdk / src / Modules / Notification.php
blocks-animation / vendor / codeinwp / themeisle-sdk / src / Modules Last commit date
About_us.php 1 week ago Abstract_Migration.php 1 month ago Announcements.php 1 month ago Compatibilities.php 1 year ago Dashboard_widget.php 1 week ago Featured_plugins.php 1 month ago Float_widget.php 1 year ago Licenser.php 1 month ago Logger.php 8 months ago Migrator.php 1 month ago Notification.php 1 year ago Promotions.php 1 week ago Recommendation.php 1 year ago Review.php 8 months ago Rollback.php 1 year ago Script_loader.php 8 months ago Translate.php 1 year ago Translations.php 8 months ago Uninstall_feedback.php 1 week ago Welcome.php 1 year ago
Notification.php
516 lines
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 'img_src' => '',
260 'message' => '',
261 'ctas' => [
262 'confirm' => [
263 'link' => '#',
264 'text' => '',
265 ],
266 'cancel' => [
267 'link' => '#',
268 'text' => '',
269 ],
270 ],
271 'type' => 'success',
272 ];
273 $notification_details = wp_parse_args( $notification_details, $default );
274 global $pagenow;
275 $type = in_array( $notification_details['type'], [ 'success', 'info', 'warning', 'error' ], true ) ? $notification_details['type'] : 'success';
276 $notification_details['ctas']['cancel']['link'] = wp_nonce_url( add_query_arg( [ 'nid' => $notification_details['id'] ], admin_url( $pagenow ) ), $notification_details['id'], 'tsdk_dismiss_nonce' );
277 $notification_html = '<div class="notice notice-' . $type . ' 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">';
278
279 if ( ! empty( $notification_details['heading'] ) ) {
280 $notification_html .= sprintf( '<h4>%s</h4>', wp_kses_post( $notification_details['heading'] ) );
281 }
282 if ( ! empty( $notification_details['img_src'] ) ) {
283 $notification_html .= '<div class="wrap-flex">';
284 $notification_html .= sprintf( '<img src="%s" alt="%s" />', esc_attr( $notification_details['img_src'] ), esc_attr( $notification_details['heading'] ) );
285 }
286 if ( ! empty( $notification_details['message'] ) ) {
287 $notification_html .= wp_kses_post( $notification_details['message'] );
288 if ( ! empty( $notification_details['img_src'] ) ) {
289 $notification_html .= '</div>';
290 }
291 }
292 $notification_html .= '<div class="actions">';
293
294 if ( ! empty( $notification_details['ctas']['confirm']['text'] ) ) {
295 $notification_html .= sprintf(
296 '<a href="%s" target="_blank" class=" button button-primary %s" data-confirm="yes" >%s</a>',
297 esc_url( $notification_details['ctas']['confirm']['link'] ),
298 esc_attr( $notification_details['id'] . '_confirm' ),
299 wp_kses_post( $notification_details['ctas']['confirm']['text'] )
300 );
301 }
302
303 if ( ! empty( $notification_details['ctas']['cancel']['text'] ) ) {
304 $notification_html .= sprintf(
305 '<a href="%s" class=" button %s" data-confirm="no">%s</a>',
306 esc_url( $notification_details['ctas']['cancel']['link'] ),
307 esc_attr( $notification_details['id'] ) . '_cancel',
308 wp_kses_post( $notification_details['ctas']['cancel']['text'] )
309 );
310 }
311
312 $notification_html .= '</div>';
313 $notification_html .= ' </div>';
314 $notification_html .= ' </div>';
315
316 return $notification_html;
317 }
318
319 /**
320 * Adds js snippet for hiding the notice.
321 */
322 public static function render_snippets() {
323
324 ?>
325 <style type="text/css">
326 .themeisle-sdk-notification-box {
327 padding: 3px;
328 }
329
330 .themeisle-sdk-notification-box .wrap-flex {
331 display: flex;
332 align-items: center;
333 justify-content: start;
334 gap: 12px;
335 }
336
337 .themeisle-sdk-notification-box .wrap-flex img {
338 width: 42px;
339 object-fit: cover;
340 }
341
342 .themeisle-sdk-notification-box .actions {
343 margin-top: 6px;
344 margin-bottom: 4px;
345 }
346
347 .themeisle-sdk-notification-box .button {
348 margin-right: 5px;
349 }
350 </style>
351 <script type="text/javascript">
352 (function ($) {
353 $(document).ready(function () {
354 $('#wpbody-content').on('click', ".themeisle-sdk-notice a.button, .themeisle-sdk-notice .notice-dismiss", function (e) {
355
356 var container = $('.themeisle-sdk-notice');
357 var link = $(this);
358 var notification_id = container.attr('data-notification-id');
359 var confirm = link.attr('data-confirm');
360 if (typeof confirm === "undefined") {
361 confirm = 'no';
362 }
363 $.post(
364 ajaxurl,
365 {
366 'nonce': '<?php echo esc_attr( wp_create_nonce( (string) __CLASS__ ) ); ?>',
367 'action': 'themeisle_sdk_dismiss_notice',
368 'id': notification_id,
369 'confirm': confirm,
370 },
371 ).fail(function() {
372 location.href = encodeURI(link.attr('href'));
373 });
374 if (confirm === 'yes') {
375 $(this).trigger('themeisle-sdk:confirmed');
376 } else {
377 $(this).trigger('themeisle-sdk:canceled');
378 }
379 container.hide();
380 if (confirm === 'no' || link.attr('href') === '#') {
381 return false;
382 }
383 });
384 });
385 })(jQuery);
386 </script>
387 <?php
388 }
389
390 /**
391 * Dismiss the notification.
392 */
393 public static function dismiss() {
394 check_ajax_referer( (string) __CLASS__, 'nonce' );
395
396 $id = isset( $_POST['id'] ) ? sanitize_text_field( $_POST['id'] ) : '';
397 $confirm = isset( $_POST['confirm'] ) ? sanitize_text_field( $_POST['confirm'] ) : 'no';
398
399 if ( empty( $id ) ) {
400 wp_send_json( [] );
401 }
402 self::setup_notifications();
403 $ids = wp_list_pluck( self::$notifications, 'id' );
404 if ( ! in_array( $id, $ids, true ) ) {
405 wp_send_json( [] );
406 }
407 self::set_last_active_notification_timestamp();
408 update_option( $id, $confirm );
409 do_action( $id . '_process_confirm', $confirm );
410 wp_send_json( [] );
411 }
412 /**
413 * Dismiss the notification.
414 */
415 public static function dismiss_get() {
416 $is_nonce_dismiss = sanitize_text_field( isset( $_GET['tsdk_dismiss_nonce'] ) ? $_GET['tsdk_dismiss_nonce'] : '' );
417 if ( strlen( $is_nonce_dismiss ) < 5 ) {
418 return;
419 }
420 $id = sanitize_text_field( isset( $_GET['nid'] ) ? $_GET['nid'] : '' );
421 if ( empty( $id ) ) {
422 return;
423 }
424 $nonce = wp_verify_nonce( sanitize_text_field( $_GET['tsdk_dismiss_nonce'] ), $id );
425 if ( $nonce !== 1 ) {
426 return;
427 }
428 $ids = wp_list_pluck( self::$notifications, 'id' );
429 if ( ! in_array( $id, $ids, true ) ) {
430 return;
431 }
432 $confirm = 'no';
433 self::set_last_active_notification_timestamp();
434 update_option( $id, $confirm );
435 do_action( $id . '_process_confirm', $confirm );
436 }
437
438 /**
439 * Check if we should load the notification module.
440 *
441 * @param Product $product Product to check.
442 *
443 * @return bool Should we load this?
444 */
445 public function can_load( $product ) {
446
447 if ( $this->is_from_partner( $product ) ) {
448 return false;
449 }
450 if ( ! current_user_can( 'manage_options' ) ) {
451 return false;
452 }
453 if ( ( time() - $product->get_install_time() ) < ( self::MIN_INSTALL_TIME * HOUR_IN_SECONDS ) ) {
454 return false;
455 }
456
457 return true;
458 }
459
460 /**
461 * Setup notifications queue.
462 */
463 public static function setup_notifications() {
464 $notifications = apply_filters( 'themeisle_sdk_registered_notifications', [] );
465 $notifications = array_filter(
466 $notifications,
467 function ( $value ) {
468 if ( ! isset( $value['id'] ) ) {
469 return false;
470 }
471 if ( get_option( $value['id'], '' ) !== '' ) {
472 return false;
473 }
474
475 return apply_filters( $value['id'] . '_should_show', true );
476 }
477 );
478 self::$notifications = $notifications;
479 }
480 /**
481 * Load the module logic.
482 *
483 * @param Product $product Product to load the module for.
484 *
485 * @return Notification Module instance.
486 */
487 public function load( $product ) {
488 if ( apply_filters( 'themeisle_sdk_hide_notifications', false ) ) {
489 return;
490 }
491 $this->product = $product;
492
493 $notifications = apply_filters( 'themeisle_sdk_registered_notifications', [] );
494 $notifications = array_filter(
495 $notifications,
496 function ( $value ) {
497 if ( ! isset( $value['id'] ) ) {
498 return false;
499 }
500 if ( get_option( $value['id'], '' ) !== '' ) {
501 return false;
502 }
503
504 return apply_filters( $value['id'] . '_should_show', true );
505 }
506 );
507 self::$notifications = $notifications;
508 add_action( 'admin_notices', array( __CLASS__, 'show_notification' ) );
509 add_action( 'wp_ajax_themeisle_sdk_dismiss_notice', array( __CLASS__, 'dismiss' ) );
510 add_action( 'admin_head', array( __CLASS__, 'dismiss_get' ) );
511 add_action( 'admin_head', array( __CLASS__, 'setup_notifications' ) );
512
513 return $this;
514 }
515 }
516