PluginProbe
Search & Replace Everything by WPCode – Find and Replace Media, Text, Links, and More / 1.0.8
Search & Replace Everything by WPCode – Find and Replace Media, Text, Links, and More v1.0.8
trunk 1.0.0 1.0.1 1.0.10 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9
search-replace-wpcode / includes / admin / class-wsrw-notice.php

class-wsrw-notice.php in Search & Replace Everything by WPCode – Find and Replace Media, Text, Links, and More 1.0.8, at includes/admin/class-wsrw-notice.php

365 lines 9.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 class WSRW_Notice {
4
5 /**
6 * Not dismissible.
7 *
8 * Constant attended to use as the value of the $args['dismiss'] argument.
9 * DISMISS_NONE means that the notice is not dismissible.
10 *
11 */
12 const DISMISS_NONE = 0;
13
14 /**
15 * Dismissible global.
16 *
17 * Constant attended to use as the value of the $args['dismiss'] argument.
18 * DISMISS_GLOBAL means that the notice will have the dismiss button, and after clicking this button, the notice will be dismissed for all users.
19 *
20 */
21 const DISMISS_GLOBAL = 1;
22
23 /**
24 * Dismissible per user.
25 *
26 * Constant attended to use as the value of the $args['dismiss'] argument.
27 * DISMISS_USER means that the notice will have the dismiss button, and after clicking this button, the notice will be dismissed only for the current user..
28 *
29 */
30 const DISMISS_USER = 2;
31
32 /**
33 * Added notices.
34 *
35 * @var array
36 */
37 public $notices = array();
38
39 /**
40 * Top notices, displayed separately.
41 *
42 * @var array
43 */
44 public $notices_top = array();
45
46 /**
47 * Init.
48 *
49 */
50 public function __construct() {
51
52 $this->hooks();
53 }
54
55 /**
56 * Hooks.
57 *
58 */
59 public function hooks() {
60 add_action( 'admin_notices', array( $this, 'display' ), 999000 );
61 // Hook for our specific pages where we hide all other admin notices.
62 add_action( 'wsrw_admin_notices', array( $this, 'display' ), 10 );
63 add_action( 'wp_ajax_wsrw_notice_dismiss', array( $this, 'dismiss_ajax' ) );
64
65 // Display notices above the header.
66 add_action( 'wsrw_admin_page', array( $this, 'display_top' ), 5 );
67 }
68
69 /**
70 * Enqueue assets.
71 */
72 public function enqueues() {
73
74 wp_enqueue_script(
75 'wsrw-admin-notices',
76 WSRW_PLUGIN_URL . 'build/notices.js',
77 array( 'jquery' ),
78 WSRW_VERSION,
79 true
80 );
81
82 wp_localize_script(
83 'wsrw-admin-notices',
84 'wsrw_admin_notices',
85 array(
86 'ajax_url' => admin_url( 'admin-ajax.php' ),
87 'nonce' => wp_create_nonce( 'wsrw-admin' ),
88 )
89 );
90 }
91
92 /**
93 * Display the notices.
94 */
95 public function display() {
96
97 $dismissed_notices = get_user_meta( get_current_user_id(), 'wsrw_admin_notices', true );
98 $dismissed_notices = is_array( $dismissed_notices ) ? $dismissed_notices : array();
99 $dismissed_notices = array_merge( $dismissed_notices, (array) get_option( 'wsrw_admin_notices', array() ) );
100
101 foreach ( $this->notices as $slug => $notice ) {
102 if ( isset( $dismissed_notices[ $slug ] ) && ! empty( $dismissed_notices[ $slug ]['dismissed'] ) ) {
103 unset( $this->notices[ $slug ] );
104 }
105 }
106
107 $output = implode( '', $this->notices );
108
109 echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
110
111 // Enqueue script only when it's needed.
112 if ( strpos( $output, 'is-dismissible' ) !== false ) {
113 $this->enqueues();
114 }
115 }
116
117 /**
118 * Display the notices at the top of the WPC pages.
119 */
120 public function display_top() {
121 $dismissed_notices = get_user_meta( get_current_user_id(), 'wsrw_admin_notices', true );
122 $dismissed_notices = is_array( $dismissed_notices ) ? $dismissed_notices : array();
123 $dismissed_notices = array_merge( $dismissed_notices, (array) get_option( 'wsrw_admin_notices', array() ) );
124
125 foreach ( $this->notices_top as $slug => $notice ) {
126 if ( isset( $dismissed_notices[ $slug ] ) && ! empty( $dismissed_notices[ $slug ]['dismissed'] ) ) {
127 unset( $this->notices_top[ $slug ] );
128 }
129 }
130
131 $output = implode( '', $this->notices_top );
132
133 if ( ! empty( $output ) ) {
134 echo '<div class="wsrw-notice-top-area">';
135 echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
136 echo '</div>';
137 }
138
139 // Enqueue script only when it's needed.
140 if ( strpos( $output, 'is-dismissible' ) !== false ) {
141 $this->enqueues();
142 }
143 }
144
145 /**
146 * Add notice to the registry.
147 *
148 *
149 * @param string $message Message to display.
150 * @param string $type Type of the notice. Can be [ '' (default) | 'info' | 'error' | 'success' | 'warning' ].
151 * @param array $args The array of additional arguments. Please see the $defaults array below.
152 */
153 public static function add( $message, $type = '', $args = [] ) {
154
155 static $uniq_id = 0;
156
157 $defaults = [
158 'dismiss' => self::DISMISS_NONE,
159 // Dismissible level: one of the self::DISMISS_* const. By default notice is not dismissible.
160 'slug' => '',
161 // Slug. Should be unique if dismissible is not equal self::DISMISS_NONE.
162 'autop' => true,
163 // `false` if not needed to pass message through wpautop().
164 'class' => '',
165 // Additional CSS class.
166 ];
167
168 $args = wp_parse_args( $args, $defaults );
169
170 $dismissible = (int) $args['dismiss'];
171 $dismissible = $dismissible > self::DISMISS_USER ? self::DISMISS_USER : $dismissible;
172
173 $class = $dismissible > self::DISMISS_NONE ? ' is-dismissible' : '';
174 $global = ( $dismissible === self::DISMISS_GLOBAL ) ? 'global-' : '';
175 $slug = sanitize_key( $args['slug'] );
176
177 ++ $uniq_id;
178
179 $uniq_id += ( $uniq_id === (int) $slug ) ? 1 : 0;
180
181 $id = 'wsrw-notice-' . $global;
182
183 $id .= empty( $slug ) ? $uniq_id : $slug;
184
185 $type_class = ! empty( $type ) ? 'notice-' . esc_attr( sanitize_key( $type ) ) : '';
186 $class = empty( $args['class'] ) ? $class : $class . ' ' . esc_attr( sanitize_key( $args['class'] ) );
187 $message = $args['autop'] ? wpautop( $message ) : $message;
188 $notice = sprintf(
189 '<div class="notice wsrw-notice %s%s" id="%s">%s</div>',
190 esc_attr( $type_class ),
191 esc_attr( $class ),
192 esc_attr( $id ),
193 $message
194 );
195
196 if ( 'top' === $type ) {
197 if ( empty( $slug ) ) {
198 wsrw_main()->notice->notices_top[] = $notice;
199 } else {
200 wsrw_main()->notice->notices_top[ $slug ] = $notice;
201 }
202
203 return; // Don't mix top notices.
204 }
205
206 if ( empty( $slug ) ) {
207 wsrw_main()->notice->notices[] = $notice;
208 } else {
209 wsrw_main()->notice->notices[ $slug ] = $notice;
210 }
211 }
212
213 /**
214 * Add info notice.
215 *
216 *
217 * @param string $message Message to display.
218 * @param array $args Array of additional arguments. Details in the self::add() method.
219 */
220 public static function info( $message, $args = [] ) {
221
222 self::add( $message, 'info', $args );
223 }
224
225 /**
226 * Add top notice (displayed before the header on wpcode pages only).
227 *
228 *
229 * @param string $message Message to display.
230 * @param array $args Array of additional arguments. Details in the self::add() method.
231 */
232 public static function top( $message, $args = [] ) {
233
234 self::add( $message, 'top', $args );
235 }
236
237 /**
238 * Add error notice.
239 *
240 *
241 * @param string $message Message to display.
242 * @param array $args Array of additional arguments. Details in the self::add() method.
243 */
244 public static function error( $message, $args = [] ) {
245
246 self::add( $message, 'error', $args );
247 }
248
249 /**
250 * Add success notice.
251 *
252 *
253 * @param string $message Message to display.
254 * @param array $args Array of additional arguments. Details in the self::add() method.
255 */
256 public static function success( $message, $args = [] ) {
257
258 self::add( $message, 'success', $args );
259 }
260
261 /**
262 * Add warning notice.
263 *
264 *
265 * @param string $message Message to display.
266 * @param array $args Array of additional arguments. Details in the self::add() method.
267 */
268 public static function warning( $message, $args = [] ) {
269
270 self::add( $message, 'warning', $args );
271 }
272
273 /**
274 * AJAX routine that updates dismissed notices meta data.
275 */
276 public function dismiss_ajax() {
277
278 // Run a security check.
279 check_ajax_referer( 'wsrw-admin' );
280
281 // Sanitize POST data.
282 $post = array_map( 'sanitize_key', wp_unslash( $_POST ) );
283
284 // Update notices meta data.
285 if ( strpos( $post['id'], 'global-' ) !== false ) {
286
287 // Check for permissions.
288 if ( ! current_user_can( 'manage_options' ) ) {
289 wp_send_json_error();
290 }
291
292 $notices = $this->dismiss_global( $post['id'] );
293 $level = self::DISMISS_GLOBAL;
294
295 } else {
296
297 $notices = $this->dismiss_user( $post['id'] );
298 $level = self::DISMISS_USER;
299 }
300
301 /**
302 * Allows developers to apply additional logic to the dismissing notice process.
303 * Executes after updating option or user meta (according to the notice level).
304 *
305 *
306 * @param string $notice_id Notice ID (slug).
307 * @param integer $level Notice level.
308 * @param array $notices Dismissed notices.
309 */
310 do_action( 'wsrw_admin_notice_dismiss_ajax', $post['id'], $level, $notices );
311
312 wp_send_json_success();
313 }
314
315 /**
316 * AJAX sub-routine that updates dismissed notices option.
317 *
318 *
319 * @param string $id Notice Id.
320 *
321 * @return array Notices.
322 */
323 private function dismiss_global( $id ) {
324
325 $id = str_replace( 'global-', '', $id );
326 $notices = get_option( 'wsrw_admin_notices', array() );
327 $notices[ $id ] = array(
328 'time' => time(),
329 'dismissed' => true,
330 );
331
332 update_option( 'wsrw_admin_notices', $notices, true );
333
334 // If this is a multisite, and they dismissed the review-request let's keep a note in the user's meta.
335 if ( is_multisite() && is_super_admin() && 'review_request' === $id ) {
336 update_user_meta( get_current_user_id(), 'wsrw_dismissed_review_request', true );
337 }
338
339 return $notices;
340 }
341
342 /**
343 * AJAX sub-routine that updates dismissed notices user meta.
344 *
345 *
346 * @param string $id Notice Id.
347 *
348 * @return array Notices.
349 */
350 private function dismiss_user( $id ) {
351
352 $user_id = get_current_user_id();
353 $notices = get_user_meta( $user_id, 'wsrw_admin_notices', true );
354 $notices = ! is_array( $notices ) ? array() : $notices;
355 $notices[ $id ] = array(
356 'time' => time(),
357 'dismissed' => true,
358 );
359
360 update_user_meta( $user_id, 'wsrw_admin_notices', $notices );
361
362 return $notices;
363 }
364 }
365