PluginProbe
Unagi / trunk
Unagi vtrunk
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 / notifications.php

notifications.php in Unagi trunk, at includes/notifications.php

139 lines 3.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Notifications page
4 *
5 * @package Unagi
6 */
7
8 namespace Unagi\Notifications;
9
10 use const Unagi\Constants\USER_META_KEY;
11 use function Unagi\Utils\required_capability;
12 use function Unagi\Utils\show_notifications_nicely;
13 use \DOMDocument as DOMDocument;
14 use \DOMXPath as DOMXPath;
15
16 /**
17 * Setup routine
18 */
19 function setup() {
20 $n = function ( $function ) {
21 return __NAMESPACE__ . "\\$function";
22 };
23
24 add_action( 'admin_menu', $n( 'add_notification_page' ) );
25 }
26
27 /**
28 * Add notification page under the dashboard
29 */
30 function add_notification_page() {
31
32 $menu_title = esc_html__( 'Notifications', 'unagi' );
33
34 /**
35 * Don't need to display count if we are not showing the output in the nice way
36 */
37 if ( show_notifications_nicely() ) {
38 $notification_info = prepare_notification_info();
39 if ( $notification_info['count'] > 0 ) {
40 $menu_title .= sprintf( '<span class="update-plugins"><span class="update-count">%d</span></span>', absint( $notification_info['count'] ) );
41 }
42 }
43
44 add_dashboard_page(
45 esc_html__( 'Notifications', 'unagi' ),
46 $menu_title,
47 required_capability(),
48 'notification',
49 __NAMESPACE__ . '\notification_screen'
50 );
51 }
52
53 /**
54 * Notification page
55 */
56 function notification_screen() {
57 global $unagi_nags;
58
59 $output = $unagi_nags;
60
61 if ( show_notifications_nicely() ) {
62 $notification_info = prepare_notification_info();
63
64 $output = $notification_info['content'];
65
66 }
67
68 if ( empty( $output ) ) {
69 $output = sprintf(
70 '<div class="notice notice-success"><p>%s</p></div>',
71 esc_html__( 'Woohoo! There aren\'t any notifications for you.', 'unagi' )
72 );
73 }
74
75 $output = apply_filters( 'unagi_notification_output', $output );
76
77 ?>
78 <div class="wrap">
79 <h1><?php esc_html_e( 'Notifications', 'unagi' ); ?></h1>
80 <div id="unagi-notification-center">
81 <?php echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
82 </div>
83 </div>
84 <?php
85 }
86
87 /**
88 * Prepare notification info by parsing buffered output
89 *
90 * @return array
91 * @since 0.1.0
92 */
93 function prepare_notification_info() {
94 $notification = get_user_meta( get_current_user_id(), USER_META_KEY, true );
95
96 $notification_content = ( isset( $notification['content'] ) ? $notification['content'] : '' );
97
98 if ( function_exists( 'mb_encode_numericentity' ) ) {
99 $convmap = array( 0x80, 0x10ffff, 0, 0xffffff ); // Range of characters to convert
100 $notification_content = mb_encode_numericentity( $notification_content, $convmap, 'UTF-8' );
101 }
102
103 if ( empty( $notification_content ) ) {
104 return [
105 'count' => 0,
106 'content' => '',
107 ];
108 }
109
110 $doc = new DOMDocument( '1.0', 'UTF-8' );
111 libxml_use_internal_errors( true );
112 $doc->loadHTML( $notification_content );
113 $xpath = new DOMXPath( $doc );
114
115 /**
116 * Don't care if the notices don't respect default "notice" classes.
117 * But adding a filter just in case someone else needed
118 *
119 * @since 0.1.0
120 */
121 $expression = apply_filters( 'unagi_xpath_expression', "//*[contains(@class, 'notice ') or contains(@class, ' notice') ]" );
122 $nodes = $xpath->query( $expression ); // notification nodes
123
124 $collector = new DOMDocument( '1.0', 'UTF-8' );
125
126 $count = (int) $nodes->length;
127
128 foreach ( $nodes as $node ) {
129 $collector->appendChild( $collector->importNode( $node, true ) );
130 }
131
132 $content = trim( $collector->saveHTML() );
133
134 return [
135 'count' => $count,
136 'content' => $content,
137 ];
138 }
139