PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 7.3.4
Jetpack – WP Security, Backup, Speed, & Growth v7.3.4
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
471 lines 12.7 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 $this->locale = $this->get_locale();
78 $this->user_id = get_current_user_id();
79
80 // Limit the masterbar to be shown only to connected Jetpack users.
81 if ( ! Jetpack::is_user_connected( $this->user_id ) ) {
82 return;
83 }
84
85 // Don't show the masterbar on WordPress mobile apps.
86 if ( Jetpack_User_Agent_Info::is_mobile_app() ) {
87 add_filter( 'show_admin_bar', '__return_false' );
88 return;
89 }
90
91 Jetpack::dns_prefetch(
92 array(
93 '//s0.wp.com',
94 '//s1.wp.com',
95 '//s2.wp.com',
96 '//0.gravatar.com',
97 '//1.gravatar.com',
98 '//2.gravatar.com',
99 )
100 );
101
102 // Atomic only.
103 if ( jetpack_is_atomic_site() ) {
104 /*
105 * override user setting that hides masterbar from site's front.
106 * https://github.com/Automattic/jetpack/issues/7667
107 */
108 add_filter( 'show_admin_bar', '__return_true' );
109 }
110
111 $this->user_data = Jetpack::get_connected_user_data( $this->user_id );
112 $this->user_login = $this->user_data['login'];
113 $this->user_email = $this->user_data['email'];
114 $this->display_name = $this->user_data['display_name'];
115 $this->user_site_count = $this->user_data['site_count'];
116
117 // Used to build menu links that point directly to Calypso.
118 $this->primary_site_slug = Jetpack::build_raw_urls( get_home_url() );
119
120 // Used for display purposes and for building WP Admin links.
121 $this->primary_site_url = str_replace( '::', '/', $this->primary_site_slug );
122
123 // We need to use user's setting here, instead of relying on current blog's text direction.
124 $this->user_text_direction = $this->user_data['text_direction'];
125
126 if ( $this->is_rtl() ) {
127 // Extend core WP_Admin_Bar class in order to add rtl styles.
128 add_filter( 'wp_admin_bar_class', array( $this, 'get_rtl_admin_bar_class' ) );
129 }
130 add_filter( 'admin_body_class', array( $this, 'admin_body_class' ) );
131
132 add_action( 'wp_before_admin_bar_render', array( $this, 'replace_core_masterbar' ), 99999 );
133
134 add_action( 'wp_enqueue_scripts', array( $this, 'add_styles_and_scripts' ) );
135 add_action( 'admin_enqueue_scripts', array( $this, 'add_styles_and_scripts' ) );
136
137 add_action( 'wp_enqueue_scripts', array( $this, 'remove_core_styles' ) );
138 add_action( 'admin_enqueue_scripts', array( $this, 'remove_core_styles' ) );
139
140 if ( Jetpack::is_module_active( 'notes' ) && $this->is_rtl() ) {
141 // Override Notification module to include RTL styles.
142 add_action( 'a8c_wpcom_masterbar_enqueue_rtl_notification_styles', '__return_true' );
143 }
144 }
145
146 /**
147 * Get class name for RTL sites.
148 */
149 public function get_rtl_admin_bar_class() {
150 return 'RTL_Admin_Bar';
151 }
152
153 /**
154 * Adds CSS classes to admin body tag.
155 *
156 * @since 5.1
157 *
158 * @param string $admin_body_classes CSS classes that will be added.
159 *
160 * @return string
161 */
162 public function admin_body_class( $admin_body_classes ) {
163 return "$admin_body_classes jetpack-masterbar";
164 }
165
166 /**
167 * Remove the default Admin Bar CSS.
168 */
169 public function remove_core_styles() {
170 wp_dequeue_style( 'admin-bar' );
171 }
172
173 /**
174 * Check if the user settings are for an RTL language or not.
175 */
176 public function is_rtl() {
177 return 'rtl' === $this->user_text_direction ? true : false;
178 }
179
180 /**
181 * Enqueue our own CSS and JS to display our custom admin bar.
182 */
183 public function add_styles_and_scripts() {
184
185 if ( $this->is_rtl() ) {
186 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 );
187 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 );
188 } else {
189 wp_enqueue_style( 'a8c-wpcom-masterbar', $this->wpcom_static_url( '/wp-content/mu-plugins/admin-bar/wpcom-admin-bar.css' ), array(), JETPACK__VERSION );
190 wp_enqueue_style( 'a8c-wpcom-masterbar-overrides', $this->wpcom_static_url( '/wp-content/mu-plugins/admin-bar/masterbar-overrides/masterbar.css' ), array(), JETPACK__VERSION );
191 }
192
193 // Local overrides.
194 wp_enqueue_style( 'a8c_wpcom_css_override', plugins_url( 'overrides.css', __FILE__ ), array(), JETPACK__VERSION );
195
196 if ( ! Jetpack::is_module_active( 'notes ' ) ) {
197 // Masterbar is relying on some icons from noticons.css.
198 wp_enqueue_style( 'noticons', $this->wpcom_static_url( '/i/noticons/noticons.css' ), array(), JETPACK__VERSION . '-' . gmdate( 'oW' ) );
199 }
200
201 wp_enqueue_script(
202 'jetpack-accessible-focus',
203 Jetpack::get_file_url_for_environment( '_inc/build/accessible-focus.min.js', '_inc/accessible-focus.js' ),
204 array(),
205 JETPACK__VERSION,
206 false
207 );
208 wp_enqueue_script(
209 'a8c_wpcom_masterbar_tracks_events',
210 Jetpack::get_file_url_for_environment(
211 '_inc/build/masterbar/tracks-events.min.js',
212 'modules/masterbar/tracks-events.js'
213 ),
214 array( 'jquery' ),
215 JETPACK__VERSION,
216 false
217 );
218
219 wp_enqueue_script(
220 'a8c_wpcom_masterbar_overrides',
221 $this->wpcom_static_url( '/wp-content/mu-plugins/admin-bar/masterbar-overrides/masterbar.js' ),
222 array( 'jquery' ),
223 JETPACK__VERSION,
224 false
225 );
226 }
227
228 /**
229 * Get base URL where our CSS and JS will come from.
230 *
231 * @param string $file File path for a static resource.
232 */
233 private function wpcom_static_url( $file ) {
234 if ( ! empty( $this->sandbox_url ) ) {
235 // For testing undeployed changes to remotely enqueued scripts and styles.
236 return set_url_scheme( $this->sandbox_url . $file, 'https' );
237 }
238
239 $i = hexdec( substr( md5( $file ), - 1 ) ) % 2;
240 $url = 'https://s' . $i . '.wp.com' . $file;
241
242 return set_url_scheme( $url, 'https' );
243 }
244
245 /**
246 * Remove the default admin bar items and replace it with our own admin bar.
247 */
248 public function replace_core_masterbar() {
249 global $wp_admin_bar;
250
251 if ( ! is_object( $wp_admin_bar ) ) {
252 return false;
253 }
254
255 $this->clear_core_masterbar( $wp_admin_bar );
256 $this->build_wpcom_masterbar( $wp_admin_bar );
257 }
258
259 /**
260 * Remove all existing toolbar entries from core Masterbar
261 *
262 * @param WP_Admin_Bar $wp_admin_bar Admin Bar instance.
263 */
264 public function clear_core_masterbar( $wp_admin_bar ) {
265 foreach ( $wp_admin_bar->get_nodes() as $node ) {
266 $wp_admin_bar->remove_node( $node->id );
267 }
268 }
269
270 /**
271 * Add entries corresponding to WordPress.com Masterbar
272 *
273 * @param WP_Admin_Bar $wp_admin_bar Admin Bar instance.
274 */
275 public function build_wpcom_masterbar( $wp_admin_bar ) {
276 // Menu groups.
277 $this->wpcom_adminbar_add_secondary_groups( $wp_admin_bar );
278
279 // Left part.
280 $this->add_my_sites_submenu( $wp_admin_bar );
281 $this->add_reader_submenu( $wp_admin_bar );
282
283 // Right part.
284 if ( Jetpack::is_module_active( 'notes' ) ) {
285 $this->add_notifications( $wp_admin_bar );
286 }
287
288 $this->add_me_submenu( $wp_admin_bar );
289 $this->add_write_button( $wp_admin_bar );
290
291 // Add a sidebar toggle on mobile.
292 wp_admin_bar_sidebar_toggle( $wp_admin_bar );
293 }
294
295 /**
296 * Get WordPress.com current locale name.
297 */
298 public function get_locale() {
299 $wpcom_locale = get_locale();
300
301 if ( ! class_exists( 'GP_Locales' ) ) {
302 if ( defined( 'JETPACK__GLOTPRESS_LOCALES_PATH' ) && file_exists( JETPACK__GLOTPRESS_LOCALES_PATH ) ) {
303 require JETPACK__GLOTPRESS_LOCALES_PATH;
304 }
305 }
306
307 if ( class_exists( 'GP_Locales' ) ) {
308 $wpcom_locale_object = GP_Locales::by_field( 'wp_locale', get_locale() );
309 if ( $wpcom_locale_object instanceof GP_Locale ) {
310 $wpcom_locale = $wpcom_locale_object->slug;
311 }
312 }
313
314 return $wpcom_locale;
315 }
316
317 /**
318 * Add the Notifications menu item.
319 *
320 * @param WP_Admin_Bar $wp_admin_bar Admin Bar instance.
321 */
322 public function add_notifications( $wp_admin_bar ) {
323 $wp_admin_bar->add_node(
324 array(
325 'id' => 'notes',
326 'title' => '<span id="wpnt-notes-unread-count" class="wpnt-loading wpn-read"></span>
327 <span class="screen-reader-text">' . esc_html__( 'Notifications', 'jetpack' ) . '</span>
328 <span class="noticon noticon-bell"></span>',
329 'meta' => array(
330 'html' => '<div id="wpnt-notes-panel2" style="display:none" lang="' . esc_attr( $this->locale ) . '" dir="' . ( $this->is_rtl() ? 'rtl' : 'ltr' ) . '">' .
331 '<div class="wpnt-notes-panel-header">' .
332 '<span class="wpnt-notes-header">' .
333 esc_html__( 'Notifications', 'jetpack' ) .
334 '</span>' .
335 '<span class="wpnt-notes-panel-link">' .
336 '</span>' .
337 '</div>' .
338 '</div>',
339 'class' => 'menupop mb-trackable',
340 ),
341 'parent' => 'top-secondary',
342 )
343 );
344 }
345
346 /**
347 * Add the "My Site" menu item in the root default group.
348 *
349 * @param WP_Admin_Bar $wp_admin_bar Admin Bar instance.
350 */
351 public function add_my_sites_submenu( $wp_admin_bar ) {
352 $wp_admin_bar->add_menu(
353 array(
354 'parent' => 'root-default',
355 'id' => 'blog',
356 'title' => _n( 'My Site', 'My Sites', $this->user_site_count, 'jetpack' ),
357 'href' => 'https://wordpress.com/stats/' . esc_attr( $this->primary_site_slug ),
358 'meta' => array(
359 'class' => 'my-sites mb-trackable',
360 ),
361 )
362 );
363 }
364
365 /**
366 * Add the "Reader" menu item in the root default group.
367 *
368 * @param WP_Admin_Bar $wp_admin_bar Admin Bar instance.
369 */
370 public function add_reader_submenu( $wp_admin_bar ) {
371 $wp_admin_bar->add_menu(
372 array(
373 'parent' => 'root-default',
374 'id' => 'newdash',
375 'title' => esc_html__( 'Reader', 'jetpack' ),
376 'href' => 'https://wordpress.com/',
377 'meta' => array(
378 'class' => 'mb-trackable',
379 ),
380 )
381 );
382 }
383
384 /**
385 * Define main groups used in our admin bar.
386 *
387 * @param WP_Admin_Bar $wp_admin_bar Admin Bar instance.
388 */
389 public function wpcom_adminbar_add_secondary_groups( $wp_admin_bar ) {
390 $wp_admin_bar->add_group(
391 array(
392 'id' => 'root-default',
393 'meta' => array(
394 'class' => 'ab-top-menu',
395 ),
396 )
397 );
398
399 $wp_admin_bar->add_group(
400 array(
401 'id' => 'top-secondary',
402 'meta' => array(
403 'class' => 'ab-top-secondary',
404 ),
405 )
406 );
407 }
408
409 /**
410 * Add User info menu item.
411 *
412 * @param WP_Admin_Bar $wp_admin_bar Admin Bar instance.
413 */
414 public function add_me_submenu( $wp_admin_bar ) {
415 $user_id = get_current_user_id();
416 if ( empty( $user_id ) ) {
417 return;
418 }
419
420 $avatar = get_avatar( $this->user_email, 32, 'mm', '', array( 'force_display' => true ) );
421 $class = empty( $avatar ) ? 'mb-trackable' : 'with-avatar mb-trackable';
422
423 // Add the 'Me' menu.
424 $wp_admin_bar->add_menu(
425 array(
426 'id' => 'my-account',
427 'parent' => 'top-secondary',
428 'title' => $avatar . '<span class="ab-text">' . esc_html__( 'Me', 'jetpack' ) . '</span>',
429 'href' => 'https://wordpress.com/me/account',
430 'meta' => array(
431 'class' => $class,
432 ),
433 )
434 );
435 }
436
437 /**
438 * Add Write Menu item.
439 *
440 * @param WP_Admin_Bar $wp_admin_bar Admin Bar instance.
441 */
442 public function add_write_button( $wp_admin_bar ) {
443 $current_user = wp_get_current_user();
444
445 $posting_blog_id = get_current_blog_id();
446 if ( ! is_user_member_of_blog( get_current_user_id(), get_current_blog_id() ) ) {
447 $posting_blog_id = $current_user->primary_blog;
448 }
449
450 $user_can_post = current_user_can_for_blog( $posting_blog_id, 'publish_posts' );
451
452 if ( ! $posting_blog_id || ! $user_can_post ) {
453 return;
454 }
455
456 $blog_post_page = 'https://wordpress.com/post/' . esc_attr( $this->primary_site_slug );
457
458 $wp_admin_bar->add_menu(
459 array(
460 'parent' => 'top-secondary',
461 'id' => 'ab-new-post',
462 'href' => $blog_post_page,
463 'title' => '<span>' . esc_html__( 'Write', 'jetpack' ) . '</span>',
464 'meta' => array(
465 'class' => 'mb-trackable',
466 ),
467 )
468 );
469 }
470 }
471