Make WordPress Core


Ignore:
Timestamp:
11/02/2011 08:34:54 PM (13 years ago)
Author:
koopersmith
Message:

Improve admin bar internal representation. Simpler signatures, with backwards compatibility. Add items without requiring parents to be added first. see #18197.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-includes/class-wp-admin-bar.php

    r18927 r19120  
    11<?php
    22class WP_Admin_Bar {
    3     var $menu;
    4     var $proto = 'http://';
    5     var $user;
     3    private $nodes = array();
     4    private $root = array();
     5
     6    public $proto = 'http://';
     7    public $user;
    68
    79    function initialize() {
     
    1113
    1214        $this->user = new stdClass;
    13         $this->menu = new stdClass;
    1415
    1516        if ( is_user_logged_in() ) {
     
    4748    }
    4849
    49     function add_menu( $args = array() ) {
     50    public function add_menu( $node ) {
     51        $this->add_node( $node );
     52    }
     53
     54    public function remove_menu( $id ) {
     55        $this->remove_node( $id );
     56    }
     57
     58    /**
     59     * Add a node to the menu.
     60     *
     61     * @param array $args - The arguments for each node.
     62     * - id       - string - The ID of the item.
     63     * - title    - string - The title of the node.
     64     * - parent   - string - The ID of the parent node. Optional.
     65     * - href     - string - The link for the item. Optional.
     66     * - meta     - array  - Meta data including the following keys: html, class, onclick, target, title.
     67     */
     68    public function add_node( $args ) {
     69        // Shim for old method signature: add_node( $parent_id, $menu_obj, $args )
     70        if ( func_num_args() >= 3 && is_string( func_get_arg(0) ) )
     71            $args = array_merge( array( 'parent' => func_get_arg(0) ), func_get_arg(2) );
     72
     73        // Ensure we have a valid ID and title.
     74        if ( empty( $args['title'] ) || empty( $args['id'] ) )
     75            return false;
     76
    5077        $defaults = array(
    51             'title' => false,
    52             'href' => false,
    53             'parent' => false, // false for a root menu, pass the ID value for a submenu of that menu.
    54             'id' => false, // defaults to a sanitized title value.
    55             'meta' => false // array of any of the following options: array( 'html' => '', 'class' => '', 'onclick' => '', target => '', title => '' );
     78            'id'      => false,
     79            'title'    => false,
     80            'parent'   => false,
     81            'href'     => false,
     82            'meta'     => array(),
    5683        );
    5784
    58         $r = wp_parse_args( $args, $defaults );
    59         extract( $r, EXTR_SKIP );
    60 
    61         if ( empty( $title ) )
    62             return false;
    63 
    64         /* Make sure we have a valid ID */
    65         if ( empty( $id ) )
    66             $id = esc_attr( sanitize_title( trim( $title ) ) );
    67 
    68         if ( ! empty( $parent ) ) {
    69             /* Add the menu to the parent item */
    70             $child = array( 'id' => $id, 'title' => $title, 'href' => $href );
    71 
    72             if ( ! empty( $meta ) )
    73                 $child['meta'] = $meta;
    74 
    75             $this->add_node( $parent, $this->menu, $child );
    76         } else {
    77             /* Add the menu item */
    78             $this->menu->{$id} = array( 'title' => $title, 'href' => $href );
    79 
    80             if ( ! empty( $meta ) )
    81                 $this->menu->{$id}['meta'] = $meta;
    82         }
    83     }
    84 
    85     function remove_menu( $id ) {
    86         return $this->remove_node( $id, $this->menu );
    87     }
    88 
    89     function render() {
     85        // If the node already exists, keep any data that isn't provided.
     86        if ( isset( $this->nodes[ $args['id'] ] ) )
     87            $defaults = (array) $this->nodes[ $args['id'] ];
     88
     89        $args = wp_parse_args( $args, $defaults );
     90
     91        $this->nodes[ $args['id'] ] = (object) $args;
     92    }
     93
     94    public function remove_node( $id ) {
     95        unset( $this->nodes[ $id ] );
     96    }
     97
     98    public function render() {
     99        // Link nodes to parents.
     100        foreach ( $this->nodes as $node ) {
     101
     102            // Handle root menu items
     103            if ( empty( $node->parent ) ) {
     104                $this->root[] = $node;
     105                continue;
     106            }
     107
     108            // If the parent node isn't registered, ignore the node.
     109            if ( ! isset( $this->nodes[ $node->parent ] ) )
     110                continue;
     111
     112            $parent = $this->nodes[ $node->parent ];
     113            if ( ! isset( $parent->children ) )
     114                $parent->children = array();
     115
     116            $parent->children[] = $node;
     117        }
     118
    90119        ?>
    91120        <div id="wpadminbar" class="nojq nojs">
    92121            <div class="quicklinks">
    93                 <ul class="ab-top-menu">
    94                     <?php foreach ( (array) $this->menu as $id => $menu_item ) : ?>
    95                         <?php $this->recursive_render( $id, $menu_item ) ?>
    96                     <?php endforeach; ?>
    97                 </ul>
     122                <ul class="ab-top-menu"><?php
     123
     124                    foreach ( $this->root as $node ) {
     125                        $this->recursive_render( $node );
     126                    }
     127
     128                ?></ul>
    98129            </div>
    99130        </div>
    100131
    101132        <?php
    102         /* Wipe the menu, might reduce memory usage, but probably not. */
    103         $this->menu = null;
    104     }
    105 
    106     /* Helpers */
    107     function recursive_render( $id, &$menu_item ) { ?>
    108         <?php
    109         $is_parent =  ! empty( $menu_item['children'] );
     133    }
     134
     135    function recursive_render( $node ) {
     136        $is_parent = ! empty( $node->children );
    110137
    111138        $menuclass = $is_parent ? 'menupop' : '';
    112         if ( ! empty( $menu_item['meta']['class'] ) )
    113             $menuclass .= ' ' . $menu_item['meta']['class'];
     139        if ( ! empty( $node->meta['class'] ) )
     140            $menuclass .= ' ' . $node->meta['class'];
    114141        ?>
    115142
    116         <li id="<?php echo esc_attr( "wp-admin-bar-$id" ); ?>" class="<?php echo esc_attr( $menuclass ); ?>">
    117             <a href="<?php echo esc_url( $menu_item['href'] ) ?>"<?php
    118                 if ( ! empty( $menu_item['meta']['onclick'] ) ) :
    119                     ?> onclick="<?php echo esc_js( $menu_item['meta']['onclick'] ); ?>"<?php
     143        <li id="<?php echo esc_attr( "wp-admin-bar-{$node->id}" ); ?>" class="<?php echo esc_attr( $menuclass ); ?>">
     144            <a href="<?php echo esc_url( $node->href ) ?>"<?php
     145                if ( ! empty( $node->meta['onclick'] ) ) :
     146                    ?> onclick="<?php echo esc_js( $node->meta['onclick'] ); ?>"<?php
    120147                endif;
    121             if ( ! empty( $menu_item['meta']['target'] ) ) :
    122                 ?> target="<?php echo esc_attr( $menu_item['meta']['target'] ); ?>"<?php
    123             endif;
    124             if ( ! empty( $menu_item['meta']['title'] ) ) :
    125                 ?> title="<?php echo esc_attr( $menu_item['meta']['title'] ); ?>"<?php
     148            if ( ! empty( $node->meta['target'] ) ) :
     149                ?> target="<?php echo esc_attr( $node->meta['target'] ); ?>"<?php
     150            endif;
     151            if ( ! empty( $node->meta['title'] ) ) :
     152                ?> title="<?php echo esc_attr( $node->meta['title'] ); ?>"<?php
    126153            endif;
    127154
     
    132159            endif;
    133160
    134             echo $menu_item['title'];
     161            echo $node->title;
    135162
    136163            if ( $is_parent ) :
     
    141168
    142169            <?php if ( $is_parent ) : ?>
    143             <ul>
    144                 <?php foreach ( $menu_item['children'] as $child_id => $child_menu_item ) : ?>
    145                     <?php $this->recursive_render( $child_id, $child_menu_item ); ?>
    146                 <?php endforeach; ?>
    147             </ul>
    148             <?php endif; ?>
    149 
    150             <?php if ( ! empty( $menu_item['meta']['html'] ) ) : ?>
    151                 <?php echo $menu_item['meta']['html']; ?>
    152             <?php endif; ?>
     170                <ul><?php
     171
     172                // Render children.
     173                foreach ( $node->children as $child_node ) {
     174                    $this->recursive_render( $child_node );
     175                }
     176
     177                ?></ul>
     178            <?php endif;
     179
     180            if ( ! empty( $node->meta['html'] ) )
     181                echo $node->meta['html'];
     182
     183            ?>
    153184        </li><?php
    154     }
    155 
    156     function add_node( $parent_id, &$menu, $child ) {
    157         foreach( $menu as $id => $menu_item ) {
    158             if ( $parent_id == $id ) {
    159                 if ( ! isset( $menu->{$parent_id}['children'] ) )
    160                     $menu->{$parent_id}['children'] = new stdClass;
    161                 $menu->{$parent_id}['children']->{$child['id']} = $child;
    162                 $child = null;
    163                 return true;
    164             }
    165 
    166             if ( ! empty( $menu->{$id}['children'] ) )
    167                 $this->add_node( $parent_id, $menu->{$id}['children'], $child );
    168         }
    169 
    170         $child = null;
    171 
    172         return false;
     185
    173186    }
    174187
     
    197210        do_action( 'add_admin_bar_menus' );
    198211    }
    199 
    200     function remove_node( $id, &$menu ) {
    201         if ( isset( $menu->$id ) ) {
    202             unset( $menu->$id );
    203             return true;
    204         }
    205 
    206         foreach( $menu as $menu_item_id => $menu_item ) {
    207             if ( ! empty( $menu->{$menu_item_id}['children'] ) )
    208                 $this->remove_node( $id, $menu->{$menu_item_id}['children'] );
    209         }
    210 
    211         return false;
    212     }
    213212}
    214213?>
Note: See TracChangeset for help on using the changeset viewer.