Completed
Push — kraftbj-patch-3 ( cb1f13 )
by
unknown
140:22 queued 129:36
created

A8C_WPCOM_Masterbar   D

Complexity

Total Complexity 71

Size/Duplication

Total Lines 1019
Duplicated Lines 10.11 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
dl 103
loc 1019
rs 4.9751
c 0
b 0
f 0
wmc 71
lcom 1
cbo 3

20 Methods

Rating   Name   Duplication   Size   Complexity  
B __construct() 0 60 6
A maybe_logout_user_from_wpcom() 0 5 3
A get_rtl_admin_bar_class() 0 3 1
A admin_body_class() 0 3 1
A remove_core_styles() 0 3 1
A is_rtl() 0 3 2
B add_styles_and_scripts() 0 36 3
A wpcom_static_url() 0 11 2
A replace_core_masterbar() 0 10 2
A clear_core_masterbar() 0 5 2
A build_wpcom_masterbar() 0 16 2
B get_locale() 6 18 6
A add_notifications() 0 21 2
B add_reader_submenu() 0 85 1
A create_menu_item_pair() 0 9 1
A create_menu_item_anchor() 0 3 1
A wpcom_adminbar_add_secondary_groups() 0 23 1
B add_me_submenu() 0 159 4
B add_write_button() 0 26 4
F add_my_sites_submenu() 97 469 26

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like A8C_WPCOM_Masterbar often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use A8C_WPCOM_Masterbar, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
require_once dirname( __FILE__ ) . '/rtl-admin-bar.php';
4
5
class A8C_WPCOM_Masterbar {
6
	/**
7
	 * Use for testing changes made to remotely enqueued scripts and styles on your sandbox.
8
	 * If not set it will default to loading the ones from WordPress.com.
9
	 *
10
	 * @var string $sandbox_url
11
	 */
12
	private $sandbox_url = '';
13
14
	private $locale;
15
16
	private $user_id;
17
	private $user_data;
18
	private $user_login;
19
	private $user_email;
20
	private $display_name;
21
	private $primary_site_slug;
22
	private $user_text_direction;
23
	private $user_site_count;
24
25
	function __construct() {
26
		$this->locale  = $this->get_locale();
27
		$this->user_id = get_current_user_id();
28
29
		// Limit the masterbar to be shown only to connected Jetpack users.
30
		if ( ! Jetpack::is_user_connected( $this->user_id ) ) {
31
			return;
32
		}
33
34
		Jetpack::dns_prefetch( array(
35
			'//s0.wp.com',
36
			'//s1.wp.com',
37
			'//s2.wp.com',
38
			'//0.gravatar.com',
39
			'//1.gravatar.com',
40
			'//2.gravatar.com',
41
		) );
42
43
		// Atomic only - override user setting that hides masterbar from site's front.
44
		// https://github.com/Automattic/jetpack/issues/7667
45
		if ( jetpack_is_atomic_site() ) {
46
			add_filter( 'show_admin_bar', '__return_true' );
47
		}
48
49
		$this->user_data = Jetpack::get_connected_user_data( $this->user_id );
50
		$this->user_login = $this->user_data['login'];
51
		$this->user_email = $this->user_data['email'];
52
		$this->display_name = $this->user_data['display_name'];
53
		$this->user_site_count = $this->user_data['site_count'];
54
55
		// Used to build menu links that point directly to Calypso.
56
		$this->primary_site_slug = Jetpack::build_raw_urls( get_home_url() );
57
58
		// Used for display purposes and for building WP Admin links.
59
		$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...
60
61
		// We need to use user's setting here, instead of relying on current blog's text direction
62
		$this->user_text_direction = $this->user_data['text_direction'];
63
64
		if ( $this->is_rtl() ) {
65
			// Extend core WP_Admin_Bar class in order to add rtl styles
66
			add_filter( 'wp_admin_bar_class', array( $this, 'get_rtl_admin_bar_class' ) );
67
		}
68
		add_filter( 'admin_body_class', array( $this, 'admin_body_class' ) );
69
70
		add_action( 'wp_before_admin_bar_render', array( $this, 'replace_core_masterbar' ), 99999 );
71
72
		add_action( 'wp_enqueue_scripts', array( $this, 'add_styles_and_scripts' ) );
73
		add_action( 'admin_enqueue_scripts', array( $this, 'add_styles_and_scripts' ) );
74
75
		add_action( 'wp_enqueue_scripts', array( $this, 'remove_core_styles' ) );
76
		add_action( 'admin_enqueue_scripts', array( $this, 'remove_core_styles' ) );
77
78
		if ( Jetpack::is_module_active( 'notes' ) && $this->is_rtl() ) {
79
			// Override Notification module to include RTL styles
80
			add_action( 'a8c_wpcom_masterbar_enqueue_rtl_notification_styles', '__return_true' );
81
		}
82
83
		add_action( 'wp_logout', array( $this, 'maybe_logout_user_from_wpcom' ) );
84
	}
85
86
	public function maybe_logout_user_from_wpcom() {
87
		if ( isset( $_GET['context'] ) && 'masterbar' === $_GET['context'] ) {
88
			do_action( 'wp_masterbar_logout' );
89
		}
90
	}
91
92
	public function get_rtl_admin_bar_class() {
93
		return 'RTL_Admin_Bar';
94
	}
95
96
	/**
97
	 * Adds CSS classes to admin body tag.
98
	 *
99
	 * @since 5.1
100
	 *
101
	 * @param string $admin_body_classes CSS classes that will be added.
102
	 *
103
	 * @return string
104
	 */
105
	public function admin_body_class( $admin_body_classes ) {
106
		return "$admin_body_classes jetpack-masterbar";
107
	}
108
109
	public function remove_core_styles() {
110
		wp_dequeue_style( 'admin-bar' );
111
	}
112
113
	public function is_rtl() {
114
		return $this->user_text_direction === 'rtl' ? true : false;
115
	}
116
117
	public function add_styles_and_scripts() {
118
119
		if ( $this->is_rtl() ) {
120
			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 );
121
			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 );
122
		} else {
123
			wp_enqueue_style( 'a8c-wpcom-masterbar', $this->wpcom_static_url( '/wp-content/mu-plugins/admin-bar/wpcom-admin-bar.css' ), array(), JETPACK__VERSION );
124
			wp_enqueue_style( 'a8c-wpcom-masterbar-overrides', $this->wpcom_static_url( '/wp-content/mu-plugins/admin-bar/masterbar-overrides/masterbar.css' ), array(), JETPACK__VERSION );
125
		}
