WordPress.org

Make WordPress Core

Changeset 14450


Ignore:
Timestamp:
05/04/2010 07:40:04 PM (10 years ago)
Author:
nacin
Message:

Non-JS menu ordering fixes, also parent handling fixes. props filosofo, fixes #13135, fixes #13249

Location:
trunk
Files:
4 edited

Legend:

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

    r14439 r14450  
    1616     * @param int $depth Depth of page.
    1717     */
    18     function start_lvl(&$output, $depth) {}
     18    function start_lvl(&$output) {}
    1919
    2020    /**
     
    2525     * @param int $depth Depth of page.
    2626     */
    27     function end_lvl(&$output, $depth) {}
     27    function end_lvl(&$output) {
     28    }
    2829
    2930    /**
     
    8081                                        remove_query_arg($removed_args, admin_url( 'nav-menus.php' ) )
    8182                                    ),
    82                                     'move-item'
     83                                    'move-menu_item'
    8384                                );
    8485                            ?>" class="item-move-up"><abbr title="<?php esc_attr_e('Move up'); ?>">&#8593;</abbr></a>
     
    9394                                        remove_query_arg($removed_args, admin_url( 'nav-menus.php' ) )
    9495                                    ),
    95                                     'move-item'
     96                                    'move-menu_item'
    9697                                );
    9798                            ?>" class="item-move-down"><abbr title="<?php esc_attr_e('Move down'); ?>">&#8595;</abbr></a>
     
    188189                <input class="menu-item-data-object-id" type="hidden" name="menu-item-object-id[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->object_id ); ?>" />
    189190                <input class="menu-item-data-object" type="hidden" name="menu-item-object[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->object ); ?>" />
    190                 <input class="menu-item-data-parent-id" type="hidden" name="menu-item-parent-id[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->post_parent ); ?>" />
     191                <input class="menu-item-data-parent-id" type="hidden" name="menu-item-parent-id[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->menu_item_parent ); ?>" />
    191192                <input class="menu-item-data-position" type="hidden" class="menu-item-position" name="menu-item-position[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->menu_order ); ?>" />
    192193                <input class="menu-item-data-type" type="hidden" name="menu-item-type[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->type ); ?>" />
  • trunk/wp-admin/nav-menus.php

    r14408 r14450  
    6262        // moving down a menu item is the same as moving up the next in order
    6363        check_admin_referer( 'move-menu_item' );
    64         $menu_item_id = (int) $_REQUEST['menu-item'];
    65         $next_item_id = 0;
     64        $menu_item_id = isset( $_REQUEST['menu-item'] ) ? (int) $_REQUEST['menu-item'] : 0;
    6665        if ( is_nav_menu_item( $menu_item_id ) ) {
    6766            $menus = isset( $_REQUEST['menu'] ) ? array( (int) $_REQUEST['menu'] ) : wp_get_object_terms( $menu_item_id, 'nav_menu', array( 'fields' => 'ids' ) );
    68             if ( ! is_wp_error( $menus ) ) {
    69                 foreach( (array) $menus as $menu_id ) {
    70                     $move_down_ordered_menu_items = (array) wp_get_nav_menu_items( $menu_id );
    71                     while ( $next = array_shift( $move_down_ordered_menu_items ) ) {
    72                         if ( isset( $next->ID ) && $next->ID == $menu_item_id ) {
    73                             break;
     67            if ( ! is_wp_error( $menus ) && ! empty( $menus[0] ) ) {
     68                $menu_id = (int) $menus[0];
     69                $ordered_menu_items = wp_get_nav_menu_items( $menu_id );
     70                $menu_item_data = (array) wp_setup_nav_menu_item( get_post( $menu_item_id ) );
     71
     72                // setup the data we need in one pass through the array of menu items
     73                $dbids_to_orders = array();
     74                $orders_to_dbids = array();
     75                foreach( (array) $ordered_menu_items as $ordered_menu_item_object ) {
     76                    if ( isset( $ordered_menu_item_object->ID ) ) {
     77                        if ( isset( $ordered_menu_item_object->menu_order ) ) {
     78                            $dbids_to_orders[$ordered_menu_item_object->ID] = $ordered_menu_item_object->menu_order;
     79                            $orders_to_dbids[$ordered_menu_item_object->menu_order] = $ordered_menu_item_object->ID;
    7480                        }
    7581                    }
    76 
    77                     if ( $following = array_shift( $move_down_ordered_menu_items ) ) {
    78                         $next_item_id = (int) $following->ID;
    79                     }
     82                }
     83
     84                // get next in order
     85                if (
     86                    isset( $orders_to_dbids[$dbids_to_orders[$menu_item_id] + 1] )
     87                ) {
     88                    $next_item_id = $orders_to_dbids[$dbids_to_orders[$menu_item_id] + 1];
     89                    $next_item_data = (array) wp_setup_nav_menu_item( get_post( $next_item_id ) );
     90
     91                    // if not siblings of same parent, bubble menu item up but keep order
     92                    if (
     93                        ! empty( $menu_item_data['menu_item_parent'] ) &&
     94                        (
     95                            empty( $next_item_data['menu_item_parent'] ) ||
     96                            $next_item_data['menu_item_parent'] != $menu_item_data['menu_item_parent']
     97                        )
     98                    ) {
     99
     100                        $parent_db_id = in_array( $menu_item_data['menu_item_parent'], $orders_to_dbids ) ? (int) $menu_item_data['menu_item_parent'] : 0;
     101   
     102                        $parent_object = wp_setup_nav_menu_item( get_post( $parent_db_id ) );
     103
     104                        if ( ! is_wp_error( $parent_object ) ) {
     105                            $parent_data = (array) $parent_object;
     106                            $menu_item_data['menu_item_parent'] = $parent_data['menu_item_parent'];
     107                            update_post_meta( $menu_item_data['ID'], '_menu_item_menu_item_parent', (int) $menu_item_data['menu_item_parent'] );
     108
     109                        }
     110
     111                    // make menu item a child of its next sibling
     112                    } else {
     113                        $next_item_data['menu_order'] = $next_item_data['menu_order'] - 1;
     114                        $menu_item_data['menu_order'] = $menu_item_data['menu_order'] + 1;
     115
     116                        $menu_item_data['menu_item_parent'] = $next_item_data['ID'];   
     117                        update_post_meta( $menu_item_data['ID'], '_menu_item_menu_item_parent', (int) $menu_item_data['menu_item_parent'] );
     118                       
     119                        wp_update_post($menu_item_data);
     120                        wp_update_post($next_item_data);
     121                    }
     122                   
     123
     124                // the item is last but still has a parent, so bubble up
     125                } elseif (
     126                    ! empty( $menu_item_data['menu_item_parent'] ) &&
     127                    in_array( $menu_item_data['menu_item_parent'], $orders_to_dbids )
     128                ) {
     129                    $menu_item_data['menu_item_parent'] = (int) get_post_meta( $menu_item_data['menu_item_parent'], '_menu_item_menu_item_parent', true);
     130                    update_post_meta( $menu_item_data['ID'], '_menu_item_menu_item_parent', (int) $menu_item_data['menu_item_parent'] );
    80131                }
    81132            }
    82133        }
    83         // fall through to next case
     134
     135        break;
    84136    case 'move-up-menu-item' :
    85137        check_admin_referer( 'move-menu_item' );
    86         $menu_item_id = empty( $next_item_id ) ? (int) $_REQUEST['menu-item'] : $next_item_id;
     138        $menu_item_id = isset( $_REQUEST['menu-item'] ) ? (int) $_REQUEST['menu-item'] : 0;
    87139        if ( is_nav_menu_item( $menu_item_id ) ) {
    88140            $menus = isset( $_REQUEST['menu'] ) ? array( (int) $_REQUEST['menu'] ) : wp_get_object_terms( $menu_item_id, 'nav_menu', array( 'fields' => 'ids' ) );
    89             if ( ! is_wp_error( $menus ) ) {
    90                 foreach( (array) $menus as $menu_id ) {
    91                     $ordered_menu_items = wp_get_nav_menu_items( $menu_id );
    92                     $menu_item_data = get_post( $menu_item_id , ARRAY_A );
    93 
    94                     // setup the data we need in one pass through the array of menu items
    95                     $dbids_to_orders = array();
    96                     $orders_to_dbids = array();
    97                     $objectids_to_dbids = array();
    98                     $dbids_to_objectids = array();
    99                     foreach( (array) $ordered_menu_items as $ordered_menu_item_object ) {
    100                         if ( isset( $ordered_menu_item_object->ID ) ) {
    101                             if ( isset( $ordered_menu_item_object->menu_order ) ) {
    102                                 $dbids_to_orders[$ordered_menu_item_object->ID] = $ordered_menu_item_object->menu_order;
    103                                 $orders_to_dbids[$ordered_menu_item_object->menu_order] = $ordered_menu_item_object->ID;
     141            if ( ! is_wp_error( $menus ) && ! empty( $menus[0] ) ) {
     142                $menu_id = (int) $menus[0];
     143                $ordered_menu_items = wp_get_nav_menu_items( $menu_id );
     144                $menu_item_data = (array) wp_setup_nav_menu_item( get_post( $menu_item_id ) );
     145
     146                // setup the data we need in one pass through the array of menu items
     147                $dbids_to_orders = array();
     148                $orders_to_dbids = array();
     149                foreach( (array) $ordered_menu_items as $ordered_menu_item_object ) {
     150                    if ( isset( $ordered_menu_item_object->ID ) ) {
     151                        if ( isset( $ordered_menu_item_object->menu_order ) ) {
     152                            $dbids_to_orders[$ordered_menu_item_object->ID] = $ordered_menu_item_object->menu_order;
     153                            $orders_to_dbids[$ordered_menu_item_object->menu_order] = $ordered_menu_item_object->ID;
     154                        }
     155                    }
     156                }
     157
     158
     159                // if this menu item is not first
     160                if ( ! empty( $dbids_to_orders[$menu_item_id] ) && ! empty( $orders_to_dbids[$dbids_to_orders[$menu_item_id] - 1] ) ) {
     161
     162                    // if this menu item is a child of the previous
     163                    if (
     164                        ! empty( $menu_item_data['menu_item_parent'] ) &&
     165                        in_array( $menu_item_data['menu_item_parent'], array_keys( $dbids_to_orders ) ) &&
     166                        isset( $orders_to_dbids[$dbids_to_orders[$menu_item_id] - 1] ) &&
     167                        ( $menu_item_data['menu_item_parent'] == $orders_to_dbids[$dbids_to_orders[$menu_item_id] - 1] )
     168                    ) {
     169                        $parent_db_id = in_array( $menu_item_data['menu_item_parent'], $orders_to_dbids ) ? (int) $menu_item_data['menu_item_parent'] : 0;
     170                        $parent_object = wp_setup_nav_menu_item( get_post( $parent_db_id ) );
     171
     172                        if ( ! is_wp_error( $parent_object ) ) {
     173                            $parent_data = (array) $parent_object;
     174
     175                            // if there is something before the parent and parent a child of it, make menu item a child also of it
     176                            if (
     177                                ! empty( $dbids_to_orders[$parent_db_id] ) &&
     178                                ! empty( $orders_to_dbids[$dbids_to_orders[$parent_db_id] - 1] ) &&
     179                                ! empty( $parent_data['menu_item_parent'] )
     180                            ) {
     181                                $menu_item_data['menu_item_parent'] = $parent_data['menu_item_parent'];
     182
     183                            // else if there is something before parent and parent not a child of it, make menu item a child of that something's parent
     184                            } elseif (
     185                                ! empty( $dbids_to_orders[$parent_db_id] ) &&
     186                                ! empty( $orders_to_dbids[$dbids_to_orders[$parent_db_id] - 1] )
     187                            ) {
     188                                $_possible_parent_id = (int) get_post_meta( $orders_to_dbids[$dbids_to_orders[$parent_db_id] - 1], '_menu_item_menu_item_parent', true);
     189                                if ( in_array( $_possible_parent_id, array_keys( $dbids_to_orders ) ) )
     190                                    $menu_item_data['menu_item_parent'] = $_possible_parent_id;
     191                                else
     192                                    $menu_item_data['menu_item_parent'] = 0;
     193
     194                            // else there isn't something before the parent
     195                            } else {
     196                                $menu_item_data['menu_item_parent'] = 0;
    104197                            }
    105198
    106                             $possible_object_id = (int) get_post_meta( $ordered_menu_item_object->ID, '_menu_item_object_id', true );
    107                             if ( ! empty( $possible_object_id ) ) {
    108                                 $dbids_to_objectids[$ordered_menu_item_object->ID] = $possible_object_id;
    109                                 $objectids_to_dbids[$possible_object_id] = $ordered_menu_item_object->ID;
    110                             }
     199                            // set former parent's [menu_order] to that of menu-item's
     200                            $parent_data['menu_order'] = $parent_data['menu_order'] + 1;
     201
     202                            // set menu-item's [menu_order] to that of former parent
     203                            $menu_item_data['menu_order'] = $menu_item_data['menu_order'] - 1;
     204
     205                            // save changes
     206                            update_post_meta( $menu_item_data['ID'], '_menu_item_menu_item_parent', (int) $menu_item_data['menu_item_parent'] );
     207                            wp_update_post($menu_item_data);
     208                            wp_update_post($parent_data);
    111209                        }
    112                     }
    113 
    114 
    115                     // if this menu item is not first
    116                     if ( ! empty( $dbids_to_orders[$menu_item_id] ) && ! empty( $orders_to_dbids[$dbids_to_orders[$menu_item_id] - 1] ) ) {
    117 
    118                         // if this menu item is a child of the previous
    119                         if (
    120                             ! empty( $menu_item_data['post_parent'] ) &&
    121                             isset( $objectids_to_dbids[$menu_item_data['post_parent']] ) &&
    122                             isset( $orders_to_dbids[$dbids_to_orders[$menu_item_id] - 1] ) &&
    123                             ( $objectids_to_dbids[$menu_item_data['post_parent']] == $orders_to_dbids[$dbids_to_orders[$menu_item_id] - 1] )
    124                         ) {
    125 
    126                             $parent_db_id = $objectids_to_dbids[$menu_item_data['post_parent']];
    127                             $parent_data = get_post( $parent_db_id, ARRAY_A );
    128 
    129                             if ( ! is_wp_error( $parent_data ) ) {
    130 
    131                                 // if there is something before the parent, make menu item a child of the parent's parent
    132                                 if ( ! empty( $dbids_to_orders[$parent_db_id] ) && ! empty( $orders_to_dbids[$dbids_to_orders[$parent_db_id] - 1] ) ) {
    133                                     $menu_item_data['post_parent'] = $parent_data['post_parent'];
    134 
    135                                 // else there isn't something before the parent
    136                                 } else {
    137                                     $menu_item_data['post_parent'] = 0;
    138                                 }
    139 
    140                                 // set former parent's [menu_order] to that of menu-item's
    141                                 $parent_data['menu_order'] = $parent_data['menu_order'] + 1;
    142 
    143                                 // set menu-item's [menu_order] to that of former parent
    144                                 $menu_item_data['menu_order'] = $menu_item_data['menu_order'] - 1;
    145 
    146                                 // save changes
    147                                 wp_update_post($menu_item_data);
    148                                 wp_update_post($parent_data);
    149                             }
    150 
    151                         // else this menu item is not a child of the previous
    152                         } elseif ( isset($dbids_to_objectids[$orders_to_dbids[$dbids_to_orders[$menu_item_id] - 1]] ) ) {
    153                             // just make it a child of the previous; keep the order
    154                             $menu_item_data['post_parent'] = (int) $dbids_to_objectids[$orders_to_dbids[$dbids_to_orders[$menu_item_id] - 1]];
    155                             wp_update_post($menu_item_data);
    156                         }
     210
     211                    // else this menu item is not a child of the previous
     212                    } elseif (
     213                        empty( $menu_item_data['menu_order'] ) ||
     214                        empty( $menu_item_data['menu_item_parent'] ) ||
     215                        ! in_array( $menu_item_data['menu_item_parent'], array_keys( $dbids_to_orders ) ) ||
     216                        empty( $orders_to_dbids[$dbids_to_orders[$menu_item_id] - 1] ) ||
     217                        $orders_to_dbids[$dbids_to_orders[$menu_item_id] - 1] != $menu_item_data['menu_item_parent']   
     218                    ) {
     219                        // just make it a child of the previous; keep the order
     220                        $menu_item_data['menu_item_parent'] = (int) $orders_to_dbids[$dbids_to_orders[$menu_item_id] - 1];
     221                        update_post_meta( $menu_item_data['ID'], '_menu_item_menu_item_parent', (int) $menu_item_data['menu_item_parent'] );
     222                        wp_update_post($menu_item_data);
    157223                    }
    158224                }
  • trunk/wp-includes/nav-menu-template.php

    r14434 r14450  
    2929     * @var array
    3030     */
    31     var $db_fields = array( 'parent' => 'post_parent', 'id' => 'object_id' );
     31    var $db_fields = array( 'parent' => 'menu_item_parent', 'id' => 'db_id' );
    3232
    3333    /**
     
    138138        $possible_object_id = isset( $item->post_type ) && 'nav_menu_item' == $item->post_type ? $item->object_id : $_nav_menu_placeholder;
    139139        $possible_db_id = ( ! empty( $item->ID ) ) && ( 0 < $possible_object_id ) ? (int) $item->ID : 0;
    140         $possible_parent_id = ( ! empty( $item->ID ) ) && ( 0 < $possible_object_id ) ? (int) $item->post_parent : 0;
    141140
    142141        $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
     
    158157        $output .= '<input type="hidden" class="menu-item-db-id" name="menu-item[' . $possible_object_id . '][menu-item-db-id]" value="' . $possible_db_id . '" />';
    159158        $output .= '<input type="hidden" class="menu-item-object" name="menu-item[' . $possible_object_id . '][menu-item-object]" value="'. esc_attr( $item->object ) .'" />';
    160         $output .= '<input type="hidden" class="menu-item-parent-id" name="menu-item[' . $possible_object_id . '][menu-item-parent-id]" value="'. $possible_parent_id .'" />';
     159        $output .= '<input type="hidden" class="menu-item-parent-id" name="menu-item[' . $possible_object_id . '][menu-item-parent-id]" value="'. esc_attr( $item->menu_item_parent ) .'" />';
    161160        $output .= '<input type="hidden" class="menu-item-type" name="menu-item[' . $possible_object_id . '][menu-item-type]" value="'. esc_attr( $item->type ) .'" />';
    162161        $output .= '<input type="hidden" class="menu-item-append" name="menu-item[' . $possible_object_id . '][menu-item-append]" value="'. esc_attr( $item->append ) .'" />';
  • trunk/wp-includes/nav-menu.php

    r14404 r14450  
    257257    }
    258258
     259    $original_parent = 0 < $menu_item_db_id ? get_post_field( 'post_parent', $menu_item_db_id ) : 0;
     260
    259261    if ( 'custom' != $args['menu-item-type'] ) {
    260262        /* if non-custom menu item, then:
     
    267269        $original_title = '';
    268270        if ( 'taxonomy' == $args['menu-item-type'] ) {
     271            $original_parent = get_term_field( 'parent', $args['menu-item-object-id'], $args['menu-item-object'], 'raw' );
    269272            $original_title = get_term_field( 'name', $args['menu-item-object-id'], $args['menu-item-object'], 'raw' );
    270273        } elseif ( 'post_type' == $args['menu-item-type'] ) {
    271274
    272275            $original_object = get_post( $args['menu-item-object-id'] );
     276            $original_parent = (int) $original_object->post_parent;
    273277            $original_title = $original_object->post_title;
    274278
     
    298302        'post_content' => $args['menu-item-description'],
    299303        'post_excerpt' => $args['menu-item-attr-title'],
    300         'post_parent' => $args['menu-item-parent-id'],
     304        'post_parent' => $original_parent,
    301305        'post_title' => $args['menu-item-title'],
    302306        'post_type' => 'nav_menu_item',
     
    327331
    328332        update_post_meta( $menu_item_db_id, '_menu_item_type', sanitize_key($args['menu-item-type']) );
     333        update_post_meta( $menu_item_db_id, '_menu_item_menu_item_parent', (int) $args['menu-item-parent-id'] );
    329334        update_post_meta( $menu_item_db_id, '_menu_item_object_id', (int) $args['menu-item-object-id'] );
    330335        update_post_meta( $menu_item_db_id, '_menu_item_object', sanitize_key($args['menu-item-object']) );
     
    440445 *
    441446 * Properties:
    442  * - db_id:         The DB ID of the this item as a nav_menu_item object, if it exists (0 if it doesn't exist).
     447 * - db_id:         The DB ID of this item as a nav_menu_item object, if it exists (0 if it doesn't exist).
    443448 * - object_id:     The DB ID of the original object this menu item represents, e.g. ID for posts and term_id for categories.
    444449 * - type:      The family of objects originally represented, such as "post_type" or "taxonomy."
    445450 * - object:        The type of object originally represented, such as "category," "post", or "attachment."
    446451 * - append:        The singular label used to describe this type of menu item.
    447  * - parent:        The DB ID of the original object's parent object, if any (0 otherwise).
     452 * - post_parent:   The DB ID of the original object's parent object, if any (0 otherwise).
     453 * - menu_item_parent:  The DB ID of the nav_menu_item that is this item's menu parent, if any.  0 otherwise.
    448454 * - url:       The URL to which this menu item points.
    449455 * - title:     The title of this menu item.
     
    463469        if ( 'nav_menu_item' == $menu_item->post_type ) {
    464470            $menu_item->db_id = (int) $menu_item->ID;
     471            $menu_item->menu_item_parent = get_post_meta( $menu_item->ID, '_menu_item_menu_item_parent', true );
    465472            $menu_item->object_id = get_post_meta( $menu_item->ID, '_menu_item_object_id', true );
    466473            $menu_item->object = get_post_meta( $menu_item->ID, '_menu_item_object', true );
     
    499506        } else {
    500507            $menu_item->db_id = 0;
     508            $menu_item->menu_item_parent = 0;
    501509            $menu_item->object_id = (int) $menu_item->ID;
    502510            $menu_item->type = 'post_type';
     
    518526        $menu_item->ID = $menu_item->term_id;
    519527        $menu_item->db_id = 0;
     528        $menu_item->menu_item_parent = 0;
    520529        $menu_item->object_id = (int) $menu_item->term_id;
    521530        $menu_item->post_parent = (int) $menu_item->parent;
Note: See TracChangeset for help on using the changeset viewer.