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


Generated : Thu Nov 12 08:20:02 2026 Cross-referenced by PHPXref