126
127
		// Local overrides
128
		wp_enqueue_style( 'a8c_wpcom_css_override', plugins_url( 'overrides.css', __FILE__ ), array(), JETPACK__VERSION );
129
130
		if ( ! Jetpack::is_module_active( 'notes ' ) ) {
131
			// Masterbar is relying on some icons from noticons.css
132
			wp_enqueue_style( 'noticons', $this->wpcom_static_url( '/i/noticons/noticons.css' ), array(), JETPACK__VERSION . '-' . gmdate( 'oW' ) );
133
		}
134
135
		wp_enqueue_script(
136
			'jetpack-accessible-focus',
137
			Jetpack::get_file_url_for_environment( '_inc/build/accessible-focus.min.js', '_inc/accessible-focus.js' ),
138
			array(),
139
			JETPACK__VERSION
140
		);
141
		wp_enqueue_script(
142
			'a8c_wpcom_masterbar_tracks_events',
143
			Jetpack::get_file_url_for_environment(
144
				'_inc/build/masterbar/tracks-events.min.js',
145
				'modules/masterbar/tracks-events.js'
146
			),
147
			array( 'jquery' ),
148
			JETPACK__VERSION
149
		);
150
151
		wp_enqueue_script( 'a8c_wpcom_masterbar_overrides', $this->wpcom_static_url( '/wp-content/mu-plugins/admin-bar/masterbar-overrides/masterbar.js' ), array( 'jquery' ), JETPACK__VERSION );
152
	}
153
154
	function wpcom_static_url( $file ) {
155
		if ( ! empty( $this->sandbox_url ) ) {
156
			// For testing undeployed changes to remotely enqueued scripts and styles.
157
			return set_url_scheme( $this->sandbox_url . $file, 'https');
158
		}
159
160
		$i   = hexdec( substr( md5( $file ), - 1 ) ) % 2;
161
		$url = 'https://s' . $i . '.wp.com' . $file;
162
163
		return set_url_scheme( $url, 'https');
164
	}
165
166
	public function replace_core_masterbar() {
167
		global $wp_admin_bar;
168
169
		if ( ! is_object( $wp_admin_bar ) ) {
170
			return false;
171
		}
172
173
		$this->clear_core_masterbar( $wp_admin_bar );
174
		$this->build_wpcom_masterbar( $wp_admin_bar );
175
	}
176
177
	// Remove all existing toolbar entries from core Masterbar
178
	public function clear_core_masterbar( $wp_admin_bar ) {
179
		foreach ( $wp_admin_bar->get_nodes() as $node ) {
180
			$wp_admin_bar->remove_node( $node->id );
181
		}
182
	}
183
184
	// Add entries corresponding to WordPress.com Masterbar
185
	public function build_wpcom_masterbar( $wp_admin_bar ) {
186
		// Menu groups
187
		$this->wpcom_adminbar_add_secondary_groups( $wp_admin_bar );
188
189
		// Left part
190
		$this->add_my_sites_submenu( $wp_admin_bar );
191
		$this->add_reader_submenu( $wp_admin_bar );
192
193
		// Right part
194
		if ( Jetpack::is_module_active( 'notes' ) ) {
195
			$this->add_notifications( $wp_admin_bar );
196
		}
197
198
		$this->add_me_submenu( $wp_admin_bar );
199
		$this->add_write_button( $wp_admin_bar );
200
	}
201
202
	public function get_locale() {
203
		$wpcom_locale = get_locale();
204
205
		if ( ! class_exists( 'GP_Locales' ) ) {
206
			if ( defined( 'JETPACK__GLOTPRESS_LOCALES_PATH' ) && file_exists( JETPACK__GLOTPRESS_LOCALES_PATH ) ) {
207
				require JETPACK__GLOTPRESS_LOCALES_PATH;
208
			}
209
		}
210
211 View Code Duplication
		if ( class_exists( 'GP_Locales' ) ) {
212
			$wpcom_locale_object = GP_Locales::by_field( 'wp_locale', get_locale() );
213
			if ( $wpcom_locale_object instanceof GP_Locale ) {
214
				$wpcom_locale = $wpcom_locale_object->slug;
215
			}
216
		}
217
218
		return $wpcom_locale;
219
	}
