PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 7.4.3
Jetpack – WP Security, Backup, Speed, & Growth v7.4.3
16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 13.8.3 13.9.2 14.0.1 14.1.1 14.2.2 14.3.1 All 501 releases
jetpack / modules / masterbar / masterbar.php

masterbar.php in Jetpack – WP Security, Backup, Speed, & Growth 7.4.3, at modules/masterbar/masterbar.php

1,322 lines 35.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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 );
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 // Recovery mode exit.
332 if ( function_exists( 'wp_admin_bar_recovery_mode_menu' ) ) {
333 wp_admin_bar_recovery_mode_menu( $wp_admin_bar );
334 }
335 }
336
337 /**
338 * Get WordPress.com current locale name.
339 */
340 public function get_locale() {
341 $wpcom_locale = get_locale();
342
343 if ( ! class_exists( 'GP_Locales' ) ) {
344 if ( defined( 'JETPACK__GLOTPRESS_LOCALES_PATH' ) && file_exists( JETPACK__GLOTPRESS_LOCALES_PATH ) ) {
345 require JETPACK__GLOTPRESS_LOCALES_PATH;
346 }
347 }
348
349 if ( class_exists( 'GP_Locales' ) ) {
350 $wpcom_locale_object = GP_Locales::by_field( 'wp_locale', get_locale() );
351 if ( $wpcom_locale_object instanceof GP_Locale ) {
352 $wpcom_locale = $wpcom_locale_object->slug;
353 }
354 }
355
356 return $wpcom_locale;
357 }
358
359 /**
360 * Add the Notifications menu item.
361 *
362 * @param WP_Admin_Bar $wp_admin_bar Admin Bar instance.
363 */
364 public function add_notifications( $wp_admin_bar ) {
365 $wp_admin_bar->add_node(
366 array(
367 'id' => 'notes',
368 'title' => '<span id="wpnt-notes-unread-count" class="wpnt-loading wpn-read"></span>
369 <span class="screen-reader-text">' . esc_html__( 'Notifications', 'jetpack' ) . '</span>
370 <span class="noticon noticon-bell"></span>',
371 'meta' => array(
372 'html' => '<div id="wpnt-notes-panel2" style="display:none" lang="' . esc_attr( $this->locale ) . '" dir="' . ( $this->is_rtl() ? 'rtl' : 'ltr' ) . '">' .
373 '<div class="wpnt-notes-panel-header">' .
374 '<span class="wpnt-notes-header">' .
375 esc_html__( 'Notifications', 'jetpack' ) .
376 '</span>' .
377 '<span class="wpnt-notes-panel-link">' .
378 '</span>' .
379 '</div>' .
380 '</div>',
381 'class' => 'menupop mb-trackable',
382 ),
383 'parent' => 'top-secondary',
384 )
385 );
386 }
387
388 /**
389 * Add the "Reader" menu item in the root default group.
390 *
391 * @param WP_Admin_Bar $wp_admin_bar Admin Bar instance.
392 */
393 public function add_reader_submenu( $wp_admin_bar ) {
394 $wp_admin_bar->add_menu(
395 array(
396 'parent' => 'root-default',
397 'id' => 'newdash',
398 'title' => esc_html__( 'Reader', 'jetpack' ),
399 'href' => '#',
400 'meta' => array(
401 'class' => 'mb-trackable',
402 ),
403 )
404 );
405
406 $wp_admin_bar->add_menu(
407 array(
408 'parent' => 'newdash',
409 'id' => 'streams-header',
410 'title' => esc_html_x(
411 'Streams',
412 'Title for Reader sub-menu that contains followed sites, likes, and recommendations',
413 'jetpack'
414 ),
415 'meta' => array(
416 'class' => 'ab-submenu-header',
417 ),
418 )
419 );
420
421 $following_title = $this->create_menu_item_pair(
422 array(
423 'url' => 'https://wordpress.com/',
424 'id' => 'wp-admin-bar-followed-sites',
425 'label' => esc_html__( 'Followed Sites', 'jetpack' ),
426 ),
427 array(
428 'url' => 'https://wordpress.com/following/edit',
429 'id' => 'wp-admin-bar-reader-followed-sites-manage',
430 'label' => esc_html__( 'Manage', 'jetpack' ),
431 )
432 );
433
434 $wp_admin_bar->add_menu(
435 array(
436 'parent' => 'newdash',
437 'id' => 'following',
438 'title' => $following_title,
439 'meta' => array( 'class' => 'inline-action' ),
440 )
441 );
442
443 $wp_admin_bar->add_menu(
444 array(
445 'parent' => 'newdash',
446 'id' => 'discover-discover',
447 'title' => esc_html__( 'Discover', 'jetpack' ),
448 'href' => 'https://wordpress.com/discover',
449 'meta' => array(
450 'class' => 'mb-icon-spacer',
451 ),
452 )
453 );
454
455 $wp_admin_bar->add_menu(
456 array(
457 'parent' => 'newdash',
458 'id' => 'discover-search',
459 'title' => esc_html__( 'Search', 'jetpack' ),
460 'href' => 'https://wordpress.com/read/search',
461 'meta' => array(
462 'class' => 'mb-icon-spacer',
463 ),
464 )
465 );
466
467 $wp_admin_bar->add_menu(
468 array(
469 'parent' => 'newdash',
470 'id' => 'discover-recommended-blogs',
471 'title' => esc_html__( 'Recommendations', 'jetpack' ),
472 'href' => 'https://wordpress.com/recommendations',
473 'meta' => array(
474 'class' => 'mb-icon-spacer',
475 ),
476 )
477 );
478
479 $wp_admin_bar->add_menu(
480 array(
481 'parent' => 'newdash',
482 'id' => 'my-activity-my-likes',
483 'title' => esc_html__( 'My Likes', 'jetpack' ),
484 'href' => 'https://wordpress.com/activities/likes',
485 'meta' => array(
486 'class' => 'mb-icon-spacer',
487 ),
488 )
489 );
490
491 }
492
493 /**
494 * Merge 2 menu items together into 2 link tags.
495 *
496 * @param array $primary Array of menu information.
497 * @param array $secondary Array of menu information.
498 */
499 public function create_menu_item_pair( $primary, $secondary ) {
500 $primary_class = 'ab-item ab-primary mb-icon';
501 $secondary_class = 'ab-secondary';
502
503 $primary_anchor = $this->create_menu_item_anchor( $primary_class, $primary['url'], $primary['label'], $primary['id'] );
504 $secondary_anchor = $this->create_menu_item_anchor( $secondary_class, $secondary['url'], $secondary['label'], $secondary['id'] );
505
506 return $primary_anchor . $secondary_anchor;
507 }
508
509 /**
510 * Create a link tag based on information about a menu item.
511 *
512 * @param string $class Menu item CSS class.
513 * @param string $url URL you go to when clicking on the menu item.
514 * @param string $label Menu item title.
515 * @param string $id Menu item slug.
516 */
517 public function create_menu_item_anchor( $class, $url, $label, $id ) {
518 return '<a href="' . $url . '" class="' . $class . '" id="' . $id . '">' . $label . '</a>';
519 }
520
521 /**
522 * Add Secondary groups for submenu items.
523 *
524 * @param WP_Admin_Bar $wp_admin_bar Admin Bar instance.
525 */
526 public function wpcom_adminbar_add_secondary_groups( $wp_admin_bar ) {
527 $wp_admin_bar->add_group(
528 array(
529 'id' => 'root-default',
530 'meta' => array(
531 'class' => 'ab-top-menu',
532 ),
533 )
534 );
535
536 $wp_admin_bar->add_group(
537 array(
538 'parent' => 'blog',
539 'id' => 'blog-secondary',
540 'meta' => array(
541 'class' => 'ab-sub-secondary',
542 ),
543 )
544 );
545
546 $wp_admin_bar->add_group(
547 array(
548 'id' => 'top-secondary',
549 'meta' => array(
550 'class' => 'ab-top-secondary',
551 ),
552 )
553 );
554 }
555
556 /**
557 * Add User info menu item.
558 *
559 * @param WP_Admin_Bar $wp_admin_bar Admin Bar instance.
560 */
561 public function add_me_submenu( $wp_admin_bar ) {
562 $user_id = get_current_user_id();
563 if ( empty( $user_id ) ) {
564 return;
565 }
566
567 $avatar = get_avatar( $this->user_email, 32, 'mm', '', array( 'force_display' => true ) );
568 $class = empty( $avatar ) ? 'mb-trackable' : 'with-avatar mb-trackable';
569
570 // Add the 'Me' menu.
571 $wp_admin_bar->add_menu(
572 array(
573 'id' => 'my-account',
574 'parent' => 'top-secondary',
575 'title' => $avatar . '<span class="ab-text">' . esc_html__( 'Me', 'jetpack' ) . '</span>',
576 'href' => '#',
577 'meta' => array(
578 'class' => $class,
579 ),
580 )
581 );
582
583 $id = 'user-actions';
584 $wp_admin_bar->add_group(
585 array(
586 'parent' => 'my-account',
587 'id' => $id,
588 )
589 );
590
591 $settings_url = 'https://wordpress.com/me/account';
592
593 $logout_url = wp_logout_url();
594 $logout_url = add_query_arg( 'context', 'masterbar', $logout_url );
595
596 $user_info = get_avatar( $this->user_email, 128, 'mm', '', array( 'force_display' => true ) );
597 $user_info .= '<span class="display-name">' . $this->display_name . '</span>';
598 $user_info .= '<a class="username" href="http://gravatar.com/' . $this->user_login . '">@' . $this->user_login . '</a>';
599
600 $user_info .= sprintf(
601 '<div><a href="%s" class="ab-sign-out">%s</a></div>',
602 $logout_url,
603 esc_html__( 'Sign Out', 'jetpack' )
604 );
605
606 $wp_admin_bar->add_menu(
607 array(
608 'parent' => $id,
609 'id' => 'user-info',
610 'title' => $user_info,
611 'meta' => array(
612 'class' => 'user-info user-info-item',
613 'tabindex' => -1,
614 ),
615 )
616 );
617
618 $wp_admin_bar->add_menu(
619 array(
620 'parent' => $id,
621 'id' => 'profile-header',
622 'title' => esc_html__( 'Profile', 'jetpack' ),
623 'meta' => array(
624 'class' => 'ab-submenu-header',
625 ),
626 )
627 );
628
629 $wp_admin_bar->add_menu(
630 array(
631 'parent' => $id,
632 'id' => 'my-profile',
633 'title' => esc_html__( 'My Profile', 'jetpack' ),
634 'href' => 'https://wordpress.com/me',
635 'meta' => array(
636 'class' => 'mb-icon',
637 ),
638 )
639 );
640
641 $wp_admin_bar->add_menu(
642 array(
643 'parent' => $id,
644 'id' => 'account-settings',
645 'title' => esc_html__( 'Account Settings', 'jetpack' ),
646 'href' => $settings_url,
647 'meta' => array(
648 'class' => 'mb-icon',
649 ),
650 )
651 );
652
653 $wp_admin_bar->add_menu(
654 array(
655 'parent' => $id,
656 'id' => 'billing',
657 'title' => esc_html__( 'Manage Purchases', 'jetpack' ),
658 'href' => 'https://wordpress.com/me/purchases',
659 'meta' => array(
660 'class' => 'mb-icon',
661 ),
662 )
663 );
664
665 $wp_admin_bar->add_menu(
666 array(
667 'parent' => $id,
668 'id' => 'security',
669 'title' => esc_html__( 'Security', 'jetpack' ),
670 'href' => 'https://wordpress.com/me/security',
671 'meta' => array(
672 'class' => 'mb-icon',
673 ),
674 )
675 );
676
677 $wp_admin_bar->add_menu(
678 array(
679 'parent' => $id,
680 'id' => 'notifications',
681 'title' => esc_html__( 'Notifications', 'jetpack' ),
682 'href' => 'https://wordpress.com/me/notifications',
683 'meta' => array(
684 'class' => 'mb-icon',
685 ),
686 )
687 );
688
689 $wp_admin_bar->add_menu(
690 array(
691 'parent' => $id,
692 'id' => 'special-header',
693 'title' => esc_html_x(
694 'Special',
695 'Title for Me sub-menu that contains Get Apps, Next Steps, and Help options',
696 'jetpack'
697 ),
698 'meta' => array(
699 'class' => 'ab-submenu-header',
700 ),
701 )
702 );
703
704 $wp_admin_bar->add_menu(
705 array(
706 'parent' => $id,
707 'id' => 'get-apps',
708 'title' => esc_html__( 'Get Apps', 'jetpack' ),
709 'href' => 'https://wordpress.com/me/get-apps',
710 'meta' => array(
711 'class' => 'mb-icon user-info-item',
712 ),
713 )
714 );
715
716 $help_link = 'https://jetpack.com/support/';
717
718 if ( jetpack_is_atomic_site() ) {
719 $help_link = 'https://wordpress.com/help';
720 }
721
722 $wp_admin_bar->add_menu(
723 array(
724 'parent' => $id,
725 'id' => 'help',
726 'title' => esc_html__( 'Help', 'jetpack' ),
727 'href' => $help_link,
728 'meta' => array(
729 'class' => 'mb-icon user-info-item',
730 ),
731 )
732 );
733 }
734
735 /**
736 * Add Write Menu item.
737 *
738 * @param WP_Admin_Bar $wp_admin_bar Admin Bar instance.
739 */
740 public function add_write_button( $wp_admin_bar ) {
741 $current_user = wp_get_current_user();
742
743 $posting_blog_id = get_current_blog_id();
744 if ( ! is_user_member_of_blog( get_current_user_id(), get_current_blog_id() ) ) {
745 $posting_blog_id = $current_user->primary_blog;
746 }
747
748 $user_can_post = current_user_can_for_blog( $posting_blog_id, 'publish_posts' );
749
750 if ( ! $posting_blog_id || ! $user_can_post ) {
751 return;
752 }
753
754 $blog_post_page = 'https://wordpress.com/post/' . esc_attr( $this->primary_site_slug );
755
756 $wp_admin_bar->add_menu(
757 array(
758 'parent' => 'top-secondary',
759 'id' => 'ab-new-post',
760 'href' => $blog_post_page,
761 'title' => '<span>' . esc_html__( 'Write', 'jetpack' ) . '</span>',
762 'meta' => array(
763 'class' => 'mb-trackable',
764 ),
765 )
766 );
767 }
768
769 /**
770 * Add the "My Site" menu item in the root default group.
771 *
772 * @param WP_Admin_Bar $wp_admin_bar Admin Bar instance.
773 */
774 public function add_my_sites_submenu( $wp_admin_bar ) {
775 $current_user = wp_get_current_user();
776
777 $blog_name = get_bloginfo( 'name' );
778 if ( empty( $blog_name ) ) {
779 $blog_name = $this->primary_site_slug;
780 }
781
782 if ( mb_strlen( $blog_name ) > 20 ) {
783 $blog_name = mb_substr( html_entity_decode( $blog_name, ENT_QUOTES ), 0, 20 ) . '&hellip;';
784 }
785
786 $wp_admin_bar->add_menu(
787 array(
788 'parent' => 'root-default',
789 'id' => 'blog',
790 'title' => _n( 'My Site', 'My Sites', $this->user_site_count, 'jetpack' ),
791 'href' => '#',
792 'meta' => array(
793 'class' => 'my-sites mb-trackable',
794 ),
795 )
796 );
797
798 if ( $this->user_site_count > 1 ) {
799 $wp_admin_bar->add_menu(
800 array(
801 'parent' => 'blog',
802 'id' => 'switch-site',
803 'title' => esc_html__( 'Switch Site', 'jetpack' ),
804 'href' => 'https://wordpress.com/sites',
805 )
806 );
807 } else {
808 $wp_admin_bar->add_menu(
809 array(
810 'parent' => 'blog',
811 'id' => 'new-site',
812 'title' => esc_html__( '+ Add New WordPress', 'jetpack' ),
813 'href' => 'https://wordpress.com/start?ref=admin-bar-logged-in',
814 )
815 );
816 }
817
818 if ( is_user_member_of_blog( $current_user->ID ) ) {
819 $blavatar = '';
820 $class = 'current-site';
821
822 if ( has_site_icon() ) {
823 $src = get_site_icon_url();
824 $blavatar = '<img class="avatar" src="' . esc_attr( $src ) . '" alt="Current site avatar">';
825 $class = 'has-blavatar';
826 }
827
828 $blog_info = '<div class="ab-site-icon">' . $blavatar . '</div>';
829 $blog_info .= '<span class="ab-site-title">' . esc_html( $blog_name ) . '</span>';
830 $blog_info .= '<span class="ab-site-description">' . esc_html( $this->primary_site_url ) . '</span>';
831
832 $wp_admin_bar->add_menu(
833 array(
834 'parent' => 'blog',
835 'id' => 'blog-info',
836 'title' => $blog_info,
837 'href' => esc_url( trailingslashit( $this->primary_site_url ) ),
838 'meta' => array(
839 'class' => $class,
840 ),
841 )
842 );
843 }
844
845 // Site Preview.
846 if ( is_admin() ) {
847 $wp_admin_bar->add_menu(
848 array(
849 'parent' => 'blog',
850 'id' => 'site-view',
851 'title' => __( 'View Site', 'jetpack' ),
852 'href' => home_url(),
853 'meta' => array(
854 'class' => 'mb-icon',
855 'target' => '_blank',
856 ),
857 )
858 );
859 }
860
861 // Stats.
862 if ( Jetpack::is_module_active( 'stats' ) ) {
863 $wp_admin_bar->add_menu(
864 array(
865 'parent' => 'blog',
866 'id' => 'blog-stats',
867 'title' => esc_html__( 'Stats', 'jetpack' ),
868 'href' => 'https://wordpress.com/stats/' . esc_attr( $this->primary_site_slug ),
869 'meta' => array(
870 'class' => 'mb-icon',
871 ),
872 )
873 );
874 }
875
876 if ( current_user_can( 'manage_options' ) ) {
877 $wp_admin_bar->add_menu(
878 array(
879 'parent' => 'blog',
880 'id' => 'activity',
881 'title' => esc_html__( 'Activity', 'jetpack' ),
882 'href' => 'https://wordpress.com/activity-log/' . esc_attr( $this->primary_site_slug ),
883 'meta' => array(
884 'class' => 'mb-icon',
885 ),
886 )
887 );
888 }
889
890 // Add Calypso plans link and plan type indicator.
891 if ( is_user_member_of_blog( $current_user->ID ) ) {
892 $plans_url = 'https://wordpress.com/plans/' . esc_attr( $this->primary_site_slug );
893 $label = esc_html__( 'Plan', 'jetpack' );
894 $plan = Jetpack_Plan::get();
895
896 $plan_title = $this->create_menu_item_pair(
897 array(
898 'url' => $plans_url,
899 'id' => 'wp-admin-bar-plan',
900 'label' => $label,
901 ),
902 array(
903 'url' => $plans_url,
904 'id' => 'wp-admin-bar-plan-badge',
905 'label' => $plan['product_name_short'],
906 )
907 );
908
909 $wp_admin_bar->add_menu(
910 array(
911 'parent' => 'blog',
912 'id' => 'plan',
913 'title' => $plan_title,
914 'meta' => array(
915 'class' => 'inline-action',
916 ),
917 )
918 );
919 }
920
921 // Publish group.
922 $wp_admin_bar->add_group(
923 array(
924 'parent' => 'blog',
925 'id' => 'publish',
926 )
927 );
928
929 // Publish header.
930 $wp_admin_bar->add_menu(
931 array(
932 'parent' => 'publish',
933 'id' => 'publish-header',
934 'title' => esc_html_x( 'Manage', 'admin bar menu group label', 'jetpack' ),
935 'meta' => array(
936 'class' => 'ab-submenu-header',
937 ),
938 )
939 );
940
941 // Pages.
942 $pages_title = $this->create_menu_item_pair(
943 array(
944 'url' => 'https://wordpress.com/pages/' . esc_attr( $this->primary_site_slug ),
945 'id' => 'wp-admin-bar-edit-page',
946 'label' => esc_html__( 'Site Pages', 'jetpack' ),
947 ),
948 array(
949 'url' => 'https://wordpress.com/page/' . esc_attr( $this->primary_site_slug ),
950 'id' => 'wp-admin-bar-new-page-badge',
951 'label' => esc_html_x( 'Add', 'admin bar menu new item label', 'jetpack' ),
952 )
953 );
954
955 if ( ! current_user_can( 'edit_pages' ) ) {
956 $pages_title = $this->create_menu_item_anchor(
957 'ab-item ab-primary mb-icon',
958 'https://wordpress.com/pages/' . esc_attr( $this->primary_site_slug ),
959 esc_html__( 'Site Pages', 'jetpack' ),
960 'wp-admin-bar-edit-page'
961 );
962 }
963
964 $wp_admin_bar->add_menu(
965 array(
966 'parent' => 'publish',
967 'id' => 'new-page',
968 'title' => $pages_title,
969 'meta' => array(
970 'class' => 'inline-action',
971 ),
972 )
973 );
974
975 // Blog Posts.
976 $posts_title = $this->create_menu_item_pair(
977 array(
978 'url' => 'https://wordpress.com/posts/' . esc_attr( $this->primary_site_slug ),
979 'id' => 'wp-admin-bar-edit-post',
980 'label' => esc_html__( 'Blog Posts', 'jetpack' ),
981 ),
982 array(
983 'url' => 'https://wordpress.com/post/' . esc_attr( $this->primary_site_slug ),
984 'id' => 'wp-admin-bar-new-post-badge',
985 'label' => esc_html_x( 'Add', 'admin bar menu new item label', 'jetpack' ),
986 )
987 );
988
989 if ( ! current_user_can( 'edit_posts' ) ) {
990 $posts_title = $this->create_menu_item_anchor(
991 'ab-item ab-primary mb-icon',
992 'https://wordpress.com/posts/' . esc_attr( $this->primary_site_slug ),
993 esc_html__( 'Blog Posts', 'jetpack' ),
994 'wp-admin-bar-edit-post'
995 );
996 }
997
998 $wp_admin_bar->add_menu(
999 array(
1000 'parent' => 'publish',
1001 'id' => 'new-post',
1002 'title' => $posts_title,
1003 'meta' => array(
1004 'class' => 'inline-action mb-trackable',
1005 ),
1006 )
1007 );
1008
1009 // Comments.
1010 if ( current_user_can( 'moderate_comments' ) ) {
1011 $wp_admin_bar->add_menu(
1012 array(
1013 'parent' => 'publish',
1014 'id' => 'comments',
1015 'title' => __( 'Comments', 'jetpack' ),
1016 'href' => 'https://wordpress.com/comments/' . esc_attr( $this->primary_site_slug ),
1017 'meta' => array(
1018 'class' => 'mb-icon',
1019 ),
1020 )
1021 );
1022 }
1023
1024 // Testimonials.
1025 if ( Jetpack::is_module_active( 'custom-content-types' ) && get_option( 'jetpack_testimonial' ) ) {
1026 $testimonials_title = $this->create_menu_item_pair(
1027 array(
1028 'url' => 'https://wordpress.com/types/jetpack-testimonial/' . esc_attr( $this->primary_site_slug ),
1029 'id' => 'wp-admin-bar-edit-testimonial',
1030 'label' => esc_html__( 'Testimonials', 'jetpack' ),
1031 ),
1032 array(
1033 'url' => 'https://wordpress.com/edit/jetpack-testimonial/' . esc_attr( $this->primary_site_slug ),
1034 'id' => 'wp-admin-bar-new-testimonial',
1035 'label' => esc_html_x( 'Add', 'Button label for adding a new item via the toolbar menu', 'jetpack' ),
1036 )
1037 );
1038
1039 if ( ! current_user_can( 'edit_pages' ) ) {
1040 $testimonials_title = $this->create_menu_item_anchor(
1041 'ab-item ab-primary mb-icon',
1042 'https://wordpress.com/types/jetpack-testimonial/' . esc_attr( $this->primary_site_slug ),
1043 esc_html__( 'Testimonials', 'jetpack' ),
1044 'wp-admin-bar-edit-testimonial'
1045 );
1046 }
1047
1048 $wp_admin_bar->add_menu(
1049 array(
1050 'parent' => 'publish',
1051 'id' => 'new-jetpack-testimonial',
1052 'title' => $testimonials_title,
1053 'meta' => array(
1054 'class' => 'inline-action',
1055 ),
1056 )
1057 );
1058 }
1059
1060 // Portfolio.
1061 if ( Jetpack::is_module_active( 'custom-content-types' ) && get_option( 'jetpack_portfolio' ) ) {
1062 $portfolios_title = $this->create_menu_item_pair(
1063 array(
1064 'url' => 'https://wordpress.com/types/jetpack-portfolio/' . esc_attr( $this->primary_site_slug ),
1065 'id' => 'wp-admin-bar-edit-portfolio',
1066 'label' => esc_html__( 'Portfolio', 'jetpack' ),
1067 ),
1068 array(
1069 'url' => 'https://wordpress.com/edit/jetpack-portfolio/' . esc_attr( $this->primary_site_slug ),
1070 'id' => 'wp-admin-bar-new-portfolio',
1071 'label' => esc_html_x( 'Add', 'Button label for adding a new item via the toolbar menu', 'jetpack' ),
1072 )
1073 );
1074
1075 if ( ! current_user_can( 'edit_pages' ) ) {
1076 $portfolios_title = $this->create_menu_item_anchor(
1077 'ab-item ab-primary mb-icon',
1078 'https://wordpress.com/types/jetpack-portfolio/' . esc_attr( $this->primary_site_slug ),
1079 esc_html__( 'Portfolio', 'jetpack' ),
1080 'wp-admin-bar-edit-portfolio'
1081 );
1082 }
1083
1084 $wp_admin_bar->add_menu(
1085 array(
1086 'parent' => 'publish',
1087 'id' => 'new-jetpack-portfolio',
1088 'title' => $portfolios_title,
1089 'meta' => array(
1090 'class' => 'inline-action',
1091 ),
1092 )
1093 );
1094 }
1095
1096 if ( current_user_can( 'edit_theme_options' ) ) {
1097 // Look and Feel group.
1098 $wp_admin_bar->add_group(
1099 array(
1100 'parent' => 'blog',
1101 'id' => 'look-and-feel',
1102 )
1103 );
1104
1105 // Look and Feel header.
1106 $wp_admin_bar->add_menu(
1107 array(
1108 'parent' => 'look-and-feel',
1109 'id' => 'look-and-feel-header',
1110 'title' => esc_html_x( 'Personalize', 'admin bar menu group label', 'jetpack' ),
1111 'meta' => array(
1112 'class' => 'ab-submenu-header',
1113 ),
1114 )
1115 );
1116
1117 if ( is_admin() ) {
1118 // In wp-admin the `return` query arg will return to that page after closing the Customizer.
1119 $customizer_url = add_query_arg(
1120 array(
1121 'return' => rawurlencode( site_url( $_SERVER['REQUEST_URI'] ) ),
1122 ),
1123 wp_customize_url()
1124 );
1125 } else {
1126 /*
1127 * On the frontend the `url` query arg will load that page in the Customizer
1128 * and also return to it after closing
1129 * non-home URLs won't work unless we undo domain mapping
1130 * since the Customizer preview is unmapped to always have HTTPS.
1131 */
1132 $current_page = '//' . $this->primary_site_slug . $_SERVER['REQUEST_URI'];
1133 $customizer_url = add_query_arg( array( 'url' => rawurlencode( $current_page ) ), wp_customize_url() );
1134 }
1135
1136 $theme_title = $this->create_menu_item_pair(
1137 array(
1138 'url' => $customizer_url,
1139 'id' => 'wp-admin-bar-cmz',
1140 'label' => esc_html_x( 'Customize', 'admin bar customize item label', 'jetpack' ),
1141 ),
1142 array(
1143 'url' => 'https://wordpress.com/themes/' . esc_attr( $this->primary_site_slug ),
1144 'id' => 'wp-admin-bar-themes',
1145 'label' => esc_html__( 'Themes', 'jetpack' ),
1146 )
1147 );
1148 $meta = array(
1149 'class' => 'mb-icon',
1150 'class' => 'inline-action',
1151 );
1152 $href = false;
1153
1154 $wp_admin_bar->add_menu(
1155 array(
1156 'parent' => 'look-and-feel',
1157 'id' => 'themes',
1158 'title' => $theme_title,
1159 'href' => $href,
1160 'meta' => $meta,
1161 )
1162 );
1163 }
1164
1165 if ( current_user_can( 'manage_options' ) ) {
1166 // Configuration group.
1167 $wp_admin_bar->add_group(
1168 array(
1169 'parent' => 'blog',
1170 'id' => 'configuration',
1171 )
1172 );
1173
1174 // Configuration header.
1175 $wp_admin_bar->add_menu(
1176 array(
1177 'parent' => 'configuration',
1178 'id' => 'configuration-header',
1179 'title' => esc_html_x( 'Configure', 'admin bar menu group label', 'jetpack' ),
1180 'meta' => array(
1181 'class' => 'ab-submenu-header',
1182 ),
1183 )
1184 );
1185
1186 if ( Jetpack::is_module_active( 'publicize' ) || Jetpack::is_module_active( 'sharedaddy' ) ) {
1187 $wp_admin_bar->add_menu(
1188 array(
1189 'parent' => 'configuration',
1190 'id' => 'sharing',
1191 'title' => esc_html__( 'Sharing', 'jetpack' ),
1192 'href' => 'https://wordpress.com/sharing/' . esc_attr( $this->primary_site_slug ),
1193 'meta' => array(
1194 'class' => 'mb-icon',
1195 ),
1196 )
1197 );
1198 }
1199
1200 $people_title = $this->create_menu_item_pair(
1201 array(
1202 'url' => 'https://wordpress.com/people/team/' . esc_attr( $this->primary_site_slug ),
1203 'id' => 'wp-admin-bar-people',
1204 'label' => esc_html__( 'People', 'jetpack' ),
1205 ),
1206 array(
1207 'url' => admin_url( 'user-new.php' ),
1208 'id' => 'wp-admin-bar-people-add',
1209 'label' => esc_html_x( 'Add', 'admin bar people item label', 'jetpack' ),
1210 )
1211 );
1212
1213 $wp_admin_bar->add_menu(
1214 array(
1215 'parent' => 'configuration',
1216 'id' => 'users-toolbar',
1217 'title' => $people_title,
1218 'href' => false,
1219 'meta' => array(
1220 'class' => 'inline-action',
1221 ),
1222 )
1223 );
1224
1225 $plugins_title = $this->create_menu_item_pair(
1226 array(
1227 'url' => 'https://wordpress.com/plugins/' . esc_attr( $this->primary_site_slug ),
1228 'id' => 'wp-admin-bar-plugins',
1229 'label' => esc_html__( 'Plugins', 'jetpack' ),
1230 ),
1231 array(
1232 'url' => 'https://wordpress.com/plugins/manage/' . esc_attr( $this->primary_site_slug ),
1233 'id' => 'wp-admin-bar-plugins-add',
1234 'label' => esc_html_x( 'Manage', 'Label for the button on the Masterbar to manage plugins', 'jetpack' ),
1235 )
1236 );
1237
1238 $wp_admin_bar->add_menu(
1239 array(
1240 'parent' => 'configuration',
1241 'id' => 'plugins',
1242 'title' => $plugins_title,
1243 'href' => false,
1244 'meta' => array(
1245 'class' => 'inline-action',
1246 ),
1247 )
1248 );
1249
1250 if ( jetpack_is_atomic_site() ) {
1251 $domain_title = $this->create_menu_item_pair(
1252 array(
1253 'url' => 'https://wordpress.com/domains/' . esc_attr( $this->primary_site_slug ),
1254 'id' => 'wp-admin-bar-domains',
1255 'label' => esc_html__( 'Domains', 'jetpack' ),
1256 ),
1257 array(
1258 'url' => 'https://wordpress.com/domains/add/' . esc_attr( $this->primary_site_slug ),
1259 'id' => 'wp-admin-bar-domains-add',
1260 'label' => esc_html_x( 'Add', 'Label for the button on the Masterbar to add a new domain', 'jetpack' ),
1261 )
1262 );
1263 $wp_admin_bar->add_menu(
1264 array(
1265 'parent' => 'configuration',
1266 'id' => 'domains',
1267 'title' => $domain_title,
1268 'href' => false,
1269 'meta' => array(
1270 'class' => 'inline-action',
1271 ),
1272 )
1273 );
1274 }
1275
1276 $wp_admin_bar->add_menu(
1277 array(
1278 'parent' => 'configuration',
1279 'id' => 'blog-settings',
1280 'title' => esc_html__( 'Settings', 'jetpack' ),
1281 'href' => 'https://wordpress.com/settings/general/' . esc_attr( $this->primary_site_slug ),
1282 'meta' => array(
1283 'class' => 'mb-icon',
1284 ),
1285 )
1286 );
1287
1288 if ( ! is_admin() ) {
1289 $wp_admin_bar->add_menu(
1290 array(
1291 'parent' => 'configuration',
1292 'id' => 'legacy-dashboard',
1293 'title' => esc_html__( 'Dashboard', 'jetpack' ),
1294 'href' => admin_url(),
1295 'meta' => array(
1296 'class' => 'mb-icon',
1297 ),
1298 )
1299 );
1300 }
1301
1302 // Restore dashboard menu toggle that is needed on mobile views.
1303 if ( is_admin() ) {
1304 $wp_admin_bar->add_menu(
1305 array(
1306 'id' => 'menu-toggle',
1307 'title' => '<span class="ab-icon"></span><span class="screen-reader-text">' . esc_html__( 'Menu', 'jetpack' ) . '</span>',
1308 'href' => '#',
1309 )
1310 );
1311 }
1312
1313 /**
1314 * Fires when menu items are added to the masterbar "My Sites" menu.
1315 *
1316 * @since 5.4.0
1317 */
1318 do_action( 'jetpack_masterbar' );
1319 }
1320 }
1321 }
1322