PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 13.2.4
Jetpack – WP Security, Backup, Speed, & Growth v13.2.4
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 13.7.2 13.8.3 13.9.2 14.0.1 14.1.1 14.2.2 14.3.1 14.4.2 14.5.1 14.6.1 14.7.1 14.8.1 14.9.2 15.0.3 15.1.2 15.2.1 15.3.2 15.4.1 15.5.1 15.6.1 15.7.2 15.8.1 15.9.2 16.0.2 16.1.3 16.2-a.5 16.2-a.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 / modules / masterbar / admin-menu / class-admin-menu.php
jetpack / modules / masterbar / admin-menu Last commit date
admin-menu-nav-unification-rtl.css 2 years ago admin-menu-nav-unification-rtl.min.css 2 years ago admin-menu-nav-unification.css 2 years ago admin-menu-nav-unification.min.css 2 years ago admin-menu-rtl.css 2 years ago admin-menu-rtl.min.css 2 years ago admin-menu.css 2 years ago admin-menu.js 2 years ago admin-menu.min.css 2 years ago class-admin-menu.php 2 years ago class-atomic-admin-menu.php 2 years ago class-base-admin-menu.php 2 years ago class-dashboard-switcher-tracking.php 3 years ago class-domain-only-admin-menu.php 2 years ago class-jetpack-admin-menu.php 2 years ago class-p2-admin-menu.php 4 years ago class-wpcom-admin-menu.php 2 years ago class-wpcom-email-subscription-checker.php 3 years ago dashicon-set.php 4 years ago globe-icon.svg 3 years ago load.php 2 years ago menu-mappings.php 3 years ago
class-admin-menu.php
513 lines
1 <?php
2 /**
3 * Admin Menu file.
4 *
5 * @package automattic/jetpack
6 */
7
8 namespace Automattic\Jetpack\Dashboard_Customizations;
9
10 use Automattic\Jetpack\Assets\Logo;
11 use Automattic\Jetpack\Redirect;
12
13 require_once __DIR__ . '/class-base-admin-menu.php';
14
15 /**
16 * Class Admin_Menu.
17 */
18 class Admin_Menu extends Base_Admin_Menu {
19
20 /**
21 * Create the desired menu output.
22 */
23 public function reregister_menu_items() {
24 // Remove separators.
25 remove_menu_page( 'separator1' );
26 $this->add_stats_menu();
27 $this->add_upgrades_menu();
28 $this->add_posts_menu();
29 $this->add_media_menu();
30 $this->add_page_menu();
31 $this->add_testimonials_menu();
32 $this->add_portfolio_menu();
33 $this->add_comments_menu();
34 $this->add_appearance_menu();
35 $this->add_plugins_menu();
36 $this->add_users_menu();
37 $this->add_tools_menu();
38 $this->add_options_menu();
39 $this->add_jetpack_menu();
40
41 // Remove Links Manager menu since its usage is discouraged. https://github.com/Automattic/wp-calypso/issues/51188.
42 // @see https://core.trac.wordpress.org/ticket/21307#comment:73.
43 if ( $this->should_disable_links_manager() ) {
44 remove_menu_page( 'link-manager.php' );
45 }
46
47 ksort( $GLOBALS['menu'] );
48 }
49
50 /**
51 * Get the preferred view for the given screen.
52 *
53 * @param string $screen Screen identifier.
54 * @param bool $fallback_global_preference (Optional) Whether the global preference for all screens should be used
55 * as fallback if there is no specific preference for the given screen.
56 * Default: true.
57 * @return string
58 */
59 public function get_preferred_view( $screen, $fallback_global_preference = true ) {
60 $force_default_view = in_array( $screen, array( 'users.php', 'options-general.php' ), true );
61 $use_wp_admin = $this->use_wp_admin_interface();
62
63 // When no preferred view has been set for "Users > All Users" or "Settings > General", keep the previous
64 // behavior that forced the default view regardless of the global preference.
65 // This behavior is overriden by the wpcom_admin_interface option when it is set to wp-admin.
66 if ( ! $use_wp_admin && $fallback_global_preference && $force_default_view ) {
67 $preferred_view = parent::get_preferred_view( $screen, false );
68 if ( self::UNKNOWN_VIEW === $preferred_view ) {
69 return self::DEFAULT_VIEW;
70 }
71 return $preferred_view;
72 }
73
74 return parent::get_preferred_view( $screen, $fallback_global_preference );
75 }
76
77 /**
78 * Check if Links Manager is being used.
79 */
80 public function should_disable_links_manager() {
81 // The max ID number of the auto-generated links.
82 // See /wp-content/mu-plugins/wpcom-wp-install-defaults.php in WP.com.
83 $max_default_id = 10;
84
85 // We are only checking the latest entry link_id so are limiting the query to 1.
86 $link_manager_links = get_bookmarks(
87 array(
88 'orderby' => 'link_id',
89 'order' => 'DESC',
90 'limit' => 1,
91 'hide_invisible' => 0,
92 )
93 );
94
95 // Ordered links by ID descending, check if the first ID is more than $max_default_id.
96 if ( is_countable( $link_manager_links ) && count( $link_manager_links ) > 0 && $link_manager_links[0]->link_id > $max_default_id ) {
97 return false;
98 }
99
100 return true;
101 }
102
103 /**
104 * Adds My Home menu.
105 */
106 public function add_my_home_menu() {
107
108 if ( self::DEFAULT_VIEW !== $this->get_preferred_view( 'index.php' ) ) {
109 return;
110 }
111
112 $this->update_menu( 'index.php', 'https://wordpress.com/home/' . $this->domain, __( 'My Home', 'jetpack' ), 'read', 'dashicons-admin-home' );
113 }
114
115 /**
116 * Adds My Mailboxes menu.
117 */
118 public function add_my_mailboxes_menu() {
119 add_menu_page( __( 'My Mailboxes', 'jetpack' ), __( 'My Mailboxes', 'jetpack' ), 'manage_options', 'https://wordpress.com/mailboxes/' . $this->domain, null, 'dashicons-email', '4.64424' );
120 }
121
122 /**
123 * Adds Stats menu.
124 */
125 public function add_stats_menu() {
126 add_menu_page( __( 'Stats', 'jetpack' ), __( 'Stats', 'jetpack' ), 'view_stats', 'https://wordpress.com/stats/day/' . $this->domain, null, 'dashicons-chart-bar', 3 );
127 }
128
129 /**
130 * Adds Upgrades menu.
131 *
132 * @param string $plan The current WPCOM plan of the blog.
133 */
134 public function add_upgrades_menu( $plan = null ) {
135 global $menu;
136
137 $menu_exists = false;
138 foreach ( $menu as $item ) {
139 if ( 'paid-upgrades.php' === $item[2] ) {
140 $menu_exists = true;
141 break;
142 }
143 }
144
145 if ( ! $menu_exists ) {
146 if ( $plan ) {
147 // Add display:none as a default for cases when CSS is not loaded.
148 $site_upgrades = '%1$s<span class="inline-text" style="display:none">%2$s</span>';
149 $site_upgrades = sprintf(
150 $site_upgrades,
151 __( 'Upgrades', 'jetpack' ),
152 // phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralText
153 __( $plan, 'jetpack' )
154 );
155 } else {
156 $site_upgrades = __( 'Upgrades', 'jetpack' );
157 }
158
159 add_menu_page( __( 'Upgrades', 'jetpack' ), $site_upgrades, 'manage_options', 'paid-upgrades.php', null, 'dashicons-cart', 4 );
160 }
161
162 add_submenu_page( 'paid-upgrades.php', __( 'Plans', 'jetpack' ), __( 'Plans', 'jetpack' ), 'manage_options', 'https://wordpress.com/plans/' . $this->domain, null, 1 );
163 add_submenu_page( 'paid-upgrades.php', __( 'Purchases', 'jetpack' ), __( 'Purchases', 'jetpack' ), 'manage_options', 'https://wordpress.com/purchases/subscriptions/' . $this->domain, null, 2 );
164
165 if ( ! $menu_exists ) {
166 // Remove the submenu auto-created by Core.
167 $this->hide_submenu_page( 'paid-upgrades.php', 'paid-upgrades.php' );
168 }
169 }
170
171 /**
172 * Adds Posts menu.
173 */
174 public function add_posts_menu() {
175 $submenus_to_update = array();
176
177 if ( self::DEFAULT_VIEW === $this->get_preferred_view( 'edit.php' ) ) {
178 $submenus_to_update['edit.php'] = 'https://wordpress.com/posts/' . $this->domain;
179 $submenus_to_update['post-new.php'] = 'https://wordpress.com/post/' . $this->domain;
180 $this->update_submenus( 'edit.php', $submenus_to_update );
181 }
182
183 if ( self::DEFAULT_VIEW === $this->get_preferred_view( 'edit-tags.php?taxonomy=category' ) ) {
184 $this->update_submenus( 'edit.php', array( 'edit-tags.php?taxonomy=category' => 'https://wordpress.com/settings/taxonomies/category/' . $this->domain ) );
185 }
186
187 if ( self::DEFAULT_VIEW === $this->get_preferred_view( 'edit-tags.php?taxonomy=post_tag' ) ) {
188 $this->update_submenus( 'edit.php', array( 'edit-tags.php?taxonomy=post_tag' => 'https://wordpress.com/settings/taxonomies/post_tag/' . $this->domain ) );
189 }
190 }
191
192 /**
193 * Adds Media menu.
194 */
195 public function add_media_menu() {
196 if ( self::CLASSIC_VIEW === $this->get_preferred_view( 'upload.php' ) ) {
197 return;
198 }
199
200 $this->hide_submenu_page( 'upload.php', 'media-new.php' );
201
202 $this->update_menu( 'upload.php', 'https://wordpress.com/media/' . $this->domain );
203 }
204
205 /**
206 * Adds Page menu.
207 */
208 public function add_page_menu() {
209 if ( self::CLASSIC_VIEW === $this->get_preferred_view( 'edit.php?post_type=page' ) ) {
210 return;
211 }
212
213 $submenus_to_update = array(
214 'edit.php?post_type=page' => 'https://wordpress.com/pages/' . $this->domain,
215 'post-new.php?post_type=page' => 'https://wordpress.com/page/' . $this->domain,
216 );
217 $this->update_submenus( 'edit.php?post_type=page', $submenus_to_update );
218 }
219
220 /**
221 * Adds Testimonials menu.
222 */
223 public function add_testimonials_menu() {
224 $this->add_custom_post_type_menu( 'jetpack-testimonial' );
225 }
226
227 /**
228 * Adds Portfolio menu.
229 */
230 public function add_portfolio_menu() {
231 $this->add_custom_post_type_menu( 'jetpack-portfolio' );
232 }
233
234 /**
235 * Adds a custom post type menu.
236 *
237 * @param string $post_type Custom post type.
238 */
239 public function add_custom_post_type_menu( $post_type ) {
240 if ( self::CLASSIC_VIEW === $this->get_preferred_view( 'edit.php?post_type=' . $post_type ) ) {
241 return;
242 }
243
244 $submenus_to_update = array(
245 'edit.php?post_type=' . $post_type => 'https://wordpress.com/types/' . $post_type . '/' . $this->domain,
246 'post-new.php?post_type=' . $post_type => 'https://wordpress.com/edit/' . $post_type . '/' . $this->domain,
247 );
248 $this->update_submenus( 'edit.php?post_type=' . $post_type, $submenus_to_update );
249 }
250
251 /**
252 * Adds Comments menu.
253 */
254 public function add_comments_menu() {
255 if ( self::CLASSIC_VIEW === $this->get_preferred_view( 'edit-comments.php' ) ) {
256 return;
257 }
258
259 $this->update_menu( 'edit-comments.php', 'https://wordpress.com/comments/all/' . $this->domain );
260 }
261
262 /**
263 * Adds Appearance menu.
264 *
265 * @return string The Customizer URL.
266 */
267 public function add_appearance_menu() {
268 $request_uri = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
269 $default_customize_slug = add_query_arg( 'return', rawurlencode( remove_query_arg( wp_removable_query_args(), $request_uri ) ), 'customize.php' );
270 $default_customize_header_slug_1 = add_query_arg( array( 'autofocus' => array( 'control' => 'header_image' ) ), $default_customize_slug );
271 // TODO: Remove WPCom_Theme_Customizer::modify_header_menu_links() and WPcom_Custom_Header::modify_admin_menu_links().
272 $default_customize_header_slug_2 = admin_url( 'themes.php?page=custom-header' );
273 $default_customize_background_slug_1 = add_query_arg( array( 'autofocus' => array( 'control' => 'background_image' ) ), $default_customize_slug );
274 // TODO: Remove Colors_Manager::modify_header_menu_links() and Colors_Manager_Common::modify_header_menu_links().
275 $default_customize_background_slug_2 = add_query_arg( array( 'autofocus' => array( 'section' => 'colors_manager_tool' ) ), admin_url( 'customize.php' ) );
276
277 if ( $this->is_api_request ) {
278 // In case this is an api request we will have to add the 'return' querystring via JS.
279 $customize_url = 'customize.php';
280 } else {
281 $customize_url = $default_customize_slug;
282 }
283
284 $submenus_to_update = array(
285 $default_customize_slug => $customize_url,
286 $default_customize_header_slug_1 => add_query_arg( array( 'autofocus' => array( 'control' => 'header_image' ) ), $customize_url ),
287 $default_customize_header_slug_2 => add_query_arg( array( 'autofocus' => array( 'control' => 'header_image' ) ), $customize_url ),
288 $default_customize_background_slug_1 => add_query_arg( array( 'autofocus' => array( 'section' => 'colors_manager_tool' ) ), $customize_url ),
289 $default_customize_background_slug_2 => add_query_arg( array( 'autofocus' => array( 'section' => 'colors_manager_tool' ) ), $customize_url ),
290 );
291
292 if ( self::DEFAULT_VIEW === $this->get_preferred_view( 'themes.php' ) || self::CLASSIC_VIEW === $this->get_preferred_view( 'themes.php' ) ) {
293 $submenus_to_update['themes.php'] = 'https://wordpress.com/themes/' . $this->domain;
294 }
295
296 $this->update_submenus( 'themes.php', $submenus_to_update );
297
298 $this->hide_submenu_page( 'themes.php', 'custom-header' );
299 $this->hide_submenu_page( 'themes.php', 'custom-background' );
300
301 return $customize_url;
302 }
303
304 /**
305 * Adds Plugins menu.
306 */
307 public function add_plugins_menu() {
308 if ( self::CLASSIC_VIEW === $this->get_preferred_view( 'plugins.php' ) ) {
309 return;
310 }
311 $this->hide_submenu_page( 'plugins.php', 'plugin-install.php' );
312 $this->hide_submenu_page( 'plugins.php', 'plugin-editor.php' );
313
314 $this->update_menu( 'plugins.php', 'https://wordpress.com/plugins/' . $this->domain );
315 }
316
317 /**
318 * Adds Users menu.
319 */
320 public function add_users_menu() {
321 $submenus_to_update = array(
322 'profile.php' => 'https://wordpress.com/me',
323 );
324
325 if ( self::DEFAULT_VIEW === $this->get_preferred_view( 'users.php' ) ) {
326 $submenus_to_update['users.php'] = 'https://wordpress.com/people/team/' . $this->domain;
327 $submenus_to_update['user-new.php'] = 'https://wordpress.com/people/new/' . $this->domain;
328 }
329
330 $slug = current_user_can( 'list_users' ) ? 'users.php' : 'profile.php';
331 $this->update_submenus( $slug, $submenus_to_update );
332 add_submenu_page( $slug, esc_attr__( 'Account Settings', 'jetpack' ), __( 'Account Settings', 'jetpack' ), 'read', 'https://wordpress.com/me/account' );
333 }
334
335 /**
336 * Adds Tools menu.
337 */
338 public function add_tools_menu() {
339 $submenus_to_update = array();
340 if ( self::DEFAULT_VIEW === $this->get_preferred_view( 'import.php' ) ) {
341 $submenus_to_update['import.php'] = 'https://wordpress.com/import/' . $this->domain;
342 }
343 if ( self::DEFAULT_VIEW === $this->get_preferred_view( 'export.php' ) ) {
344 $submenus_to_update['export.php'] = 'https://wordpress.com/export/' . $this->domain;
345 }
346 $this->update_submenus( 'tools.php', $submenus_to_update );
347
348 $this->hide_submenu_page( 'tools.php', 'tools.php' );
349 $this->hide_submenu_page( 'tools.php', 'delete-blog' );
350
351 add_submenu_page( 'tools.php', esc_attr__( 'Marketing', 'jetpack' ), __( 'Marketing', 'jetpack' ), 'publish_posts', 'https://wordpress.com/marketing/tools/' . $this->domain, null, 0 );
352 add_submenu_page( 'tools.php', esc_attr__( 'Monetize', 'jetpack' ), __( 'Monetize', 'jetpack' ), 'manage_options', 'https://wordpress.com/earn/' . $this->domain, null, 1 );
353 }
354
355 /**
356 * Adds Settings menu.
357 */
358 public function add_options_menu() {
359 $submenus_to_update = array();
360
361 if ( self::DEFAULT_VIEW === $this->get_preferred_view( 'options-general.php' ) ) {
362 $this->hide_submenu_page( 'options-general.php', 'sharing' );
363 }
364
365 if ( self::DEFAULT_VIEW === $this->get_preferred_view( 'options-general.php' ) ) {
366 $submenus_to_update['options-general.php'] = 'https://wordpress.com/settings/general/' . $this->domain;
367 }
368
369 if ( self::DEFAULT_VIEW === $this->get_preferred_view( 'options-writing.php' ) ) {
370 $submenus_to_update['options-writing.php'] = 'https://wordpress.com/settings/writing/' . $this->domain;
371 }
372
373 if ( self::DEFAULT_VIEW === $this->get_preferred_view( 'options-reading.php' )
374 ) {
375 $submenus_to_update['options-reading.php'] = 'https://wordpress.com/settings/reading/' . $this->domain;
376 }
377
378 if ( self::DEFAULT_VIEW === $this->get_preferred_view( 'options-discussion.php' ) ) {
379 $submenus_to_update['options-discussion.php'] = 'https://wordpress.com/settings/discussion/' . $this->domain;
380 }
381
382 $this->update_submenus( 'options-general.php', $submenus_to_update );
383
384 add_submenu_page( 'options-general.php', esc_attr__( 'Newsletter', 'jetpack' ), __( 'Newsletter', 'jetpack' ), 'manage_options', 'https://wordpress.com/settings/newsletter/' . $this->domain, null, 7 );
385 add_submenu_page( 'options-general.php', esc_attr__( 'Podcasting', 'jetpack' ), __( 'Podcasting', 'jetpack' ), 'manage_options', 'https://wordpress.com/settings/podcasting/' . $this->domain, null, 8 );
386 add_submenu_page( 'options-general.php', esc_attr__( 'Performance', 'jetpack' ), __( 'Performance', 'jetpack' ), 'manage_options', 'https://wordpress.com/settings/performance/' . $this->domain, null, 9 );
387 }
388
389 /**
390 * Create Jetpack menu.
391 *
392 * @param int $position Menu position.
393 * @param bool $separator Whether to add a separator before the menu.
394 */
395 public function create_jetpack_menu( $position = 50, $separator = true ) {
396 if ( $separator ) {
397 $this->add_admin_menu_separator( $position, 'manage_options' );
398 ++$position;
399 }
400
401 $icon = ( new Logo() )->get_base64_logo();
402 $is_menu_updated = $this->update_menu( 'jetpack', null, null, null, $icon, $position );
403 if ( ! $is_menu_updated ) {
404 add_menu_page( esc_attr__( 'Jetpack', 'jetpack' ), __( 'Jetpack', 'jetpack' ), 'manage_options', 'jetpack', null, $icon, $position );
405 }
406
407 add_submenu_page( 'jetpack', esc_attr__( 'Activity Log', 'jetpack' ), __( 'Activity Log', 'jetpack' ), 'manage_options', 'https://wordpress.com/activity-log/' . $this->domain, null, 2 );
408 add_submenu_page( 'jetpack', esc_attr__( 'Backup', 'jetpack' ), __( 'Backup', 'jetpack' ), 'manage_options', 'https://wordpress.com/backup/' . $this->domain, null, 3 );
409
410 if ( self::DEFAULT_VIEW === $this->get_preferred_view( 'jetpack' ) ) {
411 $this->hide_submenu_page( 'jetpack', 'jetpack#/settings' );
412 $this->hide_submenu_page( 'jetpack', 'stats' );
413 $this->hide_submenu_page( 'jetpack', esc_url( Redirect::get_url( 'calypso-backups' ) ) );
414 $this->hide_submenu_page( 'jetpack', esc_url( Redirect::get_url( 'calypso-scanner' ) ) );
415 }
416
417 if ( ! $is_menu_updated ) {
418 // Remove the submenu auto-created by Core just to be sure that there no issues on non-admin roles.
419 remove_submenu_page( 'jetpack', 'jetpack' );
420 }
421 }
422
423 /**
424 * Adds Jetpack menu.
425 */
426 public function add_jetpack_menu() {
427 $this->create_jetpack_menu();
428 }
429
430 /**
431 * Add the calypso /woocommerce-installation/ menu item.
432 *
433 * @param array $current_plan The site's plan if they have one. This is passed from WPcom_Admin_Menu to prevent
434 * redundant database queries.
435 */
436 public function add_woocommerce_installation_menu( $current_plan = null ) {
437 /**
438 * Whether to show the WordPress.com WooCommerce Installation menu.
439 *
440 * @use add_filter( 'jetpack_show_wpcom_woocommerce_installation_menu', '__return_true' );
441 * @module masterbar
442 * @since 10.3.0
443 * @param bool $jetpack_show_wpcom_woocommerce_installation_menu Load the WordPress.com WooCommerce Installation menu item. Default to false.
444 * @param array $current_plan Data about the current site's plan.
445 */
446 if ( apply_filters( 'jetpack_show_wpcom_woocommerce_installation_menu', false, $current_plan ) ) {
447 $this->add_admin_menu_separator( 54, 'activate_plugins' );
448
449 $icon_url = 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDI0IDEwMjQiPjxwYXRoIGZpbGw9IiNhMmFhYjIiIGQ9Ik02MTIuMTkyIDQyNi4zMzZjMC02Ljg5Ni0zLjEzNi01MS42LTI4LTUxLjYtMzcuMzYgMC00Ni43MDQgNzIuMjU2LTQ2LjcwNCA4Mi42MjQgMCAzLjQwOCAzLjE1MiA1OC40OTYgMjguMDMyIDU4LjQ5NiAzNC4xOTItLjAzMiA0Ni42NzItNzIuMjg4IDQ2LjY3Mi04OS41MnptMjAyLjE5MiAwYzAtNi44OTYtMy4xNTItNTEuNi0yOC4wMzItNTEuNi0zNy4yOCAwLTQ2LjYwOCA3Mi4yNTYtNDYuNjA4IDgyLjYyNCAwIDMuNDA4IDMuMDcyIDU4LjQ5NiAyNy45NTIgNTguNDk2IDM0LjE5Mi0uMDMyIDQ2LjY4OC03Mi4yODggNDYuNjg4LTg5LjUyek0xNDEuMjk2Ljc2OGMtNjguMjI0IDAtMTIzLjUwNCA1NS40ODgtMTIzLjUwNCAxMjMuOTJ2NjUwLjcyYzAgNjguNDMyIDU1LjI5NiAxMjMuOTIgMTIzLjUwNCAxMjMuOTJoMzM5LjgwOGwxMjMuNTA0IDEyMy45MzZWODk5LjMyOGgyNzguMDQ4YzY4LjIyNCAwIDEyMy41Mi01NS40NzIgMTIzLjUyLTEyMy45MnYtNjUwLjcyYzAtNjguNDMyLTU1LjI5Ni0xMjMuOTItMTIzLjUyLTEyMy45MmgtNzQxLjM2em01MjYuODY0IDQyMi4xNmMwIDU1LjA4OC0zMS4wODggMTU0Ljg4LTEwMi42NCAxNTQuODgtNi4yMDggMC0xOC40OTYtMy42MTYtMjUuNDI0LTYuMDE2LTMyLjUxMi0xMS4xNjgtNTAuMTkyLTQ5LjY5Ni01Mi4zNTItNjYuMjU2IDAgMC0zLjA3Mi0xNy43OTItMy4wNzItNDAuNzUyIDAtMjIuOTkyIDMuMDcyLTQ1LjMyOCAzLjA3Mi00NS4zMjggMTUuNTUyLTc1LjcyOCA0My41NTItMTA2LjczNiA5Ni40NDgtMTA2LjczNiA1OS4wNzItLjAzMiA4My45NjggNTguNTI4IDgzLjk2OCAxMTAuMjA4ek00ODYuNDk2IDMwMi40YzAgMy4zOTItNDMuNTUyIDE0MS4xNjgtNDMuNTUyIDIxMy40MjR2NzUuNzEyYy0yLjU5MiAxMi4wOC00LjE2IDI0LjE0NC0yMS44MjQgMjQuMTQ0LTQ2LjYwOCAwLTg4Ljg4LTE1MS40NzItOTIuMDE2LTE2MS44NC02LjIwOCA2Ljg5Ni02Mi4yNCAxNjEuODQtOTYuNDQ4IDE2MS44NC0yNC44NjQgMC00My41NTItMTEzLjY0OC00Ni42MDgtMTIzLjkzNkMxNzYuNzA0IDQzNi42NzIgMTYwIDMzNC4yMjQgMTYwIDMyNy4zMjhjMC0yMC42NzIgMS4xNTItMzguNzM2IDI2LjA0OC0zOC43MzYgNi4yMDggMCAyMS42IDYuMDY0IDIzLjcxMiAxNy4xNjggMTEuNjQ4IDYyLjAzMiAxNi42ODggMTIwLjUxMiAyOS4xNjggMTg1Ljk2OCAxLjg1NiAyLjkyOCAxLjUwNCA3LjAwOCA0LjU2IDEwLjQzMiAzLjE1Mi0xMC4yODggNjYuOTI4LTE2OC43ODQgOTQuOTYtMTY4Ljc4NCAyMi41NDQgMCAzMC40IDQ0LjU5MiAzMy41MzYgNjEuODI0IDYuMjA4IDIwLjY1NiAxMy4wODggNTUuMjE2IDIyLjQxNiA4Mi43NTIgMC0xMy43NzYgMTIuNDgtMjAzLjEyIDY1LjM5Mi0yMDMuMTIgMTguNTkyLjAzMiAyNi43MDQgNi45MjggMjYuNzA0IDI3LjU2OHpNODcwLjMyIDQyMi45MjhjMCA1NS4wODgtMzEuMDg4IDE1NC44OC0xMDIuNjQgMTU0Ljg4LTYuMTkyIDAtMTguNDQ4LTMuNjE2LTI1LjQyNC02LjAxNi0zMi40MzItMTEuMTY4LTUwLjE3Ni00OS42OTYtNTIuMjg4LTY2LjI1NiAwIDAtMy44ODgtMTcuOTItMy44ODgtNDAuODk2czMuODg4LTQ1LjE4NCAzLjg4OC00NS4xODRjMTUuNTUyLTc1LjcyOCA0My40ODgtMTA2LjczNiA5Ni4zODQtMTA2LjczNiA1OS4xMDQtLjAzMiA4My45NjggNTguNTI4IDgzLjk2OCAxMTAuMjA4eiIvPjwvc3ZnPg==';
450 $menu_url = 'https://wordpress.com/woocommerce-installation/' . $this->domain;
451
452 // Only show the menu if the user has the capability to activate_plugins.
453 add_menu_page( esc_attr__( 'WooCommerce', 'jetpack' ), esc_attr__( 'WooCommerce', 'jetpack' ), 'activate_plugins', $menu_url, null, $icon_url, 55 );
454 }
455 }
456
457 /**
458 * AJAX handler for retrieving the upsell nudge.
459 */
460 public function wp_ajax_upsell_nudge_jitm() {
461 check_ajax_referer( 'upsell_nudge_jitm' );
462
463 $nudge = $this->get_upsell_nudge();
464 if ( ! $nudge ) {
465 wp_die();
466 }
467
468 $link = $nudge['link'];
469 if ( str_starts_with( $link, '/' ) ) {
470 $link = 'https://wordpress.com' . $link;
471 }
472 ?>
473 <li class="wp-not-current-submenu menu-top menu-icon-generic toplevel_page_site-notices" id="toplevel_page_site-notices">
474 <a href="<?php echo esc_url( $link ); ?>" class="wp-not-current-submenu menu-top menu-icon-generic toplevel_page_site-notices">
475 <div class="wp-menu-arrow">
476 <div></div>
477 </div>
478 <div class="wp-menu-image dashicons-before dashicons-admin-generic" aria-hidden="true"><br></div>
479 <div class="wp-menu-name">
480 <div class="upsell_banner">
481 <div class="banner__info">
482 <div class="banner__title">
483 <?php echo wp_kses( $nudge['content'], array() ); ?>
484 </div>
485 </div>
486 <div class="banner__action">
487 <button type="button" class="button">
488 <?php echo wp_kses( $nudge['cta'], array() ); ?>
489 </button>
490 </div>
491 <?php if ( $nudge['dismissible'] ) : ?>
492 <svg xmlns="http://www.w3.org/2000/svg" data-feature_class="<?php echo esc_attr( $nudge['feature_class'] ); ?>" data-feature_id="<?php echo esc_attr( $nudge['id'] ); ?>" viewBox="0 0 24 24" class="gridicon gridicons-cross dismissible-card__close-icon" height="24" width="24"><g><path d="M18.36 19.78L12 13.41l-6.36 6.37-1.42-1.42L10.59 12 4.22 5.64l1.42-1.42L12 10.59l6.36-6.36 1.41 1.41L13.41 12l6.36 6.36z"></path></g></svg>
493 <?php endif; ?>
494 </div>
495 </div>
496 </a>
497 </li>
498 <?php
499 wp_die();
500 }
501
502 /**
503 * Returns the first available upsell nudge.
504 * Needs to be implemented separately for each child menu class.
505 * Empty by default.
506 *
507 * @return array
508 */
509 public function get_upsell_nudge() {
510 return array();
511 }
512 }
513