PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3
Jetpack – WP Security, Backup, Speed, & Growth v16.3
16.3 16.3-beta 16.3-a.5 16.3-a.7 16.3-a.3 16.3-a.1 16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 All 508 releases
← All changes | jetpack_vendor/automattic/jetpack-masterbar/src/admin-menu/class-wpcom-admin-menu.php +316 -0 16.2-beta → 16.3 View file →
@@ -1,0 +1,316 @@
1 +<?php
2 +/**
3 + * WP.com Admin Menu file.
4 + *
5 + * @package automattic/jetpack-masterbar
6 + */
7 +
8 +namespace Automattic\Jetpack\Masterbar;
9 +
10 +use Jetpack_Custom_CSS;
11 +use JITM;
12 +
13 +require_once __DIR__ . '/class-admin-menu.php';
14 +
15 +/**
16 + * Class WPcom_Admin_Menu.
17 + */
18 +class WPcom_Admin_Menu extends Admin_Menu {
19 + /**
20 + * WPcom_Admin_Menu constructor.
21 + */
22 + protected function __construct() {
23 + parent::__construct();
24 +
25 + add_action( 'wp_ajax_sidebar_state', array( $this, 'ajax_sidebar_state' ) );
26 + add_action( 'wp_ajax_jitm_dismiss', array( $this, 'wp_ajax_jitm_dismiss' ) );
27 + add_action( 'adminmenu', array( $this, 'render_upsell_nudge' ), 100 );
28 + add_action( 'admin_init', array( $this, 'sync_sidebar_collapsed_state' ) );
29 + add_action( 'admin_menu', array( $this, 'remove_submenus' ), 140 ); // After hookpress hook at 130.
30 + }
31 +
32 + /**
33 + * Create the desired menu output.
34 + */
35 + public function reregister_menu_items() {
36 + parent::reregister_menu_items();
37 +
38 + $this->remove_gutenberg_menu();
39 +
40 + // Not needed outside of wp-admin.
41 + if ( ! $this->is_api_request ) {
42 + $this->add_new_site_link();
43 + }
44 +
45 + ksort( $GLOBALS['menu'] );
46 + }
47 +
48 + /**
49 + * Get the preferred view for the given screen.
50 + *
51 + * @param string $screen Screen identifier.
52 + * @param bool $fallback_global_preference (Optional) Whether the global preference for all screens should be used
53 + * as fallback if there is no specific preference for the given screen.
54 + * Default: true.
55 + * @return string
56 + */
57 + public function get_preferred_view( $screen, $fallback_global_preference = true ) {
58 + // When no preferred view has been set for Themes, keep the previous behavior that forced the default view
59 + // regardless of the global preference.
60 + if ( $fallback_global_preference && 'themes.php' === $screen ) {
61 + $preferred_view = parent::get_preferred_view( $screen, false );
62 + if ( self::UNKNOWN_VIEW === $preferred_view ) {
63 + return self::DEFAULT_VIEW;
64 + }
65 + return $preferred_view;
66 + }
67 +
68 + // Plugins on Simple sites are always managed on Calypso.
69 + if ( 'plugins.php' === $screen ) {
70 + return self::DEFAULT_VIEW;
71 + }
72 +
73 + return parent::get_preferred_view( $screen, $fallback_global_preference );
74 + }
75 +
76 + /**
77 + * Retrieve the number of blogs that the current user has.
78 + *
79 + * @return int
80 + */
81 + public function get_current_user_blog_count() {
82 + if ( function_exists( '\get_blog_count_for_user' ) ) {
83 + return \get_blog_count_for_user( get_current_user_id() );
84 + }
85 +
86 + $blogs = get_blogs_of_user( get_current_user_id() );
87 + return is_countable( $blogs ) ? count( $blogs ) : 0;
88 + }
89 +
90 + /**
91 + * Adds a custom element class for Site Switcher menu item.
92 + *
93 + * @param array $menu Associative array of administration menu items.
94 + * @return array
95 + */
96 + public function set_browse_sites_link_class( array $menu ) {
97 + foreach ( $menu as $key => $menu_item ) {
98 + if ( 'site-switcher' !== $menu_item[3] ) {
99 + continue;
100 + }
101 +
102 + $menu[ $key ][4] = add_cssclass( 'site-switcher', $menu_item[4] );
103 + break;
104 + }
105 +
106 + return $menu;
107 + }
108 +
109 + /**
110 + * Adds a link to the menu to create a new site.
111 + */
112 + public function add_new_site_link() {
113 + if ( $this->get_current_user_blog_count() > 1 ) {
114 + return;
115 + }
116 +
117 + $this->add_admin_menu_separator();
118 + // @phan-suppress-next-line PhanTypeMismatchArgumentProbablyReal -- Core should ideally document null for no-callback arg. https://core.trac.wordpress.org/ticket/52539.
119 + add_menu_page( __( 'Add New Site', 'jetpack-masterbar' ), __( 'Add New Site', 'jetpack-masterbar' ), 'read', 'https://wordpress.com/start?ref=calypso-sidebar', null, 'dashicons-plus-alt' );
120 + }
121 +
122 + /**
123 + * Returns the first available upsell nudge.
124 + *
125 + * @return array
126 + */
127 + public function get_upsell_nudge() {
128 + require_lib( 'jetpack-jitm/jitm-engine' );
129 + $jitm_engine = new JITM\Engine();
130 +
131 + $message_path = 'calypso:sites:sidebar_notice';
132 + $current_user = wp_get_current_user();
133 + $user_id = $current_user->ID;
134 + $user_roles = implode( ',', $current_user->roles );
135 + $query_string = array(
136 + 'message_path' => $message_path,
137 + );
138 +
139 + // Get the top message only.
140 + $message = $jitm_engine->get_top_messages( $message_path, $user_id, $user_roles, $query_string );
141 +
142 + if ( isset( $message[0] ) ) {
143 + $message = $message[0];
144 + return array(
145 + 'content' => $message->content['message'],
146 + 'cta' => $message->CTA['message'], // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
147 + 'link' => $message->CTA['link'], // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
148 + 'tracks_impression_event_name' => $message->tracks['display']['name'] ?? null,
149 + 'tracks_impression_cta_name' => $message->tracks['display']['props']['cta_name'] ?? null,
150 + 'tracks_click_event_name' => $message->tracks['click']['name'] ?? null,
151 + 'tracks_click_cta_name' => $message->tracks['click']['props']['cta_name'] ?? null,
152 + 'dismissible' => $message->is_dismissible,
153 + 'feature_class' => $message->feature_class,
154 + 'id' => $message->id,
155 + );
156 + }
157 + }
158 +
159 + /**
160 + * Adds Appearance menu.
161 + *
162 + * @return string The Customizer URL.
163 + */
164 + public function add_appearance_menu() {
165 + $customize_url = parent::add_appearance_menu();
166 +
167 + $this->hide_submenu_page( 'themes.php', 'theme-editor.php' );
168 +
169 + $user_can_customize = current_user_can( 'customize' );
170 +
171 + if ( wp_is_block_theme() ) {
172 + add_filter( 'safecss_is_freetrial', '__return_false', PHP_INT_MAX );
173 + if ( class_exists( 'Jetpack_Custom_CSS' ) && empty( Jetpack_Custom_CSS::get_css() ) ) {
174 + $user_can_customize = false;
175 + }
176 + remove_filter( 'safecss_is_freetrial', '__return_false', PHP_INT_MAX );
177 + }
178 +
179 + if ( $user_can_customize ) {
180 + $customize_custom_css_url = add_query_arg( array( 'autofocus' => array( 'section' => 'jetpack_custom_css' ) ), $customize_url );
181 + // @phan-suppress-next-line PhanTypeMismatchArgumentProbablyReal -- Core should ideally document null for no-callback arg. https://core.trac.wordpress.org/ticket/52539.
182 + add_submenu_page( 'themes.php', esc_attr__( 'Additional CSS', 'jetpack-masterbar' ), __( 'Additional CSS', 'jetpack-masterbar' ), 'customize', esc_url( $customize_custom_css_url ), null, 20 );
183 + }
184 +
185 + return $customize_url;
186 + }
187 +
188 + /**
189 + * Adds Users menu.
190 + */
191 + public function add_users_menu() {
192 + $submenus_to_update = array(
193 + 'grofiles-editor' => 'https://wordpress.com/me',
194 + 'grofiles-user-settings' => 'https://wordpress.com/me/account',
195 + );
196 +
197 + if ( self::DEFAULT_VIEW === $this->get_preferred_view( 'users.php' ) ) {
198 + $submenus_to_update['users.php'] = 'https://wordpress.com/people/team/' . $this->domain;
199 + }
200 +
201 + $slug = current_user_can( 'list_users' ) ? 'users.php' : 'profile.php';
202 + $this->update_submenus( $slug, $submenus_to_update );
203 + // @phan-suppress-next-line PhanTypeMismatchArgumentProbablyReal -- Core should ideally document null for no-callback arg. https://core.trac.wordpress.org/ticket/52539.
204 + add_submenu_page( 'users.php', esc_attr__( 'Add New User', 'jetpack-masterbar' ), __( 'Add New User', 'jetpack-masterbar' ), 'promote_users', 'https://wordpress.com/people/new/' . $this->domain, null, 1 );
205 + }
206 +
207 + /**
208 + * Also remove the Gutenberg plugin menu.
209 + */
210 + public function remove_gutenberg_menu() {
211 + // Always remove the Gutenberg menu.
212 + remove_menu_page( 'gutenberg' );
213 + }
214 +
215 + /**
216 + * Whether to use wp-admin pages rather than Calypso.
217 + *
218 + * @return bool
219 + */
220 + public function should_link_to_wp_admin() {
221 + $result = false; // Calypso.
222 +
223 + $user_attribute = get_user_attribute( get_current_user_id(), 'calypso_preferences' );
224 + if ( ! empty( $user_attribute['linkDestination'] ) ) {
225 + $result = $user_attribute['linkDestination'];
226 + }
227 +
228 + return $result;
229 + }
230 +
231 + /**
232 + * Saves the sidebar state ( expanded / collapsed ) via an ajax request.
233 + *
234 + * @return never
235 + */
236 + public function ajax_sidebar_state() {
237 + $expanded = isset( $_REQUEST['expanded'] ) ? filter_var( wp_unslash( $_REQUEST['expanded'] ), FILTER_VALIDATE_BOOLEAN ) : false; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
238 + $user_id = get_current_user_id();
239 + $preferences = get_user_attribute( $user_id, 'calypso_preferences' );
240 + if ( empty( $preferences ) ) {
241 + $preferences = array();
242 + }
243 +
244 + $value = array_merge( (array) $preferences, array( 'sidebarCollapsed' => ! $expanded ) );
245 + $value = array_filter(
246 + $value,
247 + function ( $preference ) {
248 + return null !== $preference;
249 + }
250 + );
251 +
252 + update_user_attribute( $user_id, 'calypso_preferences', $value );
253 +
254 + die( 0 );
255 + }
256 +
257 + /**
258 + * Handle ajax requests to dismiss a just-in-time-message
259 + */
260 + public function wp_ajax_jitm_dismiss() {
261 + check_ajax_referer( 'jitm_dismiss' );
262 + require_lib( 'jetpack-jitm/jitm-engine' );
263 + if ( isset( $_REQUEST['id'] ) && isset( $_REQUEST['feature_class'] ) ) {
264 + JITM\Engine::dismiss( sanitize_text_field( wp_unslash( $_REQUEST['id'] ) ), sanitize_text_field( wp_unslash( $_REQUEST['feature_class'] ) ) );
265 + }
266 + wp_die();
267 + }
268 +
269 + /**
270 + * Syncs the sidebar collapsed state from Calypso Preferences.
271 + */
272 + public function sync_sidebar_collapsed_state() {
273 + $calypso_preferences = get_user_attribute( get_current_user_id(), 'calypso_preferences' );
274 +
275 + $sidebar_collapsed = $calypso_preferences['sidebarCollapsed'] ?? false;
276 +
277 + // Read the current stored setting and convert it to boolean in order to be able to compare the values later.
278 + $current_sidebar_collapsed_setting = 'f' === get_user_setting( 'mfold' );
279 +
280 + // Only set the setting if the value differs, as `set_user_setting` always updates at least the timestamp
281 + // which leads to unnecessary user meta cache purging on all wp-admin screen requests.
282 + if ( $current_sidebar_collapsed_setting !== $sidebar_collapsed ) {
283 + set_user_setting( 'mfold', $sidebar_collapsed ? 'f' : 'o' );
284 + }
285 + }
286 +
287 + /**
288 + * Removes unwanted submenu items.
289 + *
290 + * These submenus are added across wp-content and should be removed together with these function calls.
291 + */
292 + public function remove_submenus() {
293 + global $_registered_pages;
294 +
295 + remove_submenu_page( 'index.php', 'akismet-stats' );
296 + remove_submenu_page( 'index.php', 'my-comments' );
297 + remove_submenu_page( 'index.php', 'stats' );
298 + remove_submenu_page( 'index.php', 'subscriptions' );
299 +
300 + /* @see https://github.com/Automattic/wp-calypso/issues/49210 */
301 + remove_submenu_page( 'index.php', 'my-blogs' );
302 + $_registered_pages['admin_page_my-blogs'] = true; // phpcs:ignore
303 +
304 + remove_submenu_page( 'themes.php', 'customize.php?autofocus[panel]=amp_panel&return=' . rawurlencode( admin_url() ) );
305 +
306 + remove_submenu_page( 'users.php', 'wpcom-invite-users' ); // Wpcom_Invite_Users::action_admin_menu.
307 +
308 + remove_submenu_page( 'options-general.php', 'adcontrol' );
309 +
310 + // Remove menu item but continue allowing access.
311 + foreach ( array( 'openidserver', 'webhooks' ) as $page_slug ) {
312 + remove_submenu_page( 'options-general.php', $page_slug );
313 + $_registered_pages[ 'admin_page_' . $page_slug ] = true; // phpcs:ignore
314 + }
315 + }
316 +}