PluginProbe
StreamCast – bring live radio to your site with a sleek player / 2.1.4
StreamCast – bring live radio to your site with a sleek player v2.1.4
2.4.5 2.4.4 trunk 1.0 1.1 2.0.0 2.1.10 2.1.2 2.1.4 2.1.5 2.1.8 2.2.1 2.2.3 2.2.4 2.2.5 2.3.0 2.3.1 2.3.2 2.3.3 2.3.4 2.3.5 2.3.6 2.3.7 2.3.8 2.3.9 All 29 releases
streamcast / freemius / includes / managers / class-fs-admin-notice-manager.php

class-fs-admin-notice-manager.php in StreamCast – bring live radio to your site with a sleek player 2.1.4, at freemius/includes/managers/class-fs-admin-notice-manager.php

478 lines 16.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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 );
165 }
166 }
167 }
168 }
169
170 /**
171 * Remove sticky message by ID.
172 *
173 * @author Vova Feldman (@svovaf)
174 * @since 1.0.7
175 *
176 */
177 function dismiss_notice_ajax_callback() {
178 check_admin_referer( 'fs_dismiss_notice_action' );
179
180 if ( ! is_numeric( $_POST['message_id'] ) ) {
181 $this->_sticky_storage->remove( $_POST['message_id'] );
182 }
183
184 wp_die();
185 }
186
187 /**
188 * Rendered sticky message dismiss JavaScript.
189 *
190 * @author Vova Feldman (@svovaf)
191 * @since 1.0.7
192 */
193 static function _add_sticky_dismiss_javascript() {
194 $params = array();
195 fs_require_once_template( 'sticky-admin-notice-js.php', $params );
196 }
197
198 private static $_added_sticky_javascript = false;
199
200 /**
201 * Hook to the admin_footer to add sticky message dismiss JavaScript handler.
202 *
203 * @author Vova Feldman (@svovaf)
204 * @since 1.0.7
205 */
206 private static function has_sticky_messages() {
207 if ( ! self::$_added_sticky_javascript ) {
208 add_action( 'admin_footer', array( 'FS_Admin_Notice_Manager', '_add_sticky_dismiss_javascript' ) );
209 }
210 }
211
212 /**
213 * Handle admin_notices by printing the admin messages stacked in the queue.
214 *
215 * @author Vova Feldman (@svovaf)
216 * @since 1.0.4
217 *
218 */
219 function _admin_notices_hook() {
220 if ( function_exists( 'current_user_can' ) &&
221 ! current_user_can( 'manage_options' )
222 ) {
223 // Only show messages to admins.
224 return;
225 }
226
227
228 $show_admin_notices = ( ! $this->is_gutenberg_page() );
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 $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 * Add admin message to admin messages queue, and hook to admin_notices / all_admin_notices if not yet hooked.
328 *
329 * @author Vova Feldman (@svovaf)
330 * @since 1.0.4
331 *
332 * @param string $message
333 * @param string $title
334 * @param string $type
335 * @param bool $is_sticky
336 * @param string $id Message ID
337 * @param bool $store_if_sticky
338 * @param number|null $wp_user_id
339 * @param string|null $plugin_title
340 * @param bool $is_network_and_blog_admins Whether or not the message should be shown both on network
341 * and blog admin pages.
342 *
343 * @uses add_action()
344 */
345 function add(
346 $message,
347 $title = '',
348 $type = 'success',
349 $is_sticky = false,
350 $id = '',
351 $store_if_sticky = true,
352 $wp_user_id = null,
353 $plugin_title = null,
354 $is_network_and_blog_admins = false
355 ) {
356 $notices_type = $this->get_notices_type();
357
358 if ( empty( $this->_notices ) ) {
359 if ( ! $is_network_and_blog_admins ) {
360 add_action( $notices_type, array( &$this, "_admin_notices_hook" ) );
361 } else {
362 add_action( 'network_admin_notices', array( &$this, "_admin_notices_hook" ) );
363 add_action( 'admin_notices', array( &$this, "_admin_notices_hook" ) );
364 }
365
366 add_action( 'admin_enqueue_scripts', array( &$this, '_enqueue_styles' ) );
367 }
368
369 if ( '' === $id ) {
370 $id = md5( $title . ' ' . $message . ' ' . $type );
371 }
372
373 $message_object = array(
374 'message' => $message,
375 'title' => $title,
376 'type' => $type,
377 'sticky' => $is_sticky,
378 'id' => $id,
379 'manager_id' => $this->_id,
380 'plugin' => ( ! is_null( $plugin_title ) ? $plugin_title : $this->_title ),
381 'wp_user_id' => $wp_user_id,
382 );
383
384 if ( $is_sticky && $store_if_sticky ) {
385 $this->_sticky_storage->{$id} = $message_object;
386 }
387
388 $this->_notices[ $id ] = $message_object;
389 }
390
391 /**
392 * @author Vova Feldman (@svovaf)
393 * @since 1.0.7
394 *
395 * @param string|string[] $ids
396 */
397 function remove_sticky( $ids ) {
398 if ( ! is_array( $ids ) ) {
399 $ids = array( $ids );
400 }
401
402 foreach ( $ids as $id ) {
403 // Remove from sticky storage.
404 $this->_sticky_storage->remove( $id );
405
406 if ( isset( $this->_notices[ $id ] ) ) {
407 unset( $this->_notices[ $id ] );
408 }
409 }
410 }
411
412 /**
413 * Check if sticky message exists by id.
414 *
415 * @author Vova Feldman (@svovaf)
416 * @since 1.0.9
417 *
418 * @param $id
419 *
420 * @return bool
421 */
422 function has_sticky( $id ) {
423 return isset( $this->_sticky_storage[ $id ] );
424 }
425
426 /**
427 * Adds sticky admin notification.
428 *
429 * @author Vova Feldman (@svovaf)
430 * @since 1.0.7
431 *
432 * @param string $message
433 * @param string $id Message ID
434 * @param string $title
435 * @param string $type
436 * @param number|null $wp_user_id
437 * @param string|null $plugin_title
438 * @param bool $is_network_and_blog_admins Whether or not the message should be shown both on network
439 * and blog admin pages.
440 */
441 function add_sticky( $message, $id, $title = '', $type = 'success', $wp_user_id = null, $plugin_title = null, $is_network_and_blog_admins = false ) {
442 if ( ! empty( $this->_module_unique_affix ) ) {
443 $message = fs_apply_filter( $this->_module_unique_affix, "sticky_message_{$id}", $message );
444 $title = fs_apply_filter( $this->_module_unique_affix, "sticky_title_{$id}", $title );
445 }
446
447 $this->add( $message, $title, $type, true, $id, true, $wp_user_id, $plugin_title, $is_network_and_blog_admins );
448 }
449
450 /**
451 * Clear all sticky messages.
452 *
453 * @author Vova Feldman (@svovaf)
454 * @since 1.0.8
455 */
456 function clear_all_sticky() {
457 $this->_sticky_storage->clear_all();
458 }
459
460 #--------------------------------------------------------------------------------
461 #region Helper Method
462 #--------------------------------------------------------------------------------
463
464 /**
465 * @author Vova Feldman (@svovaf)
466 * @since 2.0.0
467 *
468 * @return string
469 */
470 private function get_notices_type() {
471 return $this->_is_network_notices ?
472 'network_admin_notices' :
473 'admin_notices';
474 }
475
476 #endregion
477 }
478