Completed
Push — update/calypsoify-stylings ( 08ff4c...abaa2c )
by
unknown
08:33
created

A8C_WPCOM_Masterbar::add_write_button()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

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