[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/ -> admin-bar.php (source)

   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   * Instantiates 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. This also gives you access to the `$post` global,
  66   * among others.
  67   *
  68   * @since 3.1.0
  69   * @since 5.4.0 Called on 'wp_body_open' action first, with 'wp_footer' as a fallback.
  70   *
  71   * @global WP_Admin_Bar $wp_admin_bar
  72   */
  73  function wp_admin_bar_render() {
  74      global $wp_admin_bar;
  75      static $rendered = false;
  76  
  77      if ( $rendered ) {
  78          return;
  79      }
  80  
  81      if ( ! is_admin_bar_showing() || ! is_object( $wp_admin_bar ) ) {
  82          return;
  83      }
  84  
  85      /**
  86       * Loads all necessary admin bar items.
  87       *
  88       * This hook can add, remove, or manipulate admin bar items. The priority
  89       * determines the placement for new items, and changes to existing items
  90       * would require a high priority. To remove or manipulate existing nodes
  91       * without a specific priority, use `wp_before_admin_bar_render`.
  92       *
  93       * @since 3.1.0
  94       *
  95       * @param WP_Admin_Bar $wp_admin_bar The WP_Admin_Bar instance, passed by reference.
  96       */
  97      do_action_ref_array( 'admin_bar_menu', array( &$wp_admin_bar ) );
  98  
  99      /**
 100       * Fires before the admin bar is rendered.
 101       *
 102       * @since 3.1.0
 103       */
 104      do_action( 'wp_before_admin_bar_render' );
 105  
 106      $wp_admin_bar->render();
 107  
 108      /**
 109       * Fires after the admin bar is rendered.
 110       *
 111       * @since 3.1.0
 112       */
 113      do_action( 'wp_after_admin_bar_render' );
 114  
 115      $rendered = true;
 116  }
 117  
 118  /**
 119   * Adds the WordPress logo menu.
 120   *
 121   * @since 3.3.0
 122   *
 123   * @param WP_Admin_Bar $wp_admin_bar The WP_Admin_Bar instance.
 124   */
 125  function wp_admin_bar_wp_menu( $wp_admin_bar ) {
 126      if ( current_user_can( 'read' ) ) {
 127          $about_url      = self_admin_url( 'about.php' );
 128          $contribute_url = self_admin_url( 'contribute.php' );
 129      } elseif ( is_multisite() ) {
 130          $about_url      = get_dashboard_url( get_current_user_id(), 'about.php' );
 131          $contribute_url = get_dashboard_url( get_current_user_id(), 'contribute.php' );
 132      } else {
 133          $about_url      = false;
 134          $contribute_url = false;
 135      }
 136  
 137      $wp_logo_menu_args = array(
 138          'id'    => 'wp-logo',
 139          'title' => '<span class="ab-icon" aria-hidden="true"></span><span class="screen-reader-text">' .
 140                  /* translators: Hidden accessibility text. */
 141                  __( 'About WordPress' ) .
 142              '</span>',
 143          'href'  => $about_url,
 144          'meta'  => array(
 145              'menu_title' => __( 'About WordPress' ),
 146          ),
 147      );
 148  
 149      // Set tabindex="0" to make sub menus accessible when no URL is available.
 150      if ( ! $about_url ) {
 151          $wp_logo_menu_args['meta'] = array(
 152              'tabindex' => 0,
 153          );
 154      }
 155  
 156      $wp_admin_bar->add_node( $wp_logo_menu_args );
 157  
 158      if ( $about_url ) {
 159          // Add "About WordPress" link.
 160          $wp_admin_bar->add_node(
 161              array(
 162                  'parent' => 'wp-logo',
 163                  'id'     => 'about',
 164                  'title'  => __( 'About WordPress' ),
 165                  'href'   => $about_url,
 166              )
 167          );
 168      }
 169  
 170      if ( $contribute_url ) {
 171          // Add contribute link.
 172          $wp_admin_bar->add_node(
 173              array(
 174                  'parent' => 'wp-logo',
 175                  'id'     => 'contribute',
 176                  'title'  => __( 'Get Involved' ),
 177                  'href'   => $contribute_url,
 178              )
 179          );
 180      }
 181  
 182      // Add WordPress.org link.
 183      $wp_admin_bar->add_node(
 184          array(
 185              'parent' => 'wp-logo-external',
 186              'id'     => 'wporg',
 187              'title'  => __( 'WordPress.org' ),
 188              'href'   => __( 'https://wordpress.org/' ),
 189          )
 190      );
 191  
 192      // Add documentation link.
 193      $wp_admin_bar->add_node(
 194          array(
 195              'parent' => 'wp-logo-external',
 196              'id'     => 'documentation',
 197              'title'  => __( 'Documentation' ),
 198              'href'   => __( 'https://wordpress.org/documentation/' ),
 199          )
 200      );
 201  
 202      // Add learn link.
 203      $wp_admin_bar->add_node(
 204          array(
 205              'parent' => 'wp-logo-external',
 206              'id'     => 'learn',
 207              'title'  => __( 'Learn WordPress' ),
 208              'href'   => __( 'https://learn.wordpress.org/' ),
 209          )
 210      );
 211  
 212      // Add forums link.
 213      $wp_admin_bar->add_node(
 214          array(
 215              'parent' => 'wp-logo-external',
 216              'id'     => 'support-forums',
 217              'title'  => __( 'Support' ),
 218              'href'   => __( 'https://wordpress.org/support/forums/' ),
 219          )
 220      );
 221  
 222      // Add feedback link.
 223      $wp_admin_bar->add_node(
 224          array(
 225              'parent' => 'wp-logo-external',
 226              'id'     => 'feedback',
 227              'title'  => __( 'Feedback' ),
 228              'href'   => __( 'https://wordpress.org/support/forum/requests-and-feedback' ),
 229          )
 230      );
 231  }
 232  
 233  /**
 234   * Adds the sidebar toggle button.
 235   *
 236   * @since 3.8.0
 237   *
 238   * @param WP_Admin_Bar $wp_admin_bar The WP_Admin_Bar instance.
 239   */
 240  function wp_admin_bar_sidebar_toggle( $wp_admin_bar ) {
 241      if ( is_admin() ) {
 242          $wp_admin_bar->add_node(
 243              array(
 244                  'id'    => 'menu-toggle',
 245                  'title' => '<span class="ab-icon" aria-hidden="true"></span><span class="screen-reader-text">' .
 246                          /* translators: Hidden accessibility text. */
 247                          __( 'Menu' ) .
 248                      '</span>',
 249                  'href'  => '#',
 250              )
 251          );
 252      }
 253  }
 254  
 255  /**
 256   * Adds the "My Account" item.
 257   *
 258   * @since 3.3.0
 259   *
 260   * @param WP_Admin_Bar $wp_admin_bar The WP_Admin_Bar instance.
 261   */
 262  function wp_admin_bar_my_account_item( $wp_admin_bar ) {
 263      $user_id = get_current_user_id();
 264      if ( ! $user_id ) {
 265          return;
 266      }
 267  
 268      if ( current_user_can( 'read' ) ) {
 269          $profile_url = get_edit_profile_url( $user_id );
 270      } elseif ( is_multisite() ) {
 271          $profile_url = get_dashboard_url( $user_id, 'profile.php' );
 272      } else {
 273          $profile_url = false;
 274      }
 275  
 276      /* translators: %s: Current user's display name. */
 277      $howdy = sprintf( __( 'Howdy, %s' ), '<span class="display-name">' . wp_get_current_user()->display_name . '</span>' );
 278  
 279      $avatar = get_avatar( $user_id, 28 );
 280      $wp_admin_bar->add_node(
 281          array(
 282              'id'     => 'my-account',
 283              'parent' => 'top-secondary',
 284              'title'  => $howdy . $avatar,
 285              'href'   => $profile_url,
 286              'meta'   => array(
 287                  'class'      => empty( $avatar ) ? '' : 'with-avatar',
 288                  'menu_title' => wp_strip_all_tags( $howdy ),
 289                  'tabindex'   => ( false !== $profile_url ) ? '' : 0,
 290              ),
 291          )
 292      );
 293  }
 294  
 295  /**
 296   * Adds the "My Account" submenu items.
 297   *
 298   * @since 3.1.0
 299   *
 300   * @param WP_Admin_Bar $wp_admin_bar The WP_Admin_Bar instance.
 301   */
 302  function wp_admin_bar_my_account_menu( $wp_admin_bar ) {
 303      $user_id      = get_current_user_id();
 304      $current_user = wp_get_current_user();
 305  
 306      if ( ! $user_id ) {
 307          return;
 308      }
 309  
 310      if ( current_user_can( 'read' ) ) {
 311          $profile_url = get_edit_profile_url( $user_id );
 312      } elseif ( is_multisite() ) {
 313          $profile_url = get_dashboard_url( $user_id, 'profile.php' );
 314      } else {
 315          $profile_url = false;
 316      }
 317  
 318      $wp_admin_bar->add_group(
 319          array(
 320              'parent' => 'my-account',
 321              'id'     => 'user-actions',
 322          )
 323      );
 324  
 325      $user_info  = get_avatar( $user_id, 64 );
 326      $user_info .= "<span class='display-name'>{$current_user->display_name}</span>";
 327  
 328      if ( $current_user->display_name !== $current_user->user_login ) {
 329          $user_info .= "<span class='username'>{$current_user->user_login}</span>";
 330      }
 331  
 332      if ( false !== $profile_url ) {
 333          $user_info .= "<span class='display-name edit-profile'>" . __( 'Edit Profile' ) . '</span>';
 334      }
 335  
 336      $wp_admin_bar->add_node(
 337          array(
 338              'parent' => 'user-actions',
 339              'id'     => 'user-info',
 340              'title'  => $user_info,
 341              'href'   => $profile_url,
 342          )
 343      );
 344  
 345      $wp_admin_bar->add_node(
 346          array(
 347              'parent' => 'user-actions',
 348              'id'     => 'logout',
 349              'title'  => __( 'Log Out' ),
 350              'href'   => wp_logout_url(),
 351          )
 352      );
 353  }
 354  
 355  /**
 356   * Adds the "Site Name" menu.
 357   *
 358   * @since 3.3.0
 359   *
 360   * @param WP_Admin_Bar $wp_admin_bar The WP_Admin_Bar instance.
 361   */
 362  function wp_admin_bar_site_menu( $wp_admin_bar ) {
 363      // Don't show for logged out users.
 364      if ( ! is_user_logged_in() ) {
 365          return;
 366      }
 367  
 368      // Show only when the user is a member of this site, or they're a super admin.
 369      if ( ! is_user_member_of_blog() && ! current_user_can( 'manage_network' ) ) {
 370          return;
 371      }
 372  
 373      $blogname = get_bloginfo( 'name' );
 374  
 375      if ( ! $blogname ) {
 376          $blogname = preg_replace( '#^(https?://)?(www\.)?#', '', get_home_url() );
 377      }
 378  
 379      if ( is_network_admin() ) {
 380          /* translators: %s: Site title. */
 381          $blogname = sprintf( __( 'Network Admin: %s' ), esc_html( get_network()->site_name ) );
 382      } elseif ( is_user_admin() ) {
 383          /* translators: %s: Site title. */
 384          $blogname = sprintf( __( 'User Dashboard: %s' ), esc_html( get_network()->site_name ) );
 385      }
 386  
 387      $title = wp_html_excerpt( $blogname, 40, '&hellip;' );
 388      $meta  = array(
 389          'menu_title' => $title,
 390      );
 391  
 392      if ( ! is_network_admin() && ! is_user_admin() ) {
 393          /** This filter is documented in wp-includes/admin-bar.php */
 394          $show_site_icons = apply_filters( 'wp_admin_bar_show_site_icons', true );
 395  
 396          if ( true === $show_site_icons && has_site_icon() ) {
 397              $site_icon_url    = get_site_icon_url( 32 );
 398              $site_icon_url_2x = get_site_icon_url( 64 );
 399              $srcset           = ( $site_icon_url_2x && $site_icon_url !== $site_icon_url_2x ) ? sprintf( ' srcset="%s 2x"', esc_url( $site_icon_url_2x ) ) : '';
 400              $site_icon        = sprintf(
 401                  '<img class="site-icon" src="%s"%s alt="" width="20" height="20" />',
 402                  esc_url( $site_icon_url ),
 403                  $srcset
 404              );
 405  
 406              $title         = $site_icon . $title;
 407              $meta['class'] = 'has-site-icon';
 408          }
 409      }
 410  
 411      $wp_admin_bar->add_node(
 412          array(
 413              'id'    => 'site-name',
 414              'title' => $title,
 415              'href'  => ( is_admin() || ! current_user_can( 'read' ) ) ? home_url( '/' ) : admin_url(),
 416              'meta'  => $meta,
 417          )
 418      );
 419  
 420      // Create submenu items.
 421  
 422      if ( is_admin() ) {
 423          // Add an option to visit the site.
 424          $wp_admin_bar->add_node(
 425              array(
 426                  'parent' => 'site-name',
 427                  'id'     => 'view-site',
 428                  'title'  => __( 'Visit Site' ),
 429                  'href'   => home_url( '/' ),
 430              )
 431          );
 432  
 433          if ( is_blog_admin() && is_multisite() && current_user_can( 'manage_sites' ) ) {
 434              $wp_admin_bar->add_node(
 435                  array(
 436                      'parent' => 'site-name',
 437                      'id'     => 'edit-site',
 438                      'title'  => __( 'Manage Site' ),
 439                      'href'   => network_admin_url( 'site-info.php?id=' . get_current_blog_id() ),
 440                  )
 441              );
 442          }
 443      } elseif ( current_user_can( 'read' ) ) {
 444          // We're on the front end, link to the Dashboard.
 445          $wp_admin_bar->add_node(
 446              array(
 447                  'parent' => 'site-name',
 448                  'id'     => 'dashboard',
 449                  'title'  => __( 'Dashboard' ),
 450                  'href'   => admin_url(),
 451              )
 452          );
 453  
 454          // Add the appearance submenu items.
 455          wp_admin_bar_appearance_menu( $wp_admin_bar );
 456  
 457          // Add a Plugins link.
 458          if ( current_user_can( 'activate_plugins' ) ) {
 459              $wp_admin_bar->add_node(
 460                  array(
 461                      'parent' => 'site-name',
 462                      'id'     => 'plugins',
 463                      'title'  => __( 'Plugins' ),
 464                      'href'   => admin_url( 'plugins.php' ),
 465                  )
 466              );
 467          }
 468      }
 469  }
 470  
 471  /**
 472   * Adds the "Edit Site" link to the Toolbar.
 473   *
 474   * @since 5.9.0
 475   * @since 6.3.0 Added `$_wp_current_template_id` global for editing of current template directly from the admin bar.
 476   * @since 6.6.0 Added the `canvas` query arg to the Site Editor link.
 477   *
 478   * @global string $_wp_current_template_id
 479   *
 480   * @param WP_Admin_Bar $wp_admin_bar The WP_Admin_Bar instance.
 481   */
 482  function wp_admin_bar_edit_site_menu( $wp_admin_bar ) {
 483      global $_wp_current_template_id;
 484  
 485      // Don't show if a block theme is not activated.
 486      if ( ! wp_is_block_theme() ) {
 487          return;
 488      }
 489  
 490      // Don't show for users who can't edit theme options or when in the admin.
 491      if ( ! current_user_can( 'edit_theme_options' ) || is_admin() ) {
 492          return;
 493      }
 494  
 495      $wp_admin_bar->add_node(
 496          array(
 497              'id'    => 'site-editor',
 498              'title' => __( 'Edit Site' ),
 499              'href'  => add_query_arg(
 500                  array(
 501                      'postType' => 'wp_template',
 502                      'postId'   => $_wp_current_template_id,
 503                      'canvas'   => 'edit',
 504                  ),
 505                  admin_url( 'site-editor.php' )
 506              ),
 507          )
 508      );
 509  }
 510  
 511  /**
 512   * Adds the "Customize" link to the Toolbar.
 513   *
 514   * @since 4.3.0
 515   *
 516   * @global WP_Customize_Manager $wp_customize
 517   *
 518   * @param WP_Admin_Bar $wp_admin_bar The WP_Admin_Bar instance.
 519   */
 520  function wp_admin_bar_customize_menu( $wp_admin_bar ) {
 521      global $wp_customize;
 522  
 523      // Don't show if a block theme is activated and no plugins use the customizer.
 524      if ( wp_is_block_theme() && ! has_action( 'customize_register' ) ) {
 525          return;
 526      }
 527  
 528      // Don't show for users who can't access the customizer or when in the admin.
 529      if ( ! current_user_can( 'customize' ) || is_admin() ) {
 530          return;
 531      }
 532  
 533      // Don't show if the user cannot edit a given customize_changeset post currently being previewed.
 534      if ( is_customize_preview() && $wp_customize->changeset_post_id()
 535          && ! current_user_can( get_post_type_object( 'customize_changeset' )->cap->edit_post, $wp_customize->changeset_post_id() )
 536      ) {
 537          return;
 538      }
 539  
 540      $current_url = ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
 541      if ( is_customize_preview() && $wp_customize->changeset_uuid() ) {
 542          $current_url = remove_query_arg( 'customize_changeset_uuid', $current_url );
 543      }
 544  
 545      $customize_url = add_query_arg( 'url', urlencode( $current_url ), wp_customize_url() );
 546      if ( is_customize_preview() ) {
 547          $customize_url = add_query_arg( array( 'changeset_uuid' => $wp_customize->changeset_uuid() ), $customize_url );
 548      }
 549  
 550      $wp_admin_bar->add_node(
 551          array(
 552              'id'    => 'customize',
 553              'title' => __( 'Customize' ),
 554              'href'  => $customize_url,
 555              'meta'  => array(
 556                  'class' => 'hide-if-no-customize',
 557              ),
 558          )
 559      );
 560      add_action( 'wp_before_admin_bar_render', 'wp_customize_support_script' );
 561  }
 562  
 563  /**
 564   * Adds the "My Sites/[Site Name]" menu and all submenus.
 565   *
 566   * @since 3.1.0
 567   *
 568   * @param WP_Admin_Bar $wp_admin_bar The WP_Admin_Bar instance.
 569   */
 570  function wp_admin_bar_my_sites_menu( $wp_admin_bar ) {
 571      // Don't show for logged out users or single site mode.
 572      if ( ! is_user_logged_in() || ! is_multisite() ) {
 573          return;
 574      }
 575  
 576      // Show only when the user has at least one site, or they're a super admin.
 577      if ( count( $wp_admin_bar->user->blogs ) < 1 && ! current_user_can( 'manage_network' ) ) {
 578          return;
 579      }
 580  
 581      if ( $wp_admin_bar->user->active_blog ) {
 582          $my_sites_url = get_admin_url( $wp_admin_bar->user->active_blog->blog_id, 'my-sites.php' );
 583      } else {
 584          $my_sites_url = admin_url( 'my-sites.php' );
 585      }
 586  
 587      $wp_admin_bar->add_node(
 588          array(
 589              'id'    => 'my-sites',
 590              'title' => __( 'My Sites' ),
 591              'href'  => $my_sites_url,
 592          )
 593      );
 594  
 595      if ( current_user_can( 'manage_network' ) ) {
 596          $wp_admin_bar->add_group(
 597              array(
 598                  'parent' => 'my-sites',
 599                  'id'     => 'my-sites-super-admin',
 600              )
 601          );
 602  
 603          $wp_admin_bar->add_node(
 604              array(
 605                  'parent' => 'my-sites-super-admin',
 606                  'id'     => 'network-admin',
 607                  'title'  => __( 'Network Admin' ),
 608                  'href'   => network_admin_url(),
 609              )
 610          );
 611  
 612          $wp_admin_bar->add_node(
 613              array(
 614                  'parent' => 'network-admin',
 615                  'id'     => 'network-admin-d',
 616                  'title'  => __( 'Dashboard' ),
 617                  'href'   => network_admin_url(),
 618              )
 619          );
 620  
 621          if ( current_user_can( 'manage_sites' ) ) {
 622              $wp_admin_bar->add_node(
 623                  array(
 624                      'parent' => 'network-admin',
 625                      'id'     => 'network-admin-s',
 626                      'title'  => __( 'Sites' ),
 627                      'href'   => network_admin_url( 'sites.php' ),
 628                  )
 629              );
 630          }
 631  
 632          if ( current_user_can( 'manage_network_users' ) ) {
 633              $wp_admin_bar->add_node(
 634                  array(
 635                      'parent' => 'network-admin',
 636                      'id'     => 'network-admin-u',
 637                      'title'  => __( 'Users' ),
 638                      'href'   => network_admin_url( 'users.php' ),
 639                  )
 640              );
 641          }
 642  
 643          if ( current_user_can( 'manage_network_themes' ) ) {
 644              $wp_admin_bar->add_node(
 645                  array(
 646                      'parent' => 'network-admin',
 647                      'id'     => 'network-admin-t',
 648                      'title'  => __( 'Themes' ),
 649                      'href'   => network_admin_url( 'themes.php' ),
 650                  )
 651              );
 652          }
 653  
 654          if ( current_user_can( 'manage_network_plugins' ) ) {
 655              $wp_admin_bar->add_node(
 656                  array(
 657                      'parent' => 'network-admin',
 658                      'id'     => 'network-admin-p',
 659                      'title'  => __( 'Plugins' ),
 660                      'href'   => network_admin_url( 'plugins.php' ),
 661                  )
 662              );
 663          }
 664  
 665          if ( current_user_can( 'manage_network_options' ) ) {
 666              $wp_admin_bar->add_node(
 667                  array(
 668                      'parent' => 'network-admin',
 669                      'id'     => 'network-admin-o',
 670                      'title'  => __( 'Settings' ),
 671                      'href'   => network_admin_url( 'settings.php' ),
 672                  )
 673              );
 674          }
 675      }
 676  
 677      // Add site links.
 678      $wp_admin_bar->add_group(
 679          array(
 680              'parent' => 'my-sites',
 681              'id'     => 'my-sites-list',
 682              'meta'   => array(
 683                  'class' => current_user_can( 'manage_network' ) ? 'ab-sub-secondary' : '',
 684              ),
 685          )
 686      );
 687  
 688      /**
 689       * Filters whether to show the site icons in toolbar.
 690       *
 691       * Returning false to this hook is the recommended way to hide site icons in the toolbar.
 692       * A truthy return may have negative performance impact on large multisites.
 693       *
 694       * @since 6.0.0
 695       *
 696       * @param bool $show_site_icons Whether site icons should be shown in the toolbar. Default true.
 697       */
 698      $show_site_icons = apply_filters( 'wp_admin_bar_show_site_icons', true );
 699  
 700      foreach ( (array) $wp_admin_bar->user->blogs as $blog ) {
 701          switch_to_blog( $blog->userblog_id );
 702  
 703          if ( true === $show_site_icons && has_site_icon() ) {
 704              $blavatar = sprintf(
 705                  '<img class="blavatar" src="%s" srcset="%s 2x" alt="" width="16" height="16"%s />',
 706                  esc_url( get_site_icon_url( 16 ) ),
 707                  esc_url( get_site_icon_url( 32 ) ),
 708                  ( wp_lazy_loading_enabled( 'img', 'site_icon_in_toolbar' ) ? ' loading="lazy"' : '' )
 709              );
 710          } else {
 711              $blavatar = '<div class="blavatar"></div>';
 712          }
 713  
 714          $blogname = $blog->blogname;
 715  
 716          if ( ! $blogname ) {
 717              $blogname = preg_replace( '#^(https?://)?(www\.)?#', '', get_home_url() );
 718          }
 719  
 720          $menu_id = 'blog-' . $blog->userblog_id;
 721  
 722          if ( current_user_can( 'read' ) ) {
 723              $wp_admin_bar->add_node(
 724                  array(
 725                      'parent' => 'my-sites-list',
 726                      'id'     => $menu_id,
 727                      'title'  => $blavatar . $blogname,
 728                      'href'   => admin_url(),
 729                  )
 730              );
 731  
 732              $wp_admin_bar->add_node(
 733                  array(
 734                      'parent' => $menu_id,
 735                      'id'     => $menu_id . '-d',
 736                      'title'  => __( 'Dashboard' ),
 737                      'href'   => admin_url(),
 738                  )
 739              );
 740          } else {
 741              $wp_admin_bar->add_node(
 742                  array(
 743                      'parent' => 'my-sites-list',
 744                      'id'     => $menu_id,
 745                      'title'  => $blavatar . $blogname,
 746                      'href'   => home_url(),
 747                  )
 748              );
 749          }
 750  
 751          if ( current_user_can( get_post_type_object( 'post' )->cap->create_posts ) ) {
 752              $wp_admin_bar->add_node(
 753                  array(
 754                      'parent' => $menu_id,
 755                      'id'     => $menu_id . '-n',
 756                      'title'  => get_post_type_object( 'post' )->labels->new_item,
 757                      'href'   => admin_url( 'post-new.php' ),
 758                  )
 759              );
 760          }
 761  
 762          if ( current_user_can( 'edit_posts' ) ) {
 763              $wp_admin_bar->add_node(
 764                  array(
 765                      'parent' => $menu_id,
 766                      'id'     => $menu_id . '-c',
 767                      'title'  => __( 'Manage Comments' ),
 768                      'href'   => admin_url( 'edit-comments.php' ),
 769                  )
 770              );
 771          }
 772  
 773          $wp_admin_bar->add_node(
 774              array(
 775                  'parent' => $menu_id,
 776                  'id'     => $menu_id . '-v',
 777                  'title'  => __( 'Visit Site' ),
 778                  'href'   => home_url( '/' ),
 779              )
 780          );
 781  
 782          restore_current_blog();
 783      }
 784  }
 785  
 786  /**
 787   * Provides a shortlink.
 788   *
 789   * @since 3.1.0
 790   *
 791   * @param WP_Admin_Bar $wp_admin_bar The WP_Admin_Bar instance.
 792   */
 793  function wp_admin_bar_shortlink_menu( $wp_admin_bar ) {
 794      $short = wp_get_shortlink( 0, 'query' );
 795      $id    = 'get-shortlink';
 796  
 797      if ( empty( $short ) ) {
 798          return;
 799      }
 800  
 801      $html = '<input class="shortlink-input" type="text" readonly="readonly" value="' . esc_attr( $short ) . '" aria-label="' . __( 'Shortlink' ) . '" />';
 802  
 803      $wp_admin_bar->add_node(
 804          array(
 805              'id'    => $id,
 806              'title' => __( 'Shortlink' ),
 807              'href'  => $short,
 808              'meta'  => array( 'html' => $html ),
 809          )
 810      );
 811  }
 812  
 813  /**
 814   * Provides an edit link for posts and terms.
 815   *
 816   * @since 3.1.0
 817   * @since 5.5.0 Added a "View Post" link on Comments screen for a single post.
 818   *
 819   * @global WP_Term  $tag
 820   * @global WP_Query $wp_the_query WordPress Query object.
 821   * @global int      $user_id      The ID of the user being edited. Not to be confused with the
 822   *                                global $user_ID, which contains the ID of the current user.
 823   * @global int      $post_id      The ID of the post when editing comments for a single post.
 824   *
 825   * @param WP_Admin_Bar $wp_admin_bar The WP_Admin_Bar instance.
 826   */
 827  function wp_admin_bar_edit_menu( $wp_admin_bar ) {
 828      global $tag, $wp_the_query, $user_id, $post_id;
 829  
 830      if ( is_admin() ) {
 831          $current_screen   = get_current_screen();
 832          $post             = get_post();
 833          $post_type_object = null;
 834  
 835          if ( 'post' === $current_screen->base ) {
 836              $post_type_object = get_post_type_object( $post->post_type );
 837          } elseif ( 'edit' === $current_screen->base ) {
 838              $post_type_object = get_post_type_object( $current_screen->post_type );
 839          } elseif ( 'edit-comments' === $current_screen->base && $post_id ) {
 840              $post = get_post( $post_id );
 841              if ( $post ) {
 842                  $post_type_object = get_post_type_object( $post->post_type );
 843              }
 844          }
 845  
 846          if ( ( 'post' === $current_screen->base || 'edit-comments' === $current_screen->base )
 847              && 'add' !== $current_screen->action
 848              && ( $post_type_object )
 849              && current_user_can( 'read_post', $post->ID )
 850              && ( $post_type_object->public )
 851              && ( $post_type_object->show_in_admin_bar ) ) {
 852              if ( 'draft' === $post->post_status ) {
 853                  $preview_link = get_preview_post_link( $post );
 854                  $wp_admin_bar->add_node(
 855                      array(
 856                          'id'    => 'preview',
 857                          'title' => $post_type_object->labels->view_item,
 858                          'href'  => esc_url( $preview_link ),
 859                          'meta'  => array( 'target' => 'wp-preview-' . $post->ID ),
 860                      )
 861                  );
 862              } else {
 863                  $wp_admin_bar->add_node(
 864                      array(
 865                          'id'    => 'view',
 866                          'title' => $post_type_object->labels->view_item,
 867                          'href'  => get_permalink( $post->ID ),
 868                      )
 869                  );
 870              }
 871          } elseif ( 'edit' === $current_screen->base
 872              && ( $post_type_object )
 873              && ( $post_type_object->public )
 874              && ( $post_type_object->show_in_admin_bar )
 875              && ( get_post_type_archive_link( $post_type_object->name ) )
 876              && ! ( 'post' === $post_type_object->name && 'posts' === get_option( 'show_on_front' ) ) ) {
 877              $wp_admin_bar->add_node(
 878                  array(
 879                      'id'    => 'archive',
 880                      'title' => $post_type_object->labels->view_items,
 881                      'href'  => get_post_type_archive_link( $current_screen->post_type ),
 882                  )
 883              );
 884          } elseif ( 'term' === $current_screen->base && isset( $tag ) && is_object( $tag ) && ! is_wp_error( $tag ) ) {
 885              $tax = get_taxonomy( $tag->taxonomy );
 886              if ( is_term_publicly_viewable( $tag ) ) {
 887                  $wp_admin_bar->add_node(
 888                      array(
 889                          'id'    => 'view',
 890                          'title' => $tax->labels->view_item,
 891                          'href'  => get_term_link( $tag ),
 892                      )
 893                  );
 894              }
 895          } elseif ( 'user-edit' === $current_screen->base && isset( $user_id ) ) {
 896              $user_object = get_userdata( $user_id );
 897              $view_link   = get_author_posts_url( $user_object->ID );
 898              if ( $user_object->exists() && $view_link ) {
 899                  $wp_admin_bar->add_node(
 900                      array(
 901                          'id'    => 'view',
 902                          'title' => __( 'View User' ),
 903                          'href'  => $view_link,
 904                      )
 905                  );
 906              }
 907          }
 908      } else {
 909          $current_object = $wp_the_query->get_queried_object();
 910  
 911          if ( empty( $current_object ) ) {
 912              return;
 913          }
 914  
 915          if ( ! empty( $current_object->post_type ) ) {
 916              $post_type_object = get_post_type_object( $current_object->post_type );
 917              $edit_post_link   = get_edit_post_link( $current_object->ID );
 918              if ( $post_type_object
 919                  && $edit_post_link
 920                  && current_user_can( 'edit_post', $current_object->ID )
 921                  && $post_type_object->show_in_admin_bar ) {
 922                  $wp_admin_bar->add_node(
 923                      array(
 924                          'id'    => 'edit',
 925                          'title' => $post_type_object->labels->edit_item,
 926                          'href'  => $edit_post_link,
 927                      )
 928                  );
 929              }
 930          } elseif ( ! empty( $current_object->taxonomy ) ) {
 931              $tax            = get_taxonomy( $current_object->taxonomy );
 932              $edit_term_link = get_edit_term_link( $current_object->term_id, $current_object->taxonomy );
 933              if ( $tax && $edit_term_link && current_user_can( 'edit_term', $current_object->term_id ) ) {
 934                  $wp_admin_bar->add_node(
 935                      array(
 936                          'id'    => 'edit',
 937                          'title' => $tax->labels->edit_item,
 938                          'href'  => $edit_term_link,
 939                      )
 940                  );
 941              }
 942          } elseif ( $current_object instanceof WP_User && current_user_can( 'edit_user', $current_object->ID ) ) {
 943              $edit_user_link = get_edit_user_link( $current_object->ID );
 944              if ( $edit_user_link ) {
 945                  $wp_admin_bar->add_node(
 946                      array(
 947                          'id'    => 'edit',
 948                          'title' => __( 'Edit User' ),
 949                          'href'  => $edit_user_link,
 950                      )
 951                  );
 952              }
 953          }
 954      }
 955  }
 956  
 957  /**
 958   * Adds the command palette trigger button.
 959   *
 960   * Displays a button in the admin bar that shows the keyboard shortcut
 961   * for opening the command palette.
 962   *
 963   * @since 7.0.0
 964   *
 965   * @param WP_Admin_Bar $wp_admin_bar The WP_Admin_Bar instance.
 966   */
 967  function wp_admin_bar_command_palette_menu( WP_Admin_Bar $wp_admin_bar ): void {
 968      if ( ! is_admin() || ! wp_script_is( 'wp-core-commands', 'enqueued' ) ) {
 969          return;
 970      }
 971  
 972      $shortcut_labels = array(
 973          'appleOS' => _x( '⌘K', 'keyboard shortcut to open the command palette' ),
 974          'default' => _x( 'Ctrl+K', 'keyboard shortcut to open the command palette' ),
 975      );
 976      $apple_pattern   = 'Macintosh|Mac OS X|Mac_PowerPC';
 977      $is_apple_os     = (bool) preg_match( "/{$apple_pattern}/i", $_SERVER['HTTP_USER_AGENT'] ?? '' );
 978      $shortcut_label  = $is_apple_os ? $shortcut_labels['appleOS'] : $shortcut_labels['default'];
 979      $title           = sprintf(
 980          '<span class="ab-icon" aria-hidden="true"></span><span class="ab-label"><kbd>%s</kbd><span class="screen-reader-text"> %s</span></span>',
 981          $shortcut_label,
 982          /* translators: Hidden accessibility text. */
 983          __( 'Open command palette' ),
 984      );
 985      /*
 986       * Detect Apple OS via JavaScript for sites behind a CDN blocking the UA header.
 987       *
 988       * Running the script as the admin bar is rendered avoids a flash of incorrect content
 989       * for users with Apple OS when the UA header is blocked. It also prevents the need for
 990       * wp-i18n to be loaded as a dependency.
 991       */
 992      $function = <<<'JS'
 993          ( applePattern, appleOSLabel ) => {
 994              if ( ! ( new RegExp( applePattern, 'i' ) ).test( navigator.userAgent ) ) {
 995                  return;
 996              }
 997              const kbd = document.querySelector( '#wp-admin-bar-command-palette .ab-label kbd' );
 998              if ( kbd ) {
 999                  kbd.textContent = appleOSLabel;
1000              }
1001          }
1002      JS;
1003      $script   = sprintf(
1004          '( %s )( %s, %s );',
1005          $function,
1006          wp_json_encode( $apple_pattern, JSON_HEX_TAG | JSON_UNESCAPED_SLASHES ),
1007          wp_json_encode( $shortcut_labels['appleOS'], JSON_HEX_TAG | JSON_UNESCAPED_SLASHES )
1008      );
1009      $script  .= "\n//# sourceURL=" . rawurlencode( __FUNCTION__ );
1010      $wp_admin_bar->add_node(
1011          array(
1012              'id'    => 'command-palette',
1013              'title' => $title,
1014              'href'  => '#',
1015              'meta'  => array(
1016                  'class'   => 'hide-if-no-js',
1017                  'onclick' => 'wp.data.dispatch( "core/commands" ).open(); return false;',
1018                  'html'    => wp_get_inline_script_tag( $script ),
1019              ),
1020          )
1021      );
1022  }
1023  
1024  /**
1025   * Adds "Add New" menu.
1026   *
1027   * @since 3.1.0
1028   * @since 6.5.0 Added a New Site link for network installations.
1029   *
1030   * @param WP_Admin_Bar $wp_admin_bar The WP_Admin_Bar instance.
1031   */
1032  function wp_admin_bar_new_content_menu( $wp_admin_bar ) {
1033      $actions = array();
1034  
1035      $cpts = (array) get_post_types( array( 'show_in_admin_bar' => true ), 'objects' );
1036  
1037      if ( isset( $cpts['post'] ) && current_user_can( $cpts['post']->cap->create_posts ) ) {
1038          $actions['post-new.php'] = array( $cpts['post']->labels->name_admin_bar, 'new-post' );
1039      }
1040  
1041      if ( isset( $cpts['attachment'] ) && current_user_can( 'upload_files' ) ) {
1042          $actions['media-new.php'] = array( $cpts['attachment']->labels->name_admin_bar, 'new-media' );
1043      }
1044  
1045      if ( current_user_can( 'manage_links' ) ) {
1046          $actions['link-add.php'] = array( _x( 'Link', 'add new from admin bar' ), 'new-link' );
1047      }
1048  
1049      if ( isset( $cpts['page'] ) && current_user_can( $cpts['page']->cap->create_posts ) ) {
1050          $actions['post-new.php?post_type=page'] = array( $cpts['page']->labels->name_admin_bar, 'new-page' );
1051      }
1052  
1053      unset( $cpts['post'], $cpts['page'], $cpts['attachment'] );
1054  
1055      // Add any additional custom post types.
1056      foreach ( $cpts as $cpt ) {
1057          if ( ! current_user_can( $cpt->cap->create_posts ) ) {
1058              continue;
1059          }
1060  
1061          $key             = 'post-new.php?post_type=' . $cpt->name;
1062          $actions[ $key ] = array( $cpt->labels->name_admin_bar, 'new-' . $cpt->name );
1063      }
1064      // Avoid clash with parent node and a 'content' post type.
1065      if ( isset( $actions['post-new.php?post_type=content'] ) ) {
1066          $actions['post-new.php?post_type=content'][1] = 'add-new-content';
1067      }
1068  
1069      if ( current_user_can( 'create_users' ) || ( is_multisite() && current_user_can( 'promote_users' ) ) ) {
1070          $actions['user-new.php'] = array( _x( 'User', 'add new from admin bar' ), 'new-user' );
1071      }
1072  
1073      if ( ! $actions ) {
1074          return;
1075      }
1076  
1077      $title = '<span class="ab-icon" aria-hidden="true"></span><span class="ab-label">' . _x( 'New', 'admin bar menu group label' ) . '</span>';
1078  
1079      $wp_admin_bar->add_node(
1080          array(
1081              'id'    => 'new-content',
1082              'title' => $title,
1083              'href'  => admin_url( current( array_keys( $actions ) ) ),
1084              'meta'  => array(
1085                  'menu_title' => _x( 'New', 'admin bar menu group label' ),
1086              ),
1087          )
1088      );
1089  
1090      foreach ( $actions as $link => $action ) {
1091          list( $title, $id ) = $action;
1092  
1093          $wp_admin_bar->add_node(
1094              array(
1095                  'parent' => 'new-content',
1096                  'id'     => $id,
1097                  'title'  => $title,
1098                  'href'   => admin_url( $link ),
1099              )
1100          );
1101      }
1102  
1103      if ( is_multisite() && current_user_can( 'create_sites' ) ) {
1104          $wp_admin_bar->add_node(
1105              array(
1106                  'parent' => 'new-content',
1107                  'id'     => 'add-new-site',
1108                  'title'  => _x( 'Site', 'add new from admin bar' ),
1109                  'href'   => network_admin_url( 'site-new.php' ),
1110              )
1111          );
1112      }
1113  }
1114  
1115  /**
1116   * Adds edit comments link with awaiting moderation count bubble.
1117   *
1118   * @since 3.1.0
1119   *
1120   * @param WP_Admin_Bar $wp_admin_bar The WP_Admin_Bar instance.
1121   */
1122  function wp_admin_bar_comments_menu( $wp_admin_bar ) {
1123      if ( ! current_user_can( 'edit_posts' ) ) {
1124          return;
1125      }
1126  
1127      $awaiting_mod  = wp_count_comments();
1128      $awaiting_mod  = $awaiting_mod->moderated;
1129      $awaiting_text = sprintf(
1130          /* translators: Hidden accessibility text. %s: Number of comments. */
1131          _n( '%s Comment in moderation', '%s Comments in moderation', $awaiting_mod ),
1132          number_format_i18n( $awaiting_mod )
1133      );
1134  
1135      $icon   = '<span class="ab-icon" aria-hidden="true"></span>';
1136      $title  = '<span class="ab-label awaiting-mod pending-count count-' . $awaiting_mod . '" aria-hidden="true">' . number_format_i18n( $awaiting_mod ) . '</span>';
1137      $title .= '<span class="screen-reader-text comments-in-moderation-text">' . $awaiting_text . '</span>';
1138  
1139      $wp_admin_bar->add_node(
1140          array(
1141              'id'    => 'comments',
1142              'title' => $icon . $title,
1143              'href'  => admin_url( 'edit-comments.php' ),
1144          )
1145      );
1146  }
1147  
1148  /**
1149   * Adds appearance submenu items to the "Site Name" menu.
1150   *
1151   * @since 3.1.0
1152   *
1153   * @param WP_Admin_Bar $wp_admin_bar The WP_Admin_Bar instance.
1154   */
1155  function wp_admin_bar_appearance_menu( $wp_admin_bar ) {
1156      $wp_admin_bar->add_group(
1157          array(
1158              'parent' => 'site-name',
1159              'id'     => 'appearance',
1160          )
1161      );
1162  
1163      if ( current_user_can( 'switch_themes' ) ) {
1164          $wp_admin_bar->add_node(
1165              array(
1166                  'parent' => 'appearance',
1167                  'id'     => 'themes',
1168                  'title'  => __( 'Themes' ),
1169                  'href'   => admin_url( 'themes.php' ),
1170              )
1171          );
1172      }
1173  
1174      if ( ! current_user_can( 'edit_theme_options' ) ) {
1175          return;
1176      }
1177  
1178      if ( current_theme_supports( 'widgets' ) ) {
1179          $wp_admin_bar->add_node(
1180              array(
1181                  'parent' => 'appearance',
1182                  'id'     => 'widgets',
1183                  'title'  => __( 'Widgets' ),
1184                  'href'   => admin_url( 'widgets.php' ),
1185              )
1186          );
1187      }
1188  
1189      if ( current_theme_supports( 'menus' ) || current_theme_supports( 'widgets' ) ) {
1190          $wp_admin_bar->add_node(
1191              array(
1192                  'parent' => 'appearance',
1193                  'id'     => 'menus',
1194                  'title'  => __( 'Menus' ),
1195                  'href'   => admin_url( 'nav-menus.php' ),
1196              )
1197          );
1198      }
1199  
1200      if ( current_theme_supports( 'custom-background' ) ) {
1201          $wp_admin_bar->add_node(
1202              array(
1203                  'parent' => 'appearance',
1204                  'id'     => 'background',
1205                  'title'  => _x( 'Background', 'custom background' ),
1206                  'href'   => admin_url( 'themes.php?page=custom-background' ),
1207                  'meta'   => array(
1208                      'class' => 'hide-if-customize',
1209                  ),
1210              )
1211          );
1212      }
1213  
1214      if ( current_theme_supports( 'custom-header' ) ) {
1215          $wp_admin_bar->add_node(
1216              array(
1217                  'parent' => 'appearance',
1218                  'id'     => 'header',
1219                  'title'  => _x( 'Header', 'custom image header' ),
1220                  'href'   => admin_url( 'themes.php?page=custom-header' ),
1221                  'meta'   => array(
1222                      'class' => 'hide-if-customize',
1223                  ),
1224              )
1225          );
1226      }
1227  }
1228  
1229  /**
1230   * Provides an update link if theme/plugin/core updates are available.
1231   *
1232   * @since 3.1.0
1233   *
1234   * @param WP_Admin_Bar $wp_admin_bar The WP_Admin_Bar instance.
1235   */
1236  function wp_admin_bar_updates_menu( $wp_admin_bar ) {
1237  
1238      $update_data = wp_get_update_data();
1239  
1240      if ( ! $update_data['counts']['total'] ) {
1241          return;
1242      }
1243  
1244      $updates_text = sprintf(
1245          /* translators: Hidden accessibility text. %s: Total number of updates available. */
1246          _n( '%s update available', '%s updates available', $update_data['counts']['total'] ),
1247          number_format_i18n( $update_data['counts']['total'] )
1248      );
1249  
1250      $icon   = '<span class="ab-icon" aria-hidden="true"></span>';
1251      $title  = '<span class="ab-label" aria-hidden="true">' . number_format_i18n( $update_data['counts']['total'] ) . '</span>';
1252      $title .= '<span class="screen-reader-text updates-available-text">' . $updates_text . '</span>';
1253  
1254      $wp_admin_bar->add_node(
1255          array(
1256              'id'    => 'updates',
1257              'title' => $icon . $title,
1258              'href'  => network_admin_url( 'update-core.php' ),
1259          )
1260      );
1261  }
1262  
1263  /**
1264   * Adds search form.
1265   *
1266   * @since 3.3.0
1267   *
1268   * @param WP_Admin_Bar $wp_admin_bar The WP_Admin_Bar instance.
1269   */
1270  function wp_admin_bar_search_menu( $wp_admin_bar ) {
1271      if ( is_admin() ) {
1272          return;
1273      }
1274  
1275      $form  = '<form action="' . esc_url( home_url( '/' ) ) . '" method="get" id="adminbarsearch">';
1276      $form .= '<input class="adminbar-input" name="s" id="adminbar-search" type="text" value="" maxlength="150" />';
1277      $form .= '<label for="adminbar-search" class="screen-reader-text">' .
1278              /* translators: Hidden accessibility text. */
1279              __( 'Search' ) .
1280          '</label>';
1281      $form .= '<input type="submit" class="adminbar-button" value="' . __( 'Search' ) . '" />';
1282      $form .= '</form>';
1283  
1284      $wp_admin_bar->add_node(
1285          array(
1286              'parent' => 'top-secondary',
1287              'id'     => 'search',
1288              'title'  => $form,
1289              'meta'   => array(
1290                  'class'    => 'admin-bar-search',
1291                  'tabindex' => -1,
1292              ),
1293          )
1294      );
1295  }
1296  
1297  /**
1298   * Adds a link to exit recovery mode when Recovery Mode is active.
1299   *
1300   * @since 5.2.0
1301   *
1302   * @param WP_Admin_Bar $wp_admin_bar The WP_Admin_Bar instance.
1303   */
1304  function wp_admin_bar_recovery_mode_menu( $wp_admin_bar ) {
1305      if ( ! wp_is_recovery_mode() ) {
1306          return;
1307      }
1308  
1309      $url = wp_login_url();
1310      $url = add_query_arg( 'action', WP_Recovery_Mode::EXIT_ACTION, $url );
1311      $url = wp_nonce_url( $url, WP_Recovery_Mode::EXIT_ACTION );
1312  
1313      $wp_admin_bar->add_node(
1314          array(
1315              'parent' => 'top-secondary',
1316              'id'     => 'recovery-mode',
1317              'title'  => __( 'Exit Recovery Mode' ),
1318              'href'   => $url,
1319          )
1320      );
1321  }
1322  
1323  /**
1324   * Adds secondary menus.
1325   *
1326   * @since 3.3.0
1327   *
1328   * @param WP_Admin_Bar $wp_admin_bar The WP_Admin_Bar instance.
1329   */
1330  function wp_admin_bar_add_secondary_groups( $wp_admin_bar ) {
1331      $wp_admin_bar->add_group(
1332          array(
1333              'id'   => 'top-secondary',
1334              'meta' => array(
1335                  'class' => 'ab-top-secondary',
1336              ),
1337          )
1338      );
1339  
1340      $wp_admin_bar->add_group(
1341          array(
1342              'parent' => 'wp-logo',
1343              'id'     => 'wp-logo-external',
1344              'meta'   => array(
1345                  'class' => 'ab-sub-secondary',
1346              ),
1347          )
1348      );
1349  }
1350  
1351  /**
1352   * Enqueues inline style to hide the admin bar when printing.
1353   *
1354   * @since 6.4.0
1355   */
1356  function wp_enqueue_admin_bar_header_styles() {
1357      // Back-compat for plugins that disable functionality by unhooking this action.
1358      $action = is_admin() ? 'admin_head' : 'wp_head';
1359      if ( ! has_action( $action, 'wp_admin_bar_header' ) ) {
1360          return;
1361      }
1362      remove_action( $action, 'wp_admin_bar_header' );
1363  
1364      wp_add_inline_style( 'admin-bar', '@media print { #wpadminbar { display:none; } }' );
1365  }
1366  
1367  /**
1368   * Enqueues inline bump styles to make room for the admin bar.
1369   *
1370   * @since 6.4.0
1371   */
1372  function wp_enqueue_admin_bar_bump_styles() {
1373      if ( current_theme_supports( 'admin-bar' ) ) {
1374          $admin_bar_args  = get_theme_support( 'admin-bar' );
1375          $header_callback = $admin_bar_args[0]['callback'];
1376      }
1377  
1378      if ( empty( $header_callback ) ) {
1379          $header_callback = '_admin_bar_bump_cb';
1380      }
1381  
1382      if ( '_admin_bar_bump_cb' !== $header_callback ) {
1383          return;
1384      }
1385  
1386      // Back-compat for plugins that disable functionality by unhooking this action.
1387      if ( ! has_action( 'wp_head', $header_callback ) ) {
1388          return;
1389      }
1390      remove_action( 'wp_head', $header_callback );
1391  
1392      $css = '
1393          @media screen { html { margin-top: 32px !important; } }
1394          @media screen and ( max-width: 782px ) { html { margin-top: 46px !important; } }
1395      ';
1396      wp_add_inline_style( 'admin-bar', $css );
1397  }
1398  
1399  /**
1400   * Sets the display status of the admin bar.
1401   *
1402   * This can be called immediately upon plugin load. It does not need to be called
1403   * from a function hooked to the {@see 'init'} action.
1404   *
1405   * @since 3.1.0
1406   *
1407   * @global bool $show_admin_bar
1408   *
1409   * @param bool $show Whether to allow the admin bar to show.
1410   */
1411  function show_admin_bar( $show ) {
1412      global $show_admin_bar;
1413      $show_admin_bar = (bool) $show;
1414  }
1415  
1416  /**
1417   * Determines whether the admin bar should be showing.
1418   *
1419   * For more information on this and similar theme functions, check out
1420   * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
1421   * Conditional Tags} article in the Theme Developer Handbook.
1422   *
1423   * @since 3.1.0
1424   *
1425   * @global bool   $show_admin_bar
1426   * @global string $pagenow        The filename of the current screen.
1427   *
1428   * @return bool Whether the admin bar should be showing.
1429   */
1430  function is_admin_bar_showing() {
1431      global $show_admin_bar, $pagenow;
1432  
1433      // For all these types of requests, we never want an admin bar.
1434      if ( defined( 'XMLRPC_REQUEST' ) || defined( 'DOING_AJAX' ) || defined( 'IFRAME_REQUEST' ) || wp_is_json_request() ) {
1435          return false;
1436      }
1437  
1438      if ( is_embed() ) {
1439          return false;
1440      }
1441  
1442      // Integrated into the admin.
1443      if ( is_admin() ) {
1444          return true;
1445      }
1446  
1447      if ( ! isset( $show_admin_bar ) ) {
1448          if ( ! is_user_logged_in() || 'wp-login.php' === $pagenow ) {
1449              $show_admin_bar = false;
1450          } else {
1451              $show_admin_bar = _get_admin_bar_pref();
1452          }
1453      }
1454  
1455      /**
1456       * Filters whether to show the admin bar.
1457       *
1458       * Returning false to this hook is the recommended way to hide the admin bar.
1459       * The user's display preference is used for logged in users.
1460       *
1461       * @since 3.1.0
1462       *
1463       * @param bool $show_admin_bar Whether the admin bar should be shown. Default false.
1464       */
1465      $show_admin_bar = apply_filters( 'show_admin_bar', $show_admin_bar );
1466  
1467      return $show_admin_bar;
1468  }
1469  
1470  /**
1471   * Retrieves the admin bar display preference of a user.
1472   *
1473   * @since 3.1.0
1474   * @access private
1475   *
1476   * @param string $context Context of this preference check. Defaults to 'front'. The 'admin'
1477   *                        preference is no longer used.
1478   * @param int    $user    Optional. ID of the user to check, defaults to 0 for current user.
1479   * @return bool Whether the admin bar should be showing for this user.
1480   */
1481  function _get_admin_bar_pref( $context = 'front', $user = 0 ) {
1482      $pref = get_user_option( "show_admin_bar_{$context}", $user );
1483      if ( false === $pref ) {
1484          return true;
1485      }
1486  
1487      return 'true' === $pref;
1488  }


Generated : Wed Jul 15 08:20:16 2026 Cross-referenced by PHPXref