PluginProbe
Unagi / 0.2
Unagi v0.2
0.3.1 trunk 0.1.0 0.1.1 0.1.2 0.1.3 0.1.4 0.1.5 0.2 0.2.1 0.2.2 0.3
unagi / includes / shovel.php

shovel.php in Unagi 0.2, at includes/shovel.php

126 lines 2.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Shovels the nags with the buffer and saves to user meta
4 *
5 * `Everyday I'm shoveling...`
6 *
7 * @package Unagi
8 */
9
10 namespace Unagi\Shovel;
11
12 use const Unagi\Constants\USER_META_KEY;
13 use function Unagi\Utils\show_notifications_nicely;
14
15 // phpcs:disable WordPress.WhiteSpace.PrecisionAlignment.Found
16
17 /**
18 * Setup routine
19 */
20 function setup() {
21 $n = function ( $function ) {
22 return __NAMESPACE__ . "\\$function";
23 };
24
25 add_action( 'admin_notices', $n( 'start_shoveling' ), PHP_INT_MIN );
26 add_action( 'admin_notices', $n( 'stop_shoveling' ), PHP_INT_MAX );
27 }
28
29 /**
30 * Start buffering for the `admin_notices` hook
31 */
32 function start_shoveling() {
33 if ( ! is_shoveling() ) {
34 return;
35 }
36
37 ob_start();
38 }
39
40 /**
41 * Fetch/Process buffered data
42 */
43 function stop_shoveling() {
44 global $unagi_nags;
45
46 if ( ! is_shoveling() ) {
47 return;
48 }
49
50 $buffer = ob_get_clean();
51
52 /**
53 * Don't remove script/styles if any
54 * Plugins always intend to do weird things!!1
55 * Such as injecting CSS/JS with admin notices :facepalm:
56 */
57 preg_match_all( '@<(script|style)[^>]*?>.*?</\\1>@si', $buffer, $inline_output );
58
59 if ( ! empty( $inline_output[0] ) ) {
60 foreach ( $inline_output[0] as $inline_script ) {
61 echo $inline_script; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
62 }
63 }
64
65 $unagi_nags = trim( preg_replace( '@<(script|style)[^>]*?>.*?</\\1>@si', '', $buffer ) );
66
67 if ( ! show_notifications_nicely() ) {
68 return;
69 }
70
71 $hash = hash( 'sha256', $unagi_nags );
72 $notifications = get_user_meta( get_current_user_id(), USER_META_KEY, true );
73
74 if ( isset( $notifications['hash'] ) && $notifications['hash'] === $hash ) {
75 return;
76 }
77
78 $content = ( isset( $notifications['content'] ) ? $notifications['content'] : '' );
79 $diff = str_replace( $content, '', $unagi_nags );
80
81 /**
82 * Some plugins add can add notifications to particular pages only.
83 * Since the message does not always appear, it might not get displayed on the notifications screen.
84 *
85 * `Eg: akismet adds settings banner to plugins and comments page. Should we display it?`
86 *
87 * The diff won't be displayed by default. I think plugins needs to add a better "onboarding" experience
88 * if they need some input from the user.
89 */
90 if ( $diff && apply_filters( 'unagi_show_diff', false ) ) {
91 echo $diff; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
92 }
93
94 /**
95 * Update user meta only when the content changes
96 */
97 update_user_meta(
98 get_current_user_id(),
99 USER_META_KEY,
100 [
101 'hash' => $hash,
102 'content' => $unagi_nags,
103 ]
104 );
105 }
106
107 /**
108 * Shovel this page?
109 *
110 * @return bool
111 */
112 function is_shoveling() {
113 $current_screen = get_current_screen();
114 $is_shoveling = true;
115
116 /**
117 * Dirty way to make it work with WooCommerce setup wizard
118 * It is what it is!!!...
119 */
120 if ( ! empty( $current_screen ) && false !== stripos( $current_screen->base, 'woocommerce' ) ) {
121 $is_shoveling = false;
122 }
123
124 return (bool) apply_filters( 'unagi_is_shoveling', $is_shoveling );
125 }
126