PluginProbe
WebberZone Top 10 — Popular Posts / trunk
WebberZone Top 10 — Popular Posts vtrunk
4.5.0 4.4.3 4.4.2 4.4.1 4.4.0 4.3.4 4.3.3 4.3.2 4.3.1 4.3.0 trunk 1.0 1.0.1 1.1 1.2 1.3 1.4 1.4.1 1.5 1.5.1 1.5.2 1.5.3 1.6 1.6.1 1.6.2 All 116 releases
top-10 / includes / admin / class-admin-notices-api.php

class-admin-notices-api.php in WebberZone Top 10 — Popular Posts trunk, at includes/admin/class-admin-notices-api.php

217 lines 5.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Admin notices API.
4 *
5 * @package WebberZone\Top_Ten\Admin
6 */
7
8 namespace WebberZone\Top_Ten\Admin;
9
10 use WebberZone\Top_Ten\Util\Hook_Registry;
11
12 // If this file is called directly, abort.
13 if ( ! defined( 'WPINC' ) ) {
14 die;
15 }
16
17 /**
18 * Class to handle admin notices.
19 */
20 class Admin_Notices_API {
21
22 /**
23 * Plugin prefix used for AJAX actions, nonces, and storage keys.
24 *
25 * @var string
26 */
27 protected string $prefix;
28
29 /**
30 * Array of registered notices.
31 *
32 * @var array Registered notices.
33 */
34 protected array $notices = array();
35
36 /**
37 * Constructor class.
38 *
39 * @param string $prefix Plugin prefix for AJAX actions, nonces, and storage keys. Default 'tptn'.
40 */
41 public function __construct( string $prefix = 'tptn' ) {
42 $this->prefix = $prefix;
43
44 Hook_Registry::add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
45 Hook_Registry::add_action( 'admin_notices', array( $this, 'display_notices' ) );
46 Hook_Registry::add_action( "wp_ajax_{$this->prefix}_dismiss_notice", array( $this, 'handle_notice_dismissal' ) );
47 }
48
49 /**
50 * Register and enqueue the dismiss script, pushing this instance's config
51 * into the shared window.adminNoticesConfigs array.
52 */
53 public function enqueue_scripts() {
54 $minimize = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
55 $handle = "{$this->prefix}-admin-notices";
56
57 wp_register_script(
58 $handle,
59 plugins_url( "js/admin-notices{$minimize}.js", __FILE__ ),
60 array( 'jquery' ),
61 TOP_TEN_VERSION,
62 true
63 );
64
65 $config = wp_json_encode(
66 array(
67 'prefix' => $this->prefix,
68 'action' => "{$this->prefix}_dismiss_notice",
69 'nonce' => wp_create_nonce( "{$this->prefix}_dismiss_notice" ),
70 )
71 );
72
73 wp_add_inline_script(
74 $handle,
75 'window.adminNoticesConfigs = window.adminNoticesConfigs || []; window.adminNoticesConfigs.push(' . $config . ');',
76 'before'
77 );
78
79 wp_enqueue_script( $handle );
80 }
81
82 /**
83 * Register a new notice.
84 *
85 * @param array $notice {
86 * Notice arguments.
87 *
88 * @type string $id Unique notice ID.
89 * @type string $message Notice message.
90 * @type string $type Notice type. Either 'error', 'warning', 'success' or 'info'.
91 * @type bool $dismissible Whether the notice is dismissible.
92 * @type int $dismiss_time Dismiss time in seconds. Default 0 (permanent).
93 * @type array $screens Array of screens to show notice on. Empty means all screens.
94 * @type string $capability Capability required to see the notice.
95 * @type array $conditions Array of callbacks to determine if notice should show.
96 * }
97 */
98 public function register_notice( array $notice ) {
99 $default_notice = array(
100 'id' => '',
101 'message' => '',
102 'type' => 'info',
103 'dismissible' => true,
104 'dismiss_time' => 0,
105 'screens' => array(),
106 'capability' => 'manage_options',
107 'conditions' => array(),
108 );
109
110 $notice = wp_parse_args( $notice, $default_notice );
111
112 if ( empty( $notice['id'] ) || empty( $notice['message'] ) ) {
113 return;
114 }
115
116 $this->notices[ $notice['id'] ] = $notice;
117 }
118
119 /**
120 * Display registered notices.
121 */
122 public function display_notices() {
123 $screen = get_current_screen();
124 if ( null === $screen ) {
125 return;
126 }
127
128 foreach ( $this->notices as $notice ) {
129 // Skip if user doesn't have capability.
130 if ( ! current_user_can( $notice['capability'] ) ) {
131 continue;
132 }
133
134 // Skip if not on correct screen.
135 if ( ! empty( $notice['screens'] ) && ! in_array( $screen->id, $notice['screens'], true ) ) {
136 continue;
137 }
138
139 // Check conditions.
140 foreach ( $notice['conditions'] as $condition ) {
141 if ( is_callable( $condition ) && ! call_user_func( $condition ) ) {
142 continue 2;
143 }
144 }
145
146 // Skip if notice is dismissed.
147 if ( $this->is_notice_dismissed( $notice['id'] ) ) {
148 continue;
149 }
150
151 $class = 'notice notice-' . $notice['type'];
152 if ( $notice['dismissible'] ) {
153 $class .= ' is-dismissible';
154 }
155
156 printf(
157 '<div class="%1$s" data-notice-id="%2$s" data-dismiss-time="%3$s" data-notice-prefix="%4$s">%5$s</div>',
158 esc_attr( $class ),
159 esc_attr( $notice['id'] ),
160 esc_attr( $notice['dismiss_time'] ),
161 esc_attr( $this->prefix ),
162 wp_kses_post( $notice['message'] )
163 );
164 }
165 }
166
167 /**
168 * Handle notice dismissal via AJAX.
169 */
170 public function handle_notice_dismissal() {
171 check_ajax_referer( "{$this->prefix}_dismiss_notice", 'nonce' );
172
173 if ( ! current_user_can( 'manage_options' ) ) {
174 wp_die();
175 }
176
177 $notice_id = isset( $_POST['notice_id'] ) ? sanitize_key( $_POST['notice_id'] ) : '';
178 $dismiss_time = isset( $_POST['dismiss_time'] ) ? absint( $_POST['dismiss_time'] ) : 0;
179
180 if ( ! $notice_id ) {
181 wp_die();
182 }
183
184 $key = "{$this->prefix}_notice_dismissed_{$notice_id}";
185
186 if ( $dismiss_time ) {
187 set_transient( $key, true, $dismiss_time );
188 } else {
189 update_user_meta( get_current_user_id(), $key, true );
190 }
191
192 wp_die();
193 }
194
195 /**
196 * Check if a notice has been dismissed.
197 *
198 * @param string $notice_id Notice ID.
199 * @return bool Whether the notice has been dismissed.
200 */
201 protected function is_notice_dismissed( $notice_id ) {
202 $notice = $this->notices[ $notice_id ] ?? null;
203
204 if ( ! $notice ) {
205 return false;
206 }
207
208 $key = "{$this->prefix}_notice_dismissed_{$notice_id}";
209
210 if ( $notice['dismiss_time'] ) {
211 return (bool) get_transient( $key );
212 }
213
214 return (bool) get_user_meta( get_current_user_id(), $key, true );
215 }
216 }
217