220
221
	public function add_notifications( $wp_admin_bar ) {
222
		$wp_admin_bar->add_node( array(
223
			'id'     => 'notes',
224
			'title'  => '<span id="wpnt-notes-unread-count" class="wpnt-loading wpn-read"></span>
225
						 <span class="screen-reader-text">' . esc_html__( 'Notifications', 'jetpack' ) . '</span>
226
						 <span class="noticon noticon-bell"></span>',
227
			'meta'   => array(
228
				'html'  => '<div id="wpnt-notes-panel2" style="display:none" lang="'. esc_attr( $this->locale ) . '" dir="' . ( $this->is_rtl() ? 'rtl' : 'ltr' ) . '">' .
229
				           '<div class="wpnt-notes-panel-header">' .
230
				           '<span class="wpnt-notes-header">' .
231
				           esc_html__( 'Notifications', 'jetpack' ) .
232
				           '</span>' .
233
				           '<span class="wpnt-notes-panel-link">' .
234
				           '</span>' .
235
				           '</div>' .
236
				           '</div>',
237
				'class' => 'menupop mb-trackable',
238
			),
239
			'parent' => 'top-secondary',
240
		) );
241
	}
242
243
	public function add_reader_submenu( $wp_admin_bar ) {
244
		$wp_admin_bar->add_menu( array(
245
			'parent' => 'root-default',
246
			'id'    => 'newdash',
247
			'title' => esc_html__( 'Reader', 'jetpack' ),
248
			'href'  => '#',
249
			'meta'  => array(
250
				'class' => 'mb-trackable',
251
			)
252
		) );
253
254
		$wp_admin_bar->add_menu( array(
255
			'parent' => 'newdash',
256
			'id'     => 'streams-header',
257
			'title'  => esc_html_x(
258
				'Streams',
259
				'Title for Reader sub-menu that contains followed sites, likes, and recommendations',
260
				'jetpack'
261
			),
262
			'meta'   => array(
263
				'class' => 'ab-submenu-header',
264
			)
265
		) );
266
267
		$following_title = $this->create_menu_item_pair(
268
			array(
269
				'url'   => 'https://wordpress.com/',
270
				'id'    => 'wp-admin-bar-followed-sites',
271
				'label' => esc_html__( 'Followed Sites', 'jetpack' ),
272
			),
273
			array(
274
				'url'   => 'https://wordpress.com/following/edit',
275
				'id'    => 'wp-admin-bar-reader-followed-sites-manage',
276
				'label' => esc_html__( 'Manage', 'jetpack' ),
277
			)
278
		);
279
280
		$wp_admin_bar->add_menu( array(
281
			'parent' => 'newdash',
282
			'id'     => 'following',
283
			'title'  => $following_title,
284
			'meta'	 => array( 'class' => 'inline-action' )
285
		) );
286
287
		$wp_admin_bar->add_menu( array(
288
			'parent' => 'newdash',
289
			'id'     => 'discover-discover',
290
			'title'  => esc_html__( 'Discover', 'jetpack' ),
291
			'href'   => 'https://wordpress.com/discover',
292
			'meta'   => array(
293
				'class' => 'mb-icon-spacer',
294
			)
295
		) );
296
297
		$wp_admin_bar->add_menu( array(
298
			'parent' => 'newdash',
299
			'id'     => 'discover-search',
300
			'title'  => esc_html__( 'Search', 'jetpack' ),
301
			'href'   => 'https://wordpress.com/read/search',
302
			'meta'   => array(
303
				'class' => 'mb-icon-spacer',
304
			)
305
		) );
306
307
		$wp_admin_bar->add_menu( array(
308
			'parent' => 'newdash',
309
			'id'     => 'discover-recommended-blogs',
310
			'title'  => esc_html__( 'Recommendations', 'jetpack' ),
311
			'href'   => 'https://wordpress.com/recommendations',
312
			'meta'   => array(
313
				'class' => 'mb-icon-spacer',
314
			)
315
		) );
316
317
		$wp_admin_bar->add_menu( array(
318
			'parent' => 'newdash',
319
			'id'     => 'my-activity-my-likes',
320
			'title'  => esc_html__( 'My Likes', 'jetpack' ),
321
			'href'   => 'https://wordpress.com/activities/likes',
322
			'meta'   => array(
323
				'class' => 'mb-icon-spacer',
324
			)
325
		) );
326
327
	}
328
329
	public function create_menu_item_pair( $primary, $secondary ) {
330
		$primary_class   = 'ab-item ab-primary mb-icon';
331
		$secondary_class = 'ab-secondary';
332
333
		$primary_anchor   = $this->create_menu_item_anchor( $primary_class, $primary['url'], $primary['label'], $primary['id'] );
334
		$secondary_anchor = $this->create_menu_item_anchor( $secondary_class, $secondary['url'], $secondary['label'], $secondary['id'] );
335
336
		return $primary_anchor . $secondary_anchor;
337
	}
338
339
	public function create_menu_item_anchor( $class, $url, $label, $id ) {
340
		return '<a href="' . $url . '" class="' . $class . '" id="' . $id . '">' . $label . '</a>';
341
	}
