admin-bar.php (32356B)
1 <?php 2 /** 3 * Toolbar API: Top-level Toolbar functionality 4 * 5 * @package WordPress 6 * @subpackage Toolbar 7 * @since 3.1.0 8 */ 9 10 /** 11 * Instantiate the admin bar object and set it up as a global for access elsewhere. 12 * 13 * UNHOOKING THIS FUNCTION WILL NOT PROPERLY REMOVE THE ADMIN BAR. 14 * For that, use show_admin_bar(false) or the {@see 'show_admin_bar'} filter. 15 * 16 * @since 3.1.0 17 * @access private 18 * 19 * @global WP_Admin_Bar $wp_admin_bar 20 * 21 * @return bool Whether the admin bar was successfully initialized. 22 */ 23 function _wp_admin_bar_init() { 24 global $wp_admin_bar; 25 26 if ( ! is_admin_bar_showing() ) { 27 return false; 28 } 29 30 /* Load the admin bar class code ready for instantiation */ 31 require_once ABSPATH . WPINC . '/class-wp-admin-bar.php'; 32 33 /* Instantiate the admin bar */ 34 35 /** 36 * Filters the admin bar class to instantiate. 37 * 38 * @since 3.1.0 39 * 40 * @param string $wp_admin_bar_class Admin bar class to use. Default 'WP_Admin_Bar'. 41 */ 42 $admin_bar_class = apply_filters( 'wp_admin_bar_class', 'WP_Admin_Bar' ); 43 if ( class_exists( $admin_bar_class ) ) { 44 $wp_admin_bar = new $admin_bar_class; 45 } else { 46 return false; 47 } 48 49 $wp_admin_bar->initialize(); 50 $wp_admin_bar->add_menus(); 51 52 return true; 53 } 54 55 /** 56 * Renders the admin bar to the page based on the $wp_admin_bar->menu member var. 57 * 58 * This is called very early on the {@see 'wp_body_open'} action so that it will render 59 * before anything else being added to the page body. 60 * 61 * For backward compatibility with themes not using the 'wp_body_open' action, 62 * the function is also called late on {@see 'wp_footer'}. 63 * 64 * It includes the {@see 'admin_bar_menu'} action which should be used to hook in and 65 * add new menus to the admin bar. That way you can be sure that you are adding at most 66 * optimal point, right before the admin bar is rendered. This also gives you access to 67 * the `$post` global, among others. 68 * 69 * @since 3.1.0 70 * @since 5.4.0 Called on 'wp_body_open' action first, with 'wp_footer' as a fallback. 71 * 72 * @global WP_Admin_Bar $wp_admin_bar 73 */ 74 function wp_admin_bar_render() { 75 global $wp_admin_bar; 76 static $rendered = false; 77 78 if ( $rendered ) { 79 return; 80 } 81 82 if ( ! is_admin_bar_showing() || ! is_object( $wp_admin_bar ) ) { 83 return; 84 } 85 86 /** 87 * Load all necessary admin bar items. 88 * 89 * This is the hook used to add, remove, or manipulate admin bar items. 90 * 91 * @since 3.1.0 92 * 93 * @param WP_Admin_Bar $wp_admin_bar WP_Admin_Bar instance, passed by reference 94 */ 95 do_action_ref_array( 'admin_bar_menu', array( &$wp_admin_bar ) ); 96 97 /** 98 * Fires before the admin bar is rendered. 99 * 100 * @since 3.1.0 101 */ 102 do_action( 'wp_before_admin_bar_render' ); 103 104 $wp_admin_bar->render(); 105 106 /** 107 * Fires after the admin bar is rendered. 108 * 109 * @since 3.1.0 110 */ 111 do_action( 'wp_after_admin_bar_render' ); 112 113 $rendered = true; 114 } 115 116 /** 117 * Add the WordPress logo menu. 118 * 119 * @since 3.3.0 120 * 121 * @param WP_Admin_Bar $wp_admin_bar 122 */ 123 function wp_admin_bar_wp_menu( $wp_admin_bar ) { 124 if ( current_user_can( 'read' ) ) { 125 $about_url = self_admin_url( 'about.php' ); 126 } elseif ( is_multisite() ) { 127 $about_url = get_dashboard_url( get_current_user_id(), 'about.php' ); 128 } else { 129 $about_url = false; 130 } 131 132 $wp_logo_menu_args = array( 133 'id' => 'wp-logo', 134 'title' => '<span class="ab-icon" aria-hidden="true"></span><span class="screen-reader-text">' . __( 'About WordPress' ) . '</span>', 135 'href' => $about_url, 136 ); 137 138 // Set tabindex="0" to make sub menus accessible when no URL is available. 139 if ( ! $about_url ) { 140 $wp_logo_menu_args['meta'] = array( 141 'tabindex' => 0, 142 ); 143 } 144 145 $wp_admin_bar->add_node( $wp_logo_menu_args ); 146 147 if ( $about_url ) { 148 // Add "About WordPress" link. 149 $wp_admin_bar->add_node( 150 array( 151 'parent' => 'wp-logo', 152 'id' => 'about', 153 'title' => __( 'About WordPress' ), 154 'href' => $about_url, 155 ) 156 ); 157 } 158 159 // Add WordPress.org link. 160 $wp_admin_bar->add_node( 161 array( 162 'parent' => 'wp-logo-external', 163 'id' => 'wporg', 164 'title' => __( 'WordPress.org' ), 165 'href' => __( 'https://wordpress.org/' ), 166 ) 167 ); 168 169 // Add documentation link. 170 $wp_admin_bar->add_node( 171 array( 172 'parent' => 'wp-logo-external', 173 'id' => 'documentation', 174 'title' => __( 'Documentation' ), 175 'href' => __( 'https://wordpress.org/support/' ), 176 ) 177 ); 178 179 // Add forums link. 180 $wp_admin_bar->add_node( 181 array( 182 'parent' => 'wp-logo-external', 183 'id' => 'support-forums', 184 'title' => __( 'Support' ), 185 'href' => __( 'https://wordpress.org/support/forums/' ), 186 ) 187 ); 188 189 // Add feedback link. 190 $wp_admin_bar->add_node( 191 array( 192 'parent' => 'wp-logo-external', 193 'id' => 'feedback', 194 'title' => __( 'Feedback' ), 195 'href' => __( 'https://wordpress.org/support/forum/requests-and-feedback' ), 196 ) 197 ); 198 } 199 200 /** 201 * Add the sidebar toggle button. 202 * 203 * @since 3.8.0 204 * 205 * @param WP_Admin_Bar $wp_admin_bar 206 */ 207 function wp_admin_bar_sidebar_toggle( $wp_admin_bar ) { 208 if ( is_admin() ) { 209 $wp_admin_bar->add_node( 210 array( 211 'id' => 'menu-toggle', 212 'title' => '<span class="ab-icon" aria-hidden="true"></span><span class="screen-reader-text">' . __( 'Menu' ) . '</span>', 213 'href' => '#', 214 ) 215 ); 216 } 217 } 218 219 /** 220 * Add the "My Account" item. 221 * 222 * @since 3.3.0 223 * 224 * @param WP_Admin_Bar $wp_admin_bar 225 */ 226 function wp_admin_bar_my_account_item( $wp_admin_bar ) { 227 $user_id = get_current_user_id(); 228 $current_user = wp_get_current_user(); 229 230 if ( ! $user_id ) { 231 return; 232 } 233 234 if ( current_user_can( 'read' ) ) { 235 $profile_url = get_edit_profile_url( $user_id ); 236 } elseif ( is_multisite() ) { 237 $profile_url = get_dashboard_url( $user_id, 'profile.php' ); 238 } else { 239 $profile_url = false; 240 } 241 242 $avatar = get_avatar( $user_id, 26 ); 243 /* translators: %s: Current user's display name. */ 244 $howdy = sprintf( __( 'Howdy, %s' ), '<span class="display-name">' . $current_user->display_name . '</span>' ); 245 $class = empty( $avatar ) ? '' : 'with-avatar'; 246 247 $wp_admin_bar->add_node( 248 array( 249 'id' => 'my-account', 250 'parent' => 'top-secondary', 251 'title' => $howdy . $avatar, 252 'href' => $profile_url, 253 'meta' => array( 254 'class' => $class, 255 ), 256 ) 257 ); 258 } 259 260 /** 261 * Add the "My Account" submenu items. 262 * 263 * @since 3.1.0 264 * 265 * @param WP_Admin_Bar $wp_admin_bar 266 */ 267 function wp_admin_bar_my_account_menu( $wp_admin_bar ) { 268 $user_id = get_current_user_id(); 269 $current_user = wp_get_current_user(); 270 271 if ( ! $user_id ) { 272 return; 273 } 274 275 if ( current_user_can( 'read' ) ) { 276 $profile_url = get_edit_profile_url( $user_id ); 277 } elseif ( is_multisite() ) { 278 $profile_url = get_dashboard_url( $user_id, 'profile.php' ); 279 } else { 280 $profile_url = false; 281 } 282 283 $wp_admin_bar->add_group( 284 array( 285 'parent' => 'my-account', 286 'id' => 'user-actions', 287 ) 288 ); 289 290 $user_info = get_avatar( $user_id, 64 ); 291 $user_info .= "<span class='display-name'>{$current_user->display_name}</span>"; 292 293 if ( $current_user->display_name !== $current_user->user_login ) { 294 $user_info .= "<span class='username'>{$current_user->user_login}</span>"; 295 } 296 297 $wp_admin_bar->add_node( 298 array( 299 'parent' => 'user-actions', 300 'id' => 'user-info', 301 'title' => $user_info, 302 'href' => $profile_url, 303 'meta' => array( 304 'tabindex' => -1, 305 ), 306 ) 307 ); 308 309 if ( false !== $profile_url ) { 310 $wp_admin_bar->add_node( 311 array( 312 'parent' => 'user-actions', 313 'id' => 'edit-profile', 314 'title' => __( 'Edit Profile' ), 315 'href' => $profile_url, 316 ) 317 ); 318 } 319 320 $wp_admin_bar->add_node( 321 array( 322 'parent' => 'user-actions', 323 'id' => 'logout', 324 'title' => __( 'Log Out' ), 325 'href' => wp_logout_url(), 326 ) 327 ); 328 } 329 330 /** 331 * Add the "Site Name" menu. 332 * 333 * @since 3.3.0 334 * 335 * @param WP_Admin_Bar $wp_admin_bar 336 */ 337 function wp_admin_bar_site_menu( $wp_admin_bar ) { 338 // Don't show for logged out users. 339 if ( ! is_user_logged_in() ) { 340 return; 341 } 342 343 // Show only when the user is a member of this site, or they're a super admin. 344 if ( ! is_user_member_of_blog() && ! current_user_can( 'manage_network' ) ) { 345 return; 346 } 347 348 $blogname = get_bloginfo( 'name' ); 349 350 if ( ! $blogname ) { 351 $blogname = preg_replace( '#^(https?://)?(www.)?#', '', get_home_url() ); 352 } 353 354 if ( is_network_admin() ) { 355 /* translators: %s: Site title. */ 356 $blogname = sprintf( __( 'Network Admin: %s' ), esc_html( get_network()->site_name ) ); 357 } elseif ( is_user_admin() ) { 358 /* translators: %s: Site title. */ 359 $blogname = sprintf( __( 'User Dashboard: %s' ), esc_html( get_network()->site_name ) ); 360 } 361 362 $title = wp_html_excerpt( $blogname, 40, '…' ); 363 364 $wp_admin_bar->add_node( 365 array( 366 'id' => 'site-name', 367 'title' => $title, 368 'href' => ( is_admin() || ! current_user_can( 'read' ) ) ? home_url( '/' ) : admin_url(), 369 ) 370 ); 371 372 // Create submenu items. 373 374 if ( is_admin() ) { 375 // Add an option to visit the site. 376 $wp_admin_bar->add_node( 377 array( 378 'parent' => 'site-name', 379 'id' => 'view-site', 380 'title' => __( 'Visit Site' ), 381 'href' => home_url( '/' ), 382 ) 383 ); 384 385 if ( is_blog_admin() && is_multisite() && current_user_can( 'manage_sites' ) ) { 386 $wp_admin_bar->add_node( 387 array( 388 'parent' => 'site-name', 389 'id' => 'edit-site', 390 'title' => __( 'Edit Site' ), 391 'href' => network_admin_url( 'site-info.php?id=' . get_current_blog_id() ), 392 ) 393 ); 394 } 395 } elseif ( current_user_can( 'read' ) ) { 396 // We're on the front end, link to the Dashboard. 397 $wp_admin_bar->add_node( 398 array( 399 'parent' => 'site-name', 400 'id' => 'dashboard', 401 'title' => __( 'Dashboard' ), 402 'href' => admin_url(), 403 ) 404 ); 405 406 // Add the appearance submenu items. 407 wp_admin_bar_appearance_menu( $wp_admin_bar ); 408 } 409 } 410 411 /** 412 * Adds the "Customize" link to the Toolbar. 413 * 414 * @since 4.3.0 415 * 416 * @param WP_Admin_Bar $wp_admin_bar WP_Admin_Bar instance. 417 * @global WP_Customize_Manager $wp_customize 418 */ 419 function wp_admin_bar_customize_menu( $wp_admin_bar ) { 420 global $wp_customize; 421 422 // Don't show for users who can't access the customizer or when in the admin. 423 if ( ! current_user_can( 'customize' ) || is_admin() ) { 424 return; 425 } 426 427 // Don't show if the user cannot edit a given customize_changeset post currently being previewed. 428 if ( is_customize_preview() && $wp_customize->changeset_post_id() 429 && ! current_user_can( get_post_type_object( 'customize_changeset' )->cap->edit_post, $wp_customize->changeset_post_id() ) 430 ) { 431 return; 432 } 433 434 $current_url = ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; 435 if ( is_customize_preview() && $wp_customize->changeset_uuid() ) { 436 $current_url = remove_query_arg( 'customize_changeset_uuid', $current_url ); 437 } 438 439 $customize_url = add_query_arg( 'url', urlencode( $current_url ), wp_customize_url() ); 440 if ( is_customize_preview() ) { 441 $customize_url = add_query_arg( array( 'changeset_uuid' => $wp_customize->changeset_uuid() ), $customize_url ); 442 } 443 444 $wp_admin_bar->add_node( 445 array( 446 'id' => 'customize', 447 'title' => __( 'Customize' ), 448 'href' => $customize_url, 449 'meta' => array( 450 'class' => 'hide-if-no-customize', 451 ), 452 ) 453 ); 454 add_action( 'wp_before_admin_bar_render', 'wp_customize_support_script' ); 455 } 456 457 /** 458 * Add the "My Sites/[Site Name]" menu and all submenus. 459 * 460 * @since 3.1.0 461 * 462 * @param WP_Admin_Bar $wp_admin_bar 463 */ 464 function wp_admin_bar_my_sites_menu( $wp_admin_bar ) { 465 // Don't show for logged out users or single site mode. 466 if ( ! is_user_logged_in() || ! is_multisite() ) { 467 return; 468 } 469 470 // Show only when the user has at least one site, or they're a super admin. 471 if ( count( $wp_admin_bar->user->blogs ) < 1 && ! current_user_can( 'manage_network' ) ) { 472 return; 473 } 474 475 if ( $wp_admin_bar->user->active_blog ) { 476 $my_sites_url = get_admin_url( $wp_admin_bar->user->active_blog->blog_id, 'my-sites.php' ); 477 } else { 478 $my_sites_url = admin_url( 'my-sites.php' ); 479 } 480 481 $wp_admin_bar->add_node( 482 array( 483 'id' => 'my-sites', 484 'title' => __( 'My Sites' ), 485 'href' => $my_sites_url, 486 ) 487 ); 488 489 if ( current_user_can( 'manage_network' ) ) { 490 $wp_admin_bar->add_group( 491 array( 492 'parent' => 'my-sites', 493 'id' => 'my-sites-super-admin', 494 ) 495 ); 496 497 $wp_admin_bar->add_node( 498 array( 499 'parent' => 'my-sites-super-admin', 500 'id' => 'network-admin', 501 'title' => __( 'Network Admin' ), 502 'href' => network_admin_url(), 503 ) 504 ); 505 506 $wp_admin_bar->add_node( 507 array( 508 'parent' => 'network-admin', 509 'id' => 'network-admin-d', 510 'title' => __( 'Dashboard' ), 511 'href' => network_admin_url(), 512 ) 513 ); 514 515 if ( current_user_can( 'manage_sites' ) ) { 516 $wp_admin_bar->add_node( 517 array( 518 'parent' => 'network-admin', 519 'id' => 'network-admin-s', 520 'title' => __( 'Sites' ), 521 'href' => network_admin_url( 'sites.php' ), 522 ) 523 ); 524 } 525 526 if ( current_user_can( 'manage_network_users' ) ) { 527 $wp_admin_bar->add_node( 528 array( 529 'parent' => 'network-admin', 530 'id' => 'network-admin-u', 531 'title' => __( 'Users' ), 532 'href' => network_admin_url( 'users.php' ), 533 ) 534 ); 535 } 536 537 if ( current_user_can( 'manage_network_themes' ) ) { 538 $wp_admin_bar->add_node( 539 array( 540 'parent' => 'network-admin', 541 'id' => 'network-admin-t', 542 'title' => __( 'Themes' ), 543 'href' => network_admin_url( 'themes.php' ), 544 ) 545 ); 546 } 547 548 if ( current_user_can( 'manage_network_plugins' ) ) { 549 $wp_admin_bar->add_node( 550 array( 551 'parent' => 'network-admin', 552 'id' => 'network-admin-p', 553 'title' => __( 'Plugins' ), 554 'href' => network_admin_url( 'plugins.php' ), 555 ) 556 ); 557 } 558 559 if ( current_user_can( 'manage_network_options' ) ) { 560 $wp_admin_bar->add_node( 561 array( 562 'parent' => 'network-admin', 563 'id' => 'network-admin-o', 564 'title' => __( 'Settings' ), 565 'href' => network_admin_url( 'settings.php' ), 566 ) 567 ); 568 } 569 } 570 571 // Add site links. 572 $wp_admin_bar->add_group( 573 array( 574 'parent' => 'my-sites', 575 'id' => 'my-sites-list', 576 'meta' => array( 577 'class' => current_user_can( 'manage_network' ) ? 'ab-sub-secondary' : '', 578 ), 579 ) 580 ); 581 582 foreach ( (array) $wp_admin_bar->user->blogs as $blog ) { 583 switch_to_blog( $blog->userblog_id ); 584 585 if ( has_site_icon() ) { 586 $blavatar = sprintf( 587 '<img class="blavatar" src="%s" srcset="%s 2x" alt="" width="16" height="16" />', 588 esc_url( get_site_icon_url( 16 ) ), 589 esc_url( get_site_icon_url( 32 ) ) 590 ); 591 } else { 592 $blavatar = '<div class="blavatar"></div>'; 593 } 594 595 $blogname = $blog->blogname; 596 597 if ( ! $blogname ) { 598 $blogname = preg_replace( '#^(https?://)?(www.)?#', '', get_home_url() ); 599 } 600 601 $menu_id = 'blog-' . $blog->userblog_id; 602 603 if ( current_user_can( 'read' ) ) { 604 $wp_admin_bar->add_node( 605 array( 606 'parent' => 'my-sites-list', 607 'id' => $menu_id, 608 'title' => $blavatar . $blogname, 609 'href' => admin_url(), 610 ) 611 ); 612 613 $wp_admin_bar->add_node( 614 array( 615 'parent' => $menu_id, 616 'id' => $menu_id . '-d', 617 'title' => __( 'Dashboard' ), 618 'href' => admin_url(), 619 ) 620 ); 621 } else { 622 $wp_admin_bar->add_node( 623 array( 624 'parent' => 'my-sites-list', 625 'id' => $menu_id, 626 'title' => $blavatar . $blogname, 627 'href' => home_url(), 628 ) 629 ); 630 } 631 632 if ( current_user_can( get_post_type_object( 'post' )->cap->create_posts ) ) { 633 $wp_admin_bar->add_node( 634 array( 635 'parent' => $menu_id, 636 'id' => $menu_id . '-n', 637 'title' => get_post_type_object( 'post' )->labels->new_item, 638 'href' => admin_url( 'post-new.php' ), 639 ) 640 ); 641 } 642 643 if ( current_user_can( 'edit_posts' ) ) { 644 $wp_admin_bar->add_node( 645 array( 646 'parent' => $menu_id, 647 'id' => $menu_id . '-c', 648 'title' => __( 'Manage Comments' ), 649 'href' => admin_url( 'edit-comments.php' ), 650 ) 651 ); 652 } 653 654 $wp_admin_bar->add_node( 655 array( 656 'parent' => $menu_id, 657 'id' => $menu_id . '-v', 658 'title' => __( 'Visit Site' ), 659 'href' => home_url( '/' ), 660 ) 661 ); 662 663 restore_current_blog(); 664 } 665 } 666 667 /** 668 * Provide a shortlink. 669 * 670 * @since 3.1.0 671 * 672 * @param WP_Admin_Bar $wp_admin_bar 673 */ 674 function wp_admin_bar_shortlink_menu( $wp_admin_bar ) { 675 $short = wp_get_shortlink( 0, 'query' ); 676 $id = 'get-shortlink'; 677 678 if ( empty( $short ) ) { 679 return; 680 } 681 682 $html = '<input class="shortlink-input" type="text" readonly="readonly" value="' . esc_attr( $short ) . '" />'; 683 684 $wp_admin_bar->add_node( 685 array( 686 'id' => $id, 687 'title' => __( 'Shortlink' ), 688 'href' => $short, 689 'meta' => array( 'html' => $html ), 690 ) 691 ); 692 } 693 694 /** 695 * Provide an edit link for posts and terms. 696 * 697 * @since 3.1.0 698 * @since 5.5.0 Added a "View Post" link on Comments screen for a single post. 699 * 700 * @global WP_Term $tag 701 * @global WP_Query $wp_the_query WordPress Query object. 702 * @global int $user_id The ID of the user being edited. Not to be confused with the 703 * global $user_ID, which contains the ID of the current user. 704 * @global int $post_id The ID of the post when editing comments for a single post. 705 * 706 * @param WP_Admin_Bar $wp_admin_bar 707 */ 708 function wp_admin_bar_edit_menu( $wp_admin_bar ) { 709 global $tag, $wp_the_query, $user_id, $post_id; 710 711 if ( is_admin() ) { 712 $current_screen = get_current_screen(); 713 $post = get_post(); 714 $post_type_object = null; 715 716 if ( 'post' === $current_screen->base ) { 717 $post_type_object = get_post_type_object( $post->post_type ); 718 } elseif ( 'edit' === $current_screen->base ) { 719 $post_type_object = get_post_type_object( $current_screen->post_type ); 720 } elseif ( 'edit-comments' === $current_screen->base && $post_id ) { 721 $post = get_post( $post_id ); 722 if ( $post ) { 723 $post_type_object = get_post_type_object( $post->post_type ); 724 } 725 } 726 727 if ( ( 'post' === $current_screen->base || 'edit-comments' === $current_screen->base ) 728 && 'add' !== $current_screen->action 729 && ( $post_type_object ) 730 && current_user_can( 'read_post', $post->ID ) 731 && ( $post_type_object->public ) 732 && ( $post_type_object->show_in_admin_bar ) ) { 733 if ( 'draft' === $post->post_status ) { 734 $preview_link = get_preview_post_link( $post ); 735 $wp_admin_bar->add_node( 736 array( 737 'id' => 'preview', 738 'title' => $post_type_object->labels->view_item, 739 'href' => esc_url( $preview_link ), 740 'meta' => array( 'target' => 'wp-preview-' . $post->ID ), 741 ) 742 ); 743 } else { 744 $wp_admin_bar->add_node( 745 array( 746 'id' => 'view', 747 'title' => $post_type_object->labels->view_item, 748 'href' => get_permalink( $post->ID ), 749 ) 750 ); 751 } 752 } elseif ( 'edit' === $current_screen->base 753 && ( $post_type_object ) 754 && ( $post_type_object->public ) 755 && ( $post_type_object->show_in_admin_bar ) 756 && ( get_post_type_archive_link( $post_type_object->name ) ) 757 && ! ( 'post' === $post_type_object->name && 'posts' === get_option( 'show_on_front' ) ) ) { 758 $wp_admin_bar->add_node( 759 array( 760 'id' => 'archive', 761 'title' => $post_type_object->labels->view_items, 762 'href' => get_post_type_archive_link( $current_screen->post_type ), 763 ) 764 ); 765 } elseif ( 'term' === $current_screen->base && isset( $tag ) && is_object( $tag ) && ! is_wp_error( $tag ) ) { 766 $tax = get_taxonomy( $tag->taxonomy ); 767 if ( is_taxonomy_viewable( $tax ) ) { 768 $wp_admin_bar->add_node( 769 array( 770 'id' => 'view', 771 'title' => $tax->labels->view_item, 772 'href' => get_term_link( $tag ), 773 ) 774 ); 775 } 776 } elseif ( 'user-edit' === $current_screen->base && isset( $user_id ) ) { 777 $user_object = get_userdata( $user_id ); 778 $view_link = get_author_posts_url( $user_object->ID ); 779 if ( $user_object->exists() && $view_link ) { 780 $wp_admin_bar->add_node( 781 array( 782 'id' => 'view', 783 'title' => __( 'View User' ), 784 'href' => $view_link, 785 ) 786 ); 787 } 788 } 789 } else { 790 $current_object = $wp_the_query->get_queried_object(); 791 792 if ( empty( $current_object ) ) { 793 return; 794 } 795 796 if ( ! empty( $current_object->post_type ) ) { 797 $post_type_object = get_post_type_object( $current_object->post_type ); 798 $edit_post_link = get_edit_post_link( $current_object->ID ); 799 if ( $post_type_object 800 && $edit_post_link 801 && current_user_can( 'edit_post', $current_object->ID ) 802 && $post_type_object->show_in_admin_bar ) { 803 $wp_admin_bar->add_node( 804 array( 805 'id' => 'edit', 806 'title' => $post_type_object->labels->edit_item, 807 'href' => $edit_post_link, 808 ) 809 ); 810 } 811 } elseif ( ! empty( $current_object->taxonomy ) ) { 812 $tax = get_taxonomy( $current_object->taxonomy ); 813 $edit_term_link = get_edit_term_link( $current_object->term_id, $current_object->taxonomy ); 814 if ( $tax && $edit_term_link && current_user_can( 'edit_term', $current_object->term_id ) ) { 815 $wp_admin_bar->add_node( 816 array( 817 'id' => 'edit', 818 'title' => $tax->labels->edit_item, 819 'href' => $edit_term_link, 820 ) 821 ); 822 } 823 } elseif ( is_a( $current_object, 'WP_User' ) && current_user_can( 'edit_user', $current_object->ID ) ) { 824 $edit_user_link = get_edit_user_link( $current_object->ID ); 825 if ( $edit_user_link ) { 826 $wp_admin_bar->add_node( 827 array( 828 'id' => 'edit', 829 'title' => __( 'Edit User' ), 830 'href' => $edit_user_link, 831 ) 832 ); 833 } 834 } 835 } 836 } 837 838 /** 839 * Add "Add New" menu. 840 * 841 * @since 3.1.0 842 * 843 * @param WP_Admin_Bar $wp_admin_bar 844 */ 845 function wp_admin_bar_new_content_menu( $wp_admin_bar ) { 846 $actions = array(); 847 848 $cpts = (array) get_post_types( array( 'show_in_admin_bar' => true ), 'objects' ); 849 850 if ( isset( $cpts['post'] ) && current_user_can( $cpts['post']->cap->create_posts ) ) { 851 $actions['post-new.php'] = array( $cpts['post']->labels->name_admin_bar, 'new-post' ); 852 } 853 854 if ( isset( $cpts['attachment'] ) && current_user_can( 'upload_files' ) ) { 855 $actions['media-new.php'] = array( $cpts['attachment']->labels->name_admin_bar, 'new-media' ); 856 } 857 858 if ( current_user_can( 'manage_links' ) ) { 859 $actions['link-add.php'] = array( _x( 'Link', 'add new from admin bar' ), 'new-link' ); 860 } 861 862 if ( isset( $cpts['page'] ) && current_user_can( $cpts['page']->cap->create_posts ) ) { 863 $actions['post-new.php?post_type=page'] = array( $cpts['page']->labels->name_admin_bar, 'new-page' ); 864 } 865 866 unset( $cpts['post'], $cpts['page'], $cpts['attachment'] ); 867 868 // Add any additional custom post types. 869 foreach ( $cpts as $cpt ) { 870 if ( ! current_user_can( $cpt->cap->create_posts ) ) { 871 continue; 872 } 873 874 $key = 'post-new.php?post_type=' . $cpt->name; 875 $actions[ $key ] = array( $cpt->labels->name_admin_bar, 'new-' . $cpt->name ); 876 } 877 // Avoid clash with parent node and a 'content' post type. 878 if ( isset( $actions['post-new.php?post_type=content'] ) ) { 879 $actions['post-new.php?post_type=content'][1] = 'add-new-content'; 880 } 881 882 if ( current_user_can( 'create_users' ) || ( is_multisite() && current_user_can( 'promote_users' ) ) ) { 883 $actions['user-new.php'] = array( _x( 'User', 'add new from admin bar' ), 'new-user' ); 884 } 885 886 if ( ! $actions ) { 887 return; 888 } 889 890 $title = '<span class="ab-icon" aria-hidden="true"></span><span class="ab-label">' . _x( 'New', 'admin bar menu group label' ) . '</span>'; 891 892 $wp_admin_bar->add_node( 893 array( 894 'id' => 'new-content', 895 'title' => $title, 896 'href' => admin_url( current( array_keys( $actions ) ) ), 897 ) 898 ); 899 900 foreach ( $actions as $link => $action ) { 901 list( $title, $id ) = $action; 902 903 $wp_admin_bar->add_node( 904 array( 905 'parent' => 'new-content', 906 'id' => $id, 907 'title' => $title, 908 'href' => admin_url( $link ), 909 ) 910 ); 911 } 912 } 913 914 /** 915 * Add edit comments link with awaiting moderation count bubble. 916 * 917 * @since 3.1.0 918 * 919 * @param WP_Admin_Bar $wp_admin_bar 920 */ 921 function wp_admin_bar_comments_menu( $wp_admin_bar ) { 922 if ( ! current_user_can( 'edit_posts' ) ) { 923 return; 924 } 925 926 $awaiting_mod = wp_count_comments(); 927 $awaiting_mod = $awaiting_mod->moderated; 928 $awaiting_text = sprintf( 929 /* translators: %s: Number of comments. */ 930 _n( '%s Comment in moderation', '%s Comments in moderation', $awaiting_mod ), 931 number_format_i18n( $awaiting_mod ) 932 ); 933 934 $icon = '<span class="ab-icon" aria-hidden="true"></span>'; 935 $title = '<span class="ab-label awaiting-mod pending-count count-' . $awaiting_mod . '" aria-hidden="true">' . number_format_i18n( $awaiting_mod ) . '</span>'; 936 $title .= '<span class="screen-reader-text comments-in-moderation-text">' . $awaiting_text . '</span>'; 937 938 $wp_admin_bar->add_node( 939 array( 940 'id' => 'comments', 941 'title' => $icon . $title, 942 'href' => admin_url( 'edit-comments.php' ), 943 ) 944 ); 945 } 946 947 /** 948 * Add appearance submenu items to the "Site Name" menu. 949 * 950 * @since 3.1.0 951 * 952 * @param WP_Admin_Bar $wp_admin_bar 953 */ 954 function wp_admin_bar_appearance_menu( $wp_admin_bar ) { 955 $wp_admin_bar->add_group( 956 array( 957 'parent' => 'site-name', 958 'id' => 'appearance', 959 ) 960 ); 961 962 if ( current_user_can( 'switch_themes' ) ) { 963 $wp_admin_bar->add_node( 964 array( 965 'parent' => 'appearance', 966 'id' => 'themes', 967 'title' => __( 'Themes' ), 968 'href' => admin_url( 'themes.php' ), 969 ) 970 ); 971 } 972 973 if ( ! current_user_can( 'edit_theme_options' ) ) { 974 return; 975 } 976 977 if ( current_theme_supports( 'widgets' ) ) { 978 $wp_admin_bar->add_node( 979 array( 980 'parent' => 'appearance', 981 'id' => 'widgets', 982 'title' => __( 'Widgets' ), 983 'href' => admin_url( 'widgets.php' ), 984 ) 985 ); 986 } 987 988 if ( current_theme_supports( 'menus' ) || current_theme_supports( 'widgets' ) ) { 989 $wp_admin_bar->add_node( 990 array( 991 'parent' => 'appearance', 992 'id' => 'menus', 993 'title' => __( 'Menus' ), 994 'href' => admin_url( 'nav-menus.php' ), 995 ) 996 ); 997 } 998 999 if ( current_theme_supports( 'custom-background' ) ) { 1000 $wp_admin_bar->add_node( 1001 array( 1002 'parent' => 'appearance', 1003 'id' => 'background', 1004 'title' => __( 'Background' ), 1005 'href' => admin_url( 'themes.php?page=custom-background' ), 1006 'meta' => array( 1007 'class' => 'hide-if-customize', 1008 ), 1009 ) 1010 ); 1011 } 1012 1013 if ( current_theme_supports( 'custom-header' ) ) { 1014 $wp_admin_bar->add_node( 1015 array( 1016 'parent' => 'appearance', 1017 'id' => 'header', 1018 'title' => __( 'Header' ), 1019 'href' => admin_url( 'themes.php?page=custom-header' ), 1020 'meta' => array( 1021 'class' => 'hide-if-customize', 1022 ), 1023 ) 1024 ); 1025 } 1026 1027 } 1028 1029 /** 1030 * Provide an update link if theme/plugin/core updates are available. 1031 * 1032 * @since 3.1.0 1033 * 1034 * @param WP_Admin_Bar $wp_admin_bar 1035 */ 1036 function wp_admin_bar_updates_menu( $wp_admin_bar ) { 1037 1038 $update_data = wp_get_update_data(); 1039 1040 if ( ! $update_data['counts']['total'] ) { 1041 return; 1042 } 1043 1044 $updates_text = sprintf( 1045 /* translators: %s: Total number of updates available. */ 1046 _n( '%s update available', '%s updates available', $update_data['counts']['total'] ), 1047 number_format_i18n( $update_data['counts']['total'] ) 1048 ); 1049 1050 $icon = '<span class="ab-icon" aria-hidden="true"></span>'; 1051 $title = '<span class="ab-label" aria-hidden="true">' . number_format_i18n( $update_data['counts']['total'] ) . '</span>'; 1052 $title .= '<span class="screen-reader-text updates-available-text">' . $updates_text . '</span>'; 1053 1054 $wp_admin_bar->add_node( 1055 array( 1056 'id' => 'updates', 1057 'title' => $icon . $title, 1058 'href' => network_admin_url( 'update-core.php' ), 1059 ) 1060 ); 1061 } 1062 1063 /** 1064 * Add search form. 1065 * 1066 * @since 3.3.0 1067 * 1068 * @param WP_Admin_Bar $wp_admin_bar 1069 */ 1070 function wp_admin_bar_search_menu( $wp_admin_bar ) { 1071 if ( is_admin() ) { 1072 return; 1073 } 1074 1075 $form = '<form action="' . esc_url( home_url( '/' ) ) . '" method="get" id="adminbarsearch">'; 1076 $form .= '<input class="adminbar-input" name="s" id="adminbar-search" type="text" value="" maxlength="150" />'; 1077 $form .= '<label for="adminbar-search" class="screen-reader-text">' . __( 'Search' ) . '</label>'; 1078 $form .= '<input type="submit" class="adminbar-button" value="' . __( 'Search' ) . '" />'; 1079 $form .= '</form>'; 1080 1081 $wp_admin_bar->add_node( 1082 array( 1083 'parent' => 'top-secondary', 1084 'id' => 'search', 1085 'title' => $form, 1086 'meta' => array( 1087 'class' => 'admin-bar-search', 1088 'tabindex' => -1, 1089 ), 1090 ) 1091 ); 1092 } 1093 1094 /** 1095 * Add a link to exit recovery mode when Recovery Mode is active. 1096 * 1097 * @since 5.2.0 1098 * 1099 * @param WP_Admin_Bar $wp_admin_bar 1100 */ 1101 function wp_admin_bar_recovery_mode_menu( $wp_admin_bar ) { 1102 if ( ! wp_is_recovery_mode() ) { 1103 return; 1104 } 1105 1106 $url = wp_login_url(); 1107 $url = add_query_arg( 'action', WP_Recovery_Mode::EXIT_ACTION, $url ); 1108 $url = wp_nonce_url( $url, WP_Recovery_Mode::EXIT_ACTION ); 1109 1110 $wp_admin_bar->add_node( 1111 array( 1112 'parent' => 'top-secondary', 1113 'id' => 'recovery-mode', 1114 'title' => __( 'Exit Recovery Mode' ), 1115 'href' => $url, 1116 ) 1117 ); 1118 } 1119 1120 /** 1121 * Add secondary menus. 1122 * 1123 * @since 3.3.0 1124 * 1125 * @param WP_Admin_Bar $wp_admin_bar 1126 */ 1127 function wp_admin_bar_add_secondary_groups( $wp_admin_bar ) { 1128 $wp_admin_bar->add_group( 1129 array( 1130 'id' => 'top-secondary', 1131 'meta' => array( 1132 'class' => 'ab-top-secondary', 1133 ), 1134 ) 1135 ); 1136 1137 $wp_admin_bar->add_group( 1138 array( 1139 'parent' => 'wp-logo', 1140 'id' => 'wp-logo-external', 1141 'meta' => array( 1142 'class' => 'ab-sub-secondary', 1143 ), 1144 ) 1145 ); 1146 } 1147 1148 /** 1149 * Style and scripts for the admin bar. 1150 * 1151 * @since 3.1.0 1152 */ 1153 function wp_admin_bar_header() { 1154 $type_attr = current_theme_supports( 'html5', 'style' ) ? '' : ' type="text/css"'; 1155 ?> 1156 <style<?php echo $type_attr; ?> media="print">#wpadminbar { display:none; }</style> 1157 <?php 1158 } 1159 1160 /** 1161 * Default admin bar callback. 1162 * 1163 * @since 3.1.0 1164 */ 1165 function _admin_bar_bump_cb() { 1166 $type_attr = current_theme_supports( 'html5', 'style' ) ? '' : ' type="text/css"'; 1167 ?> 1168 <style<?php echo $type_attr; ?> media="screen"> 1169 html { margin-top: 32px !important; } 1170 * html body { margin-top: 32px !important; } 1171 @media screen and ( max-width: 782px ) { 1172 html { margin-top: 46px !important; } 1173 * html body { margin-top: 46px !important; } 1174 } 1175 </style> 1176 <?php 1177 } 1178 1179 /** 1180 * Sets the display status of the admin bar. 1181 * 1182 * This can be called immediately upon plugin load. It does not need to be called 1183 * from a function hooked to the {@see 'init'} action. 1184 * 1185 * @since 3.1.0 1186 * 1187 * @global bool $show_admin_bar 1188 * 1189 * @param bool $show Whether to allow the admin bar to show. 1190 */ 1191 function show_admin_bar( $show ) { 1192 global $show_admin_bar; 1193 $show_admin_bar = (bool) $show; 1194 } 1195 1196 /** 1197 * Determines whether the admin bar should be showing. 1198 * 1199 * For more information on this and similar theme functions, check out 1200 * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/ 1201 * Conditional Tags} article in the Theme Developer Handbook. 1202 * 1203 * @since 3.1.0 1204 * 1205 * @global bool $show_admin_bar 1206 * @global string $pagenow 1207 * 1208 * @return bool Whether the admin bar should be showing. 1209 */ 1210 function is_admin_bar_showing() { 1211 global $show_admin_bar, $pagenow; 1212 1213 // For all these types of requests, we never want an admin bar. 1214 if ( defined( 'XMLRPC_REQUEST' ) || defined( 'DOING_AJAX' ) || defined( 'IFRAME_REQUEST' ) || wp_is_json_request() ) { 1215 return false; 1216 } 1217 1218 if ( is_embed() ) { 1219 return false; 1220 } 1221 1222 // Integrated into the admin. 1223 if ( is_admin() ) { 1224 return true; 1225 } 1226 1227 if ( ! isset( $show_admin_bar ) ) { 1228 if ( ! is_user_logged_in() || 'wp-login.php' === $pagenow ) { 1229 $show_admin_bar = false; 1230 } else { 1231 $show_admin_bar = _get_admin_bar_pref(); 1232 } 1233 } 1234 1235 /** 1236 * Filters whether to show the admin bar. 1237 * 1238 * Returning false to this hook is the recommended way to hide the admin bar. 1239 * The user's display preference is used for logged in users. 1240 * 1241 * @since 3.1.0 1242 * 1243 * @param bool $show_admin_bar Whether the admin bar should be shown. Default false. 1244 */ 1245 $show_admin_bar = apply_filters( 'show_admin_bar', $show_admin_bar ); 1246 1247 return $show_admin_bar; 1248 } 1249 1250 /** 1251 * Retrieve the admin bar display preference of a user. 1252 * 1253 * @since 3.1.0 1254 * @access private 1255 * 1256 * @param string $context Context of this preference check. Defaults to 'front'. The 'admin' 1257 * preference is no longer used. 1258 * @param int $user Optional. ID of the user to check, defaults to 0 for current user. 1259 * @return bool Whether the admin bar should be showing for this user. 1260 */ 1261 function _get_admin_bar_pref( $context = 'front', $user = 0 ) { 1262 $pref = get_user_option( "show_admin_bar_{$context}", $user ); 1263 if ( false === $pref ) { 1264 return true; 1265 } 1266 1267 return 'true' === $pref; 1268 }