Completed
Push — fix/sso_atomic_users ( 866d56...9ebcb8 )
by
unknown
10:04
created

Admin_Menu::add_gutenberg_menus()   A

Complexity

Conditions 5
Paths 3

Size

Total Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
nc 3
nop 1
dl 0
loc 23
rs 9.2408
c 0
b 0
f 0
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\Redirect;
11
use Automattic\Jetpack\Status;
12
13
/**
14
 * Class Admin_Menu.
15
 */
16
class Admin_Menu {
17
	/**
18
	 * Holds class instances.
19
	 *
20
	 * @var array
21
	 */
22
	protected static $instances;
23
24
	/**
25
	 * Whether the current request is a REST API request.
26
	 *
27
	 * @var bool
28
	 */
29
	protected $is_api_request = false;
30
31
	/**
32
	 * Domain of the current site.
33
	 *
34
	 * @var string
35
	 */
36
	protected $domain;
37
38
	/**
39
	 * Admin_Menu constructor.
40
	 */
41
	protected function __construct() {
42
		add_action( 'admin_menu', array( $this, 'reregister_menu_items' ), 99999 );
43
		add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
44
		add_action( 'wp_enqueue_scripts', array( $this, 'dequeue_scripts' ), 20 );
45
		add_action( 'admin_enqueue_scripts', array( $this, 'dequeue_scripts' ), 20 );
46
		add_filter( 'rest_request_before_callbacks', array( $this, 'rest_api_init' ), 11 );
47
48
		$this->domain = ( new Status() )->get_site_suffix();
49
	}
50
51
	/**
52
	 * Returns class instance.
53
	 *
54
	 * @return Admin_Menu
55
	 */
56
	public static function get_instance() {
57
		$class = get_called_class();
58
59
		if ( empty( static::$instances[ $class ] ) ) {
60
			static::$instances[ $class ] = new $class();
61
		}
62
63
		return static::$instances[ $class ];
64
	}
65
66
	/**
67
	 * Sets up class properties for REST API requests.
68
	 *
69
	 * @param WP_REST_Response $response Response from the endpoint.
70
	 */
71
	public function rest_api_init( $response ) {
72
		$this->is_api_request = true;
73
74
		return $response;
75
	}
76
77
	/**
78
	 * Create the desired menu output.
79
	 */
80
	public function reregister_menu_items() {
81
		// Constant is not defined until parse_request.
82
		if ( ! $this->is_api_request ) {
83
			$this->is_api_request = defined( 'REST_REQUEST' ) && REST_REQUEST;
84
		}
85
86
		/*
87
		 * Whether links should point to Calypso or wp-admin.
88
		 *
89
		 * Options:
90
		 * false - Calypso (Default).
91
		 * true  - wp-admin.
92
		 */
93
		$wp_admin = $this->should_link_to_wp_admin();
94
95
		// Remove separators.
96
		remove_menu_page( 'separator1' );
97
98
		$this->add_stats_menu();
99
		$this->add_upgrades_menu();
100
		$this->add_posts_menu( $wp_admin );
101
		$this->add_media_menu( $wp_admin );
102
		$this->add_page_menu( $wp_admin );
103
		$this->add_testimonials_menu( $wp_admin );
104
		$this->add_portfolio_menu( $wp_admin );
105
		$this->add_comments_menu( $wp_admin );
106
107
		// Whether Themes/Customize links should point to Calypso (false) or wp-admin (true).
108
		$wp_admin_themes    = $wp_admin;
109
		$wp_admin_customize = $wp_admin;
110
		$this->add_appearance_menu( $wp_admin_themes, $wp_admin_customize );
111
		$this->add_plugins_menu( $wp_admin );
112
		$this->add_users_menu( $wp_admin );
113
114
		// Whether Import/Export links should point to Calypso (false) or wp-admin (true).
115
		$wp_admin_import = $wp_admin;
116
		$wp_admin_export = $wp_admin;
117
		$this->add_tools_menu( $wp_admin_import, $wp_admin_export );
118
119
		$this->add_options_menu( $wp_admin );
120
		$this->add_jetpack_menu();
121
		$this->add_gutenberg_menus( $wp_admin );
122
123
		// Remove Links Manager menu since its usage is discouraged.
124
		// @see https://core.trac.wordpress.org/ticket/21307#comment:73.
125
		remove_menu_page( 'link-manager.php' );
126
127
		ksort( $GLOBALS['menu'] );
128
	}
129
130
	/**
131
	 * Adds My Home menu.
132
	 */
133
	public function add_my_home_menu() {
134
		$this->update_menu( 'index.php', 'https://wordpress.com/home/' . $this->domain, __( 'My Home', 'jetpack' ), 'manage_options', 'dashicons-admin-home' );
135
	}
136
137
	/**
138
	 * Adds Stats menu.
139
	 */
140
	public function add_stats_menu() {
141
		add_menu_page( __( 'Stats', 'jetpack' ), __( 'Stats', 'jetpack' ), 'view_stats', 'https://wordpress.com/stats/day/' . $this->domain, null, 'dashicons-chart-bar', 3 );
142
	}
143
144
	/**
145
	 * Adds Upgrades menu.
146
	 */
147
	public function add_upgrades_menu() {
148
		global $menu;
149
150
		$menu_exists = false;
151
		foreach ( $menu as $item ) {
152
			if ( 'paid-upgrades.php' === $item[2] ) {
153
				$menu_exists = true;
154
				break;
155
			}
156
		}
157
158
		if ( ! $menu_exists ) {
159
			add_menu_page( __( 'Upgrades', 'jetpack' ), __( 'Upgrades', 'jetpack' ), '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, 5 );
163
		add_submenu_page( 'paid-upgrades.php', __( 'Purchases', 'jetpack' ), __( 'Purchases', 'jetpack' ), 'manage_options', 'https://wordpress.com/purchases/subscriptions/' . $this->domain, null, 15 );
164
165
		if ( ! $menu_exists ) {
166
			// Remove the submenu auto-created by Core.
167
			remove_submenu_page( 'paid-upgrades.php', 'paid-upgrades.php' );
168
		}
169
	}
170
171
	/**
172
	 * Adds Posts menu.
173
	 *
174
	 * @param bool $wp_admin Optional. Whether links should point to Calypso or wp-admin. Default false (Calypso).
175
	 */
176 View Code Duplication
	public function add_posts_menu( $wp_admin = false ) {
177
		if ( $wp_admin ) {
178
			return;
179
		}
180
181
		$submenus_to_update = array(
182
			'edit.php'     => 'https://wordpress.com/posts/' . $this->domain,
183
			'post-new.php' => 'https://wordpress.com/post/' . $this->domain,
184
		);
185
		$this->update_submenus( 'edit.php', $submenus_to_update );
186
	}
187
188
	/**
189
	 * Adds Media menu.
190
	 *
191
	 * @param bool $wp_admin Optional. Whether links should point to Calypso or wp-admin. Default false (Calypso).
192
	 */
193
	public function add_media_menu( $wp_admin = false ) {
194
		if ( $wp_admin ) {
195
			return;
196
		}
197
198
		remove_submenu_page( 'upload.php', 'media-new.php' );
199
200
		$this->update_menu( 'upload.php', 'https://wordpress.com/media/' . $this->domain );
201
	}
202
203
	/**
204
	 * Adds Page menu.
205
	 *
206
	 * @param bool $wp_admin Optional. Whether links should point to Calypso or wp-admin. Default false (Calypso).
207
	 */
208 View Code Duplication
	public function add_page_menu( $wp_admin = false ) {
209
		if ( $wp_admin ) {
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
	 * @param bool $wp_admin Optional. Whether links should point to Calypso or wp-admin. Default false (Calypso).
224
	 */
225
	public function add_testimonials_menu( $wp_admin = false ) {
226
		$this->add_custom_post_type_menu( 'jetpack-testimonial', $wp_admin );
227
	}
228
229
	/**
230
	 * Adds Portfolio menu.
231
	 *
232
	 * @param bool $wp_admin Optional. Whether links should point to Calypso or wp-admin. Default false (Calypso).
233
	 */
234
	public function add_portfolio_menu( $wp_admin = false ) {
235
		$this->add_custom_post_type_menu( 'jetpack-portfolio', $wp_admin );
236
	}
237
238
	/**
239
	 * Adds a custom post type menu.
240
	 *
241
	 * @param string $post_type Custom post type.
242
	 * @param bool   $wp_admin Optional. Whether links should point to Calypso or wp-admin. Default false (Calypso).
243
	 */
244
	public function add_custom_post_type_menu( $post_type, $wp_admin = false ) {
245
		if ( $wp_admin ) {
246
			return;
247
		}
248
249
		$submenus_to_update = array(
250
			'edit.php?post_type=' . $post_type     => 'https://wordpress.com/types/' . $post_type . '/' . $this->domain,
251
			'post-new.php?post_type=' . $post_type => 'https://wordpress.com/edit/' . $post_type . '/' . $this->domain,
252
		);
253
		$this->update_submenus( 'edit.php?post_type=' . $post_type, $submenus_to_update );
254
	}
255
256
	/**
257
	 * Adds Comments menu.
258
	 *
259
	 * @param bool $wp_admin Optional. Whether links should point to Calypso or wp-admin. Default false (Calypso).
260
	 */
261
	public function add_comments_menu( $wp_admin = false ) {
262
		if ( $wp_admin ) {
263
			return;
264
		}
265
266
		$this->update_menu( 'edit-comments.php', 'https://wordpress.com/comments/all/' . $this->domain );
267
	}
268
269
	/**
270
	 * Adds Appearance menu.
271
	 *
272
	 * @param bool $wp_admin_themes Optional. Whether Themes link should point to Calypso or wp-admin. Default false (Calypso).
273
	 * @param bool $wp_admin_customize Optional. Whether Customize link should point to Calypso or wp-admin. Default false (Calypso).
274
	 * @return string The Customizer URL.
275
	 */
276
	public function add_appearance_menu( $wp_admin_themes = false, $wp_admin_customize = false ) {
277
		$request_uri                     = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
278
		$default_customize_slug          = add_query_arg( 'return', rawurlencode( remove_query_arg( wp_removable_query_args(), $request_uri ) ), 'customize.php' );
279
		$default_customize_header_slug_1 = add_query_arg( array( 'autofocus' => array( 'control' => 'header_image' ) ), $default_customize_slug );
280
		// TODO: Remove WPCom_Theme_Customizer::modify_header_menu_links() and WPcom_Custom_Header::modify_admin_menu_links().
281
		$default_customize_header_slug_2     = admin_url( 'themes.php?page=custom-header' );
282
		$default_customize_background_slug_1 = add_query_arg( array( 'autofocus' => array( 'control' => 'background_image' ) ), $default_customize_slug );
283
		// TODO: Remove Colors_Manager::modify_header_menu_links() and Colors_Manager_Common::modify_header_menu_links().
284
		$default_customize_background_slug_2 = add_query_arg( array( 'autofocus' => array( 'section' => 'colors_manager_tool' ) ), admin_url( 'customize.php' ) );
285
286
		if ( ! $wp_admin_customize ) {
287
			$customize_url = 'https://wordpress.com/customize/' . $this->domain;
288
		} elseif ( $this->is_api_request ) {
289
			// In case this is an api request we will have to add the 'return' querystring via JS.
290
			$customize_url = 'customize.php';
291
		} else {
292
			$customize_url = $default_customize_slug;
293
		}
294
295
		$submenus_to_update = array(
296
			$default_customize_slug              => $customize_url,
297
			$default_customize_header_slug_1     => add_query_arg( array( 'autofocus' => array( 'control' => 'header_image' ) ), $customize_url ),
298
			$default_customize_header_slug_2     => add_query_arg( array( 'autofocus' => array( 'control' => 'header_image' ) ), $customize_url ),
299
			$default_customize_background_slug_1 => add_query_arg( array( 'autofocus' => array( 'section' => 'colors_manager_tool' ) ), $customize_url ),
300
			$default_customize_background_slug_2 => add_query_arg( array( 'autofocus' => array( 'section' => 'colors_manager_tool' ) ), $customize_url ),
301
		);
302
303
		if ( ! $wp_admin_themes ) {
304
			$submenus_to_update['themes.php'] = 'https://wordpress.com/themes/' . $this->domain;
305
		}
306
307
		if ( ! $wp_admin_customize ) {
308
			$submenus_to_update['widgets.php']       = add_query_arg( array( 'autofocus' => array( 'panel' => 'widgets' ) ), $customize_url );
309
			$submenus_to_update['gutenberg-widgets'] = add_query_arg( array( 'autofocus' => array( 'panel' => 'widgets' ) ), $customize_url );
310
			$submenus_to_update['nav-menus.php']     = add_query_arg( array( 'autofocus' => array( 'panel' => 'nav_menus' ) ), $customize_url );
311
		}
312
313
		$this->update_submenus( 'themes.php', $submenus_to_update );
314
315
		remove_submenu_page( 'themes.php', 'custom-header' );
316
		remove_submenu_page( 'themes.php', 'custom-background' );
317
318
		return $customize_url;
319
	}
320
321
	/**
322
	 * Adds Plugins menu.
323
	 *
324
	 * @param bool $wp_admin Optional. Whether links should point to Calypso or wp-admin. Default false (Calypso).
325
	 */
326
	public function add_plugins_menu( $wp_admin = false ) {
327
		if ( $wp_admin ) {
328
			return;
329
		}
330
331
		remove_submenu_page( 'plugins.php', 'plugin-install.php' );
332
		remove_submenu_page( 'plugins.php', 'plugin-editor.php' );
333
334
		$this->update_menu( 'plugins.php', 'https://wordpress.com/plugins/' . $this->domain );
335
	}
336
337
	/**
338
	 * Adds Users menu.
339
	 *
340
	 * @param bool $wp_admin Optional. Whether links should point to Calypso or wp-admin. Default false (Calypso).
341
	 */
342
	public function add_users_menu( $wp_admin = false ) {
343
		if ( current_user_can( 'list_users' ) ) {
344
			// We shall add the Calypso user management & add new user screens at all cases ( Calypso & Atomic ).
345
			$submenus_to_update = array(
346
				'user-new.php' => 'https://wordpress.com/people/new/' . $this->domain,
347
				'users.php'    => 'https://wordpress.com/people/team/' . $this->domain,
348
			);
349
			if ( ! $wp_admin ) {
350
				$submenus_to_update = array_merge( $submenus_to_update, array( 'profile.php' => 'https://wordpress.com/me' ) );
351
			}
352
			$this->update_submenus( 'users.php', $submenus_to_update );
353
			add_submenu_page( 'users.php', esc_attr__( 'Account Settings', 'jetpack' ), __( 'Account Settings', 'jetpack' ), 'read', 'https://wordpress.com/me/account' );
354
		} else {
355
			if ( ! $wp_admin ) {
356
				$submenus_to_update = array(
357
					'user-new.php' => 'https://wordpress.com/people/new/' . $this->domain,
358
					'profile.php'  => 'https://wordpress.com/me',
359
				);
360
				$this->update_submenus( 'profile.php', $submenus_to_update );
361
			}
362
363
			add_submenu_page( 'profile.php', esc_attr__( 'Account Settings', 'jetpack' ), __( 'Account Settings', 'jetpack' ), 'read', 'https://wordpress.com/me/account' );
364
		}
365
	}
366
367
	/**
368
	 * Adds Tools menu.
369
	 *
370
	 * @param bool $wp_admin_import Optional. Whether Import link should point to Calypso or wp-admin. Default false (Calypso).
371
	 * @param bool $wp_admin_export Optional. Whether Export link should point to Calypso or wp-admin. Default false (Calypso).
372
	 */
373
	public function add_tools_menu( $wp_admin_import = false, $wp_admin_export = false ) {
374
		$submenus_to_update = array();
375
		if ( ! $wp_admin_import ) {
376
			$submenus_to_update['import.php'] = 'https://wordpress.com/import/' . $this->domain;
377
		}
378
		if ( ! $wp_admin_export ) {
379
			$submenus_to_update['export.php'] = 'https://wordpress.com/export/' . $this->domain;
380
		}
381
		$this->update_submenus( 'tools.php', $submenus_to_update );
382
383
		remove_submenu_page( 'tools.php', 'tools.php' );
384
		remove_submenu_page( 'tools.php', 'delete-blog' );
385
386
		add_submenu_page( 'tools.php', esc_attr__( 'Marketing', 'jetpack' ), __( 'Marketing', 'jetpack' ), 'publish_posts', 'https://wordpress.com/marketing/tools/' . $this->domain, null, 0 );
387
		add_submenu_page( 'tools.php', esc_attr__( 'Earn', 'jetpack' ), __( 'Earn', 'jetpack' ), 'manage_options', 'https://wordpress.com/earn/' . $this->domain, null, 1 );
388
	}
389
390
	/**
391
	 * Adds Settings menu.
392
	 *
393
	 * @param bool $wp_admin Optional. Whether links should point to Calypso or wp-admin. Default false (Calypso).
394
	 */
395
	public function add_options_menu( $wp_admin = false ) {
396
		if ( $wp_admin ) {
397
			return;
398
		}
399
400
		$this->update_submenus( 'options-general.php', array( 'options-general.php' => 'https://wordpress.com/settings/general/' . $this->domain ) );
401
402
		remove_submenu_page( 'options-general.php', 'options-discussion.php' );
403
		remove_submenu_page( 'options-general.php', 'options-writing.php' );
404
	}
405
406
	/**
407
	 * Adds Jetpack menu.
408
	 */
409
	public function add_jetpack_menu() {
410
		global $menu;
411
412
		$position = 50;
413
		while ( isset( $menu[ $position ] ) ) {
414
			$position++;
415
		}
416
		$this->add_admin_menu_separator( $position++, 'manage_options' );
417
418
		// TODO: Replace with proper SVG data url.
419
		$icon = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 32 32' %3E%3Cpath fill='%23a0a5aa' d='M16,0C7.2,0,0,7.2,0,16s7.2,16,16,16s16-7.2,16-16S24.8,0,16,0z'%3E%3C/path%3E%3Cpolygon fill='%23fff' points='15,19 7,19 15,3 '%3E%3C/polygon%3E%3Cpolygon fill='%23fff' points='17,29 17,13 25,13 '%3E%3C/polygon%3E%3C/svg%3E";
420
421
		$is_menu_updated = $this->update_menu( 'jetpack', null, null, null, $icon, $position );
422
		if ( ! $is_menu_updated ) {
423
			add_menu_page( esc_attr__( 'Jetpack', 'jetpack' ), __( 'Jetpack', 'jetpack' ), 'manage_options', 'jetpack', null, $icon, $position );
424
		}
425
426
		add_submenu_page( 'jetpack', esc_attr__( 'Activity Log', 'jetpack' ), __( 'Activity Log', 'jetpack' ), 'manage_options', 'https://wordpress.com/activity-log/' . $this->domain, null, 2 );
427
		add_submenu_page( 'jetpack', esc_attr__( 'Backup', 'jetpack' ), __( 'Backup', 'jetpack' ), 'manage_options', 'https://wordpress.com/backup/' . $this->domain, null, 3 );
428
		/* translators: Jetpack sidebar menu item. */
429
		add_submenu_page( 'jetpack', esc_attr__( 'Search', 'jetpack' ), __( 'Search', 'jetpack' ), 'read', 'https://wordpress.com/jetpack-search/' . $this->domain, null, 4 );
430
431
		remove_submenu_page( 'jetpack', 'stats' );
432
		remove_submenu_page( 'jetpack', esc_url( Redirect::get_url( 'calypso-backups' ) ) );
433
		remove_submenu_page( 'jetpack', esc_url( Redirect::get_url( 'calypso-scanner' ) ) );
434
435
		if ( ! $is_menu_updated ) {
436
			// Remove the submenu auto-created by Core.
437
			remove_submenu_page( 'jetpack', 'jetpack' );
438
		}
439
	}
440
441
	/**
442
	 * Re-adds the Site Editor menu without the (beta) tag, and where we want it.
443
	 *
444
	 * @param bool $wp_admin Optional. Whether links should point to Calypso or wp-admin. Default false (Calypso).
445
	 */
446
	public function add_gutenberg_menus( $wp_admin = false ) {
447
		// We can bail if we don't meet the conditions of the Site Editor.
448
		if ( ! ( function_exists( 'gutenberg_is_fse_theme' ) && gutenberg_is_fse_theme() ) ) {
449
			return;
450
		}
451
452
		// Core Gutenberg registers without an explicit position, and we don't want the (beta) tag.
453
		remove_menu_page( 'gutenberg-edit-site' );
454
		// Core Gutenberg tries to manage its position, foiling our best laid plans. Unfoil.
455
		remove_filter( 'menu_order', 'gutenberg_menu_order' );
456
457
		$link = $wp_admin ? 'gutenberg-edit-site' : 'https://wordpress.com/site-editor/' . $this->domain;
458
459
		add_menu_page(
460
			__( 'Site Editor', 'jetpack' ),
461
			__( 'Site Editor', 'jetpack' ),
462
			'edit_theme_options',
463
			$link,
464
			$wp_admin ? 'gutenberg_edit_site_page' : null,
465
			'dashicons-layout',
466
			61 // Just under Appearance.
467
		);
468
	}
469
470
	/**
471
	 * Updates the menu data of the given menu slug.
472
	 *
473
	 * @param string $slug Slug of the menu to update.
474
	 * @param string $url New menu URL.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $url not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
475
	 * @param string $title New menu title.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $title not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
476
	 * @param string $cap New menu capability.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $cap not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
477
	 * @param string $icon New menu icon.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $icon not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
478
	 * @param int    $position New menu position.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $position not be integer|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
479
	 * @return bool Whether the menu has been updated.
480
	 */
481
	public function update_menu( $slug, $url = null, $title = null, $cap = null, $icon = null, $position = null ) {
482
		global $menu, $submenu;
483
484
		$menu_item     = null;
485
		$menu_position = null;
486
487
		foreach ( $menu as $i => $item ) {
488
			if ( $slug === $item[2] ) {
489
				$menu_item     = $item;
490
				$menu_position = $i;
491
				break;
492
			}
493
		}
494
495
		if ( ! $menu_item ) {
496
			return false;
497
		}
498
499
		if ( $title ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $title of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
500
			$menu_item[0] = $title;
501
			$menu_item[3] = esc_attr( $title );
502
		}
503
504
		if ( $cap ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $cap of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
505
			$menu_item[1] = $cap;
506
		}
507
508
		// Change parent slug only if there are no submenus (the slug of the 1st submenu will be used if there are submenus).
509
		if ( $url ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $url of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
510
			remove_submenu_page( $slug, $slug );
511
			if ( empty( $submenu[ $slug ] ) ) {
512
				$menu_item[2] = $url;
513
			}
514
		}
515
516
		if ( $icon ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $icon of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
517
			$menu_item[4] = 'menu-top';
518
			$menu_item[6] = $icon;
519
		}
520
521
		if ( $position ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $position of type integer|null is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
522
			// phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
523
			unset( $menu[ $menu_position ] );
524
			$menu_position = $position;
525
		}
526
		// phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
527
		$menu[ $menu_position ] = $menu_item;
528
529
		// Only add submenu when there are other submenu items.
530
		if ( $url && ! empty( $submenu[ $slug ] ) ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $url of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
531
			add_submenu_page( $slug, $menu_item[3], $menu_item[0], $menu_item[1], $url, null, 0 );
532
		}
533
534
		return true;
535
	}
536
537
	/**
538
	 * Updates the submenus of the given menu slug.
539
	 *
540
	 * @param string $slug Menu slug.
541
	 * @param array  $submenus_to_update Array of new submenu slugs.
542
	 */
543
	public function update_submenus( $slug, $submenus_to_update ) {
544
		global $submenu;
545
546
		if ( ! isset( $submenu[ $slug ] ) ) {
547
			return;
548
		}
549
550
		foreach ( $submenu[ $slug ] as $i => $submenu_item ) {
551
			if ( array_key_exists( $submenu_item[2], $submenus_to_update ) ) {
552
				$submenu_item[2] = $submenus_to_update[ $submenu_item[2] ];
553
				// phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
554
				$submenu[ $slug ][ $i ] = $submenu_item;
555
			}
556
		}
557
	}
558
559
	/**
560
	 * Remove submenu items from given menu slug.
561
	 *
562
	 * @param string $slug Menu slug.
563
	 */
564
	public function remove_submenus( $slug ) {
565
		global $submenu;
566
567
		if ( isset( $submenu[ $slug ] ) ) {
568
			// phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
569
			$submenu[ $slug ] = array();
570
		}
571
	}
572
573
	/**
574
	 * Adds a menu separator.
575
	 *
576
	 * @param int    $position The position in the menu order this item should appear.
577
	 * @param string $cap Optional. The capability required for this menu to be displayed to the user.
578
	 *                         Default: 'read'.
579
	 */
580
	public function add_admin_menu_separator( $position, $cap = 'read' ) {
581
		global $menu;
582
583
		// phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
584
		$menu[ $position ] = array(
585
			'',                                  // Menu title (ignored).
586
			$cap,                                // Required capability.
587
			wp_unique_id( 'separator-custom-' ), // URL or file (ignored, but must be unique).
588
			'',                                  // Page title (ignored).
589
			'wp-menu-separator',                 // CSS class. Identifies this item as a separator.
590
		);
591
		ksort( $menu );
592
	}
593
594
	/**
595
	 * Enqueues scripts and styles.
596
	 */
597
	public function enqueue_scripts() {
598
		$style_dependencies = array();
0 ignored issues
show
Unused Code introduced by
$style_dependencies is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
599
		$rtl                = is_rtl() ? '-rtl' : '';
600 View Code Duplication
		if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
601
			$style_dependencies = array( 'wpcom-admin-bar', 'wpcom-masterbar-css' );
602
		} else {
603
			$style_dependencies = array( 'a8c-wpcom-masterbar' . $rtl, 'a8c-wpcom-masterbar-overrides' . $rtl );
604
		}
605
		wp_enqueue_style(
606
			'jetpack-admin-menu',
607
			plugins_url( 'admin-menu.css', __FILE__ ),
608
			$style_dependencies,
609
			JETPACK__VERSION
610
		);
611
		wp_enqueue_script(
612
			'jetpack-admin-menu',
613
			plugins_url( 'admin-menu.js', __FILE__ ),
614
			array(),
615
			JETPACK__VERSION,
616
			true
617
		);
618
	}
619
620
	/**
621
	 * Dequeues unnecessary scripts.
622
	 */
623
	public function dequeue_scripts() {
624
		wp_dequeue_script( 'a8c_wpcom_masterbar_overrides' ); // Initially loaded in modules/masterbar/masterbar/class-masterbar.php.
625
	}
626
627
	/**
628
	 * Whether to use wp-admin pages rather than Calypso.
629
	 *
630
	 * @return bool
631
	 */
632
	public function should_link_to_wp_admin() {
633
		return get_user_option( 'jetpack_admin_menu_link_destination' );
634
	}
635
}
636