[ Index ] |
WordPress Cross Reference |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * The WordPress Toolbar 4 * 5 * @since 3.1.0 6 * 7 * @package WordPress 8 * @subpackage Toolbar 9 */ 10 class WP_Admin_Bar { 11 private $nodes = array(); 12 private $bound = false; 13 public $user; 14 15 public function __get( $name ) { 16 switch ( $name ) { 17 case 'proto' : 18 return is_ssl() ? 'https://' : 'http://'; 19 break; 20 case 'menu' : 21 _deprecated_argument( 'WP_Admin_Bar', '3.3', 'Modify admin bar nodes with WP_Admin_Bar::get_node(), WP_Admin_Bar::add_node(), and WP_Admin_Bar::remove_node(), not the <code>menu</code> property.' ); 22 return array(); // Sorry, folks. 23 break; 24 } 25 } 26 27 public function initialize() { 28 $this->user = new stdClass; 29 30 if ( is_user_logged_in() ) { 31 /* Populate settings we need for the menu based on the current user. */ 32 $this->user->blogs = get_blogs_of_user( get_current_user_id() ); 33 if ( is_multisite() ) { 34 $this->user->active_blog = get_active_blog_for_user( get_current_user_id() ); 35 $this->user->domain = empty( $this->user->active_blog ) ? user_admin_url() : trailingslashit( get_home_url( $this->user->active_blog->blog_id ) ); 36 $this->user->account_domain = $this->user->domain; 37 } else { 38 $this->user->active_blog = $this->user->blogs[get_current_blog_id()]; 39 $this->user->domain = trailingslashit( home_url() ); 40 $this->user->account_domain = $this->user->domain; 41 } 42 } 43 44 add_action( 'wp_head', 'wp_admin_bar_header' ); 45 46 add_action( 'admin_head', 'wp_admin_bar_header' ); 47 48 if ( current_theme_supports( 'admin-bar' ) ) { 49 /** 50 * To remove the default padding styles from WordPress for the Toolbar, use the following code: 51 * add_theme_support( 'admin-bar', array( 'callback' => '__return_false' ) ); 52 */ 53 $admin_bar_args = get_theme_support( 'admin-bar' ); 54 $header_callback = $admin_bar_args[0]['callback']; 55 } 56 57 if ( empty($header_callback) ) 58 $header_callback = '_admin_bar_bump_cb'; 59 60 add_action('wp_head', $header_callback); 61 62 wp_enqueue_script( 'admin-bar' ); 63 wp_enqueue_style( 'admin-bar' ); 64 65 /** 66 * Fires after WP_Admin_Bar is initialized. 67 * 68 * @since 3.1.0 69 */ 70 do_action( 'admin_bar_init' ); 71 } 72 73 public function add_menu( $node ) { 74 $this->add_node( $node ); 75 } 76 77 public function remove_menu( $id ) { 78 $this->remove_node( $id ); 79 } 80 81 /** 82 * Add a node to the menu. 83 * 84 * @param array $args - The arguments for each node. 85 * - id - string - The ID of the item. 86 * - title - string - The title of the node. 87 * - parent - string - The ID of the parent node. Optional. 88 * - href - string - The link for the item. Optional. 89 * - group - boolean - If the node is a group. Optional. Default false. 90 * - meta - array - Meta data including the following keys: html, class, onclick, target, title, tabindex. 91 */ 92 public function add_node( $args ) { 93 // Shim for old method signature: add_node( $parent_id, $menu_obj, $args ) 94 if ( func_num_args() >= 3 && is_string( func_get_arg(0) ) ) 95 $args = array_merge( array( 'parent' => func_get_arg(0) ), func_get_arg(2) ); 96 97 if ( is_object( $args ) ) 98 $args = get_object_vars( $args ); 99 100 // Ensure we have a valid title. 101 if ( empty( $args['id'] ) ) { 102 if ( empty( $args['title'] ) ) 103 return; 104 105 _doing_it_wrong( __METHOD__, __( 'The menu ID should not be empty.' ), '3.3' ); 106 // Deprecated: Generate an ID from the title. 107 $args['id'] = esc_attr( sanitize_title( trim( $args['title'] ) ) ); 108 } 109 110 $defaults = array( 111 'id' => false, 112 'title' => false, 113 'parent' => false, 114 'href' => false, 115 'group' => false, 116 'meta' => array(), 117 ); 118 119 // If the node already exists, keep any data that isn't provided. 120 if ( $maybe_defaults = $this->get_node( $args['id'] ) ) 121 $defaults = get_object_vars( $maybe_defaults ); 122 123 // Do the same for 'meta' items. 124 if ( ! empty( $defaults['meta'] ) && ! empty( $args['meta'] ) ) 125 $args['meta'] = wp_parse_args( $args['meta'], $defaults['meta'] ); 126 127 $args = wp_parse_args( $args, $defaults ); 128 129 $back_compat_parents = array( 130 'my-account-with-avatar' => array( 'my-account', '3.3' ), 131 'my-blogs' => array( 'my-sites', '3.3' ), 132 ); 133 134 if ( isset( $back_compat_parents[ $args['parent'] ] ) ) { 135 list( $new_parent, $version ) = $back_compat_parents[ $args['parent'] ]; 136 _deprecated_argument( __METHOD__, $version, sprintf( 'Use <code>%s</code> as the parent for the <code>%s</code> admin bar node instead of <code>%s</code>.', $new_parent, $args['id'], $args['parent'] ) ); 137 $args['parent'] = $new_parent; 138 } 139 140 $this->_set_node( $args ); 141 } 142 143 final protected function _set_node( $args ) { 144 $this->nodes[ $args['id'] ] = (object) $args; 145 } 146 147 /** 148 * Gets a node. 149 * 150 * @return object Node. 151 */ 152 final public function get_node( $id ) { 153 if ( $node = $this->_get_node( $id ) ) 154 return clone $node; 155 } 156 157 final protected function _get_node( $id ) { 158 if ( $this->bound ) 159 return; 160 161 if ( empty( $id ) ) 162 $id = 'root'; 163 164 if ( isset( $this->nodes[ $id ] ) ) 165 return $this->nodes[ $id ]; 166 } 167 168 final public function get_nodes() { 169 if ( ! $nodes = $this->_get_nodes() ) 170 return; 171 172 foreach ( $nodes as &$node ) { 173 $node = clone $node; 174 } 175 return $nodes; 176 } 177 178 final protected function _get_nodes() { 179 if ( $this->bound ) 180 return; 181 182 return $this->nodes; 183 } 184 185 /** 186 * Add a group to a menu node. 187 * 188 * @since 3.3.0 189 * 190 * @param array $args - The arguments for each node. 191 * - id - string - The ID of the item. 192 * - parent - string - The ID of the parent node. Optional. Default root. 193 * - meta - array - Meta data including the following keys: class, onclick, target, title. 194 */ 195 final public function add_group( $args ) { 196 $args['group'] = true; 197 198 $this->add_node( $args ); 199 } 200 201 /** 202 * Remove a node. 203 * 204 * @param string The ID of the item. 205 */ 206 public function remove_node( $id ) { 207 $this->_unset_node( $id ); 208 } 209 210 final protected function _unset_node( $id ) { 211 unset( $this->nodes[ $id ] ); 212 } 213 214 public function render() { 215 $root = $this->_bind(); 216 if ( $root ) 217 $this->_render( $root ); 218 } 219 220 final protected function _bind() { 221 if ( $this->bound ) 222 return; 223 224 // Add the root node. 225 // Clear it first, just in case. Don't mess with The Root. 226 $this->remove_node( 'root' ); 227 $this->add_node( array( 228 'id' => 'root', 229 'group' => false, 230 ) ); 231 232 // Normalize nodes: define internal 'children' and 'type' properties. 233 foreach ( $this->_get_nodes() as $node ) { 234 $node->children = array(); 235 $node->type = ( $node->group ) ? 'group' : 'item'; 236 unset( $node->group ); 237 238 // The Root wants your orphans. No lonely items allowed. 239 if ( ! $node->parent ) 240 $node->parent = 'root'; 241 } 242 243 foreach ( $this->_get_nodes() as $node ) { 244 if ( 'root' == $node->id ) 245 continue; 246 247 // Fetch the parent node. If it isn't registered, ignore the node. 248 if ( ! $parent = $this->_get_node( $node->parent ) ) { 249 continue; 250 } 251 252 // Generate the group class (we distinguish between top level and other level groups). 253 $group_class = ( $node->parent == 'root' ) ? 'ab-top-menu' : 'ab-submenu'; 254 255 if ( $node->type == 'group' ) { 256 if ( empty( $node->meta['class'] ) ) 257 $node->meta['class'] = $group_class; 258 else 259 $node->meta['class'] .= ' ' . $group_class; 260 } 261 262 // Items in items aren't allowed. Wrap nested items in 'default' groups. 263 if ( $parent->type == 'item' && $node->type == 'item' ) { 264 $default_id = $parent->id . '-default'; 265 $default = $this->_get_node( $default_id ); 266 267 // The default group is added here to allow groups that are 268 // added before standard menu items to render first. 269 if ( ! $default ) { 270 // Use _set_node because add_node can be overloaded. 271 // Make sure to specify default settings for all properties. 272 $this->_set_node( array( 273 'id' => $default_id, 274 'parent' => $parent->id, 275 'type' => 'group', 276 'children' => array(), 277 'meta' => array( 278 'class' => $group_class, 279 ), 280 'title' => false, 281 'href' => false, 282 ) ); 283 $default = $this->_get_node( $default_id ); 284 $parent->children[] = $default; 285 } 286 $parent = $default; 287 288 // Groups in groups aren't allowed. Add a special 'container' node. 289 // The container will invisibly wrap both groups. 290 } elseif ( $parent->type == 'group' && $node->type == 'group' ) { 291 $container_id = $parent->id . '-container'; 292 $container = $this->_get_node( $container_id ); 293 294 // We need to create a container for this group, life is sad. 295 if ( ! $container ) { 296 // Use _set_node because add_node can be overloaded. 297 // Make sure to specify default settings for all properties. 298 $this->_set_node( array( 299 'id' => $container_id, 300 'type' => 'container', 301 'children' => array( $parent ), 302 'parent' => false, 303 'title' => false, 304 'href' => false, 305 'meta' => array(), 306 ) ); 307 308 $container = $this->_get_node( $container_id ); 309 310 // Link the container node if a grandparent node exists. 311 $grandparent = $this->_get_node( $parent->parent ); 312 313 if ( $grandparent ) { 314 $container->parent = $grandparent->id; 315 316 $index = array_search( $parent, $grandparent->children, true ); 317 if ( $index === false ) 318 $grandparent->children[] = $container; 319 else 320 array_splice( $grandparent->children, $index, 1, array( $container ) ); 321 } 322 323 $parent->parent = $container->id; 324 } 325 326 $parent = $container; 327 } 328 329 // Update the parent ID (it might have changed). 330 $node->parent = $parent->id; 331 332 // Add the node to the tree. 333 $parent->children[] = $node; 334 } 335 336 $root = $this->_get_node( 'root' ); 337 $this->bound = true; 338 return $root; 339 } 340 341 final protected function _render( $root ) { 342 global $is_IE; 343 344 // Add browser classes. 345 // We have to do this here since admin bar shows on the front end. 346 $class = 'nojq nojs'; 347 if ( $is_IE ) { 348 if ( strpos( $_SERVER['HTTP_USER_AGENT'], 'MSIE 7' ) ) 349 $class .= ' ie7'; 350 elseif ( strpos( $_SERVER['HTTP_USER_AGENT'], 'MSIE 8' ) ) 351 $class .= ' ie8'; 352 elseif ( strpos( $_SERVER['HTTP_USER_AGENT'], 'MSIE 9' ) ) 353 $class .= ' ie9'; 354 } elseif ( wp_is_mobile() ) { 355 $class .= ' mobile'; 356 } 357 358 ?> 359 <div id="wpadminbar" class="<?php echo $class; ?>" role="navigation"> 360 <a class="screen-reader-shortcut" href="#wp-toolbar" tabindex="1"><?php _e('Skip to toolbar'); ?></a> 361 <div class="quicklinks" id="wp-toolbar" role="navigation" aria-label="<?php esc_attr_e('Top navigation toolbar.'); ?>" tabindex="0"> 362 <?php foreach ( $root->children as $group ) { 363 $this->_render_group( $group ); 364 } ?> 365 </div> 366 <?php if ( is_user_logged_in() ) : ?> 367 <a class="screen-reader-shortcut" href="<?php echo esc_url( wp_logout_url() ); ?>"><?php _e('Log Out'); ?></a> 368 <?php endif; ?> 369 </div> 370 371 <?php 372 } 373 374 final protected function _render_container( $node ) { 375 if ( $node->type != 'container' || empty( $node->children ) ) 376 return; 377 378 ?><div id="<?php echo esc_attr( 'wp-admin-bar-' . $node->id ); ?>" class="ab-group-container"><?php 379 foreach ( $node->children as $group ) { 380 $this->_render_group( $group ); 381 } 382 ?></div><?php 383 } 384 385 final protected function _render_group( $node ) { 386 if ( $node->type == 'container' ) 387 return $this->_render_container( $node ); 388 389 if ( $node->type != 'group' || empty( $node->children ) ) 390 return; 391 392 if ( ! empty( $node->meta['class'] ) ) 393 $class = ' class="' . esc_attr( trim( $node->meta['class'] ) ) . '"'; 394 else 395 $class = ''; 396 397 ?><ul id="<?php echo esc_attr( 'wp-admin-bar-' . $node->id ); ?>"<?php echo $class; ?>><?php 398 foreach ( $node->children as $item ) { 399 $this->_render_item( $item ); 400 } 401 ?></ul><?php 402 } 403 404 final protected function _render_item( $node ) { 405 if ( $node->type != 'item' ) 406 return; 407 408 $is_parent = ! empty( $node->children ); 409 $has_link = ! empty( $node->href ); 410 411 $tabindex = isset( $node->meta['tabindex'] ) ? (int) $node->meta['tabindex'] : ''; 412 $aria_attributes = $tabindex ? 'tabindex="' . $tabindex . '"' : ''; 413 414 $menuclass = ''; 415 416 if ( $is_parent ) { 417 $menuclass = 'menupop '; 418 $aria_attributes .= ' aria-haspopup="true"'; 419 } 420 421 if ( ! empty( $node->meta['class'] ) ) 422 $menuclass .= $node->meta['class']; 423 424 if ( $menuclass ) 425 $menuclass = ' class="' . esc_attr( trim( $menuclass ) ) . '"'; 426 427 ?> 428 429 <li id="<?php echo esc_attr( 'wp-admin-bar-' . $node->id ); ?>"<?php echo $menuclass; ?>><?php 430 if ( $has_link ): 431 ?><a class="ab-item" <?php echo $aria_attributes; ?> href="<?php echo esc_url( $node->href ) ?>"<?php 432 if ( ! empty( $node->meta['onclick'] ) ) : 433 ?> onclick="<?php echo esc_js( $node->meta['onclick'] ); ?>"<?php 434 endif; 435 if ( ! empty( $node->meta['target'] ) ) : 436 ?> target="<?php echo esc_attr( $node->meta['target'] ); ?>"<?php 437 endif; 438 if ( ! empty( $node->meta['title'] ) ) : 439 ?> title="<?php echo esc_attr( $node->meta['title'] ); ?>"<?php 440 endif; 441 ?>><?php 442 else: 443 ?><div class="ab-item ab-empty-item" <?php echo $aria_attributes; 444 if ( ! empty( $node->meta['title'] ) ) : 445 ?> title="<?php echo esc_attr( $node->meta['title'] ); ?>"<?php 446 endif; 447 ?>><?php 448 endif; 449 450 echo $node->title; 451 452 if ( $has_link ) : 453 ?></a><?php 454 else: 455 ?></div><?php 456 endif; 457 458 if ( $is_parent ) : 459 ?><div class="ab-sub-wrapper"><?php 460 foreach ( $node->children as $group ) { 461 $this->_render_group( $group ); 462 } 463 ?></div><?php 464 endif; 465 466 if ( ! empty( $node->meta['html'] ) ) 467 echo $node->meta['html']; 468 469 ?> 470 </li><?php 471 } 472 473 public function recursive_render( $id, $node ) { 474 _deprecated_function( __METHOD__, '3.3', 'WP_Admin_bar::render(), WP_Admin_Bar::_render_item()' ); 475 $this->_render_item( $node ); 476 } 477 478 public function add_menus() { 479 // User related, aligned right. 480 add_action( 'admin_bar_menu', 'wp_admin_bar_my_account_menu', 0 ); 481 add_action( 'admin_bar_menu', 'wp_admin_bar_search_menu', 4 ); 482 add_action( 'admin_bar_menu', 'wp_admin_bar_my_account_item', 7 ); 483 484 // Site related. 485 add_action( 'admin_bar_menu', 'wp_admin_bar_sidebar_toggle', 0 ); 486 add_action( 'admin_bar_menu', 'wp_admin_bar_wp_menu', 10 ); 487 add_action( 'admin_bar_menu', 'wp_admin_bar_my_sites_menu', 20 ); 488 add_action( 'admin_bar_menu', 'wp_admin_bar_site_menu', 30 ); 489 add_action( 'admin_bar_menu', 'wp_admin_bar_updates_menu', 40 ); 490 491 // Content related. 492 if ( ! is_network_admin() && ! is_user_admin() ) { 493 add_action( 'admin_bar_menu', 'wp_admin_bar_comments_menu', 60 ); 494 add_action( 'admin_bar_menu', 'wp_admin_bar_new_content_menu', 70 ); 495 } 496 add_action( 'admin_bar_menu', 'wp_admin_bar_edit_menu', 80 ); 497 498 add_action( 'admin_bar_menu', 'wp_admin_bar_add_secondary_groups', 200 ); 499 500 /** 501 * Fires after menus are added to the menu bar. 502 * 503 * @since 3.1.0 504 */ 505 do_action( 'add_admin_bar_menus' ); 506 } 507 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Tue Mar 25 01:41:18 2014 | WordPress honlapkészítés: online1.hu |