PluginProbe
BlockSpare – Gutenberg Blocks, AI Content Generator & Site Builder for news, magazine, blog and business sites / 2.6.6
BlockSpare – Gutenberg Blocks, AI Content Generator & Site Builder for news, magazine, blog and business sites v2.6.6
5.0.1 4.1.0 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.1.0 1.1.1 1.1.2 1.2.0 1.2.1 1.2.2 1.2.3 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 2.1.2 2.5.0 2.5.3 All 39 releases
← All changes | freemius/includes/managers/class-fs-admin-notice-manager.php +532 -538 5.0.1 → 2.6.6 View file →
@@ -1,538 +1,532 @@
1 -<?php
2 - /**
3 - * @package Freemius
4 - * @copyright Copyright (c) 2015, Freemius, Inc.
5 - * @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
6 - * @since 1.0.7
7 - */
8 -
9 - if ( ! defined( 'ABSPATH' ) ) {
10 - exit;
11 - }
12 -
13 - class FS_Admin_Notice_Manager {
14 - /**
15 - * @since 1.2.2
16 - *
17 - * @var string
18 - */
19 - protected $_module_unique_affix;
20 - /**
21 - * @var string
22 - */
23 - protected $_id;
24 - /**
25 - * @var string
26 - */
27 - protected $_title;
28 - /**
29 - * @var array[string]array
30 - */
31 - private $_notices = array();
32 - /**
33 - * @var FS_Key_Value_Storage
34 - */
35 - private $_sticky_storage;
36 - /**
37 - * @var FS_Logger
38 - */
39 - protected $_logger;
40 - /**
41 - * @since 2.0.0
42 - * @var int The ID of the blog that is associated with the current site level admin notices.
43 - */
44 - private $_blog_id = 0;
45 - /**
46 - * @since 2.0.0
47 - * @var bool
48 - */
49 - private $_is_network_notices;
50 -
51 - /**
52 - * @var FS_Admin_Notice_Manager[]
53 - */
54 - private static $_instances = array();
55 -
56 - /**
57 - * @param string $id
58 - * @param string $title
59 - * @param string $module_unique_affix
60 - * @param bool $is_network_and_blog_admins Whether or not the message should be shown both on
61 - * network and blog admin pages.
62 - * @param bool $network_level_or_blog_id Since 2.0.0
63 - *
64 - * @return \FS_Admin_Notice_Manager
65 - */
66 - static function instance(
67 - $id,
68 - $title = '',
69 - $module_unique_affix = '',
70 - $is_network_and_blog_admins = false,
71 - $network_level_or_blog_id = false
72 - ) {
73 - if ( $is_network_and_blog_admins ) {
74 - $network_level_or_blog_id = true;
75 - }
76 -
77 - $key = strtolower( $id );
78 -
79 - if ( is_multisite() ) {
80 - if ( true === $network_level_or_blog_id ) {
81 - $key .= ':ms';
82 - } else if ( is_numeric( $network_level_or_blog_id ) && $network_level_or_blog_id > 0 ) {
83 - $key .= ":{$network_level_or_blog_id}";
84 - } else {
85 - $network_level_or_blog_id = get_current_blog_id();
86 -
87 - $key .= ":{$network_level_or_blog_id}";
88 - }
89 - }
90 -
91 - if ( ! isset( self::$_instances[ $key ] ) ) {
92 - self::$_instances[ $key ] = new FS_Admin_Notice_Manager(
93 - $id,
94 - $title,
95 - $module_unique_affix,
96 - $is_network_and_blog_admins,
97 - $network_level_or_blog_id
98 - );
99 - }
100 -
101 - return self::$_instances[ $key ];
102 - }
103 -
104 - /**
105 - * @param string $id
106 - * @param string $title
107 - * @param string $module_unique_affix
108 - * @param bool $is_network_and_blog_admins Whether or not the message should be shown both on network and
109 - * blog admin pages.
110 - * @param bool|int $network_level_or_blog_id
111 - */
112 - protected function __construct(
113 - $id,
114 - $title = '',
115 - $module_unique_affix = '',
116 - $is_network_and_blog_admins = false,
117 - $network_level_or_blog_id = false
118 - ) {
119 - $this->_id = $id;
120 - $this->_logger = FS_Logger::get_logger( WP_FS__SLUG . '_' . $this->_id . '_data', WP_FS__DEBUG_SDK, WP_FS__ECHO_DEBUG_SDK );
121 - $this->_title = ! empty( $title ) ? $title : '';
122 - $this->_module_unique_affix = $module_unique_affix;
123 - $this->_sticky_storage = FS_Key_Value_Storage::instance( 'admin_notices', $this->_id, $network_level_or_blog_id );
124 -
125 - if ( is_multisite() ) {
126 - $this->_is_network_notices = ( true === $network_level_or_blog_id );
127 -
128 - if ( is_numeric( $network_level_or_blog_id ) ) {
129 - $this->_blog_id = $network_level_or_blog_id;
130 - }
131 - } else {
132 - $this->_is_network_notices = false;
133 - }
134 -
135 - $is_network_admin = fs_is_network_admin();
136 - $is_blog_admin = fs_is_blog_admin();
137 -
138 - if ( ( $this->_is_network_notices && $is_network_admin ) ||
139 - ( ! $this->_is_network_notices && $is_blog_admin ) ||
140 - ( $is_network_and_blog_admins && ( $is_network_admin || $is_blog_admin ) )
141 - ) {
142 - if ( 0 < count( $this->_sticky_storage ) ) {
143 - $ajax_action_suffix = str_replace( ':', '-', $this->_id );
144 -
145 - // If there are sticky notices for the current slug, add a callback
146 - // to the AJAX action that handles message dismiss.
147 - add_action( "wp_ajax_fs_dismiss_notice_action_{$ajax_action_suffix}", array(
148 - &$this,
149 - 'dismiss_notice_ajax_callback'
150 - ) );
151 -
152 - foreach ( $this->_sticky_storage as $msg ) {
153 - // Add admin notice.
154 - $this->add(
155 - $msg['message'],
156 - $msg['title'],
157 - $msg['type'],
158 - true,
159 - $msg['id'],
160 - false,
161 - isset( $msg['wp_user_id'] ) ? $msg['wp_user_id'] : null,
162 - ! empty( $msg['plugin'] ) ? $msg['plugin'] : null,
163 - $is_network_and_blog_admins,
164 - isset( $msg['dismissible'] ) ?
165 - $msg['dismissible'] :
166 - null
167 - );
168 - }
169 - }
170 - }
171 - }
172 -
173 - /**
174 - * Remove sticky message by ID.
175 - *
176 - * @author Vova Feldman (@svovaf)
177 - * @since 1.0.7
178 - *
179 - */
180 - function dismiss_notice_ajax_callback() {
181 - check_admin_referer( 'fs_dismiss_notice_action' );
182 -
183 - if ( ! is_numeric( $_POST['message_id'] ) ) {
184 - $this->_sticky_storage->remove( $_POST['message_id'] );
185 - }
186 -
187 - wp_die();
188 - }
189 -
190 - /**
191 - * Rendered sticky message dismiss JavaScript.
192 - *
193 - * @author Vova Feldman (@svovaf)
194 - * @since 1.0.7
195 - */
196 - static function _add_sticky_dismiss_javascript() {
197 - $sticky_admin_notice_js_template_name = 'sticky-admin-notice-js.php';
198 -
199 - if ( ! file_exists( fs_get_template_path( $sticky_admin_notice_js_template_name ) ) ) {
200 - return;
201 - }
202 -
203 - $params = array();
204 - fs_require_once_template( $sticky_admin_notice_js_template_name, $params );
205 - }
206 -
207 - private static $_added_sticky_javascript = false;
208 -
209 - /**
210 - * Hook to the admin_footer to add sticky message dismiss JavaScript handler.
211 - *
212 - * @author Vova Feldman (@svovaf)
213 - * @since 1.0.7
214 - */
215 - private static function has_sticky_messages() {
216 - if ( ! self::$_added_sticky_javascript ) {
217 - add_action( 'admin_footer', array( 'FS_Admin_Notice_Manager', '_add_sticky_dismiss_javascript' ) );
218 - }
219 - }
220 -
221 - /**
222 - * Handle admin_notices by printing the admin messages stacked in the queue.
223 - *
224 - * @author Vova Feldman (@svovaf)
225 - * @since 1.0.4
226 - *
227 - */
228 - function _admin_notices_hook() {
229 - if ( function_exists( 'current_user_can' ) &&
230 - ! current_user_can( 'manage_options' )
231 - ) {
232 - // Only show messages to admins.
233 - return;
234 - }
235 -
236 - foreach ( $this->_notices as $id => $msg ) {
237 - if ( isset( $msg['wp_user_id'] ) && is_numeric( $msg['wp_user_id'] ) ) {
238 - if ( get_current_user_id() != $msg['wp_user_id'] ) {
239 - continue;
240 - }
241 - }
242 -
243 - /**
244 - * Added a filter to control the visibility of admin notices.
245 - *
246 - * Usage example:
247 - *
248 - * /**
249 - * * @param bool $show
250 - * * @param array $msg {
251 - * * @var string $message The actual message.
252 - * * @var string $title An optional message title.
253 - * * @var string $type The type of the message ('success', 'update', 'warning', 'promotion').
254 - * * @var string $id The unique identifier of the message.
255 - * * @var string $manager_id The unique identifier of the notices manager. For plugins it would be the plugin's slug, for themes - `<slug>-theme`.
256 - * * @var string $plugin The product's title.
257 - * * @var string $wp_user_id An optional WP user ID that this admin notice is for.
258 - * * }
259 - * *
260 - * * @return bool
261 - * *\/
262 - * function my_custom_show_admin_notice( $show, $msg ) {
263 - * if ('trial_promotion' != $msg['id']) {
264 - * return false;
265 - * }
266 - *
267 - * return $show;
268 - * }
269 - *
270 - * my_fs()->add_filter( 'show_admin_notice', 'my_custom_show_admin_notice', 10, 2 );
271 - *
272 - * @author Vova Feldman
273 - * @since 2.2.0
274 - */
275 - $show_notice = call_user_func_array( 'fs_apply_filter', array(
276 - $this->_module_unique_affix,
277 - 'show_admin_notice',
278 - $this->show_admin_notices(),
279 - $msg
280 - ) );
281 -
282 - if ( true !== $show_notice ) {
283 - continue;
284 - }
285 -
286 - fs_require_template( 'admin-notice.php', $msg );
287 -
288 - if ( $msg['sticky'] ) {
289 - self::has_sticky_messages();
290 - }
291 - }
292 - }
293 -
294 - /**
295 - * Enqueue common stylesheet to style admin notice.
296 - *
297 - * @author Vova Feldman (@svovaf)
298 - * @since 1.0.7
299 - */
300 - function _enqueue_styles() {
301 - fs_enqueue_local_style( 'fs_common', '/admin/common.css' );
302 - }
303 -
304 - /**
305 - * Check if the current page is the Gutenberg block editor.
306 - *
307 - * @author Vova Feldman (@svovaf)
308 - * @since 2.2.3
309 - *
310 - * @return bool
311 - */
312 - function is_gutenberg_page() {
313 - if ( function_exists( 'is_gutenberg_page' ) &&
314 - is_gutenberg_page()
315 - ) {
316 - // The Gutenberg plugin is on.
317 - return true;
318 - }
319 -
320 - $current_screen = get_current_screen();
321 -
322 - if ( method_exists( $current_screen, 'is_block_editor' ) &&
323 - $current_screen->is_block_editor()
324 - ) {
325 - // Gutenberg page on 5+.
326 - return true;
327 - }
328 -
329 - return false;
330 - }
331 -
332 - /**
333 - * Check if admin notices should be shown on page. E.g., we don't want to show notices in the Visual Editor.
334 - *
335 - * @author Xiaheng Chen (@xhchen)
336 - * @since 2.4.2
337 - *
338 - * @return bool
339 - */
340 - function show_admin_notices() {
341 - global $pagenow;
342 -
343 - if ( 'about.php' === $pagenow ) {
344 - // Don't show admin notices on the About page.
345 - return false;
346 - }
347 -
348 - if ( $this->is_gutenberg_page() ) {
349 - // Don't show admin notices in Gutenberg (visual editor).
350 - return false;
351 - }
352 -
353 - return true;
354 - }
355 -
356 - /**
357 - * Add admin message to admin messages queue, and hook to admin_notices / all_admin_notices if not yet hooked.
358 - *
359 - * @author Vova Feldman (@svovaf)
360 - * @since 1.0.4
361 - *
362 - * @param string $message
363 - * @param string $title
364 - * @param string $type
365 - * @param bool $is_sticky
366 - * @param string $id Message ID
367 - * @param bool $store_if_sticky
368 - * @param number|null $wp_user_id
369 - * @param string|null $plugin_title
370 - * @param bool $is_network_and_blog_admins Whether or not the message should be shown both on network
371 - * and blog admin pages.
372 - * @param bool|null $is_dismissible
373 - * @param array $data
374 - *
375 - * @uses add_action()
376 - */
377 - function add(
378 - $message,
379 - $title = '',
380 - $type = 'success',
381 - $is_sticky = false,
382 - $id = '',
383 - $store_if_sticky = true,
384 - $wp_user_id = null,
385 - $plugin_title = null,
386 - $is_network_and_blog_admins = false,
387 - $is_dismissible = null,
388 - $data = array()
389 - ) {
390 - $notices_type = $this->get_notices_type();
391 -
392 - if ( empty( $this->_notices ) ) {
393 - if ( ! $is_network_and_blog_admins ) {
394 - add_action( $notices_type, array( &$this, "_admin_notices_hook" ) );
395 - } else {
396 - add_action( 'network_admin_notices', array( &$this, "_admin_notices_hook" ) );
397 - add_action( 'admin_notices', array( &$this, "_admin_notices_hook" ) );
398 - }
399 -
400 - add_action( 'admin_enqueue_scripts', array( &$this, '_enqueue_styles' ) );
401 - }
402 -
403 - if ( '' === $id ) {
404 - $id = md5( $title . ' ' . $message . ' ' . $type );
405 - }
406 -
407 - $message_object = array(
408 - 'message' => $message,
409 - 'title' => $title,
410 - 'type' => $type,
411 - 'sticky' => $is_sticky,
412 - 'id' => $id,
413 - 'manager_id' => $this->_id,
414 - 'plugin' => ( ! is_null( $plugin_title ) ? $plugin_title : $this->_title ),
415 - 'wp_user_id' => $wp_user_id,
416 - 'dismissible' => $is_dismissible,
417 - 'data' => $data
418 - );
419 -
420 - if ( $is_sticky && $store_if_sticky ) {
421 - $this->_sticky_storage->{$id} = $message_object;
422 - }
423 -
424 - $this->_notices[ $id ] = $message_object;
425 - }
426 -
427 - /**
428 - * @author Vova Feldman (@svovaf)
429 - * @since 1.0.7
430 - *
431 - * @param string|string[] $ids
432 - * @param bool $store
433 - */
434 - function remove_sticky( $ids, $store = true ) {
435 - if ( ! is_array( $ids ) ) {
436 - $ids = array( $ids );
437 - }
438 -
439 - foreach ( $ids as $id ) {
440 - // Remove from sticky storage.
441 - $this->_sticky_storage->remove( $id, $store );
442 -
443 - if ( isset( $this->_notices[ $id ] ) ) {
444 - unset( $this->_notices[ $id ] );
445 - }
446 - }
447 - }
448 -
449 - /**
450 - * Check if sticky message exists by id.
451 - *
452 - * @author Vova Feldman (@svovaf)
453 - * @since 1.0.9
454 - *
455 - * @param $id
456 - *
457 - * @return bool
458 - */
459 - function has_sticky( $id ) {
460 - return isset( $this->_sticky_storage[ $id ] );
461 - }
462 -
463 - /**
464 - * Adds sticky admin notification.
465 - *
466 - * @author Vova Feldman (@svovaf)
467 - * @since 1.0.7
468 - *
469 - * @param string $message
470 - * @param string $id Message ID
471 - * @param string $title
472 - * @param string $type
473 - * @param number|null $wp_user_id
474 - * @param string|null $plugin_title
475 - * @param bool $is_network_and_blog_admins Whether or not the message should be shown both on network
476 - * and blog admin pages.
477 - * @param bool $is_dimissible
478 - * @param array $data
479 - */
480 - function add_sticky( $message, $id, $title = '', $type = 'success', $wp_user_id = null, $plugin_title = null, $is_network_and_blog_admins = false, $is_dimissible = true, $data = array() ) {
481 - if ( ! empty( $this->_module_unique_affix ) ) {
482 - $message = fs_apply_filter( $this->_module_unique_affix, "sticky_message_{$id}", $message );
483 - $title = fs_apply_filter( $this->_module_unique_affix, "sticky_title_{$id}", $title );
484 - }
485 -
486 - $this->add( $message, $title, $type, true, $id, true, $wp_user_id, $plugin_title, $is_network_and_blog_admins, $is_dimissible, $data );
487 - }
488 -
489 - /**
490 - * Retrieves the data of an sticky notice.
491 - *
492 - * @author Leo Fajardo (@leorw)
493 - * @since 2.4.3
494 - *
495 - * @param string $id Message ID.
496 - *
497 - * @return array|null
498 - */
499 - function get_sticky( $id ) {
500 - return isset( $this->_sticky_storage->{$id} ) ?
501 - $this->_sticky_storage->{$id} :
502 - null;
503 - }
504 -
505 - /**
506 - * Clear all sticky messages.
507 - *
508 - * @author Vova Feldman (@svovaf)
509 - * @since 1.0.8
510 - *
511 - * @param bool $is_temporary @since 2.5.1
512 - */
513 - function clear_all_sticky( $is_temporary = false ) {
514 - if ( $is_temporary ) {
515 - $this->_notices = array();
516 - } else {
517 - $this->_sticky_storage->clear_all();
518 - }
519 - }
520 -
521 - #--------------------------------------------------------------------------------
522 - #region Helper Method
523 - #--------------------------------------------------------------------------------
524 -
525 - /**
526 - * @author Vova Feldman (@svovaf)
527 - * @since 2.0.0
528 - *
529 - * @return string
530 - */
531 - private function get_notices_type() {
532 - return $this->_is_network_notices ?
533 - 'network_admin_notices' :
534 - 'admin_notices';
535 - }
536 -
537 - #endregion
538 - }
1 +<?php
2 + /**
3 + * @package Freemius
4 + * @copyright Copyright (c) 2015, Freemius, Inc.
5 + * @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
6 + * @since 1.0.7
7 + */
8 +
9 + if ( ! defined( 'ABSPATH' ) ) {
10 + exit;
11 + }
12 +
13 + class FS_Admin_Notice_Manager {
14 + /**
15 + * @since 1.2.2
16 + *
17 + * @var string
18 + */
19 + protected $_module_unique_affix;
20 + /**
21 + * @var string
22 + */
23 + protected $_id;
24 + /**
25 + * @var string
26 + */
27 + protected $_title;
28 + /**
29 + * @var array[string]array
30 + */
31 + private $_notices = array();
32 + /**
33 + * @var FS_Key_Value_Storage
34 + */
35 + private $_sticky_storage;
36 + /**
37 + * @var FS_Logger
38 + */
39 + protected $_logger;
40 + /**
41 + * @since 2.0.0
42 + * @var int The ID of the blog that is associated with the current site level admin notices.
43 + */
44 + private $_blog_id = 0;
45 + /**
46 + * @since 2.0.0
47 + * @var bool
48 + */
49 + private $_is_network_notices;
50 +
51 + /**
52 + * @var FS_Admin_Notice_Manager[]
53 + */
54 + private static $_instances = array();
55 +
56 + /**
57 + * @param string $id
58 + * @param string $title
59 + * @param string $module_unique_affix
60 + * @param bool $is_network_and_blog_admins Whether or not the message should be shown both on
61 + * network and blog admin pages.
62 + * @param bool $network_level_or_blog_id Since 2.0.0
63 + *
64 + * @return \FS_Admin_Notice_Manager
65 + */
66 + static function instance(
67 + $id,
68 + $title = '',
69 + $module_unique_affix = '',
70 + $is_network_and_blog_admins = false,
71 + $network_level_or_blog_id = false
72 + ) {
73 + if ( $is_network_and_blog_admins ) {
74 + $network_level_or_blog_id = true;
75 + }
76 +
77 + $key = strtolower( $id );
78 +
79 + if ( is_multisite() ) {
80 + if ( true === $network_level_or_blog_id ) {
81 + $key .= ':ms';
82 + } else if ( is_numeric( $network_level_or_blog_id ) && $network_level_or_blog_id > 0 ) {
83 + $key .= ":{$network_level_or_blog_id}";
84 + } else {
85 + $network_level_or_blog_id = get_current_blog_id();
86 +
87 + $key .= ":{$network_level_or_blog_id}";
88 + }
89 + }
90 +
91 + if ( ! isset( self::$_instances[ $key ] ) ) {
92 + self::$_instances[ $key ] = new FS_Admin_Notice_Manager(
93 + $id,
94 + $title,
95 + $module_unique_affix,
96 + $is_network_and_blog_admins,
97 + $network_level_or_blog_id
98 + );
99 + }
100 +
101 + return self::$_instances[ $key ];
102 + }
103 +
104 + /**
105 + * @param string $id
106 + * @param string $title
107 + * @param string $module_unique_affix
108 + * @param bool $is_network_and_blog_admins Whether or not the message should be shown both on network and
109 + * blog admin pages.
110 + * @param bool|int $network_level_or_blog_id
111 + */
112 + protected function __construct(
113 + $id,
114 + $title = '',
115 + $module_unique_affix = '',
116 + $is_network_and_blog_admins = false,
117 + $network_level_or_blog_id = false
118 + ) {
119 + $this->_id = $id;
120 + $this->_logger = FS_Logger::get_logger( WP_FS__SLUG . '_' . $this->_id . '_data', WP_FS__DEBUG_SDK, WP_FS__ECHO_DEBUG_SDK );
121 + $this->_title = ! empty( $title ) ? $title : '';
122 + $this->_module_unique_affix = $module_unique_affix;
123 + $this->_sticky_storage = FS_Key_Value_Storage::instance( 'admin_notices', $this->_id, $network_level_or_blog_id );
124 +
125 + if ( is_multisite() ) {
126 + $this->_is_network_notices = ( true === $network_level_or_blog_id );
127 +
128 + if ( is_numeric( $network_level_or_blog_id ) ) {
129 + $this->_blog_id = $network_level_or_blog_id;
130 + }
131 + } else {
132 + $this->_is_network_notices = false;
133 + }
134 +
135 + $is_network_admin = fs_is_network_admin();
136 + $is_blog_admin = fs_is_blog_admin();
137 +
138 + if ( ( $this->_is_network_notices && $is_network_admin ) ||
139 + ( ! $this->_is_network_notices && $is_blog_admin ) ||
140 + ( $is_network_and_blog_admins && ( $is_network_admin || $is_blog_admin ) )
141 + ) {
142 + if ( 0 < count( $this->_sticky_storage ) ) {
143 + $ajax_action_suffix = str_replace( ':', '-', $this->_id );
144 +
145 + // If there are sticky notices for the current slug, add a callback
146 + // to the AJAX action that handles message dismiss.
147 + add_action( "wp_ajax_fs_dismiss_notice_action_{$ajax_action_suffix}", array(
148 + &$this,
149 + 'dismiss_notice_ajax_callback'
150 + ) );
151 +
152 + foreach ( $this->_sticky_storage as $msg ) {
153 + // Add admin notice.
154 + $this->add(
155 + $msg['message'],
156 + $msg['title'],
157 + $msg['type'],
158 + true,
159 + $msg['id'],
160 + false,
161 + isset( $msg['wp_user_id'] ) ? $msg['wp_user_id'] : null,
162 + ! empty( $msg['plugin'] ) ? $msg['plugin'] : null,
163 + $is_network_and_blog_admins,
164 + isset( $msg['dismissible'] ) ?
165 + $msg['dismissible'] :
166 + null
167 + );
168 + }
169 + }
170 + }
171 + }
172 +
173 + /**
174 + * Remove sticky message by ID.
175 + *
176 + * @author Vova Feldman (@svovaf)
177 + * @since 1.0.7
178 + *
179 + */
180 + function dismiss_notice_ajax_callback() {
181 + check_admin_referer( 'fs_dismiss_notice_action' );
182 +
183 + if ( ! is_numeric( $_POST['message_id'] ) ) {
184 + $this->_sticky_storage->remove( $_POST['message_id'] );
185 + }
186 +
187 + wp_die();
188 + }
189 +
190 + /**
191 + * Rendered sticky message dismiss JavaScript.
192 + *
193 + * @author Vova Feldman (@svovaf)
194 + * @since 1.0.7
195 + */
196 + static function _add_sticky_dismiss_javascript() {
197 + $params = array();
198 + fs_require_once_template( 'sticky-admin-notice-js.php', $params );
199 + }
200 +
201 + private static $_added_sticky_javascript = false;
202 +
203 + /**
204 + * Hook to the admin_footer to add sticky message dismiss JavaScript handler.
205 + *
206 + * @author Vova Feldman (@svovaf)
207 + * @since 1.0.7
208 + */
209 + private static function has_sticky_messages() {
210 + if ( ! self::$_added_sticky_javascript ) {
211 + add_action( 'admin_footer', array( 'FS_Admin_Notice_Manager', '_add_sticky_dismiss_javascript' ) );
212 + }
213 + }
214 +
215 + /**
216 + * Handle admin_notices by printing the admin messages stacked in the queue.
217 + *
218 + * @author Vova Feldman (@svovaf)
219 + * @since 1.0.4
220 + *
221 + */
222 + function _admin_notices_hook() {
223 + if ( function_exists( 'current_user_can' ) &&
224 + ! current_user_can( 'manage_options' )
225 + ) {
226 + // Only show messages to admins.
227 + return;
228 + }
229 +
230 + foreach ( $this->_notices as $id => $msg ) {
231 + if ( isset( $msg['wp_user_id'] ) && is_numeric( $msg['wp_user_id'] ) ) {
232 + if ( get_current_user_id() != $msg['wp_user_id'] ) {
233 + continue;
234 + }
235 + }
236 +
237 + /**
238 + * Added a filter to control the visibility of admin notices.
239 + *
240 + * Usage example:
241 + *
242 + * /**
243 + * * @param bool $show
244 + * * @param array $msg {
245 + * * @var string $message The actual message.
246 + * * @var string $title An optional message title.
247 + * * @var string $type The type of the message ('success', 'update', 'warning', 'promotion').
248 + * * @var string $id The unique identifier of the message.
249 + * * @var string $manager_id The unique identifier of the notices manager. For plugins it would be the plugin's slug, for themes - `<slug>-theme`.
250 + * * @var string $plugin The product's title.
251 + * * @var string $wp_user_id An optional WP user ID that this admin notice is for.
252 + * * }
253 + * *
254 + * * @return bool
255 + * *\/
256 + * function my_custom_show_admin_notice( $show, $msg ) {
257 + * if ('trial_promotion' != $msg['id']) {
258 + * return false;
259 + * }
260 + *
261 + * return $show;
262 + * }
263 + *
264 + * my_fs()->add_filter( 'show_admin_notice', 'my_custom_show_admin_notice', 10, 2 );
265 + *
266 + * @author Vova Feldman
267 + * @since 2.2.0
268 + */
269 + $show_notice = call_user_func_array( 'fs_apply_filter', array(
270 + $this->_module_unique_affix,
271 + 'show_admin_notice',
272 + $this->show_admin_notices(),
273 + $msg
274 + ) );
275 +
276 + if ( true !== $show_notice ) {
277 + continue;
278 + }
279 +
280 + fs_require_template( 'admin-notice.php', $msg );
281 +
282 + if ( $msg['sticky'] ) {
283 + self::has_sticky_messages();
284 + }
285 + }
286 + }
287 +
288 + /**
289 + * Enqueue common stylesheet to style admin notice.
290 + *
291 + * @author Vova Feldman (@svovaf)
292 + * @since 1.0.7
293 + */
294 + function _enqueue_styles() {
295 + fs_enqueue_local_style( 'fs_common', '/admin/common.css' );
296 + }
297 +
298 + /**
299 + * Check if the current page is the Gutenberg block editor.
300 + *
301 + * @author Vova Feldman (@svovaf)
302 + * @since 2.2.3
303 + *
304 + * @return bool
305 + */
306 + function is_gutenberg_page() {
307 + if ( function_exists( 'is_gutenberg_page' ) &&
308 + is_gutenberg_page()
309 + ) {
310 + // The Gutenberg plugin is on.
311 + return true;
312 + }
313 +
314 + $current_screen = get_current_screen();
315 +
316 + if ( method_exists( $current_screen, 'is_block_editor' ) &&
317 + $current_screen->is_block_editor()
318 + ) {
319 + // Gutenberg page on 5+.
320 + return true;
321 + }
322 +
323 + return false;
324 + }
325 +
326 + /**
327 + * Check if admin notices should be shown on page. E.g., we don't want to show notices in the Visual Editor.
328 + *
329 + * @author Xiaheng Chen (@xhchen)
330 + * @since 2.4.2
331 + *
332 + * @return bool
333 + */
334 + function show_admin_notices() {
335 + global $pagenow;
336 +
337 + if ( 'about.php' === $pagenow ) {
338 + // Don't show admin notices on the About page.
339 + return false;
340 + }
341 +
342 + if ( $this->is_gutenberg_page() ) {
343 + // Don't show admin notices in Gutenberg (visual editor).
344 + return false;
345 + }
346 +
347 + return true;
348 + }
349 +
350 + /**
351 + * Add admin message to admin messages queue, and hook to admin_notices / all_admin_notices if not yet hooked.
352 + *
353 + * @author Vova Feldman (@svovaf)
354 + * @since 1.0.4
355 + *
356 + * @param string $message
357 + * @param string $title
358 + * @param string $type
359 + * @param bool $is_sticky
360 + * @param string $id Message ID
361 + * @param bool $store_if_sticky
362 + * @param number|null $wp_user_id
363 + * @param string|null $plugin_title
364 + * @param bool $is_network_and_blog_admins Whether or not the message should be shown both on network
365 + * and blog admin pages.
366 + * @param bool|null $is_dismissible
367 + * @param array $data
368 + *
369 + * @uses add_action()
370 + */
371 + function add(
372 + $message,
373 + $title = '',
374 + $type = 'success',
375 + $is_sticky = false,
376 + $id = '',
377 + $store_if_sticky = true,
378 + $wp_user_id = null,
379 + $plugin_title = null,
380 + $is_network_and_blog_admins = false,
381 + $is_dismissible = null,
382 + $data = array()
383 + ) {
384 + $notices_type = $this->get_notices_type();
385 +
386 + if ( empty( $this->_notices ) ) {
387 + if ( ! $is_network_and_blog_admins ) {
388 + add_action( $notices_type, array( &$this, "_admin_notices_hook" ) );
389 + } else {
390 + add_action( 'network_admin_notices', array( &$this, "_admin_notices_hook" ) );
391 + add_action( 'admin_notices', array( &$this, "_admin_notices_hook" ) );
392 + }
393 +
394 + add_action( 'admin_enqueue_scripts', array( &$this, '_enqueue_styles' ) );
395 + }
396 +
397 + if ( '' === $id ) {
398 + $id = md5( $title . ' ' . $message . ' ' . $type );
399 + }
400 +
401 + $message_object = array(
402 + 'message' => $message,
403 + 'title' => $title,
404 + 'type' => $type,
405 + 'sticky' => $is_sticky,
406 + 'id' => $id,
407 + 'manager_id' => $this->_id,
408 + 'plugin' => ( ! is_null( $plugin_title ) ? $plugin_title : $this->_title ),
409 + 'wp_user_id' => $wp_user_id,
410 + 'dismissible' => $is_dismissible,
411 + 'data' => $data
412 + );
413 +
414 + if ( $is_sticky && $store_if_sticky ) {
415 + $this->_sticky_storage->{$id} = $message_object;
416 + }
417 +
418 + $this->_notices[ $id ] = $message_object;
419 + }
420 +
421 + /**
422 + * @author Vova Feldman (@svovaf)
423 + * @since 1.0.7
424 + *
425 + * @param string|string[] $ids
426 + * @param bool $store
427 + */
428 + function remove_sticky( $ids, $store = true ) {
429 + if ( ! is_array( $ids ) ) {
430 + $ids = array( $ids );
431 + }
432 +
433 + foreach ( $ids as $id ) {
434 + // Remove from sticky storage.
435 + $this->_sticky_storage->remove( $id, $store );
436 +
437 + if ( isset( $this->_notices[ $id ] ) ) {
438 + unset( $this->_notices[ $id ] );
439 + }
440 + }
441 + }
442 +
443 + /**
444 + * Check if sticky message exists by id.
445 + *
446 + * @author Vova Feldman (@svovaf)
447 + * @since 1.0.9
448 + *
449 + * @param $id
450 + *
451 + * @return bool
452 + */
453 + function has_sticky( $id ) {
454 + return isset( $this->_sticky_storage[ $id ] );
455 + }
456 +
457 + /**
458 + * Adds sticky admin notification.
459 + *
460 + * @author Vova Feldman (@svovaf)
461 + * @since 1.0.7
462 + *
463 + * @param string $message
464 + * @param string $id Message ID
465 + * @param string $title
466 + * @param string $type
467 + * @param number|null $wp_user_id
468 + * @param string|null $plugin_title
469 + * @param bool $is_network_and_blog_admins Whether or not the message should be shown both on network
470 + * and blog admin pages.
471 + * @param bool $is_dimissible
472 + * @param array $data
473 + */
474 + function add_sticky( $message, $id, $title = '', $type = 'success', $wp_user_id = null, $plugin_title = null, $is_network_and_blog_admins = false, $is_dimissible = true, $data = array() ) {
475 + if ( ! empty( $this->_module_unique_affix ) ) {
476 + $message = fs_apply_filter( $this->_module_unique_affix, "sticky_message_{$id}", $message );
477 + $title = fs_apply_filter( $this->_module_unique_affix, "sticky_title_{$id}", $title );
478 + }
479 +
480 + $this->add( $message, $title, $type, true, $id, true, $wp_user_id, $plugin_title, $is_network_and_blog_admins, $is_dimissible, $data );
481 + }
482 +
483 + /**
484 + * Retrieves the data of an sticky notice.
485 + *
486 + * @author Leo Fajardo (@leorw)
487 + * @since 2.4.3
488 + *
489 + * @param string $id Message ID.
490 + *
491 + * @return array|null
492 + */
493 + function get_sticky( $id ) {
494 + return isset( $this->_sticky_storage->{$id} ) ?
495 + $this->_sticky_storage->{$id} :
496 + null;
497 + }
498 +
499 + /**
500 + * Clear all sticky messages.
501 + *
502 + * @author Vova Feldman (@svovaf)
503 + * @since 1.0.8
504 + *
505 + * @param bool $is_temporary @since 2.5.1
506 + */
507 + function clear_all_sticky( $is_temporary = false ) {
508 + if ( $is_temporary ) {
509 + $this->_notices = array();
510 + } else {
511 + $this->_sticky_storage->clear_all();
512 + }
513 + }
514 +
515 + #--------------------------------------------------------------------------------
516 + #region Helper Method
517 + #--------------------------------------------------------------------------------
518 +
519 + /**
520 + * @author Vova Feldman (@svovaf)
521 + * @since 2.0.0
522 + *
523 + * @return string
524 + */
525 + private function get_notices_type() {
526 + return $this->_is_network_notices ?
527 + 'network_admin_notices' :
528 + 'admin_notices';
529 + }
530 +
531 + #endregion
532 + }