WordPress.org

Make WordPress Core


Ignore:
Timestamp:
04/27/2010 01:05:58 AM (11 years ago)
Author:
ryan
Message:

New menu UI. Props filosofo. see #12713

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-includes/nav-menu.php

    r14031 r14248  
    1717 */
    1818function wp_get_nav_menu_object( $menu ) {
    19     return is_nav_menu( $menu );
     19    if ( ! $menu )
     20        return false;
     21
     22    $menu_obj = get_term( $menu, 'nav_menu' );
     23
     24    if ( ! $menu_obj )
     25        $menu_obj = get_term_by( 'slug', $menu, 'nav_menu' );
     26
     27    if ( ! $menu_obj )
     28        $menu_obj = get_term_by( 'name', $menu, 'nav_menu' );
     29
     30    if ( ! $menu_obj ) {
     31        $menu_obj = false;
     32    }
     33
     34    return $menu_obj;
    2035}
    2136
     
    2843 *
    2944 * @param int|string $menu The menu to check
    30  * @return mixed Menu Object, if it exists. Else, false or WP_Error
     45 * @return bool Whether the menu exists.
    3146 */
    3247function is_nav_menu( $menu ) {
    33     if ( !$menu )
     48    if ( ! $menu )
    3449        return false;
    35 
    36     $menu_obj = get_term( $menu, 'nav_menu' );
    37 
    38     if ( !$menu_obj )
    39         $menu_obj = get_term_by( 'slug', $menu, 'nav_menu' );
    40 
    41     if ( !$menu_obj )
    42         $menu_obj = get_term_by( 'name', $menu, 'nav_menu' );
    43 
    44     if ( !$menu_obj ) {
    45         $menu_obj = false;
    46     }
    47 
    48     return $menu_obj;
     50   
     51    $menu_obj = wp_get_nav_menu_object( $menu );
     52
     53    if ( $menu_obj && ! is_wp_error( $menu_obj ) && ! empty( $menu_obj->term_id ) )
     54        return true;
     55   
     56    return false;
    4957}
    5058
     
    97105function wp_delete_nav_menu( $menu ) {
    98106    $menu = wp_get_nav_menu_object( $menu );
    99     if ( !$menu  )
     107    if ( ! $menu  )
    100108        return false;
    101109
     
    118126
    119127/**
     128 * Save the properties of a menu or create a new menu with those properties.
     129 *
     130 * @since 3.0.0
     131 *
     132 * @param int $menu_id The ID of the menu
     133 * @param array $menu_data The array of menu data.
     134 * @return int The menu's ID.
     135 */
     136function wp_update_nav_menu_object( $menu_id = 0, $menu_data = array() ) {
     137    $menu_id = (int) $menu_id;
     138
     139    $_menu = wp_get_nav_menu_object( $menu_id );
     140
     141    // menu doesn't already exist
     142    if ( ! $_menu || is_wp_error( $_menu ) ) {
     143        $_menu = wp_create_nav_menu( $menu_data['menu-name'] );
     144    }
     145
     146    if ( $_menu && isset( $_menu->term_id ) && ! is_wp_error( $_menu ) ) {
     147        $args = array(
     148            'description' => ( isset( $menu_data['description'] ) ? $menu_data['description'] : '' ),
     149            'name' => ( isset( $menu_data['menu-name'] ) ? $menu_data['menu-name'] : '' ),
     150            'parent' => ( isset( $menu_data['parent'] ) ? (int) $menu_data['parent'] : 0 ),
     151            'slug' => null,
     152        );
     153   
     154        $menu_id = (int) $_menu->term_id;
     155
     156        $update_response = wp_update_term( $menu_id, 'nav_menu', $args );
     157
     158        if ( ! is_wp_error( $update_response ) ) {
     159            return $menu_id;
     160        }
     161    } else {
     162        return 0;
     163    }
     164}
     165
     166/**
     167 * Save the properties of a menu item or create a new one.
     168 *
     169 * @since 3.0.0
     170 *
     171 * @param int $menu_id The ID of the menu. Required.
     172 * @param int $menu_item_db_id The ID of the menu item. If "0", creates a new menu item.
     173 * @param array $menu_item_data The menu item's data.
     174 * @return int The menu item's database ID or WP_Error object on failure.
     175 */
     176function wp_update_nav_menu_item( $menu_id = 0, $menu_item_db_id = 0, $menu_item_data = array() ) {
     177
     178    $menu_id = (int) $menu_id;
     179    $menu_item_db_id = (int) $menu_item_db_id;
     180
     181    $menu = wp_get_nav_menu_object( $menu_id );
     182
     183    if ( ! $menu || is_wp_error( $menu ) ) {
     184        return $menu;
     185    }
     186
     187    $menu_items = (array) wp_get_nav_menu_items( $menu_id );
     188
     189    $count = count( $menu_items );
     190
     191    $defaults = array(
     192        'menu-item-db-id' => $menu_item_db_id,
     193        'menu-item-object-id' => 0,
     194        'menu-item-object' => '',
     195        'menu-item-parent-id' => 0,
     196        'menu-item-position' => 0,
     197        'menu-item-type' => 'custom',
     198        'menu-item-append' => 'custom',
     199        'menu-item-title' => '',
     200        'menu-item-url' => '',
     201        'menu-item-description' => '',
     202        'menu-item-attr-title' => '',
     203        'menu-item-target' => '',
     204        'menu-item-classes' => '',
     205        'menu-item-xfn' => '',
     206    );
     207
     208    $args = wp_parse_args( $menu_item_data, $defaults );
     209
     210    if ( 0 == (int) $args['menu-item-position'] ) {
     211        $last_item = array_pop( $menu_items );
     212        if ( $last_item && isset( $last_item->ID ) ) {
     213            $last_data = get_post( $last_item->ID );
     214            if ( ! is_wp_error( $last_data ) && isset( $last_data->menu_order ) ) {
     215                $args['menu-item-position'] = 1 + (int) $last_data->menu_order;
     216            }
     217
     218        } else {
     219            $args['menu-item-position'] = $count;
     220        }
     221    }
     222   
     223    // Populate the menu item object
     224    $post = array(
     225        'menu_order' => $args['menu-item-position'],
     226        'ping_status' => 0,
     227        'post_content' => $args['menu-item-description'],
     228        'post_excerpt' => $args['menu-item-attr-title'],
     229        'post_parent' => $args['menu-item-parent-id'],
     230        'post_status' => 'publish',
     231        'post_title' => $args['menu-item-title'],
     232        'post_type' => 'nav_menu_item',
     233        'tax_input' => array( 'nav_menu' => $menu->name ),
     234    );
     235
     236    // New menu item
     237    if ( 0 == $menu_item_db_id ) {
     238        $menu_item_db_id = wp_insert_post( $post );
     239
     240    // Update existing menu item
     241    } else {
     242        $post['ID'] = $menu_item_db_id;
     243        wp_update_post( $post );
     244    }
     245
     246    if ( 'custom' == $args['menu-item-type'] ) {
     247        $args['menu-item-object-id'] = $menu_item_db_id;
     248        $args['menu-item-object'] = 'custom';
     249    }
     250
     251    if ( $menu_item_db_id && ! is_wp_error( $menu_item_db_id ) ) {
     252
     253        $menu_item_db_id = (int) $menu_item_db_id;
     254
     255        update_post_meta( $menu_item_db_id, '_menu_item_type', sanitize_key($args['menu-item-type']) );
     256        update_post_meta( $menu_item_db_id, '_menu_item_object_id', (int) $args['menu-item-object-id'] );
     257        update_post_meta( $menu_item_db_id, '_menu_item_object', sanitize_key($args['menu-item-object']) );
     258        update_post_meta( $menu_item_db_id, '_menu_item_target', sanitize_key($args['menu-item-target']) );
     259        // @todo handle sanitizing multiple classes separated by whitespace.
     260        update_post_meta( $menu_item_db_id, '_menu_item_classes', sanitize_html_class($args['menu-item-classes']) );
     261        update_post_meta( $menu_item_db_id, '_menu_item_xfn', sanitize_html_class($args['menu-item-xfn']) );
     262
     263        // @todo: only save custom link urls.
     264        update_post_meta( $menu_item_db_id, '_menu_item_url', esc_url_raw($args['menu-item-url']) );
     265
     266        do_action('wp_update_nav_menu_item', $menu_id, $menu_item_db_id, $args );
     267    }
     268
     269    return $menu_item_db_id;
     270}
     271
     272/**
    120273 * Returns all navigation menu objects.
    121274 *
     
    126279function wp_get_nav_menus() {
    127280    return get_terms( 'nav_menu', array( 'hide_empty' => false, 'orderby' => 'id' ) );
     281}
     282
     283
     284/**
     285 * Sort menu items by the desired key.
     286 *
     287 * @since 3.0.0
     288 * @access private
     289 *
     290 * @param object $a The first object to compare
     291 * @param object $b The second object to compare
     292 * @return int -1, 0, or 1 if $a is considered to be respectively less than, equal to, or greater than $b.
     293 */
     294function _sort_nav_menu_items($a, $b) {
     295    global $_menu_item_sort_prop;
     296
     297    if ( empty( $_menu_item_sort_prop ) ) {
     298        return 0;
     299    }
     300
     301    if ( isset( $a->$_menu_item_sort_prop ) && isset( $b->$_menu_item_sort_prop ) ) {
     302        $_a = (int) $a->$_menu_item_sort_prop;
     303        $_b = (int) $b->$_menu_item_sort_prop;
     304
     305        if ( $a->$_menu_item_sort_prop == $b->$_menu_item_sort_prop ) {
     306            return 0;   
     307        } elseif (
     308            ( $_a == $a->$_menu_item_sort_prop ) &&
     309            ( $_b == $b->$_menu_item_sort_prop )
     310        ) {
     311            return $_a < $_b ? -1 : 1;
     312        } else {
     313            return strcmp( $a->$_menu_item_sort_prop, $b->$_menu_item_sort_prop );
     314        }
     315    } else {
     316        return 0;
     317    }
    128318}
    129319
     
    140330    $menu = wp_get_nav_menu_object( $menu );
    141331
    142     if ( !$menu )
     332    if ( ! $menu )
    143333        return false;
    144 
     334   
    145335    $items = get_objects_in_term( $menu->term_id, 'nav_menu' );
    146336
    147337    if ( ! empty( $items ) ) {
    148         $defaults = array( 'orderby' => 'menu_order', 'post_type' => 'nav_menu_item', 'post_status' => 'publish', 'output' => ARRAY_A, 'output_key' => 'menu_order' );
     338        $defaults = array( 'order' => 'ASC', 'orderby' => 'menu_order', 'post_type' => 'nav_menu_item', 'post_status' => 'publish', 'output' => ARRAY_A, 'output_key' => 'menu_order' );
    149339        $args = wp_parse_args( $args, $defaults );
    150340        if ( count( $items ) > 1 )
     
    156346
    157347        if ( ARRAY_A == $args['output'] ) {
    158             $output = array();
    159             foreach ( $items as $item ) {
    160                 $output[$item->$args['output_key']] = $item;
     348            $GLOBALS['_menu_item_sort_prop'] = $args['output_key'];
     349            usort($items, '_sort_nav_menu_items');
     350            $i = 1;
     351            foreach( $items as $k => $item ) {
     352                $items[$k]->$args['output_key'] = $i++;
    161353            }
    162             unset( $items );
    163             ksort( $output );
    164             return $output;
    165354        }
    166355    }
     
    169358
    170359/**
    171  * Retrieve the HTML list content for nav menu items.
    172  *
    173  * @uses Walker_Nav_Menu to create HTML list content.
    174  * @since 2.1.0
    175  * @see Walker::walk() for parameters and return description.
    176  */
    177 function walk_nav_menu_tree( $items, $depth, $r ) {
    178     $walker = ( empty($r->walker) ) ? new Walker_Nav_Menu : $r->walker;
    179     $args = array( $items, $depth, $r );
    180 
    181     return call_user_func_array( array(&$walker, 'walk'), $args );
    182 }
    183 
    184 /**
    185  * Adds all the navigation menu properties to the menu item.
    186  *
    187  * @since 3.0.0
    188  *
    189  * @param string $menu_item The menu item to modify
    190  * @param string $menu_item_type The menu item type (frontend, custom, post_type, taxonomy).
    191  * @param string $menu_item_object Optional. The menu item object type (post type or taxonomy).
    192  * @return object $menu_item The modified menu item.
    193  */
    194 function wp_setup_nav_menu_item( $menu_item, $menu_item_type = null, $menu_item_object = '' ) {
    195     switch ( $menu_item_type ) {
    196         case 'frontend':
     360 * Decorates a menu item object with the shared navigation menu item properties.
     361 *
     362 * Properties:
     363 * - db_id:         The DB ID of the this item as a nav_menu_item object, if it exists (0 if it doesn't exist).
     364 * - object_id:     The DB ID of the original object this menu item represents, e.g. ID for posts and term_id for categories.
     365 * - type:      The family of objects originally represented, such as "post_type" or "taxonomy."
     366 * - object:        The type of object originally represented, such as "category," "post", or "attachment."
     367 * - append:        The singular label used to describe this type of menu item.
     368 * - parent:        The DB ID of the original object's parent object, if any (0 otherwise).
     369 * - url:       The URL to which this menu item points.
     370 * - title:     The title of this menu item.
     371 * - target:        The target attribute of the link element for this menu item.
     372 * - attr_title:    The title attribute of the link element for this menu item. 
     373 * - classes:       The class attribute value for the link element of this menu item.
     374 * - xfn:       The XFN relationship expressed in the link of this menu item.
     375 * - description:   The description of this menu item.
     376 *
     377 * @since 3.0.0
     378 *
     379 * @param object $menu_item The menu item to modify.
     380 * @return object $menu_item The menu item with standard menu item properties.
     381 */
     382function wp_setup_nav_menu_item( $menu_item ) {
     383    if ( isset( $menu_item->post_type ) ) {
     384        if ( 'nav_menu_item' == $menu_item->post_type ) {
    197385            $menu_item->db_id = (int) $menu_item->ID;
    198386            $menu_item->object_id = get_post_meta( $menu_item->ID, '_menu_item_object_id', true );
    199387            $menu_item->object = get_post_meta( $menu_item->ID, '_menu_item_object', true );
    200388            $menu_item->type = get_post_meta( $menu_item->ID, '_menu_item_type', true );
    201 
     389           
    202390            if ( 'post_type' == $menu_item->type ) {
    203391                $object = get_post_type_object( $menu_item->object );
     
    214402                $menu_item->url = get_post_meta( $menu_item->ID, '_menu_item_url', true );
    215403            }
    216 
     404           
    217405            $menu_item->title = $menu_item->post_title;
    218406            $menu_item->target = get_post_meta( $menu_item->ID, '_menu_item_target', true );
     
    223411            $menu_item->classes = get_post_meta( $menu_item->ID, '_menu_item_classes', true );
    224412            $menu_item->xfn = get_post_meta( $menu_item->ID, '_menu_item_xfn', true );
    225             break;
    226        
    227         case 'custom':
     413        } else {
    228414            $menu_item->db_id = 0;
    229415            $menu_item->object_id = (int) $menu_item->ID;
    230             $menu_item->object = 'custom';
    231             $menu_item->type = 'custom';
    232             $menu_item->append = __('custom');
    233 
    234             $menu_item->attr_title = strip_tags( $menu_item->post_excerpt );
    235             $menu_item->description = strip_tags( $menu_item->post_content );
    236 
    237             $menu_item->title = $menu_item->post_title;
    238             $menu_item->url = get_post_meta( $menu_item->ID, '_menu_item_url', true );
    239             $menu_item->target = get_post_meta( $menu_item->ID, '_menu_item_target', true );
    240             $menu_item->classes = get_post_meta( $menu_item->ID, '_menu_item_target', true );
    241             $menu_item->xfn = get_post_meta( $menu_item->ID, '_menu_item_xfn', true );
    242             break;
    243 
    244         case 'post_type':
    245             $menu_item->db_id = 0;
    246             $menu_item->object_id = (int) $menu_item->ID;
    247             $menu_item->type = $menu_item_type;
    248 
    249             $object = get_post_type_object( $menu_item_object );
     416            $menu_item->type = 'post_type';
     417
     418            $object = get_post_type_object( $menu_item->post_type );
    250419            $menu_item->object = $object->name;
    251420            $menu_item->append = strtolower( $object->singular_label );
     
    255424            $menu_item->target = '';
    256425
    257             $menu_item->attr_title = '';
     426            $menu_item->attr_title = strip_tags( $menu_item->post_excerpt );
    258427            $menu_item->description = strip_tags( $menu_item->post_content );
    259428            $menu_item->classes = '';
    260429            $menu_item->xfn = '';
    261             break;
    262 
    263         case 'taxonomy':
    264             $menu_item->ID = $menu_item->term_id;
    265             $menu_item->db_id = 0;
    266             $menu_item->object_id = (int) $menu_item->term_id;
    267             $menu_item->post_parent = (int) $menu_item->parent;
    268             $menu_item->type = $menu_item_type;
    269 
    270             $object = get_taxonomy( $menu_item_object );
    271             $menu_item->object = $object->name;
    272             $menu_item->append = strtolower( $object->singular_label );
    273 
    274             $menu_item->title = $menu_item->name;
    275             $menu_item->url = get_term_link( $menu_item, $menu_item_object );
    276             $menu_item->target = '';
    277             $menu_item->attr_title = '';
    278             $menu_item->description = '';
    279             $menu_item->classes = '';
    280             $menu_item->xfn = '';
    281             break;
    282     }
    283    
    284     return apply_filters( 'wp_setup_nav_menu_item', $menu_item, $menu_item_type, $menu_item_object );
     430        }
     431    } elseif ( isset( $menu_item->taxonomy ) ) {
     432        $menu_item->ID = $menu_item->term_id;
     433        $menu_item->db_id = 0;
     434        $menu_item->object_id = (int) $menu_item->term_id;
     435        $menu_item->post_parent = (int) $menu_item->parent;
     436        $menu_item->type = 'taxonomy';
     437
     438        $object = get_taxonomy( $menu_item->taxonomy );
     439        $menu_item->object = $object->name;
     440        $menu_item->append = strtolower( $object->singular_label );
     441
     442        $menu_item->title = $menu_item->name;
     443        $menu_item->url = get_term_link( $menu_item, $menu_item->taxonomy );
     444        $menu_item->target = '';
     445        $menu_item->attr_title = '';
     446        $menu_item->description = strip_tags( get_term_field( 'description', $menu_item->term_id, $menu_item->taxonomy ) );
     447        $menu_item->classes = '';
     448        $menu_item->xfn = '';
     449
     450    }
     451
     452    return apply_filters( 'wp_setup_nav_menu_item', $menu_item );
    285453}
    286454?>
Note: See TracChangeset for help on using the changeset viewer.