This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * Dismissible Notices Handler. |
||
4 | * |
||
5 | * This library is designed to handle dismissible admin notices. |
||
6 | * |
||
7 | * LICENSE: This program is free software; you can redistribute it and/or modify it under the terms of the GNU |
||
8 | * General Public License as published by the Free Software Foundation; either version 3 of the License, or (at |
||
9 | * your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY |
||
10 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||
11 | * General Public License for more details. You should have received a copy of the GNU General Public License along |
||
12 | * with this program. If not, see <http://opensource.org/licenses/gpl-license.php> |
||
13 | * |
||
14 | * @package Dismissible Notices Handler |
||
15 | * @author Julien Liabeuf <[email protected]> |
||
16 | * @version 1.2.0 |
||
17 | * @license GPL-2.0+ |
||
18 | * @link https://julienliabeuf.com |
||
19 | * @copyright 2018 Julien Liabeuf |
||
20 | */ |
||
21 | |||
22 | if ( ! class_exists( 'Dismissible_Notices_Handler' ) ) { |
||
23 | |||
24 | final class Dismissible_Notices_Handler { |
||
25 | |||
26 | /** |
||
27 | * @var Dismissible_Notices_Handler Holds the unique instance of the handler |
||
28 | * @since 1.0 |
||
29 | */ |
||
30 | private static $instance; |
||
31 | |||
32 | /** |
||
33 | * Library version |
||
34 | * |
||
35 | * @since 1.0 |
||
36 | * @var string |
||
37 | */ |
||
38 | public $version = '1.2.2'; |
||
39 | |||
40 | /** |
||
41 | * Required version of PHP. |
||
42 | * |
||
43 | * @since 1.0 |
||
44 | * @var string |
||
45 | */ |
||
46 | public $php_version_required = '5.5'; |
||
47 | |||
48 | /** |
||
49 | * Minimum version of WordPress required to use the library |
||
50 | * |
||
51 | * @since 1.0 |
||
52 | * @var string |
||
53 | */ |
||
54 | public $wordpress_version_required = '4.7'; |
||
55 | |||
56 | /** |
||
57 | * @var array Holds all our registered notices |
||
58 | * @since 1.0 |
||
59 | */ |
||
60 | private $notices; |
||
61 | |||
62 | /** |
||
63 | * Instantiate and return the unique Dismissible_Notices_Handler object |
||
64 | * |
||
65 | * @since 1.0 |
||
66 | * @return object Dismissible_Notices_Handler Unique instance of the handler |
||
67 | */ |
||
68 | public static function instance() { |
||
69 | |||
70 | if ( ! isset( self::$instance ) && ! ( self::$instance instanceof Dismissible_Notices_Handler ) ) { |
||
71 | self::$instance = new Dismissible_Notices_Handler; |
||
72 | self::$instance->init(); |
||
73 | } |
||
74 | |||
75 | return self::$instance; |
||
76 | |||
77 | } |
||
78 | |||
79 | /** |
||
80 | * Initialize the library |
||
81 | * |
||
82 | * @since 1.0 |
||
83 | * @return void |
||
84 | */ |
||
85 | private function init() { |
||
86 | |||
87 | // Make sure WordPress is compatible |
||
88 | if ( ! self::$instance->is_wp_compatible() ) { |
||
89 | self::$instance->spit_error( |
||
90 | sprintf( |
||
91 | /* translators: %s: required wordpress version */ |
||
92 | esc_html__( 'The library can not be used because your version of WordPress is too old. You need version %s at least.', 'wp-dismissible-notices-handler' ), |
||
93 | self::$instance->wordpress_version_required |
||
94 | ) |
||
95 | ); |
||
96 | |||
97 | return; |
||
98 | } |
||
99 | |||
100 | // Make sure PHP is compatible |
||
101 | if ( ! self::$instance->is_php_compatible() ) { |
||
102 | self::$instance->spit_error( |
||
103 | sprintf( |
||
104 | /* translators: %s: required php version */ |
||
105 | esc_html__( 'The library can not be used because your version of PHP is too old. You need version %s at least.', 'wp-dismissible-notices-handler' ), |
||
106 | self::$instance->php_version_required |
||
107 | ) |
||
108 | ); |
||
109 | |||
110 | return; |
||
111 | } |
||
112 | |||
113 | add_action( 'admin_notices', array( self::$instance, 'display' ) ); |
||
114 | add_action( 'admin_print_scripts', array( self::$instance, 'load_script' ) ); |
||
115 | add_action( 'wp_ajax_dnh_dismiss_notice', array( self::$instance, 'dismiss_notice_ajax' ) ); |
||
116 | |||
117 | } |
||
118 | |||
119 | /** |
||
120 | * Check if the current WordPress version fits the requirements |
||
121 | * |
||
122 | * @since 1.0 |
||
123 | * @return boolean |
||
124 | */ |
||
125 | private function is_wp_compatible() { |
||
126 | |||
127 | if ( version_compare( get_bloginfo( 'version' ), self::$instance->wordpress_version_required, '<' ) ) { |
||
128 | return false; |
||
129 | } |
||
130 | |||
131 | return true; |
||
132 | |||
133 | } |
||
134 | |||
135 | /** |
||
136 | * Check if the version of PHP is compatible with this library |
||
137 | * |
||
138 | * @since 1.0 |
||
139 | * @return boolean |
||
140 | */ |
||
141 | private function is_php_compatible() { |
||
142 | |||
143 | if ( version_compare( phpversion(), self::$instance->php_version_required, '<' ) ) { |
||
144 | return false; |
||
145 | } |
||
146 | |||
147 | return true; |
||
148 | |||
149 | } |
||
150 | |||
151 | /** |
||
152 | * Load the script |
||
153 | * |
||
154 | * @since 1.0 |
||
155 | * @return void |
||
156 | */ |
||
157 | public function load_script() { |
||
158 | wp_register_script( 'dnh', trailingslashit( plugin_dir_url( __FILE__ ) ) . 'assets/js/main.js', array( 'jquery' ), self::$instance->version, true ); |
||
159 | wp_enqueue_script( 'dnh' ); |
||
160 | } |
||
161 | |||
162 | /** |
||
163 | * Display all the registered notices |
||
164 | * |
||
165 | * @since 1.0 |
||
166 | * @return void |
||
167 | */ |
||
168 | public function display() { |
||
169 | |||
170 | if ( is_null( self::$instance->notices ) || empty( self::$instance->notices ) ) { |
||
171 | return; |
||
172 | } |
||
173 | |||
174 | foreach ( self::$instance->notices as $id => $notice ) { |
||
175 | |||
176 | $id = self::$instance->get_id( $id ); |
||
177 | |||
178 | // Check if the notice was dismissed |
||
179 | if ( self::$instance->is_dismissed( $id ) ) { |
||
180 | continue; |
||
181 | } |
||
182 | |||
183 | // Check if the current user has required capability |
||
184 | if ( ! empty( $notice['cap'] ) && ! current_user_can( $notice['cap'] ) ) { |
||
185 | continue; |
||
186 | } |
||
187 | |||
188 | $class = array( |
||
189 | 'notice', |
||
190 | $notice['type'], |
||
191 | 'is-dismissible', |
||
192 | $notice['class'], |
||
193 | ); |
||
194 | |||
195 | printf( '<div id="%3$s" class="%1$s"><p>%2$s</p></div>', trim( implode( ' ', $class ) ), $notice['content'], "dnh-$id" ); |
||
196 | |||
197 | } |
||
198 | |||
199 | } |
||
200 | |||
201 | /** |
||
202 | * Spits an error message at the top of the admin screen |
||
203 | * |
||
204 | * @since 1.0 |
||
205 | * |
||
206 | * @param string $error Error message to spit |
||
207 | * |
||
208 | * @return void |
||
209 | */ |
||
210 | protected function spit_error( $error ) { |
||
211 | printf( |
||
212 | '<div style="margin: 20px; text-align: center;"><strong>%1$s</strong> %2$s</pre></div>', |
||
213 | esc_html__( 'Dismissible Notices Handler Error:', 'wp-dismissible-notices-handler' ), |
||
214 | wp_kses_post( $error ) |
||
215 | ); |
||
216 | } |
||
217 | |||
218 | /** |
||
219 | * Sanitize a notice ID and return it |
||
220 | * |
||
221 | * @since 1.0 |
||
222 | * |
||
223 | * @param string $id |
||
224 | * |
||
225 | * @return string |
||
226 | */ |
||
227 | public function get_id( $id ) { |
||
228 | return sanitize_key( $id ); |
||
229 | } |
||
230 | |||
231 | /** |
||
232 | * Get available notice types |
||
233 | * |
||
234 | * @since 1.0 |
||
235 | * @return array |
||
236 | */ |
||
237 | public function get_types() { |
||
238 | |||
239 | $types = array( |
||
240 | 'error', |
||
241 | 'updated', |
||
242 | // New types of notification style. |
||
243 | 'notice-error', |
||
244 | 'notice-warning', |
||
245 | 'notice-success', |
||
246 | 'notice-info', |
||
247 | ); |
||
248 | |||
249 | return apply_filters( 'dnh_notice_types', $types ); |
||
250 | |||
251 | } |
||
252 | |||
253 | /** |
||
254 | * Get the default arguments for a notice |
||
255 | * |
||
256 | * @since 1.0 |
||
257 | * @return array |
||
258 | */ |
||
259 | private function default_args() { |
||
260 | |||
261 | $args = array( |
||
262 | 'screen' => '', // Coming soon |
||
263 | 'scope' => 'user', // Scope of the dismissal. Either user or global |
||
264 | 'cap' => '', // Required user capability |
||
265 | 'class' => '', // Additional class to add to the notice |
||
266 | ); |
||
267 | |||
268 | return apply_filters( 'dnh_default_args', $args ); |
||
269 | |||
270 | } |
||
271 | |||
272 | /** |
||
273 | * Register a new notice |
||
274 | * |
||
275 | * @since 1.0 |
||
276 | * |
||
277 | * @param string $id Notice ID, used to identify it |
||
278 | * @param string $type Type of notice to display |
||
279 | * @param string $content Notice content |
||
280 | * @param array $args Additional parameters |
||
281 | * |
||
282 | * @return bool |
||
283 | */ |
||
284 | public function register_notice( $id, $type, $content, $args = array() ) { |
||
285 | |||
286 | if ( is_null( self::$instance->notices ) ) { |
||
287 | self::$instance->notices = array(); |
||
288 | } |
||
289 | |||
290 | $id = self::$instance->get_id( $id ); |
||
291 | $type = in_array( $t = sanitize_text_field( $type ), self::$instance->get_types() ) ? $t : 'updated'; |
||
292 | $content = wp_kses_post( $content ); |
||
293 | $args = wp_parse_args( $args, self::$instance->default_args() ); |
||
294 | |||
295 | if ( array_key_exists( $id, self::$instance->notices ) ) { |
||
296 | |||
297 | self::$instance->spit_error( |
||
298 | sprintf( |
||
299 | /* translators: %s: required php version */ |
||
300 | esc_html__( 'A notice with the ID %s has already been registered.', 'wp-dismissible-notices-handler' ), |
||
301 | "<code>$id</code>" |
||
302 | ) |
||
303 | ); |
||
304 | |||
305 | return false; |
||
306 | } |
||
307 | |||
308 | $notice = array( |
||
309 | 'type' => $type, |
||
310 | 'content' => $content, |
||
311 | ); |
||
312 | |||
313 | $notice = array_merge( $notice, $args ); |
||
314 | |||
315 | self::$instance->notices[ $id ] = $notice; |
||
316 | |||
317 | return true; |
||
318 | |||
319 | } |
||
320 | |||
321 | /** |
||
322 | * Notice dismissal triggered by Ajax |
||
323 | * |
||
324 | * @since 1.0 |
||
325 | * @return void |
||
326 | */ |
||
327 | public function dismiss_notice_ajax() { |
||
328 | |||
329 | if ( ! isset( $_POST['id'] ) ) { |
||
330 | echo 0; |
||
331 | exit; |
||
332 | } |
||
333 | |||
334 | if ( empty( $_POST['id'] ) || false === strpos( $_POST['id'], 'dnh-' ) ) { |
||
335 | echo 0; |
||
336 | exit; |
||
337 | } |
||
338 | |||
339 | $id = self::$instance->get_id( str_replace( 'dnh-', '', $_POST['id'] ) ); |
||
340 | |||
341 | echo self::$instance->dismiss_notice( $id ); |
||
342 | exit; |
||
343 | |||
344 | } |
||
345 | |||
346 | /** |
||
347 | * Dismiss a notice |
||
348 | * |
||
349 | * @since 1.0 |
||
350 | * |
||
351 | * @param string $id ID of the notice to dismiss |
||
352 | * |
||
353 | * @return bool |
||
354 | */ |
||
355 | public function dismiss_notice( $id ) { |
||
356 | |||
357 | $notice = self::$instance->get_notice( self::$instance->get_id( $id ) ); |
||
358 | |||
359 | if ( false === $notice ) { |
||
360 | return false; |
||
361 | } |
||
362 | |||
363 | if ( self::$instance->is_dismissed( $id ) ) { |
||
364 | return false; |
||
365 | } |
||
366 | |||
367 | return 'user' === $notice['scope'] ? self::$instance->dismiss_user( $id ) : self::$instance->dismiss_global( $id ); |
||
368 | |||
369 | } |
||
370 | |||
371 | /** |
||
372 | * Dismiss notice for the current user |
||
373 | * |
||
374 | * @since 1.0 |
||
375 | * |
||
376 | * @param string $id Notice ID |
||
377 | * |
||
378 | * @return int|bool |
||
379 | */ |
||
380 | private function dismiss_user( $id ) { |
||
381 | |||
382 | $dismissed = self::$instance->dismissed_user(); |
||
383 | |||
384 | if ( in_array( $id, $dismissed ) ) { |
||
385 | return false; |
||
386 | } |
||
387 | |||
388 | array_push( $dismissed, $id ); |
||
389 | |||
390 | return update_user_meta( get_current_user_id(), 'dnh_dismissed_notices', $dismissed ); |
||
391 | |||
392 | } |
||
393 | |||
394 | /** |
||
395 | * Dismiss notice globally on the site |
||
396 | * |
||
397 | * @since 1.0 |
||
398 | * |
||
399 | * @param string $id Notice ID |
||
400 | * |
||
401 | * @return bool |
||
402 | */ |
||
403 | private function dismiss_global( $id ) { |
||
404 | |||
405 | $dismissed = self::$instance->dismissed_global(); |
||
406 | |||
407 | if ( in_array( $id, $dismissed ) ) { |
||
408 | return false; |
||
409 | } |
||
410 | |||
411 | array_push( $dismissed, $id ); |
||
412 | |||
413 | return update_option( 'dnh_dismissed_notices', $dismissed ); |
||
414 | |||
415 | } |
||
416 | |||
417 | /** |
||
418 | * Restore a dismissed notice |
||
419 | * |
||
420 | * @since 1.0 |
||
421 | * |
||
422 | * @param string $id ID of the notice to restore |
||
423 | * |
||
424 | * @return bool |
||
425 | */ |
||
426 | public function restore_notice( $id ) { |
||
427 | |||
428 | $id = self::$instance->get_id( $id ); |
||
429 | $notice = self::$instance->get_notice( $id ); |
||
430 | |||
431 | if ( false === $notice ) { |
||
432 | return false; |
||
433 | } |
||
434 | |||
435 | return 'user' === $notice['scope'] ? self::$instance->restore_user( $id ) : self::$instance->restore_global( $id ); |
||
436 | |||
437 | } |
||
438 | |||
439 | /** |
||
440 | * Restore a notice dismissed by the current user |
||
441 | * |
||
442 | * @since 1.0 |
||
443 | * |
||
444 | * @param string $id ID of the notice to restore |
||
445 | * |
||
446 | * @return bool |
||
447 | */ |
||
448 | View Code Duplication | private function restore_user( $id ) { |
|
0 ignored issues
–
show
|
|||
449 | |||
450 | $id = self::$instance->get_id( $id ); |
||
451 | $notice = self::$instance->get_notice( $id ); |
||
452 | |||
453 | if ( false === $notice ) { |
||
454 | return false; |
||
455 | } |
||
456 | |||
457 | $dismissed = self::$instance->dismissed_user(); |
||
458 | |||
459 | if ( ! in_array( $id, $dismissed ) ) { |
||
460 | return false; |
||
461 | } |
||
462 | |||
463 | $flip = array_flip( $dismissed ); |
||
464 | $key = $flip[ $id ]; |
||
465 | |||
466 | unset( $dismissed[ $key ] ); |
||
467 | |||
468 | return update_user_meta( get_current_user_id(), 'dnh_dismissed_notices', $dismissed ); |
||
469 | |||
470 | } |
||
471 | |||
472 | /** |
||
473 | * Restore a notice dismissed globally |
||
474 | * |
||
475 | * @since 1.0 |
||
476 | * |
||
477 | * @param string $id ID of the notice to restore |
||
478 | * |
||
479 | * @return bool |
||
480 | */ |
||
481 | View Code Duplication | private function restore_global( $id ) { |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
482 | |||
483 | $id = self::$instance->get_id( $id ); |
||
484 | $notice = self::$instance->get_notice( $id ); |
||
485 | |||
486 | if ( false === $notice ) { |
||
487 | return false; |
||
488 | } |
||
489 | |||
490 | $dismissed = self::$instance->dismissed_global(); |
||
491 | |||
492 | if ( ! in_array( $id, $dismissed ) ) { |
||
493 | return false; |
||
494 | } |
||
495 | |||
496 | $flip = array_flip( $dismissed ); |
||
497 | $key = $flip[ $id ]; |
||
498 | |||
499 | unset( $dismissed[ $key ] ); |
||
500 | |||
501 | return update_option( 'dnh_dismissed_notices', $dismissed ); |
||
502 | |||
503 | } |
||
504 | |||
505 | /** |
||
506 | * Get all dismissed notices |
||
507 | * |
||
508 | * This includes notices dismissed globally or per user. |
||
509 | * |
||
510 | * @since 1.0 |
||
511 | * @return array |
||
512 | */ |
||
513 | public function dismissed_notices() { |
||
514 | |||
515 | $user = self::$instance->dismissed_user(); |
||
516 | $global = self::$instance->dismissed_global(); |
||
517 | |||
518 | return array_merge( $user, $global ); |
||
519 | |||
520 | } |
||
521 | |||
522 | /** |
||
523 | * Get user dismissed notices |
||
524 | * |
||
525 | * @since 1.0 |
||
526 | * @return array |
||
527 | */ |
||
528 | private function dismissed_user() { |
||
529 | |||
530 | $dismissed = get_user_meta( get_current_user_id(), 'dnh_dismissed_notices', true ); |
||
531 | |||
532 | if ( '' === $dismissed ) { |
||
533 | $dismissed = array(); |
||
534 | } |
||
535 | |||
536 | return $dismissed; |
||
537 | |||
538 | } |
||
539 | |||
540 | /** |
||
541 | * Get globally dismissed notices |
||
542 | * |
||
543 | * @since 1.0 |
||
544 | * @return array |
||
545 | */ |
||
546 | private function dismissed_global() { |
||
547 | return get_option( 'dnh_dismissed_notices', array() ); |
||
548 | } |
||
549 | |||
550 | /** |
||
551 | * Check if a notice has been dismissed |
||
552 | * |
||
553 | * @since 1.0 |
||
554 | * |
||
555 | * @param string $id Notice ID |
||
556 | * |
||
557 | * @return bool |
||
558 | */ |
||
559 | public function is_dismissed( $id ) { |
||
560 | |||
561 | $dismissed = self::$instance->dismissed_notices(); |
||
562 | |||
563 | if ( ! in_array( self::$instance->get_id( $id ), $dismissed ) ) { |
||
564 | return false; |
||
565 | } |
||
566 | |||
567 | return true; |
||
568 | |||
569 | } |
||
570 | |||
571 | /** |
||
572 | * Get all the registered notices |
||
573 | * |
||
574 | * @since 1.0 |
||
575 | * @return array|null |
||
576 | */ |
||
577 | public function get_notices() { |
||
578 | return self::$instance->notices; |
||
579 | } |
||
580 | |||
581 | /** |
||
582 | * Return a specific notice |
||
583 | * |
||
584 | * @since 1.0 |
||
585 | * |
||
586 | * @param string $id Notice ID |
||
587 | * |
||
588 | * @return array|false |
||
589 | */ |
||
590 | public function get_notice( $id ) { |
||
591 | |||
592 | $id = self::$instance->get_id( $id ); |
||
593 | |||
594 | if ( ! is_array( self::$instance->notices ) || ! array_key_exists( $id, self::$instance->notices ) ) { |
||
595 | return false; |
||
596 | } |
||
597 | |||
598 | return self::$instance->notices[ $id ]; |
||
599 | |||
600 | } |
||
601 | |||
602 | } |
||
603 | |||
604 | } |
||
605 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.