PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 16.1-beta.3
Jetpack – WP Security, Backup, Speed, & Growth v16.1-beta.3
16.1.2 16.2-a.1 16.1.1 16.1 16.1-beta 16.1-beta.2 16.1-beta.3 16.1-a.5 16.1-a.3 16.0.1 16.1-a.1 16.0 16.0-beta 16.0-a.7 16.0-a.5 15.9.1 16.0-a.3 16.0-a.1 15.9 15.9-beta 15.9-a.7 15.9-a.5 15.9-a.3 15.9-a.1 15.8 15.8-beta 15.8-a.7 15.8-a.5 5.2.5 5.3.4 5.4.4 5.5.5 5.6.5 5.7.5 5.8.4 5.9.4 6.0.4 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.2 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.3 6.3.1 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.4 6.4.1 6.4.2 6.4.3 6.4.4 6.4.5 6.4.6 6.5 6.5.1 6.5.2 6.5.3 6.5.4 6.6 6.6.1 6.6.2 6.6.3 6.6.4 6.6.5 6.7 6.7.1 6.7.2 6.7.3 6.7.4 6.8 6.8.1 6.8.2 6.8.3 6.8.4 6.8.5 6.9 6.9.1 6.9.2 6.9.3 6.9.4 7.0 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2 7.2.1 7.2.1.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3 7.3.0.1 7.3.1 7.3.1.1 7.3.2 7.3.3 7.3.4 7.3.5 7.4 7.4.1 7.4.2 7.4.3 7.4.4 7.4.5 7.5 7.5.0.1 7.5.1 7.5.2 7.5.3 7.5.4 7.5.5 7.5.6 7.5.7 7.6 7.6.1 7.6.2 7.6.3 7.6.4 7.7 7.7.1 7.7.2 7.7.3 7.7.4 7.7.5 7.7.6 7.8 7.8.1 7.8.2 7.8.3 7.8.4 7.9 7.9.1 7.9.2 7.9.3 7.9.4 8.0 8.0.1 8.0.2 8.0.3 8.1 8.1.1 8.1.2 8.1.3 8.1.4 8.2 8.2.0.1 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.2.6 8.3 8.3.1 8.3.2 8.3.3 8.4 8.4.1 8.4.2 8.4.3 8.4.4 8.4.5 8.5 8.5.1 8.5.2 8.5.3 8.6 8.6.1 8.6.2 8.6.3 8.6.4 8.7 8.7.0.1 8.7.1 8.7.2 8.7.3 8.7.4 8.8 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.9 8.9.1 8.9.2 8.9.3 8.9.4 9.0 9.0.1 9.0.2 9.0.3 9.0.4 9.0.5 9.1 9.1.1 9.1.2 9.1.3 9.2 9.2.1 9.2.2 9.2.3 9.2.4 9.3 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.4 9.4.1 9.4.2 9.4.3 9.4.4 9.5 9.5.1 9.5.2 9.5.3 9.5.4 9.5.5 9.6 9.6.1 9.6.2 9.6.3 9.6.4 9.7 9.7.1 9.7.2 15.7-beta.2 9.7.3 15.7.1 9.8 15.8-a.1 9.8.1 15.8-a.3 9.8.2 2.0.9 9.8.3 2.1.7 9.9 2.2.10 9.9.1 2.3.10 9.9.2 2.4.7 9.9.3 2.5.5 2.6.6 2.7.5 2.8.5 2.9.6 3.0.6 3.1.5 3.2.5 3.3.6 3.4.6 3.5.6 3.6.4 3.7.5 3.8.5 3.9.10 4.0.7 4.1.4 4.2.5 4.3.5 4.4.5 4.5.3 4.6.3 4.7.4 4.8.5 4.9.3 5.0.3 5.1.4 trunk 10.0 10.0.1 10.0.2 10.1 10.1.1 10.1.2 10.2 10.2.1 10.2.2 10.2.3 10.3 10.3.1 10.3.2 10.4 10.4.1 10.4.2 10.5 10.5.1 10.5.2 10.5.3 10.6 10.6.1 10.6.2 10.7 10.7.1 10.7.2 10.8 10.8.1 10.8.2 10.9 10.9.1 10.9.2 10.9.3 11.0 11.0.1 11.0.2 11.1 11.1.1 11.1.2 11.1.3 11.1.4 11.2 11.2.1 11.2.2 11.3 11.3.1 11.3.2 11.3.3 11.3.4 11.4 11.4.1 11.4.2 11.5 11.5.1 11.5.2 11.5.3 11.6 11.6.1 11.6.2 11.7 11.7.1 11.7.2 11.7.3 11.8 11.8.3 11.8.4 11.8.5 11.8.6 11.9 11.9.1 11.9.2 11.9.3 12.0 12.0.1 12.0.2 12.1 12.1.1 12.1.2 12.2 12.2.1 12.2.2 12.3 12.3.1 12.4 12.4.1 12.5 12.5.1 12.6 12.6.1 12.6.2 12.6.3 12.7 12.7.1 12.7.2 12.8 12.8.1 12.8.2 12.9 12.9.1 12.9.2 12.9.3 12.9.4 13.0 13.0.1 13.1 13.1.1 13.1.2 13.1.3 13.1.4 13.2 13.2.1 13.2.2 13.2.3 13.3 13.3.1 13.3.2 13.4 13.4.1 13.4.2 13.4.3 13.4.4 13.5 13.5.1 13.6 13.6.1 13.7 13.7.1 13.8 13.8.1 13.8.2 13.9 13.9.1 14.0 14.1 14.2 14.2.1 14.3 14.4 14.4.1 14.5 14.6 14.7 14.8 14.9 14.9.1 15.0 15.0.1 15.0.2 15.1 15.1.1 15.2 15.3 15.3.1 15.4 15.5 15.6 15.7 15.7-a.1 15.7-a.3 15.7-a.5 15.7-a.7 15.7-beta
jetpack / jetpack_vendor / automattic / jetpack-menu-badges / src / class-menu-renderer.php
jetpack / jetpack_vendor / automattic / jetpack-menu-badges / src Last commit date
js 1 month ago class-menu-badges.php 1 month ago class-menu-renderer.php 1 month ago class-notification-counts.php 1 month ago
class-menu-renderer.php
147 lines
1 <?php
2 /**
3 * Renders notification-count badges into the wp-admin $menu/$submenu globals.
4 *
5 * @package automattic/jetpack-menu-badges
6 */
7
8 namespace Automattic\Jetpack\Menu_Badges;
9
10 /**
11 * Reads the Notification_Counts registry and writes the top-level and submenu
12 * badges. Sole writer of Jetpack menu badges in wp-admin. Idempotent.
13 */
14 class Menu_Renderer {
15
16 /**
17 * Build a single badge span.
18 *
19 * @param string $id Owning entry id (or 'total').
20 * @param int $count Count to show.
21 * @param bool $is_total Whether this is the top-level total badge.
22 * @return string
23 */
24 public static function badge_markup( $id, $count, $is_total = false ) {
25 $count = (int) $count;
26 // A zero-count badge still renders (so client live-updates have an element to
27 // target) but ships hidden. The inline style trails the data-jp-* attributes so
28 // strip()'s idempotency regex still matches; setBadgeCount() clears it to reveal.
29 $hidden = $count > 0 ? '' : ' style="display:none"';
30 // The top-level Jetpack total badge carries the core `awaiting-mod` and
31 // `update-plugins` classes so it picks up WordPress's standard menu-bubble styling;
32 // submenu badges use only our own `menu-counter` hook. `menu-counter` is always
33 // present for CSS/JS targeting.
34 $classes = $is_total ? 'awaiting-mod update-plugins menu-counter' : 'menu-counter';
35 $attrs = sprintf(
36 'class="%1$s count-%2$d" data-jp-menu-badge="%3$s" data-jp-menu-count="%2$d"%4$s%5$s',
37 $classes,
38 $count,
39 esc_attr( $id ),
40 $is_total ? ' data-jp-menu-badge-total="1"' : '',
41 $hidden
42 );
43 return sprintf(
44 ' <span %1$s><span class="count">%2$s</span></span>',
45 $attrs,
46 number_format_i18n( $count )
47 );
48 }
49
50 /**
51 * Strip any badge this renderer previously wrote from a menu title (idempotency).
52 *
53 * @param string $title Menu title.
54 * @return string
55 */
56 private static function strip( $title ) {
57 return trim( (string) preg_replace( '/\s*<span class="[^"]*menu-counter count-\d+" data-jp-menu-badge=.*$/s', '', (string) $title ) );
58 }
59
60 /**
61 * Render badges into the current $menu/$submenu globals.
62 *
63 * @return void
64 */
65 public static function render() {
66 global $menu, $submenu;
67
68 if ( ! is_array( $menu ) ) {
69 return;
70 }
71
72 $entries = Notification_Counts::all();
73
74 // Submenu badges: one per registered menu_slug. A registered slug always gets a
75 // badge span — even at count 0 — so a later client live-update (0 -> positive)
76 // has an element to reveal. badge_markup() ships the zero case hidden.
77 if ( isset( $submenu['jetpack'] ) && is_array( $submenu['jetpack'] ) ) {
78 foreach ( $submenu['jetpack'] as $i => $item ) {
79 if ( ! isset( $item[2] ) || ! isset( $item[0] ) ) {
80 continue;
81 }
82 $slug = $item[2];
83 $title = self::strip( $item[0] );
84 if ( self::has_registered_slug( $entries, $slug ) ) {
85 $title .= self::badge_markup( $slug, Notification_Counts::get_for_menu( $slug ) );
86 }
87 // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
88 $submenu['jetpack'][ $i ][0] = $title;
89 }
90 }
91
92 // Nothing registered: leave the Jetpack parent untouched (no badge to write or strip).
93 if ( empty( $entries ) ) {
94 return;
95 }
96
97 // Top-level total on the Jetpack parent. Rendered even at 0 (hidden) so a live
98 // update can reveal it without a reload.
99 $parent_index = self::find_parent_index( $menu );
100 if ( null === $parent_index ) {
101 return;
102 }
103 // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
104 $menu[ $parent_index ][0] = self::strip( $menu[ $parent_index ][0] ) . self::badge_markup( 'total', Notification_Counts::get_total(), true );
105 }
106
107 /**
108 * Whether any registered entry badges the given submenu slug.
109 *
110 * @param array<string,array> $entries Registry entries (from Notification_Counts::all()).
111 * @param string $slug Submenu slug.
112 * @return bool
113 */
114 private static function has_registered_slug( array $entries, $slug ) {
115 foreach ( $entries as $entry ) {
116 if ( isset( $entry['menu_slug'] ) && $entry['menu_slug'] === $slug ) {
117 return true;
118 }
119 }
120 return false;
121 }
122
123 /**
124 * Locate the Jetpack top-level menu row to carry the total badge.
125 *
126 * Prefers the row whose slug (item[2]) is 'jetpack' — portable across self-hosted,
127 * Atomic, and WP.com Simple, where jetpack-mu-wpcom builds the parent with a different
128 * capability. Falls back to the plugin's 'jetpack_admin_page' capability (item[1]).
129 *
130 * @param array $menu The wp-admin $menu global.
131 * @return int|string|null Matching key, or null when no Jetpack parent is present.
132 */
133 private static function find_parent_index( array $menu ) {
134 foreach ( $menu as $i => $item ) {
135 if ( isset( $item[0] ) && isset( $item[2] ) && 'jetpack' === $item[2] ) {
136 return $i;
137 }
138 }
139 foreach ( $menu as $i => $item ) {
140 if ( isset( $item[0] ) && isset( $item[1] ) && 'jetpack_admin_page' === $item[1] ) {
141 return $i;
142 }
143 }
144 return null;
145 }
146 }
147