Completed
Push — try/woocommerce-analytics ( 2b8c13...0a25c9 )
by
unknown
32:37 queued 22:26
created

A8C_WPCOM_Masterbar   D

Complexity

Total Complexity 72

Size/Duplication

Total Lines 1034
Duplicated Lines 8.9 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 72
lcom 1
cbo 3
dl 92
loc 1034
rs 4.203
c 0
b 0
f 0

20 Methods

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