342
343
	public function wpcom_adminbar_add_secondary_groups( $wp_admin_bar ) {
344
		$wp_admin_bar->add_group( array(
345
			'id'     => 'root-default',
346
			'meta'   => array(
347
				'class' => 'ab-top-menu',
348
			),
349
		) );
350
351
		$wp_admin_bar->add_group( array(
352
			'parent' => 'blog',
353
			'id'     => 'blog-secondary',
354
			'meta'   => array(
355
				'class' => 'ab-sub-secondary',
356
			),
357
		) );
358
359
		$wp_admin_bar->add_group( array(
360
			'id'     => 'top-secondary',
361
			'meta'   => array(
362
				'class' => 'ab-top-secondary',
363
			),
364
		) );
365
	}
366
367
	public function add_me_submenu( $wp_admin_bar ) {
368
		$user_id = get_current_user_id();
369
		if ( empty( $user_id ) ) {
370
			return;
371
		}
372
373
		$avatar = get_avatar( $this->user_email, 32, 'mm', '', array( 'force_display' => true ) );
374
		$class  = empty( $avatar ) ? 'mb-trackable' : 'with-avatar mb-trackable';
375
376
		// Add the 'Me' menu
377
		$wp_admin_bar->add_menu( array(
378
			'id'     => 'my-account',
379
			'parent' => 'top-secondary',
380
			'title'  => $avatar . '<span class="ab-text">' . esc_html__( 'Me', 'jetpack' ) . '</span>',
381
			'href'   => '#',
382
			'meta'   => array(
383
				'class' => $class,
384
			),
385
		) );
386
387
		$id = 'user-actions';
388
		$wp_admin_bar->add_group( array(
389
			'parent' => 'my-account',
390
			'id'     => $id,
391
		) );
392
393
		$settings_url = 'https://wordpress.com/me/account';
394
395
		$logout_url = wp_logout_url();
396
		$logout_url = add_query_arg( 'context', 'masterbar', $logout_url );
397
398
		$user_info  = get_avatar( $this->user_email, 128, 'mm', '', array( 'force_display' => true ) );
399
		$user_info .= '<span class="display-name">' . $this->display_name . '</span>';
400
		$user_info .= '<a class="username" href="http://gravatar.com/' . $this->user_login . '">@' . $this->user_login . '</a>';
401
402
		$user_info .= sprintf(
403
			'<div><a href="%s" class="ab-sign-out">%s</a></div>',
404
			$logout_url,
405
			esc_html__( 'Sign Out', 'jetpack' )
406
		);
407
408
		$wp_admin_bar->add_menu( array(
409
			'parent' => $id,
410
			'id'     => 'user-info',
411
			'title'  => $user_info,
412
			'meta'   => array(
413
				'class' => 'user-info user-info-item',
414
				'tabindex' => -1,
415
			),
416
		) );
417
418
		$wp_admin_bar->add_menu( array(
419
			'parent' => $id,
420
			'id'     => 'profile-header',
421
			'title'  => esc_html__( 'Profile', 'jetpack' ),
422
			'meta'   => array(
423
				'class' => 'ab-submenu-header',
424
			),
425
		) );
426
427
		$wp_admin_bar->add_menu( array(
428
			'parent' => $id,
429
			'id'     => 'my-profile',
430
			'title'  => esc_html__( 'My Profile', 'jetpack' ),
431
			'href'   => 'https://wordpress.com/me',
432
			'meta'   => array(
433
				'class' => 'mb-icon',
434
			),
435
		) );
436
437
		$wp_admin_bar->add_menu( array(
438
			'parent' => $id,
439
			'id'     => 'account-settings',
440
			'title'  => esc_html__( 'Account Settings', 'jetpack' ),
441
			'href'   => $settings_url,
442
			'meta'   => array(
443
				'class' => 'mb-icon',
444
			),
445
		) );
446
447
		$wp_admin_bar->add_menu( array(
448
			'parent' => $id,
449
			'id'     => 'billing',
450
			'title'  => esc_html__( 'Manage Purchases', 'jetpack' ),
451
			'href'   => 'https://wordpress.com/me/purchases',
452
			'meta'   => array(
453
				'class' => 'mb-icon',
454
			),
455
		) );
456
457
		$wp_admin_bar->add_menu( array(
458
			'parent' => $id,
459
			'id'     => 'security',
460
			'title'  => esc_html__( 'Security', 'jetpack' ),
461
			'href'   => 'https://wordpress.com/me/security',
462
			'meta'   => array(
463
				'class' => 'mb-icon',
464
			),
465
		) );
466
467
		$wp_admin_bar->add_menu( array(
468
			'parent' => $id,
469
			'id'     => 'notifications',
470
			'title'  => esc_html__( 'Notifications', 'jetpack' ),
471
			'href'   => 'https://wordpress.com/me/notifications',
472
			'meta'   => array(
473
				'class' => 'mb-icon',
474
			),
475
		) );
476
477
		$wp_admin_bar->add_menu( array(
478
			'parent' => $id,
479
			'id'     => 'special-header',
480
			'title'  => esc_html_x(
481
				'Special',
482
				'Title for Me sub-menu that contains Get Apps, Next Steps, and Help options',
483
				'jetpack'
484
			),
485
			'meta'   => array(
486
				'class' => 'ab-submenu-header',
487
			),
488
		) );
489
490
		$wp_admin_bar->add_menu( array(
491
			'parent' => $id,
492
			'id'     => 'get-apps',
493
			'title'  => esc_html__( 'Get Apps', 'jetpack' ),
494
			'href'   => 'https://wordpress.com/me/get-apps',
495
			'meta'   => array(
496
				'class' => 'mb-icon user-info-item',
497
			),
498
		) );
499
500
		$wp_admin_bar->add_menu( array(
501
			'parent' => $id,
502
			'id'     => 'next-steps',
503
			'title'  => esc_html__( 'Next Steps', 'jetpack' ),
504
			'href'   => 'https://wordpress.com/me/next',
505
			'meta'   => array(
506
				'class' => 'mb-icon user-info-item',
507
			),
508
		) );
509
510
		$help_link = 'https://jetpack.com/support/';
511
512
		if ( jetpack_is_atomic_site() ) {
513
			$help_link = 'https://wordpress.com/help';
514
		}
515
516
		$wp_admin_bar->add_menu( array(
517
			'parent' => $id,
518
			'id'     => 'help',
519
			'title'  => esc_html__( 'Help', 'jetpack' ),
520
			'href'   => $help_link,
521
			'meta'   => array(
522
				'class' => 'mb-icon user-info-item',
523
			),
524
		) );
525
	}
