Masterbar::add_my_sites_submenu()   F
last analyzed

Complexity

Conditions 31
Paths > 20000

Size

Total Lines 554

Duplication

Lines 94
Ratio 16.97 %

Importance

Changes 0
Metric Value
cc 31
nc 1410052
nop 1
dl 94
loc 554
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Masterbar file.
4
 *
5
 * @package automattic/jetpack
6
 */
7
8
namespace Automattic\Jetpack\Dashboard_Customizations;
9
10
use Automattic\Jetpack\Assets;
11
use Automattic\Jetpack\Connection\Manager as Connection_Manager;
12
use Automattic\Jetpack\Device_Detection\User_Agent_Info;
13
use Automattic\Jetpack\Redirect;
14
use Automattic\Jetpack\Scan\Admin_Bar_Notice;
15
use Automattic\Jetpack\Status;
16
use GP_Locale;
17
use GP_Locales;
18
use Jetpack;
19
use Jetpack_AMP_Support;
20
use Jetpack_Plan;
21
use WP_Admin_Bar;
22
23
/**
24
 * Provides custom admin bar instead of the default WordPress admin bar.
25
 */
26
class Masterbar {
27
	/**
28
	 * Use for testing changes made to remotely enqueued scripts and styles on your sandbox.
29
	 * If not set it will default to loading the ones from WordPress.com.
30
	 *
31
	 * @var string $sandbox_url
32
	 */
33
	private $sandbox_url = '';
34
35
	/**
36
	 * Current locale.
37
	 *
38
	 * @var string
39
	 */
40
	private $locale;
41
42
	/**
43
	 * WordPress.com user locale of the connected user.
44
	 *
45
	 * @var string
46
	 */
47
	private $user_locale;
48
49
	/**
50
	 * Current User ID.
51
	 *
52
	 * @var int
53
	 */
54
	private $user_id;
55
	/**
56
	 * WordPress.com user data of the connected user.
57
	 *
58
	 * @var array
59
	 */
60
	private $user_data;
61
	/**
62
	 * WordPress.com username for the connected user.
63
	 *
64
	 * @var string
65
	 */
66
	private $user_login;
67
	/**
68
	 * WordPress.com email address for the connected user.
69
	 *
70
	 * @var string
71
	 */
72
	private $user_email;
73
	/**
74
	 * WordPress.com display name for the connected user.
75
	 *
76
	 * @var string
77
	 */
78
	private $display_name;
79
	/**
80
	 * Site URL sanitized for usage in WordPress.com slugs.
81
	 *
82
	 * @var string
83
	 */
84
	private $primary_site_slug;
85
	/**
86
	 * Whether the text direction is RTL (based on connected WordPress.com user's interface settings).
87
	 *
88
	 * @var boolean
89
	 */
90
	private $is_rtl;
91
	/**
92
	 * Number of sites owned by connected WordPress.com user.
93
	 *
94
	 * @var int
95
	 */
96
	private $user_site_count;
97
98
	/**
99
	 * Constructor
100
	 */
101
	public function __construct() {
102
		$this->user_id      = get_current_user_id();
103
		$connection_manager = new Connection_Manager( 'jetpack' );
104
105
		if ( ! $connection_manager->is_user_connected( $this->user_id ) ) {
106
			return;
107
		}
108
109
		$this->user_data       = $connection_manager->get_connected_user_data( $this->user_id );
0 ignored issues
show
Documentation Bug introduced by
It seems like $connection_manager->get...er_data($this->user_id) of type object is incompatible with the declared type array of property $user_data.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
110
		$this->user_login      = $this->user_data['login'];
111
		$this->user_email      = $this->user_data['email'];
112
		$this->display_name    = $this->user_data['display_name'];
113
		$this->user_site_count = $this->user_data['site_count'];
114
		$this->is_rtl          = 'rtl' === $this->user_data['text_direction'];
115
		$this->user_locale     = $this->user_data['user_locale'];
116
117
		// Store part of the connected user data as user options so it can be used
118
		// by other files of the masterbar module without making another XMLRPC
119
		// request. Although `get_connected_user_data` tries to save the data for
120
		// future uses on a transient, the data is not guaranteed to be cached.
121
		update_user_option( $this->user_id, 'jetpack_wpcom_is_rtl', $this->is_rtl ? '1' : '0' );
122
		if ( isset( $this->user_data['use_wp_admin_links'] ) ) {
123
			update_user_option( $this->user_id, 'jetpack_admin_menu_link_destination', $this->user_data['use_wp_admin_links'] ? '1' : '0' );
124
		}
125
		// If Atomic, store and install user locale.
126
		if ( jetpack_is_atomic_site() ) {
127
			$this->user_locale = $this->get_jetpack_locale( $this->user_locale );
128
			$this->install_locale( $this->user_locale );
129
			update_user_option( $this->user_id, 'locale', $this->user_locale, true );
130
		}
131
132
		add_action( 'admin_bar_init', array( $this, 'init' ) );
133
134
		if ( ! empty( $this->user_data['ID'] ) ) {
135
			// Post logout on the site, also log the user out of WordPress.com.
136
			add_filter( 'logout_redirect', array( $this, 'maybe_logout_user_from_wpcom' ) );
137
		}
138
	}
139
140
	/**
141
	 * Initialize our masterbar.
142
	 */
143
	public function init() {
144
		$this->locale = $this->get_locale();
145
146
		// Don't show the masterbar on WordPress mobile apps.
147
		if ( User_Agent_Info::is_mobile_app() ) {
148
			add_filter( 'show_admin_bar', '__return_false' );
149
			return;
150
		}
151
152
		// Disable the Masterbar on AMP views.
153
		if (
154
			class_exists( 'Jetpack_AMP_Support' )
155
			&& Jetpack_AMP_Support::is_amp_available()
156
			&& Jetpack_AMP_Support::is_amp_request()
157
		) {
158
			return;
159
		}
160
161
		Assets::add_resource_hint(
162
			array(
163
				'//s0.wp.com',
164
				'//s1.wp.com',
165
				'//s2.wp.com',
166
				'//0.gravatar.com',
167
				'//1.gravatar.com',
168
				'//2.gravatar.com',
169
			),
170
			'dns-prefetch'
171
		);
172
173
		// Atomic only.
174
		if ( jetpack_is_atomic_site() ) {
175
			/*
176
			 * override user setting that hides masterbar from site's front.
177
			 * https://github.com/Automattic/jetpack/issues/7667
178
			 */
179
			add_filter( 'show_admin_bar', '__return_true' );
180
		}
181
182
		// Used to build menu links that point directly to Calypso.
183
		$this->primary_site_slug = ( new Status() )->get_site_suffix();
184
185
		// Used for display purposes and for building WP Admin links.
186
		$this->primary_site_url = str_replace( '::', '/', $this->primary_site_slug );
0 ignored issues
show
Bug introduced by
The property primary_site_url does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
187
188
		add_filter( 'admin_body_class', array( $this, 'admin_body_class' ) );
189
190
		add_action( 'wp_before_admin_bar_render', array( $this, 'replace_core_masterbar' ), 99999 );
191
192
		add_action( 'wp_enqueue_scripts', array( $this, 'add_styles_and_scripts' ) );
193
		add_action( 'admin_enqueue_scripts', array( $this, 'add_styles_and_scripts' ) );
194
195
		add_action( 'wp_enqueue_scripts', array( $this, 'remove_core_styles' ) );
196
		add_action( 'admin_enqueue_scripts', array( $this, 'remove_core_styles' ) );
197
198
		if ( Jetpack::is_module_active( 'notes' ) && $this->is_rtl ) {
199
			// Override Notification module to include RTL styles.
200
			add_action( 'a8c_wpcom_masterbar_enqueue_rtl_notification_styles', '__return_true' );
201
		}
202
203
		// Hides and replaces the language dropdown for the current user, on Atomic.
204
		if ( jetpack_is_atomic_site() &&
205
			defined( 'IS_PROFILE_PAGE' ) && IS_PROFILE_PAGE ) {
206
			add_action( 'user_edit_form_tag', array( $this, 'hide_language_dropdown' ) );
207
			add_action( 'personal_options', array( $this, 'replace_language_dropdown' ), 9 );
208
		}
209
	}
210
211
	/**
212
	 * Log out from WordPress.com when logging out of the local site.
213
	 *
214
	 * @param string $redirect_to The redirect destination URL.
215
	 */
216
	public function maybe_logout_user_from_wpcom( $redirect_to ) {
217
		/**
218
		 * Whether we should sign out from wpcom too when signing out from the masterbar.
219
		 *
220
		 * @since 5.9.0
221
		 *
222
		 * @param bool $masterbar_should_logout_from_wpcom True by default.
223
		 */
224
		$masterbar_should_logout_from_wpcom = apply_filters( 'jetpack_masterbar_should_logout_from_wpcom', true );
225
		if (
226
			// No need to check for a nonce here, it happens further up.
227
			isset( $_GET['context'] ) // phpcs:ignore WordPress.Security.NonceVerification.Recommended
228
			&& 'masterbar' === $_GET['context'] // phpcs:ignore WordPress.Security.NonceVerification.Recommended
229
			&& $masterbar_should_logout_from_wpcom
230
		) {
231
			/**
232
			 * Hook into the log out event happening from the Masterbar.
233
			 *
234
			 * @since 5.1.0
235
			 * @since 7.9.0 Added the $wpcom_user_id parameter to the action.
236
			 *
237
			 * @module masterbar
238
			 *
239
			 * @param int $wpcom_user_id WordPress.com User ID.
240
			 */
241
			do_action( 'wp_masterbar_logout', $this->user_data['ID'] );
242
		}
243
244
		return $redirect_to;
245
	}
246
247
	/**
248
	 * Adds CSS classes to admin body tag.
249
	 *
250
	 * @since 5.1
251
	 *
252
	 * @param string $admin_body_classes CSS classes that will be added.
253
	 *
254
	 * @return string
255
	 */
256
	public function admin_body_class( $admin_body_classes ) {
257
		return "$admin_body_classes jetpack-masterbar";
258
	}
259
260
	/**
261
	 * Remove the default Admin Bar CSS.
262
	 */
263
	public function remove_core_styles() {
264
		/*
265
		 * Notifications need the admin bar styles,
266
		 * so let's not remove them when the module is active.
267
		 */
268
		if ( ! Jetpack::is_module_active( 'notes' ) ) {
269
			wp_dequeue_style( 'admin-bar' );
270
		}
271
	}
272
273
	/**
274
	 * Enqueue our own CSS and JS to display our custom admin bar.
275
	 */
276
	public function add_styles_and_scripts() {
277
278
		if ( $this->is_rtl ) {
279
			wp_enqueue_style( 'a8c-wpcom-masterbar-rtl', $this->wpcom_static_url( '/wp-content/mu-plugins/admin-bar/rtl/wpcom-admin-bar-rtl.css' ), array(), JETPACK__VERSION );
280
			wp_enqueue_style( 'a8c-wpcom-masterbar-overrides-rtl', $this->wpcom_static_url( '/wp-content/mu-plugins/admin-bar/masterbar-overrides/rtl/masterbar-rtl.css' ), array(), JETPACK__VERSION );
281
		} else {
282
			wp_enqueue_style( 'a8c-wpcom-masterbar', $this->wpcom_static_url( '/wp-content/mu-plugins/admin-bar/wpcom-admin-bar.css' ), array(), JETPACK__VERSION );
283
			wp_enqueue_style( 'a8c-wpcom-masterbar-overrides', $this->wpcom_static_url( '/wp-content/mu-plugins/admin-bar/masterbar-overrides/masterbar.css' ), array(), JETPACK__VERSION );
284
		}
285
286
		// Local overrides.
287
		wp_enqueue_style( 'a8c_wpcom_css_override', plugins_url( 'overrides.css', __FILE__ ), array(), JETPACK__VERSION );
288
289
		if ( ! Jetpack::is_module_active( 'notes ' ) ) {
290
			// Masterbar is relying on some icons from noticons.css.
291
			wp_enqueue_style( 'noticons', $this->wpcom_static_url( '/i/noticons/noticons.css' ), array(), JETPACK__VERSION . '-' . gmdate( 'oW' ) );
292
		}
293
294
		wp_enqueue_script(
295
			'jetpack-accessible-focus',
296
			Assets::get_file_url_for_environment( '_inc/build/accessible-focus.min.js', '_inc/accessible-focus.js' ),
297
			array(),
298
			JETPACK__VERSION,
299
			false
300
		);
301
		wp_enqueue_script(
302
			'a8c_wpcom_masterbar_tracks_events',
303
			Assets::get_file_url_for_environment(
304
				'_inc/build/masterbar/masterbar/tracks-events.min.js',
305
				'modules/masterbar/masterbar/tracks-events.js'
306
			),
307
			array( 'jquery' ),
308
			JETPACK__VERSION,
309
			false
310
		);
311
312
		wp_enqueue_script(
313
			'a8c_wpcom_masterbar_overrides',
314
			$this->wpcom_static_url( '/wp-content/mu-plugins/admin-bar/masterbar-overrides/masterbar.js' ),
315
			array( 'jquery' ),
316
			JETPACK__VERSION,
317
			false
318
		);
319
	}
320
321
	/**
322
	 * Get base URL where our CSS and JS will come from.
323
	 *
324
	 * @param string $file File path for a static resource.
325
	 */
326
	private function wpcom_static_url( $file ) {
327
		if ( ! empty( $this->sandbox_url ) ) {
328
			// For testing undeployed changes to remotely enqueued scripts and styles.
329
			return set_url_scheme( $this->sandbox_url . $file, 'https' );
330
		}
331
332
		$i   = hexdec( substr( md5( $file ), - 1 ) ) % 2;
333
		$url = 'https://s' . $i . '.wp.com' . $file;
334
335
		return set_url_scheme( $url, 'https' );
336
	}
337
338
	/**
339
	 * Remove the default admin bar items and replace it with our own admin bar.
340
	 */
341
	public function replace_core_masterbar() {
342
		global $wp_admin_bar;
343
344
		if ( ! is_object( $wp_admin_bar ) ) {
345
			return false;
346
		}
347
348
		$this->clear_core_masterbar( $wp_admin_bar );
349
		$this->build_wpcom_masterbar( $wp_admin_bar );
350
	}
351
352
	/**
353
	 * Remove all existing toolbar entries from core Masterbar
354
	 *
355
	 * @param WP_Admin_Bar $wp_admin_bar Admin Bar instance.
356
	 */
357
	public function clear_core_masterbar( $wp_admin_bar ) {
358
		foreach ( $wp_admin_bar->get_nodes() as $node ) {
359
			$wp_admin_bar->remove_node( $node->id );
360
		}
361
	}
362
363
	/**
364
	 * Add entries corresponding to WordPress.com Masterbar
365
	 *
366
	 * @param WP_Admin_Bar $wp_admin_bar Admin Bar instance.
367
	 */
368
	public function build_wpcom_masterbar( $wp_admin_bar ) {
369
		// Menu groups.
370
		$this->wpcom_adminbar_add_secondary_groups( $wp_admin_bar );
371
372
		// Left part.
373
		$this->add_my_sites_submenu( $wp_admin_bar );
374
		$this->add_reader_submenu( $wp_admin_bar );
375
376
		// Right part.
377
		if ( Jetpack::is_module_active( 'notes' ) ) {
378
			$this->add_notifications( $wp_admin_bar );
379
		}
380
381
		$this->add_me_submenu( $wp_admin_bar );
382
		$this->add_write_button( $wp_admin_bar );
383
384
		// Recovery mode exit.
385
		if ( function_exists( 'wp_admin_bar_recovery_mode_menu' ) ) {
386
			wp_admin_bar_recovery_mode_menu( $wp_admin_bar );
387
		}
388
389
		if ( class_exists( 'Automattic\Jetpack\Scan\Admin_Bar_Notice' ) ) {
390
			$scan_admin_bar_notice = Admin_Bar_Notice::instance();
391
			$scan_admin_bar_notice->add_threats_to_toolbar( $wp_admin_bar );
392
		}
393
	}
394
395
	/**
396
	 * Get WordPress.com current locale name.
397
	 */
398
	public function get_locale() {
399
		$wpcom_locale = get_locale();
400
401
		if ( ! class_exists( 'GP_Locales' ) ) {
402
			if ( defined( 'JETPACK__GLOTPRESS_LOCALES_PATH' ) && file_exists( JETPACK__GLOTPRESS_LOCALES_PATH ) ) {
403
				require JETPACK__GLOTPRESS_LOCALES_PATH;
404
			}
405
		}
406
407 View Code Duplication
		if ( class_exists( 'GP_Locales' ) ) {
408
			$wpcom_locale_object = GP_Locales::by_field( 'wp_locale', get_locale() );
409
			if ( $wpcom_locale_object instanceof GP_Locale ) {
410
				$wpcom_locale = $wpcom_locale_object->slug;
411
			}
412
		}
413
414
		return $wpcom_locale;
415
	}
416
417
	/**
418
	 * Get Jetpack locale name.
419
	 *
420
	 * @param  string $slug Locale slug.
421
	 * @return string Jetpack locale.
422
	 */
423
	public function get_jetpack_locale( $slug = '' ) {
424
		if ( ! class_exists( 'GP_Locales' ) ) {
425
			if ( defined( 'JETPACK__GLOTPRESS_LOCALES_PATH' ) && file_exists( JETPACK__GLOTPRESS_LOCALES_PATH ) ) {
426
				require JETPACK__GLOTPRESS_LOCALES_PATH;
427
			}
428
		}
429
430 View Code Duplication
		if ( class_exists( 'GP_Locales' ) ) {
431
			$jetpack_locale_object = GP_Locales::by_field( 'slug', $slug );
432
			if ( $jetpack_locale_object instanceof GP_Locale ) {
433
				$jetpack_locale = $jetpack_locale_object->wp_locale ? $jetpack_locale_object->wp_locale : 'en_US';
434
			}
435
		}
436
437
		return $jetpack_locale;
0 ignored issues
show
Bug introduced by
The variable $jetpack_locale does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
438
	}
439
440
	/**
441
	 * Install locale if not yet available.
442
	 *
443
	 * @param string $locale The new locale slug.
444
	 */
445
	public function install_locale( $locale = '' ) {
446
		if ( ! in_array( $locale, get_available_languages(), true )
447
			&& ! empty( $locale ) && current_user_can( 'install_languages' ) ) {
448
449
			if ( ! function_exists( 'wp_download_language_pack' ) ) {
450
				require_once ABSPATH . 'wp-admin/includes/translation-install.php';
451
			}
452
453
			if ( ! function_exists( 'request_filesystem_credentials' ) ) {
454
				require_once ABSPATH . 'wp-admin/includes/file.php';
455
			}
456
457
			if ( wp_can_install_language_pack() ) {
458
				wp_download_language_pack( $locale );
459
				load_default_textdomain( $locale );
460
			}
461
		}
462
	}
463
464
	/**
465
	 * Hide language dropdown on user edit form.
466
	 */
467
	public function hide_language_dropdown() {
468
		add_filter( 'get_available_languages', '__return_null' );
469
	}
470
471
	/**
472
	 * Replace language dropdown with link to WordPress.com.
473
	 */
474
	public function replace_language_dropdown() {
475
		$language_row  = printf( '<tr class="user-language-wrap"><th scope="row">' );
476
		$language_row .= printf(
477
			'<label for="locale">%1$s<span class="dashicons dashicons-translation" aria-hidden="true"></span></label>',
478
			esc_html__( 'Language', 'jetpack' )
479
		);
480
		$language_row .= printf( '</th><td>' );
481
		$language_row .= printf(
482
			'<a target="_blank" href="%1$s">%2$s</a>',
483
			esc_url( 'https://wordpress.com/me/account' ),
484
			esc_html__( 'Set your profile language on WordPress.com.', 'jetpack' )
485
		);
486
		$language_row .= printf( '</td></tr>' );
487
		return $language_row;
488
	}
489
490
	/**
491
	 * Add the Notifications menu item.
492
	 *
493
	 * @param WP_Admin_Bar $wp_admin_bar Admin Bar instance.
494
	 */
495
	public function add_notifications( $wp_admin_bar ) {
496
		$wp_admin_bar->add_node(
497
			array(
498
				'id'     => 'notes',
499
				'title'  => '<span id="wpnt-notes-unread-count" class="wpnt-loading wpn-read"></span>
500
						 <span class="screen-reader-text">' . esc_html__( 'Notifications', 'jetpack' ) . '</span>
501
						 <span class="noticon noticon-bell"></span>',
502
				'meta'   => array(
503
					'html'  => '<div id="wpnt-notes-panel2" style="display:none" lang="' . esc_attr( $this->locale ) . '" dir="' . ( $this->is_rtl ? 'rtl' : 'ltr' ) . '">' .
504
								'<div class="wpnt-notes-panel-header">' .
505
								'<span class="wpnt-notes-header">' .
506
								esc_html__( 'Notifications', 'jetpack' ) .
507
								'</span>' .
508
								'<span class="wpnt-notes-panel-link">' .
509
								'</span>' .
510
								'</div>' .
511
								'</div>',
512
					'class' => 'menupop mb-trackable',
513
				),
514
				'parent' => 'top-secondary',
515
			)
516
		);
517
	}
518
519
	/**
520
	 * Add the "Reader" menu item in the root default group.
521
	 *
522
	 * @param WP_Admin_Bar $wp_admin_bar Admin Bar instance.
523
	 */
524
	public function add_reader_submenu( $wp_admin_bar ) {
525
		$wp_admin_bar->add_menu(
526
			array(
527
				'parent' => 'root-default',
528
				'id'     => 'newdash',
529
				'title'  => esc_html__( 'Reader', 'jetpack' ),
530
				'href'   => 'https://wordpress.com/read',
531
				'meta'   => array(
532
					'class' => 'mb-trackable',
533
				),
534
			)
535
		);
536
537
		/** This filter is documented in modules/masterbar.php */
538
		if ( apply_filters( 'jetpack_load_admin_menu_class', false ) ) {
539
			return;
540
		}
541
542
		$wp_admin_bar->add_menu(
543
			array(
544
				'parent' => 'newdash',
545
				'id'     => 'streams-header',
546
				'title'  => esc_html_x(
547
					'Streams',
548
					'Title for Reader sub-menu that contains followed sites, likes, and search',
549
					'jetpack'
550
				),
551
				'meta'   => array(
552
					'class' => 'ab-submenu-header',
553
				),
554
			)
555
		);
556
557
		$following_title = $this->create_menu_item_pair(
558
			array(
559
				'url'   => Redirect::get_url( 'calypso-read' ),
560
				'id'    => 'wp-admin-bar-followed-sites',
561
				'label' => esc_html__( 'Followed Sites', 'jetpack' ),
562
			),
563
			array(
564
				'url'   => Redirect::get_url( 'calypso-following-edit' ),
565
				'id'    => 'wp-admin-bar-reader-followed-sites-manage',
566
				'label' => esc_html__( 'Manage', 'jetpack' ),
567
			)
568
		);
569
570
		$wp_admin_bar->add_menu(
571
			array(
572
				'parent' => 'newdash',
573
				'id'     => 'following',
574
				'title'  => $following_title,
575
				'meta'   => array( 'class' => 'inline-action' ),
576
			)
577
		);
578
579
		$wp_admin_bar->add_menu(
580
			array(
581
				'parent' => 'newdash',
582
				'id'     => 'discover-discover',
583
				'title'  => esc_html__( 'Discover', 'jetpack' ),
584
				'href'   => Redirect::get_url( 'calypso-discover' ),
585
				'meta'   => array(
586
					'class' => 'mb-icon-spacer',
587
				),
588
			)
589
		);
590
591
		$wp_admin_bar->add_menu(
592
			array(
593
				'parent' => 'newdash',
594
				'id'     => 'discover-search',
595
				'title'  => esc_html__( 'Search', 'jetpack' ),
596
				'href'   => Redirect::get_url( 'calypso-read-search' ),
597
				'meta'   => array(
598
					'class' => 'mb-icon-spacer',
599
				),
600
			)
601
		);
602
603
		$wp_admin_bar->add_menu(
604
			array(
605
				'parent' => 'newdash',
606
				'id'     => 'my-activity-my-likes',
607
				'title'  => esc_html__( 'My Likes', 'jetpack' ),
608
				'href'   => Redirect::get_url( 'calypso-activities-likes' ),
609
				'meta'   => array(
610
					'class' => 'mb-icon-spacer',
611
				),
612
			)
613
		);
614
615
	}
616
617
	/**
618
	 * Merge 2 menu items together into 2 link tags.
619
	 *
620
	 * @param array $primary   Array of menu information.
621
	 * @param array $secondary Array of menu information.
622
	 */
623
	public function create_menu_item_pair( $primary, $secondary ) {
624
		$primary_class   = 'ab-item ab-primary mb-icon';
625
		$secondary_class = 'ab-secondary';
626
627
		$primary_anchor   = $this->create_menu_item_anchor( $primary_class, $primary['url'], $primary['label'], $primary['id'] );
628
		$secondary_anchor = $this->create_menu_item_anchor( $secondary_class, $secondary['url'], $secondary['label'], $secondary['id'] );
629
630
		return $primary_anchor . $secondary_anchor;
631
	}
632
633
	/**
634
	 * Create a link tag based on information about a menu item.
635
	 *
636
	 * @param string $class Menu item CSS class.
637
	 * @param string $url   URL you go to when clicking on the menu item.
638
	 * @param string $label Menu item title.
639
	 * @param string $id    Menu item slug.
640
	 */
641
	public function create_menu_item_anchor( $class, $url, $label, $id ) {
642
		return '<a href="' . $url . '" class="' . $class . '" id="' . $id . '">' . $label . '</a>';
643
	}
644
645
	/**
646
	 * Add Secondary groups for submenu items.
647
	 *
648
	 * @param WP_Admin_Bar $wp_admin_bar Admin Bar instance.
649
	 */
650
	public function wpcom_adminbar_add_secondary_groups( $wp_admin_bar ) {
651
		$wp_admin_bar->add_group(
652
			array(
653
				'id'   => 'root-default',
654
				'meta' => array(
655
					'class' => 'ab-top-menu',
656
				),
657
			)
658
		);
659
660
		$wp_admin_bar->add_group(
661
			array(
662
				'parent' => 'blog',
663
				'id'     => 'blog-secondary',
664
				'meta'   => array(
665
					'class' => 'ab-sub-secondary',
666
				),
667
			)
668
		);
669
670
		$wp_admin_bar->add_group(
671
			array(
672
				'id'   => 'top-secondary',
673
				'meta' => array(
674
					'class' => 'ab-top-secondary',
675
				),
676
			)
677
		);
678
	}
679
680
	/**
681
	 * Add User info menu item.
682
	 *
683
	 * @param WP_Admin_Bar $wp_admin_bar Admin Bar instance.
684
	 */
685
	public function add_me_submenu( $wp_admin_bar ) {
686
		$user_id = get_current_user_id();
687
		if ( empty( $user_id ) ) {
688
			return;
689
		}
690
691
		$avatar = get_avatar( $this->user_email, 32, 'mm', '', array( 'force_display' => true ) );
692
		$class  = empty( $avatar ) ? 'mb-trackable' : 'with-avatar mb-trackable';
693
694
		// Add the 'Me' menu.
695
		$wp_admin_bar->add_menu(
696
			array(
697
				'id'     => 'my-account',
698
				'parent' => 'top-secondary',
699
				'title'  => $avatar . '<span class="ab-text">' . esc_html__( 'Me', 'jetpack' ) . '</span>',
700
				'href'   => 'https://wordpress.com/me',
701
				'meta'   => array(
702
					'class' => $class,
703
				),
704
			)
705
		);
706
707
		/** This filter is documented in modules/masterbar.php */
708
		if ( apply_filters( 'jetpack_load_admin_menu_class', false ) ) {
709
			return;
710
		}
711
712
		$id = 'user-actions';
713
		$wp_admin_bar->add_group(
714
			array(
715
				'parent' => 'my-account',
716
				'id'     => $id,
717
			)
718
		);
719
720
		$settings_url = Redirect::get_url( 'calypso-me-account' );
721
722
		$logout_url = wp_logout_url();
723
		$logout_url = add_query_arg( 'context', 'masterbar', $logout_url );
724
725
		$user_info  = get_avatar( $this->user_email, 128, 'mm', '', array( 'force_display' => true ) );
726
		$user_info .= '<span class="display-name">' . $this->display_name . '</span>';
727
		$user_info .= '<a class="username" href="https://gravatar.com/' . $this->user_login . '">@' . $this->user_login . '</a>';
728
729
		$user_info .= sprintf(
730
			'<div><a href="%s" class="ab-sign-out">%s</a></div>',
731
			$logout_url,
732
			esc_html__( 'Sign Out', 'jetpack' )
733
		);
734
735
		$wp_admin_bar->add_menu(
736
			array(
737
				'parent' => $id,
738
				'id'     => 'user-info',
739
				'title'  => $user_info,
740
				'meta'   => array(
741
					'class'    => 'user-info user-info-item',
742
					'tabindex' => -1,
743
				),
744
			)
745
		);
746
747
		$wp_admin_bar->add_menu(
748
			array(
749
				'parent' => $id,
750
				'id'     => 'profile-header',
751
				'title'  => esc_html__( 'Profile', 'jetpack' ),
752
				'meta'   => array(
753
					'class' => 'ab-submenu-header',
754
				),
755
			)
756
		);
757
758
		$wp_admin_bar->add_menu(
759
			array(
760
				'parent' => $id,
761
				'id'     => 'my-profile',
762
				'title'  => esc_html__( 'My Profile', 'jetpack' ),
763
				'href'   => Redirect::get_url( 'calypso-me' ),
764
				'meta'   => array(
765
					'class' => 'mb-icon',
766
				),
767
			)
768
		);
769
770
		$wp_admin_bar->add_menu(
771
			array(
772
				'parent' => $id,
773
				'id'     => 'account-settings',
774
				'title'  => esc_html__( 'Account Settings', 'jetpack' ),
775
				'href'   => $settings_url,
776
				'meta'   => array(
777
					'class' => 'mb-icon',
778
				),
779
			)
780
		);
781
782
		$wp_admin_bar->add_menu(
783
			array(
784
				'parent' => $id,
785
				'id'     => 'billing',
786
				'title'  => esc_html__( 'Manage Purchases', 'jetpack' ),
787
				'href'   => Redirect::get_url( 'calypso-me-purchases' ),
788
				'meta'   => array(
789
					'class' => 'mb-icon',
790
				),
791
			)
792
		);
793
794
		$wp_admin_bar->add_menu(
795
			array(
796
				'parent' => $id,
797
				'id'     => 'security',
798
				'title'  => esc_html__( 'Security', 'jetpack' ),
799
				'href'   => Redirect::get_url( 'calypso-me-security' ),
800
				'meta'   => array(
801
					'class' => 'mb-icon',
802
				),
803
			)
804
		);
805
806
		$wp_admin_bar->add_menu(
807
			array(
808
				'parent' => $id,
809
				'id'     => 'notifications',
810
				'title'  => esc_html__( 'Notifications', 'jetpack' ),
811
				'href'   => Redirect::get_url( 'calypso-me-notifications' ),
812
				'meta'   => array(
813
					'class' => 'mb-icon',
814
				),
815
			)
816
		);
817
818
		$wp_admin_bar->add_menu(
819
			array(
820
				'parent' => $id,
821
				'id'     => 'special-header',
822
				'title'  => esc_html_x(
823
					'Special',
824
					'Title for Me sub-menu that contains Get Apps, Next Steps, and Help options',
825
					'jetpack'
826
				),
827
				'meta'   => array(
828
					'class' => 'ab-submenu-header',
829
				),
830
			)
831
		);
832
833
		$wp_admin_bar->add_menu(
834
			array(
835
				'parent' => $id,
836
				'id'     => 'get-apps',
837
				'title'  => esc_html__( 'Get Apps', 'jetpack' ),
838
				'href'   => Redirect::get_url( 'calypso-me-get-apps' ),
839
				'meta'   => array(
840
					'class' => 'mb-icon user-info-item',
841
				),
842
			)
843
		);
844
845
		$help_link = Redirect::get_url( 'jetpack-support' );
846
847
		if ( jetpack_is_atomic_site() ) {
848
			$help_link = Redirect::get_url( 'calypso-help' );
849
		}
850
851
		$wp_admin_bar->add_menu(
852
			array(
853
				'parent' => $id,
854
				'id'     => 'help',
855
				'title'  => esc_html__( 'Help', 'jetpack' ),
856
				'href'   => $help_link,
857
				'meta'   => array(
858
					'class' => 'mb-icon user-info-item',
859
				),
860
			)
861
		);
862
	}
863
864
	/**
865
	 * Add Write Menu item.
866
	 *
867
	 * @param WP_Admin_Bar $wp_admin_bar Admin Bar instance.
868
	 */
869
	public function add_write_button( $wp_admin_bar ) {
870
		$current_user = wp_get_current_user();
871
872
		$posting_blog_id = get_current_blog_id();
873
		if ( ! is_user_member_of_blog( get_current_user_id(), get_current_blog_id() ) ) {
874
			$posting_blog_id = $current_user->primary_blog;
875
		}
876
877
		$user_can_post = current_user_can_for_blog( $posting_blog_id, 'publish_posts' );
878
879
		if ( ! $posting_blog_id || ! $user_can_post ) {
880
			return;
881
		}
882
883
		$wp_admin_bar->add_menu(
884
			array(
885
				'parent' => 'top-secondary',
886
				'id'     => 'ab-new-post',
887
				'href'   => admin_url( 'post-new.php' ),
888
				'title'  => '<span>' . esc_html__( 'Write', 'jetpack' ) . '</span>',
889
				'meta'   => array(
890
					'class' => 'mb-trackable',
891
				),
892
			)
893
		);
894
	}
895
896
	/**
897
	 * Add the "My Site" menu item in the root default group.
898
	 *
899
	 * @param WP_Admin_Bar $wp_admin_bar Admin Bar instance.
900
	 */
901
	public function add_my_sites_submenu( $wp_admin_bar ) {
902
		$current_user = wp_get_current_user();
903
904
		$blog_name = get_bloginfo( 'name' );
905
		if ( empty( $blog_name ) ) {
906
			$blog_name = $this->primary_site_slug;
907
		}
908
909
		if ( mb_strlen( $blog_name ) > 20 ) {
910
			$blog_name = mb_substr( html_entity_decode( $blog_name, ENT_QUOTES ), 0, 20 ) . '&hellip;';
911
		}
912
913
		$wp_admin_bar->add_menu(
914
			array(
915
				'parent' => 'root-default',
916
				'id'     => 'blog',
917
				'title'  => _n( 'My Site', 'My Sites', $this->user_site_count, 'jetpack' ),
918
				'href'   => 'https://wordpress.com/sites/' . $this->primary_site_url,
919
				'meta'   => array(
920
					'class' => 'my-sites mb-trackable',
921
				),
922
			)
923
		);
924
925
		/** This filter is documented in modules/masterbar.php */
926
		if ( apply_filters( 'jetpack_load_admin_menu_class', false ) ) {
927
			return;
928
		}
929
930
		if ( $this->user_site_count > 1 ) {
931
			$wp_admin_bar->add_menu(
932
				array(
933
					'parent' => 'blog',
934
					'id'     => 'switch-site',
935
					'title'  => esc_html__( 'Switch Site', 'jetpack' ),
936
					'href'   => Redirect::get_url( 'calypso-sites' ),
937
				)
938
			);
939
		} else {
940
			$wp_admin_bar->add_menu(
941
				array(
942
					'parent' => 'blog',
943
					'id'     => 'new-site',
944
					'title'  => esc_html__( '+ Add New WordPress', 'jetpack' ),
945
					'href'   => Redirect::get_url( 'calypso-start', array( 'query' => 'ref=admin-bar-logged-in' ) ),
946
				)
947
			);
948
		}
949
950
		if ( is_user_member_of_blog( $current_user->ID ) ) {
951
			$blavatar = '';
952
			$class    = 'current-site';
953
954
			if ( has_site_icon() ) {
955
				$src      = get_site_icon_url();
956
				$blavatar = '<img class="avatar" src="' . esc_attr( $src ) . '" alt="Current site avatar">';
957
				$class    = 'has-blavatar';
958
			}
959
960
			$blog_info  = '<div class="ab-site-icon">' . $blavatar . '</div>';
961
			$blog_info .= '<span class="ab-site-title">' . esc_html( $blog_name ) . '</span>';
962
			$blog_info .= '<span class="ab-site-description">' . esc_html( $this->primary_site_url ) . '</span>';
963
964
			$wp_admin_bar->add_menu(
965
				array(
966
					'parent' => 'blog',
967
					'id'     => 'blog-info',
968
					'title'  => $blog_info,
969
					'href'   => esc_url( trailingslashit( $this->primary_site_url ) ),
970
					'meta'   => array(
971
						'class' => $class,
972
					),
973
				)
974
			);
975
		}
976
977
		// Site Preview.
978
		if ( is_admin() ) {
979
			$wp_admin_bar->add_menu(
980
				array(
981
					'parent' => 'blog',
982
					'id'     => 'site-view',
983
					'title'  => __( 'View Site', 'jetpack' ),
984
					'href'   => home_url(),
985
					'meta'   => array(
986
						'class'  => 'mb-icon',
987
						'target' => '_blank',
988
					),
989
				)
990
			);
991
		}
992
993
		$this->add_my_home_submenu_item( $wp_admin_bar );
994
995
		// Stats.
996 View Code Duplication
		if ( Jetpack::is_module_active( 'stats' ) && current_user_can( 'view_stats' ) ) {
997
			$wp_admin_bar->add_menu(
998
				array(
999
					'parent' => 'blog',
1000
					'id'     => 'blog-stats',
1001
					'title'  => esc_html__( 'Stats', 'jetpack' ),
1002
					'href'   => Redirect::get_url( 'calypso-stats' ),
1003
					'meta'   => array(
1004
						'class' => 'mb-icon',
1005
					),
1006
				)
1007
			);
1008
		}
1009
1010
		if ( current_user_can( 'manage_options' ) ) {
1011
			$wp_admin_bar->add_menu(
1012
				array(
1013
					'parent' => 'blog',
1014
					'id'     => 'activity',
1015
					'title'  => esc_html__( 'Activity', 'jetpack' ),
1016
					'href'   => Redirect::get_url( 'calypso-activity-log' ),
1017
					'meta'   => array(
1018
						'class' => 'mb-icon',
1019
					),
1020
				)
1021
			);
1022
		}
1023
1024
		// Add Calypso plans link and plan type indicator.
1025
		if ( is_user_member_of_blog( $current_user->ID ) && current_user_can( 'manage_options' ) ) {
1026
			$plans_url = Redirect::get_url( 'calypso-plans' );
1027
			$label     = esc_html__( 'Plan', 'jetpack' );
1028
			$plan      = Jetpack_Plan::get();
1029
1030
			$plan_title = $this->create_menu_item_pair(
1031
				array(
1032
					'url'   => $plans_url,
1033
					'id'    => 'wp-admin-bar-plan',
1034
					'label' => $label,
1035
				),
1036
				array(
1037
					'url'   => $plans_url,
1038
					'id'    => 'wp-admin-bar-plan-badge',
1039
					'label' => ! empty( $plan['product_name_short'] ) ? $plan['product_name_short'] : esc_html__( 'Free', 'jetpack' ),
1040
				)
1041
			);
1042
1043
			$wp_admin_bar->add_menu(
1044
				array(
1045
					'parent' => 'blog',
1046
					'id'     => 'plan',
1047
					'title'  => $plan_title,
1048
					'meta'   => array(
1049
						'class' => 'inline-action',
1050
					),
1051
				)
1052
			);
1053
		}
1054
1055
		// Publish group.
1056
		$wp_admin_bar->add_group(
1057
			array(
1058
				'parent' => 'blog',
1059
				'id'     => 'publish',
1060
			)
1061
		);
1062
1063
		// Publish header.
1064
		$wp_admin_bar->add_menu(
1065
			array(
1066
				'parent' => 'publish',
1067
				'id'     => 'publish-header',
1068
				'title'  => esc_html_x( 'Manage', 'admin bar menu group label', 'jetpack' ),
1069
				'meta'   => array(
1070
					'class' => 'ab-submenu-header',
1071
				),
1072
			)
1073
		);
1074
1075
		// Pages.
1076
		$pages_title = $this->create_menu_item_pair(
1077
			array(
1078
				'url'   => Redirect::get_url( 'calypso-edit-pages' ),
1079
				'id'    => 'wp-admin-bar-edit-page',
1080
				'label' => esc_html__( 'Site Pages', 'jetpack' ),
1081
			),
1082
			array(
1083
				'url'   => Redirect::get_url( 'calypso-edit-page' ),
1084
				'id'    => 'wp-admin-bar-new-page-badge',
1085
				'label' => esc_html_x( 'Add', 'admin bar menu new item label', 'jetpack' ),
1086
			)
1087
		);
1088
1089
		if ( ! current_user_can( 'edit_pages' ) ) {
1090
			$pages_title = $this->create_menu_item_anchor(
1091
				'ab-item ab-primary mb-icon',
1092
				Redirect::get_url( 'calypso-edit-pages' ),
1093
				esc_html__( 'Site Pages', 'jetpack' ),
1094
				'wp-admin-bar-edit-page'
1095
			);
1096
		}
1097
1098
		$wp_admin_bar->add_menu(
1099
			array(
1100
				'parent' => 'publish',
1101
				'id'     => 'new-page',
1102
				'title'  => $pages_title,
1103
				'meta'   => array(
1104
					'class' => 'inline-action',
1105
				),
1106
			)
1107
		);
1108
1109
		// Blog Posts.
1110
		$posts_title = $this->create_menu_item_pair(
1111
			array(
1112
				'url'   => Redirect::get_url( 'calypso-edit-posts' ),
1113
				'id'    => 'wp-admin-bar-edit-post',
1114
				'label' => esc_html__( 'Blog Posts', 'jetpack' ),
1115
			),
1116
			array(
1117
				'url'   => Redirect::get_url( 'calypso-edit-post' ),
1118
				'id'    => 'wp-admin-bar-new-post-badge',
1119
				'label' => esc_html_x( 'Add', 'admin bar menu new item label', 'jetpack' ),
1120
			)
1121
		);
1122
1123
		if ( ! current_user_can( 'edit_posts' ) ) {
1124
			$posts_title = $this->create_menu_item_anchor(
1125
				'ab-item ab-primary mb-icon',
1126
				Redirect::get_url( 'calypso-edit-posts' ),
1127
				esc_html__( 'Blog Posts', 'jetpack' ),
1128
				'wp-admin-bar-edit-post'
1129
			);
1130
		}
1131
1132
		$wp_admin_bar->add_menu(
1133
			array(
1134
				'parent' => 'publish',
1135
				'id'     => 'new-post',
1136
				'title'  => $posts_title,
1137
				'meta'   => array(
1138
					'class' => 'inline-action mb-trackable',
1139
				),
1140
			)
1141
		);
1142
1143
		// Comments.
1144
		if ( current_user_can( 'moderate_comments' ) ) {
1145
			$wp_admin_bar->add_menu(
1146
				array(
1147
					'parent' => 'publish',
1148
					'id'     => 'comments',
1149
					'title'  => __( 'Comments', 'jetpack' ),
1150
					'href'   => Redirect::get_url( 'calypso-comments' ),
1151
					'meta'   => array(
1152
						'class' => 'mb-icon',
1153
					),
1154
				)
1155
			);
1156
		}
1157
1158
		// Testimonials.
1159 View Code Duplication
		if ( Jetpack::is_module_active( 'custom-content-types' ) && get_option( 'jetpack_testimonial' ) ) {
1160
			$testimonials_title = $this->create_menu_item_pair(
1161
				array(
1162
					'url'   => Redirect::get_url( 'calypso-list-jetpack-testimonial' ),
1163
					'id'    => 'wp-admin-bar-edit-testimonial',
1164
					'label' => esc_html__( 'Testimonials', 'jetpack' ),
1165
				),
1166
				array(
1167
					'url'   => Redirect::get_url( 'calypso-edit-jetpack-testimonial' ),
1168
					'id'    => 'wp-admin-bar-new-testimonial',
1169
					'label' => esc_html_x( 'Add', 'Button label for adding a new item via the toolbar menu', 'jetpack' ),
1170
				)
1171
			);
1172
1173
			if ( ! current_user_can( 'edit_pages' ) ) {
1174
				$testimonials_title = $this->create_menu_item_anchor(
1175
					'ab-item ab-primary mb-icon',
1176
					Redirect::get_url( 'calypso-list-jetpack-testimonial' ),
1177
					esc_html__( 'Testimonials', 'jetpack' ),
1178
					'wp-admin-bar-edit-testimonial'
1179
				);
1180
			}
1181
1182
			$wp_admin_bar->add_menu(
1183
				array(
1184
					'parent' => 'publish',
1185
					'id'     => 'new-jetpack-testimonial',
1186
					'title'  => $testimonials_title,
1187
					'meta'   => array(
1188
						'class' => 'inline-action',
1189
					),
1190
				)
1191
			);
1192
		}
1193
1194
		// Portfolio.
1195 View Code Duplication
		if ( Jetpack::is_module_active( 'custom-content-types' ) && get_option( 'jetpack_portfolio' ) ) {
1196
			$portfolios_title = $this->create_menu_item_pair(
1197
				array(
1198
					'url'   => Redirect::get_url( 'calypso-list-jetpack-portfolio' ),
1199
					'id'    => 'wp-admin-bar-edit-portfolio',
1200
					'label' => esc_html__( 'Portfolio', 'jetpack' ),
1201
				),
1202
				array(
1203
					'url'   => Redirect::get_url( 'calypso-edit-jetpack-portfolio' ),
1204
					'id'    => 'wp-admin-bar-new-portfolio',
1205
					'label' => esc_html_x( 'Add', 'Button label for adding a new item via the toolbar menu', 'jetpack' ),
1206
				)
1207
			);
1208
1209
			if ( ! current_user_can( 'edit_pages' ) ) {
1210
				$portfolios_title = $this->create_menu_item_anchor(
1211
					'ab-item ab-primary mb-icon',
1212
					Redirect::get_url( 'calypso-list-jetpack-portfolio' ),
1213
					esc_html__( 'Portfolio', 'jetpack' ),
1214
					'wp-admin-bar-edit-portfolio'
1215
				);
1216
			}
1217
1218
			$wp_admin_bar->add_menu(
1219
				array(
1220
					'parent' => 'publish',
1221
					'id'     => 'new-jetpack-portfolio',
1222
					'title'  => $portfolios_title,
1223
					'meta'   => array(
1224
						'class' => 'inline-action',
1225
					),
1226
				)
1227
			);
1228
		}
1229
1230
		if ( current_user_can( 'edit_theme_options' ) ) {
1231
			// Look and Feel group.
1232
			$wp_admin_bar->add_group(
1233
				array(
1234
					'parent' => 'blog',
1235
					'id'     => 'look-and-feel',
1236
				)
1237
			);
1238
1239
			// Look and Feel header.
1240
			$wp_admin_bar->add_menu(
1241
				array(
1242
					'parent' => 'look-and-feel',
1243
					'id'     => 'look-and-feel-header',
1244
					'title'  => esc_html_x( 'Personalize', 'admin bar menu group label', 'jetpack' ),
1245
					'meta'   => array(
1246
						'class' => 'ab-submenu-header',
1247
					),
1248
				)
1249
			);
1250
1251
			if ( is_admin() ) {
1252
				// In wp-admin the `return` query arg will return to that page after closing the Customizer.
1253
				$customizer_url = add_query_arg(
1254
					array(
1255
						'return' => rawurlencode( site_url( $_SERVER['REQUEST_URI'] ) ),
1256
					),
1257
					wp_customize_url()
1258
				);
1259
			} else {
1260
				/*
1261
				 * On the frontend the `url` query arg will load that page in the Customizer
1262
				 * and also return to it after closing
1263
				 * non-home URLs won't work unless we undo domain mapping
1264
				 * since the Customizer preview is unmapped to always have HTTPS.
1265
				 */
1266
				$current_page   = '//' . $this->primary_site_slug . $_SERVER['REQUEST_URI'];
1267
				$customizer_url = add_query_arg( array( 'url' => rawurlencode( $current_page ) ), wp_customize_url() );
1268
			}
1269
1270
			$theme_title = $this->create_menu_item_pair(
1271
				array(
1272
					'url'   => $customizer_url,
1273
					'id'    => 'wp-admin-bar-cmz',
1274
					'label' => esc_html_x( 'Customize', 'admin bar customize item label', 'jetpack' ),
1275
				),
1276
				array(
1277
					'url'   => Redirect::get_url( 'calypso-themes' ),
1278
					'id'    => 'wp-admin-bar-themes',
1279
					'label' => esc_html__( 'Themes', 'jetpack' ),
1280
				)
1281
			);
1282
			$meta        = array(
1283
				'class' => 'mb-icon',
1284
				'class' => 'inline-action',
1285
			);
1286
			$href        = false;
1287
1288
			$wp_admin_bar->add_menu(
1289
				array(
1290
					'parent' => 'look-and-feel',
1291
					'id'     => 'themes',
1292
					'title'  => $theme_title,
1293
					'href'   => $href,
1294
					'meta'   => $meta,
1295
				)
1296
			);
1297
		}
1298
1299
		if ( current_user_can( 'manage_options' ) ) {
1300
			// Configuration group.
1301
			$wp_admin_bar->add_group(
1302
				array(
1303
					'parent' => 'blog',
1304
					'id'     => 'configuration',
1305
				)
1306
			);
1307
1308
			// Configuration header.
1309
			$wp_admin_bar->add_menu(
1310
				array(
1311
					'parent' => 'configuration',
1312
					'id'     => 'configuration-header',
1313
					'title'  => esc_html_x( 'Configure', 'admin bar menu group label', 'jetpack' ),
1314
					'meta'   => array(
1315
						'class' => 'ab-submenu-header',
1316
					),
1317
				)
1318
			);
1319
1320 View Code Duplication
			if ( Jetpack::is_module_active( 'publicize' ) || Jetpack::is_module_active( 'sharedaddy' ) ) {
1321
				$wp_admin_bar->add_menu(
1322
					array(
1323
						'parent' => 'configuration',
1324
						'id'     => 'sharing',
1325
						'title'  => esc_html__( 'Sharing', 'jetpack' ),
1326
						'href'   => Redirect::get_url( 'calypso-sharing' ),
1327
						'meta'   => array(
1328
							'class' => 'mb-icon',
1329
						),
1330
					)
1331
				);
1332
			}
1333
1334
			$people_title = $this->create_menu_item_pair(
1335
				array(
1336
					'url'   => Redirect::get_url( 'calypso-people-team' ),
1337
					'id'    => 'wp-admin-bar-people',
1338
					'label' => esc_html__( 'People', 'jetpack' ),
1339
				),
1340
				array(
1341
					'url'   => admin_url( 'user-new.php' ),
1342
					'id'    => 'wp-admin-bar-people-add',
1343
					'label' => esc_html_x( 'Add', 'admin bar people item label', 'jetpack' ),
1344
				)
1345
			);
1346
1347
			$wp_admin_bar->add_menu(
1348
				array(
1349
					'parent' => 'configuration',
1350
					'id'     => 'users-toolbar',
1351
					'title'  => $people_title,
1352
					'href'   => false,
1353
					'meta'   => array(
1354
						'class' => 'inline-action',
1355
					),
1356
				)
1357
			);
1358
1359
			$plugins_title = $this->create_menu_item_pair(
1360
				array(
1361
					'url'   => Redirect::get_url( 'calypso-plugins' ),
1362
					'id'    => 'wp-admin-bar-plugins',
1363
					'label' => esc_html__( 'Plugins', 'jetpack' ),
1364
				),
1365
				array(
1366
					'url'   => Redirect::get_url( 'calypso-plugins-manage' ),
1367
					'id'    => 'wp-admin-bar-plugins-add',
1368
					'label' => esc_html_x( 'Manage', 'Label for the button on the Masterbar to manage plugins', 'jetpack' ),
1369
				)
1370
			);
1371
1372
			$wp_admin_bar->add_menu(
1373
				array(
1374
					'parent' => 'configuration',
1375
					'id'     => 'plugins',
1376
					'title'  => $plugins_title,
1377
					'href'   => false,
1378
					'meta'   => array(
1379
						'class' => 'inline-action',
1380
					),
1381
				)
1382
			);
1383
1384
			if ( jetpack_is_atomic_site() ) {
1385
				$domain_title = $this->create_menu_item_pair(
1386
					array(
1387
						'url'   => Redirect::get_url( 'calypso-domains' ),
1388
						'id'    => 'wp-admin-bar-domains',
1389
						'label' => esc_html__( 'Domains', 'jetpack' ),
1390
					),
1391
					array(
1392
						'url'   => Redirect::get_url( 'calypso-domains-add' ),
1393
						'id'    => 'wp-admin-bar-domains-add',
1394
						'label' => esc_html_x( 'Add', 'Label for the button on the Masterbar to add a new domain', 'jetpack' ),
1395
					)
1396
				);
1397
				$wp_admin_bar->add_menu(
1398
					array(
1399
						'parent' => 'configuration',
1400
						'id'     => 'domains',
1401
						'title'  => $domain_title,
1402
						'href'   => false,
1403
						'meta'   => array(
1404
							'class' => 'inline-action',
1405
						),
1406
					)
1407
				);
1408
			}
1409
1410
			$wp_admin_bar->add_menu(
1411
				array(
1412
					'parent' => 'configuration',
1413
					'id'     => 'blog-settings',
1414
					'title'  => esc_html__( 'Settings', 'jetpack' ),
1415
					'href'   => Redirect::get_url( 'calypso-settings-general' ),
1416
					'meta'   => array(
1417
						'class' => 'mb-icon',
1418
					),
1419
				)
1420
			);
1421
1422
			if ( ! is_admin() ) {
1423
				$wp_admin_bar->add_menu(
1424
					array(
1425
						'parent' => 'configuration',
1426
						'id'     => 'legacy-dashboard',
1427
						'title'  => esc_html__( 'Dashboard', 'jetpack' ),
1428
						'href'   => admin_url(),
1429
						'meta'   => array(
1430
							'class' => 'mb-icon',
1431
						),
1432
					)
1433
				);
1434
			}
1435
1436
			// Restore dashboard menu toggle that is needed on mobile views.
1437
			if ( is_admin() ) {
1438
				$wp_admin_bar->add_menu(
1439
					array(
1440
						'id'    => 'menu-toggle',
1441
						'title' => '<span class="ab-icon"></span><span class="screen-reader-text">' . esc_html__( 'Menu', 'jetpack' ) . '</span>',
1442
						'href'  => '#',
1443
					)
1444
				);
1445
			}
1446
1447
			/**
1448
			 * Fires when menu items are added to the masterbar "My Sites" menu.
1449
			 *
1450
			 * @since 5.4.0
1451
			 */
1452
			do_action( 'jetpack_masterbar' );
1453
		}
1454
	}
1455
1456
	/**
1457
	 * Adds "My Home" submenu item to sites that are eligible.
1458
	 *
1459
	 * @param WP_Admin_Bar $wp_admin_bar Admin Bar instance.
1460
	 * @return void
1461
	 */
1462
	private function add_my_home_submenu_item( &$wp_admin_bar ) {
1463
		if ( ! current_user_can( 'manage_options' ) || ! jetpack_is_atomic_site() ) {
1464
			return;
1465
		}
1466
1467
		$wp_admin_bar->add_menu(
1468
			array(
1469
				'parent' => 'blog',
1470
				'id'     => 'my-home',
1471
				'title'  => __( 'My Home', 'jetpack' ),
1472
				'href'   => Redirect::get_url( 'calypso-home' ),
1473
				'meta'   => array(
1474
					'class' => 'mb-icon',
1475
				),
1476
			)
1477
		);
1478
	}
1479
}
1480