526
527
	public function add_write_button( $wp_admin_bar ) {
528
		$current_user = wp_get_current_user();
529
530
		$posting_blog_id = get_current_blog_id();
531
		if ( ! is_user_member_of_blog( get_current_user_id(), get_current_blog_id() ) ) {
532
			$posting_blog_id = $current_user->primary_blog;
533
		}
534
535
		$user_can_post = current_user_can_for_blog( $posting_blog_id, 'publish_posts' );
536
537
		if ( ! $posting_blog_id || ! $user_can_post ) {
538
			return;
539
		}
540
541
		$blog_post_page = 'https://wordpress.com/post/' . esc_attr( $this->primary_site_slug );
542
543
		$wp_admin_bar->add_menu( array(
544
			'parent'    => 'top-secondary',
545
			'id' => 'ab-new-post',
546
			'href' => $blog_post_page,
547
			'title' => '<span>' . esc_html__( 'Write', 'jetpack' ) . '</span>',
548
			'meta'  => array(
549
				'class' => 'mb-trackable',
550
			)
551
		) );
552
	}
553
554
	public function add_my_sites_submenu( $wp_admin_bar ) {
555
		$current_user = wp_get_current_user();
556
557
		$blog_name = get_bloginfo( 'name' );
558
		if ( empty( $blog_name ) ) {
559
			$blog_name = $this->primary_site_slug;
560
		}
561
562
		if ( mb_strlen( $blog_name ) > 20 ) {
563
			$blog_name = mb_substr( html_entity_decode( $blog_name, ENT_QUOTES ), 0, 20 ) . '&hellip;';
564
		}
565
566
		$wp_admin_bar->add_menu( array(
567
			'parent' => 'root-default',
568
			'id'    => 'blog',
569
			'title' => _n( 'My Site', 'My Sites', $this->user_site_count, 'jetpack' ),
570
			'href'  => '#',
571
			'meta'  => array(
572
				'class' => 'my-sites mb-trackable',
573
			),
574
		) );
575
576
		if ( $this->user_site_count > 1 ) {
577
			$wp_admin_bar->add_menu( array(
578
				'parent' => 'blog',
579
				'id'     => 'switch-site',
580
				'title'  => esc_html__( 'Switch Site', 'jetpack' ),
581
				'href'   => 'https://wordpress.com/sites',
582
			) );
583
		} else {
584
			$wp_admin_bar->add_menu( array(
585
				'parent' => 'blog',
586
				'id'     => 'new-site',
587
				'title'  => esc_html__( '+ Add New WordPress', 'jetpack' ),
588
				'href'   => 'https://wordpress.com/start?ref=admin-bar-logged-in',
589
			) );
590
		}
591
592
		if ( is_user_member_of_blog( $current_user->ID ) ) {
593
			$blavatar = '';
594
			$class    = 'current-site';
595
596
			if ( has_site_icon() ) {
597
				$src = get_site_icon_url();
598
				$blavatar = '<img class="avatar" src="'. esc_attr( $src ) . '" alt="Current site avatar">';
599
				$class = 'has-blavatar';
600
			}
601
602
			$blog_info = '<div class="ab-site-icon">' . $blavatar . '</div>';
603
			$blog_info .= '<span class="ab-site-title">' . esc_html( $blog_name ) . '</span>';
604
			$blog_info .= '<span class="ab-site-description">' . esc_html( $this->primary_site_url ) . '</span>';
605
606
			$wp_admin_bar->add_menu( array(
607
				'parent' => 'blog',
608
				'id'     => 'blog-info',
609
				'title'  => $blog_info,
610
				'href'   => esc_url( trailingslashit( $this->primary_site_url ) ),
611
				'meta'   => array(
612
					'class' => $class,
613
				),
614
			) );
615
		}
616
617
		// Site Preview
618
		if ( is_admin() ) {
619
			$wp_admin_bar->add_menu( array(
620
				'parent' => 'blog',
621
				'id'     => 'site-view',
622
				'title'  => __( 'View Site', 'jetpack' ),
623
				'href'   => home_url(),
624
				'meta'   => array(
625
					'class' => 'mb-icon',
626
					'target' => '_blank',
627
				),
628
			) );
629
		}
630
631
		// Stats
632 View Code Duplication
		if ( Jetpack::is_module_active( 'stats' ) ) {
633
			$wp_admin_bar->add_menu( array(
634
				'parent' => 'blog',
635
				'id'     => 'blog-stats',
636
				'title'  => esc_html__( 'Stats', 'jetpack' ),
637
				'href'   => 'https://wordpress.com/stats/' . esc_attr( $this->primary_site_slug ),
638
				'meta'   => array(
639
					'class' => 'mb-icon',
640
				),
641
			) );
642
		}
643
644
		// Add Calypso plans link and plan type indicator
645
		if ( is_user_member_of_blog( $current_user->ID ) ) {
646
			$plans_url = 'https://wordpress.com/plans/' . esc_attr( $this->primary_site_slug );
647
			$label = esc_html__( 'Plan', 'jetpack' );
648
			$plan = Jetpack::get_active_plan();
649
650
			$plan_title = $this->create_menu_item_pair(
651
				array(
652
					'url'   => $plans_url,
653
					'id'    => 'wp-admin-bar-plan',
654
					'label' => $label,
655
				),
656
				array(
657
					'url'   => $plans_url,
658
					'id'    => 'wp-admin-bar-plan-badge',
659
					'label' => $plan['product_name_short']
660
				)
661
			);
662
663
			$wp_admin_bar->add_menu( array(
664
				'parent' => 'blog',
665
				'id'     => 'plan',
666
				'title'  => $plan_title,
667
				'meta'   => array(
668
					'class' => 'inline-action',
669
				),
670
			) );
671
		}
672
673
		// Publish group
674
		$wp_admin_bar->add_group( array(
675
			'parent' => 'blog',
676
			'id'     => 'publish',
677
		) );
678
679
		// Publish header
680
		$wp_admin_bar->add_menu( array(
681
			'parent' => 'publish',
682
			'id'     => 'publish-header',
683
			'title'  => esc_html_x( 'Manage', 'admin bar menu group label', 'jetpack' ),
684
			'meta'   => array(
685
				'class' => 'ab-submenu-header',
686
			),
687
		) );
688
689
		// Pages
690
		$pages_title = $this->create_menu_item_pair(
691
			array(
692
				'url'   => 'https://wordpress.com/pages/' . esc_attr( $this->primary_site_slug ),
693
				'id'    => 'wp-admin-bar-edit-page',
694
				'label' => esc_html__( 'Site Pages', 'jetpack' ),
695
			),
696
			array(
697
				'url'   => 'https://wordpress.com/page/' . esc_attr( $this->primary_site_slug ),
698
				'id'    => 'wp-admin-bar-new-page-badge',
699
				'label' => esc_html_x( 'Add', 'admin bar menu new item label', 'jetpack' ),
700
			)
701
		);
702
703
		if ( ! current_user_can( 'edit_pages' ) ) {
704
			$pages_title = $this->create_menu_item_anchor(
705
				'ab-item ab-primary mb-icon',
706
				'https://wordpress.com/pages/' . esc_attr( $this->primary_site_slug ),
707
				esc_html__( 'Site Pages', 'jetpack' ),
708
				'wp-admin-bar-edit-page'
709
			);
710
		}
711
712
		$wp_admin_bar->add_menu( array(
713
			'parent' => 'publish',
714
			'id'     => 'new-page',
715
			'title'  => $pages_title,
716
			'meta'   => array(
717
				'class' => 'inline-action',
718
			),
719
		) );
720
721
		// Blog Posts
722
		$posts_title = $this->create_menu_item_pair(
723
			array(
724
				'url'   => 'https://wordpress.com/posts/' . esc_attr( $this->primary_site_slug ),
725
				'id'    => 'wp-admin-bar-edit-post',
726
				'label' => esc_html__( 'Blog Posts', 'jetpack' ),
727
			),
728
			array(
729
				'url'   => 'https://wordpress.com/post/' . esc_attr( $this->primary_site_slug ),
730
				'id'    => 'wp-admin-bar-new-post-badge',
731
				'label' => esc_html_x( 'Add', 'admin bar menu new item label', 'jetpack' ),
732
			)
733
		);
734
735
		if ( ! current_user_can( 'edit_posts' ) ) {
736
			$posts_title = $this->create_menu_item_anchor(
737
				'ab-item ab-primary mb-icon',
738
				'https://wordpress.com/posts/' . esc_attr( $this->primary_site_slug ),
739
				esc_html__( 'Blog Posts', 'jetpack' ),
740
				'wp-admin-bar-edit-post'
741
			);
742
		}
743
744
		$wp_admin_bar->add_menu( array(
745
			'parent' => 'publish',
746
			'id'     => 'new-post',
747
			'title'  => $posts_title,
748
			'meta'   => array(
749
				'class' => 'inline-action mb-trackable',
750
			),
751
		) );
752
753
		// Comments
754 View Code Duplication
		if ( current_user_can( 'moderate_comments' ) ) {
755
			$wp_admin_bar->add_menu( array(
756
				'parent' => 'publish',
757
				'id'     => 'comments',
758
				'title'  => __( 'Comments' ),
759
				'href'   => 'https://wordpress.com/comments/' . esc_attr( $this->primary_site_slug ),
760
				'meta'   => array(
761
					'class' => 'mb-icon',
762
				),
763
			) );
764
		}
765
766
		// Testimonials
767 View Code Duplication
		if ( Jetpack::is_module_active( 'custom-content-types' ) && get_option( 'jetpack_testimonial' ) ) {
768
			$testimonials_title = $this->create_menu_item_pair(
769
				array(
770
					'url'   => 'https://wordpress.com/types/jetpack-testimonial/' . esc_attr( $this->primary_site_slug ),
771
					'id'    => 'wp-admin-bar-edit-testimonial',
772
					'label' => esc_html__( 'Testimonials', 'jetpack' ),
773
				),
774
				array(
775
					'url'   => 'https://wordpress.com/edit/jetpack-testimonial/' . esc_attr( $this->primary_site_slug ),
776
					'id'    => 'wp-admin-bar-new-testimonial',
777
					'label' => esc_html_x( 'Add', 'Button label for adding a new item via the toolbar menu', 'jetpack' ),
778
				)
779
			);
780
781
			if ( ! current_user_can( 'edit_pages' ) ) {
782
				$testimonials_title = $this->create_menu_item_anchor(
783
					'ab-item ab-primary mb-icon',
784
					'https://wordpress.com/types/jetpack-testimonial/' . esc_attr( $this->primary_site_slug ),
785
					esc_html__( 'Testimonials', 'jetpack' ),
786
					'wp-admin-bar-edit-testimonial'
787
				);
788
			}
789
790
			$wp_admin_bar->add_menu( array(
791
				'parent' => 'publish',
792
				'id'     => 'new-jetpack-testimonial',
793
				'title'  => $testimonials_title,
794
				'meta'   => array(
795
					'class' => 'inline-action',
796
				),
797
			) );
798
		}
799
800
		// Portfolio
801 View Code Duplication
		if ( Jetpack::is_module_active( 'custom-content-types' ) && get_option( 'jetpack_portfolio' ) ) {
802
			$portfolios_title = $this->create_menu_item_pair(
803
				array(
804
					'url'   => 'https://wordpress.com/types/jetpack-portfolio/' . esc_attr( $this->primary_site_slug ),
805
					'id'    => 'wp-admin-bar-edit-portfolio',
806
					'label' => esc_html__( 'Portfolio', 'jetpack' ),
807
				),
808
				array(
809
					'url'   => 'https://wordpress.com/edit/jetpack-portfolio/' . esc_attr( $this->primary_site_slug ),
810
					'id'    => 'wp-admin-bar-new-portfolio',
811
					'label' => esc_html_x( 'Add', 'Button label for adding a new item via the toolbar menu', 'jetpack' ),
812
				)
813
			);
814
815
			if ( ! current_user_can( 'edit_pages' ) ) {
816
				$portfolios_title = $this->create_menu_item_anchor(
817
					'ab-item ab-primary mb-icon',
818
					'https://wordpress.com/types/jetpack-portfolio/' . esc_attr( $this->primary_site_slug ),
819
					esc_html__( 'Portfolio', 'jetpack' ),
820
					'wp-admin-bar-edit-portfolio'
821
				);
822
			}
823
824
			$wp_admin_bar->add_menu( array(
825
				'parent' => 'publish',
826
				'id'     => 'new-jetpack-portfolio',
827
				'title'  => $portfolios_title,
828
				'meta'   => array(
829
					'class' => 'inline-action',
830
				),
831
			) );
832
		}
833
834
		if ( current_user_can( 'edit_theme_options' ) ) {
835
			// Look and Feel group
836
			$wp_admin_bar->add_group( array(
837
				'parent' => 'blog',
838
				'id'     => 'look-and-feel',
839
			) );
840
841
			// Look and Feel header
842
			$wp_admin_bar->add_menu( array(
843
				'parent' => 'look-and-feel',
844
				'id'     => 'look-and-feel-header',
845
				'title'  => esc_html_x( 'Personalize', 'admin bar menu group label', 'jetpack' ),
846
				'meta'   => array(
847
					'class' => 'ab-submenu-header',
848
				),
849
			) );
850
851
			if ( is_admin() ) {
852
				// In wp-admin the `return` query arg will return to that page after closing the Customizer
853
				$customizer_url = add_query_arg( array( 'return' => urlencode( site_url( $_SERVER['REQUEST_URI'] ) ) ), wp_customize_url() );
854
			} else {
855
				// On the frontend the `url` query arg will load that page in the Customizer and also return to it after closing
856
				// non-home URLs won't work unless we undo domain mapping since the Customizer preview is unmapped to always have HTTPS
857
				$current_page = '//' . $this->primary_site_slug . $_SERVER['REQUEST_URI'];
858
				$customizer_url = add_query_arg( array( 'url' => urlencode( $current_page ) ), wp_customize_url() );
859
			}
860
861
			$theme_title = $this->create_menu_item_pair(
862
				array(
863
					'url'   => 'https://wordpress.com/themes/' . esc_attr( $this->primary_site_slug ),
864
					'id'    => 'wp-admin-bar-themes',
865
					'label' => esc_html__( 'Themes', 'jetpack' ),
866
				),
867
				array(
868
					'url'   => $customizer_url,
869
					'id'    => 'wp-admin-bar-cmz',
870
					'label' => esc_html_x( 'Customize', 'admin bar customize item label', 'jetpack' ),
871
				)
872
			);
873
			$meta = array( 'class' => 'mb-icon', 'class' => 'inline-action' );
874
			$href = false;
875
876
			$wp_admin_bar->add_menu( array(
877
				'parent' => 'look-and-feel',
878
				'id'     => 'themes',
879
				'title'  => $theme_title,
880
				'href'   => $href,
881
				'meta'   => $meta
882
			) );
883
		}
884
885
		if ( current_user_can( 'manage_options' ) ) {
886
			// Configuration group
887
			$wp_admin_bar->add_group( array(
888
				'parent' => 'blog',
889
				'id'     => 'configuration',
890
			) );
891
892
			// Configuration header
893
			$wp_admin_bar->add_menu( array(
894
				'parent' => 'configuration',
895
				'id'     => 'configuration-header',
896
				'title'  => esc_html__( 'Configure', 'admin bar menu group label', 'jetpack' ),
897
				'meta'   => array(
898
					'class' => 'ab-submenu-header',
899
				),
900
			) );
901
902 View Code Duplication
			if ( Jetpack::is_module_active( 'publicize' ) || Jetpack::is_module_active( 'sharedaddy' ) ) {
903
				$wp_admin_bar->add_menu( array(
904
					'parent' => 'configuration',
905
					'id'     => 'sharing',
906
					'title'  => esc_html__( 'Sharing', 'jetpack' ),
907
					'href'   => 'https://wordpress.com/sharing/' . esc_attr( $this->primary_site_slug ),
908
					'meta'   => array(
909
						'class' => 'mb-icon',
910
					),
911
				) );
912
			}
913
914
			$people_title = $this->create_menu_item_pair(
915
				array(
916
					'url'   => 'https://wordpress.com/people/team/' . esc_attr( $this->primary_site_slug ),
917
					'id'    => 'wp-admin-bar-people',
918
					'label' => esc_html__( 'People', 'jetpack' ),
919
				),
920
				array(
921
					'url'   => admin_url( 'user-new.php' ),
922
					'id'    => 'wp-admin-bar-people-add',
923
					'label' => esc_html_x( 'Add', 'admin bar people item label', 'jetpack' ),
924
				)
925
			);
926
927
			$wp_admin_bar->add_menu( array(
928
				'parent' => 'configuration',
929
				'id'     => 'users-toolbar',
930
				'title'  => $people_title,
931
				'href'   => false,
932
				'meta'   => array(
933
					'class' => 'inline-action',
934
				),
935
			) );
936
937
			$plugins_title = $this->create_menu_item_pair(
938
				array(
939
					'url'   => 'https://wordpress.com/plugins/' . esc_attr( $this->primary_site_slug ),
940
					'id'    => 'wp-admin-bar-plugins',
941
					'label' => esc_html__( 'Plugins', 'jetpack' ),
942
				),
943
				array(
944
					'url'   => 'https://wordpress.com/plugins/manage/' . esc_attr( $this->primary_site_slug ),
945
					'id'    => 'wp-admin-bar-plugins-add',
946
					'label' => esc_html_x( 'Manage', 'Label for the button on the Masterbar to manage plugins', 'jetpack' ),
947
				)
948
			);
949
950
			$wp_admin_bar->add_menu( array(
951
				'parent' => 'configuration',
952
				'id'     => 'plugins',
953
				'title'  => $plugins_title,
954
				'href'   => false,
955
				'meta'   => array(
956
					'class' => 'inline-action',
957
				),
958
			) );
959
960
			if ( jetpack_is_atomic_site() ) {
961
				$domain_title = $this->create_menu_item_pair(
962
					array(
963
						'url'   => 'https://wordpress.com/domains/' . esc_attr( $this->primary_site_slug ),
964
						'id'    => 'wp-admin-bar-domains',
965
						'label' => esc_html__( 'Domains', 'jetpack' ),
966
					),
967
					array(
968
						'url'   => 'https://wordpress.com/domains/add/' . esc_attr( $this->primary_site_slug ),
969
						'id'    => 'wp-admin-bar-domains-add',
970
						'label' => esc_html_x( 'Add', 'Label for the button on the Masterbar to add a new domain', 'jetpack' ),
971
					)
972
				);
973
				$wp_admin_bar->add_menu( array(
974
					'parent' => 'configuration',
975
					'id'     => 'domains',
976
					'title'  => $domain_title,
977
					'href'   => false,
978
					'meta'   => array(
979
						'class' => 'inline-action',
980
					),
981
				) );
982
			}
983
984
			$wp_admin_bar->add_menu( array(
985
				'parent' => 'configuration',
986
				'id'     => 'blog-settings',
987
				'title'  => esc_html__( 'Settings', 'jetpack' ),
988
				'href'   => 'https://wordpress.com/settings/general/' . esc_attr( $this->primary_site_slug ),
989
				'meta'   => array(
990
					'class' => 'mb-icon',
991
				),
992
			) );
993
994
			if ( ! is_admin() ) {
995
				$wp_admin_bar->add_menu( array(
996
					'parent' => 'configuration',
997
					'id'     => 'legacy-dashboard',
998
					'title'  => esc_html__( 'Dashboard', 'jetpack' ),
999
					'href'   => admin_url(),
1000
					'meta'   => array(
1001
						'class' => 'mb-icon',
1002
					),
1003
				) );
1004
			}
1005
1006
			// Restore dashboard menu toggle that is needed on mobile views.
1007
			if ( is_admin() ) {
1008
				$wp_admin_bar->add_menu( array(
1009
				'id'    => 'menu-toggle',
1010
				'title' => '<span class="ab-icon"></span><span class="screen-reader-text">' . esc_html__( 'Menu', 'jetpack' ) . '</span>',
1011
				'href'  => '#',
1012
				) );
1013
			}
1014
1015
			/**
1016
			 * Fires when menu items are added to the masterbar "My Sites" menu.
1017
			 *
1018
			 * @since 5.4
1019
			 */
1020
			do_action( 'jetpack_masterbar' );
1021
		}
1022
	}
1023
}
1024