WordPress.org

Make WordPress Core

Ticket #13148: menu_item_api_and_fixes.2.13148.diff

File menu_item_api_and_fixes.2.13148.diff, 16.2 KB (added by filosofo, 4 years ago)
  • wp-includes/default-filters.php

     
    169169add_filter( 'comments_open',        '_close_comments_for_old_post', 10, 2 ); 
    170170add_filter( 'pings_open',           '_close_comments_for_old_post', 10, 2 ); 
    171171add_filter( 'editable_slug',        'urldecode'                           ); 
     172add_filter( 'nav_menu_meta_box_object','_wp_nav_menu_meta_box_object'     ); 
    172173 
    173174// Atom SSL support 
    174175add_filter( 'atom_service_url','atom_service_url_filter' ); 
  • wp-includes/nav-menu-template.php

     
    132132         * @param object $args 
    133133         */ 
    134134        function start_el(&$output, $item, $depth, $args) { 
    135                 static $_placeholder; 
    136                 $_placeholder = 0 > $_placeholder ? $_placeholder - 1 : -1; 
    137                 $possible_object_id = isset( $item->post_type ) && 'nav_menu_item' == $item->post_type ? $item->object_id : $_placeholder; 
     135                global $_nav_menu_placeholder; 
     136 
     137                $_nav_menu_placeholder = ( 0 > $_nav_menu_placeholder ) ? intval($_nav_menu_placeholder) - 1 : -1; 
     138                $possible_object_id = isset( $item->post_type ) && 'nav_menu_item' == $item->post_type ? $item->object_id : $_nav_menu_placeholder; 
    138139                $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; 
    139141 
    140142                $indent = ( $depth ) ? str_repeat( "\t", $depth ) : ''; 
    141143 
     
    147149                // Menu item hidden fields 
    148150                $output .= '<input type="hidden" class="menu-item-db-id" name="menu-item[' . $possible_object_id . '][menu-item-db-id]" value="' . $possible_db_id . '" />'; 
    149151                $output .= '<input type="hidden" class="menu-item-object" name="menu-item[' . $possible_object_id . '][menu-item-object]" value="'. esc_attr( $item->object ) .'" />'; 
    150                 $output .= '<input type="hidden" class="menu-item-parent-id" name="menu-item[' . $possible_object_id . '][menu-item-parent-id]" value="'. esc_attr( $item->post_parent ) .'" />'; 
     152                $output .= '<input type="hidden" class="menu-item-parent-id" name="menu-item[' . $possible_object_id . '][menu-item-parent-id]" value="'. $possible_parent_id .'" />'; 
    151153                $output .= '<input type="hidden" class="menu-item-type" name="menu-item[' . $possible_object_id . '][menu-item-type]" value="'. esc_attr( $item->type ) .'" />'; 
    152154                $output .= '<input type="hidden" class="menu-item-append" name="menu-item[' . $possible_object_id . '][menu-item-append]" value="'. esc_attr( $item->append ) .'" />'; 
    153155                $output .= '<input type="hidden" class="menu-item-title" name="menu-item[' . $possible_object_id . '][menu-item-title]" value="'. esc_attr( $item->title ) .'" />'; 
  • wp-includes/nav-menu.php

     
    5050         
    5151        $menu_obj = wp_get_nav_menu_object( $menu ); 
    5252 
    53         if ( $menu_obj && ! is_wp_error( $menu_obj ) && ! empty( $menu_obj->term_id ) )  
     53        if (  
     54                $menu_obj &&  
     55                ! is_wp_error( $menu_obj ) &&  
     56                ! empty( $menu_obj->taxonomy ) && 
     57                'nav_menu' == $menu_obj->taxonomy 
     58        )  
    5459                return true; 
    5560         
    5661        return false; 
     
    143148 * 
    144149 * @param int $menu_id The ID of the menu 
    145150 * @param array $menu_data The array of menu data. 
    146  * @return int The menu's ID. 
     151 * @return int|error object The menu's ID or WP_Error object. 
    147152 */ 
    148153function wp_update_nav_menu_object( $menu_id = 0, $menu_data = array() ) { 
    149154        $menu_id = (int) $menu_id; 
     
    151156        $_menu = wp_get_nav_menu_object( $menu_id ); 
    152157 
    153158        // menu doesn't already exist 
    154         if ( ! $_menu || is_wp_error( $_menu ) ) { 
     159        if ( ! $_menu || is_wp_error( $_menu ) ) 
    155160                $_menu = wp_create_nav_menu( $menu_data['menu-name'] ); 
    156         } 
    157161 
    158         if ( $_menu && isset( $_menu->term_id ) && ! is_wp_error( $_menu ) ) { 
     162        if ( is_wp_error( $_menu ) ) 
     163                return $_menu; 
     164 
     165        if ( $_menu && isset( $_menu->term_id ) ) { 
    159166                $args = array(  
    160167                        'description' => ( isset( $menu_data['description'] ) ? $menu_data['description'] : '' ),  
    161168                        'name' => ( isset( $menu_data['menu-name'] ) ? $menu_data['menu-name'] : '' ),  
     
    167174 
    168175                $update_response = wp_update_term( $menu_id, 'nav_menu', $args ); 
    169176 
    170                 if ( ! is_wp_error( $update_response ) ) { 
     177                if ( ! is_wp_error( $update_response ) ) 
    171178                        return $menu_id; 
    172                 } 
     179                else 
     180                        return $update_response; 
    173181        } else { 
    174182                return 0; 
    175183        } 
     
    237245                } 
    238246        } 
    239247         
     248        if ( 'custom' != $args['menu-item-type'] ) { 
     249                /* if non-custom menu item, then: 
     250                        * use original object's URL 
     251                        * blank default title to sync with original object's 
     252                */ 
     253 
     254                $args['menu-item-url'] = ''; 
     255 
     256                $original_title = ''; 
     257                if ( 'taxonomy' == $args['menu-item-type'] ) { 
     258                        $original_title = get_term_field( 'name', $args['menu-item-object-id'], $args['menu-item-object'], 'raw' ); 
     259                } elseif ( 'post_type' == $args['menu-item-type'] ) { 
     260                        $original_object = get_post( $args['menu-item-object-id'] ); 
     261                        $original_title = $original_object->post_title; 
     262                } 
     263 
     264                if ( empty( $args['menu-item-title'] ) || $args['menu-item-title'] == $original_title ) { 
     265                        $args['menu-item-title'] = ''; 
     266 
     267                        // hack to get wp to create a post object when too many properties are empty 
     268                        if ( empty( $args['menu-item-description'] ) ) { 
     269                                $args['menu-item-description'] = ' '; 
     270                        } 
     271                } 
     272        } 
     273 
    240274        // Populate the menu item object 
    241275        $post = array( 
    242276                'menu_order' => $args['menu-item-position'], 
     
    363397 
    364398                $items = get_posts( $args ); 
    365399 
     400                if ( is_wp_error( $items ) || ! is_array( $items ) ) { 
     401                        return false; 
     402                } 
     403 
     404                $items = array_map( 'wp_setup_nav_menu_item', $items ); 
     405 
    366406                if ( ARRAY_A == $args['output'] ) { 
    367407                        $GLOBALS['_menu_item_sort_prop'] = $args['output_key']; 
    368408                        usort($items, '_sort_nav_menu_items'); 
     
    410450                                $object = get_post_type_object( $menu_item->object ); 
    411451                                $menu_item->append = $object->singular_label; 
    412452                                $menu_item->url = get_permalink( $menu_item->object_id ); 
     453                         
     454                                $original_object = get_post( $menu_item->object_id ); 
     455                                $original_title = $original_object->post_title; 
     456                                $menu_item->title = '' == $menu_item->post_title ? $original_title : $menu_item->post_title; 
    413457 
    414458                        } elseif ( 'taxonomy' == $menu_item->type ) { 
    415459                                $object = get_taxonomy( $menu_item->object ); 
    416460                                $menu_item->append = $object->singular_label; 
    417461                                $menu_item->url = get_term_link( (int) $menu_item->object_id, $menu_item->object ); 
    418462 
     463                                $original_title = get_term_field( 'name', $menu_item->object_id, $menu_item->object, 'raw' ); 
     464                                $menu_item->title = '' == $menu_item->post_title ? $original_title : $menu_item->post_title; 
     465 
    419466                        } else { 
    420467                                $menu_item->append = __('Custom'); 
     468                                $menu_item->title = $menu_item->post_title; 
    421469                                $menu_item->url = get_post_meta( $menu_item->ID, '_menu_item_url', true ); 
    422470                        } 
    423471                         
    424                         $menu_item->title = $menu_item->post_title; 
    425472                        $menu_item->target = get_post_meta( $menu_item->ID, '_menu_item_target', true ); 
    426473 
    427474                        $menu_item->attr_title = strip_tags( $menu_item->post_excerpt ); 
  • wp-admin/includes/nav-menu.php

     
    305305function wp_nav_menu_post_type_meta_boxes() { 
    306306        $post_types = get_post_types( array( 'public' => true ), 'object' ); 
    307307 
    308         if ( !$post_types ) 
     308        if ( ! $post_types ) 
    309309                return; 
    310310 
    311311        foreach ( $post_types as $post_type ) { 
    312                 $id = $post_type->name; 
    313                 add_meta_box( "add-{$id}", $post_type->label, 'wp_nav_menu_item_post_type_meta_box', 'nav-menus', 'side', 'default', $post_type ); 
     312                $post_type = apply_filters( 'nav_menu_meta_box_object', $post_type ); 
     313                if ( $post_type ) { 
     314                        $id = $post_type->name; 
     315                        add_meta_box( "add-{$id}", $post_type->label, 'wp_nav_menu_item_post_type_meta_box', 'nav-menus', 'side', 'default', $post_type ); 
     316                } 
    314317        } 
    315318} 
    316319 
     
    326329                return; 
    327330 
    328331        foreach ( $taxonomies as $tax ) { 
    329                 $id = $tax->name; 
    330                 add_meta_box( "add-{$id}", $tax->label, 'wp_nav_menu_item_taxonomy_meta_box', 'nav-menus', 'side', 'default', $tax ); 
     332                $tax = apply_filters( 'nav_menu_meta_box_object', $tax ); 
     333                if ( $tax ) { 
     334                        $id = $tax->name; 
     335                        add_meta_box( "add-{$id}", $tax->label, 'wp_nav_menu_item_taxonomy_meta_box', 'nav-menus', 'side', 'default', $tax ); 
     336                } 
    331337        } 
    332338} 
    333339 
     
    337343 * @since 3.0.0 
    338344 */ 
    339345function wp_nav_menu_item_link_meta_box() { 
    340         static $_placeholder; 
    341         $_placeholder = 0 > $_placeholder ? $_placeholder - 1 : -1; 
     346        global $_nav_menu_placeholder; 
     347        $_nav_menu_placeholder = 0 > $_nav_menu_placeholder ? $_nav_menu_placeholder - 1 : -1; 
    342348 
    343349        // @note: hacky query, see #12660 
    344350        $args = array( 'post_type' => 'nav_menu_item', 'post_status' => 'any', 'meta_key' => '_menu_item_type', 'numberposts' => -1, 'orderby' => 'title', ); 
     
    364370        <div class="customlinkdiv"> 
    365371                <ul id="customlink-tabs" class="customlink-tabs add-menu-item-tabs"> 
    366372                        <li <?php echo ( 'create' == $current_tab ? ' class="tabs"' : '' ); ?>><a class="menu-tab-link" href="<?php echo add_query_arg('customlink-tab', 'create', remove_query_arg($removed_args)); ?>#tabs-panel-create-custom"><?php _e('Create New'); ?></a></li> 
    367                         <li <?php echo ( 'all' == $current_tab ? ' class="tabs"' : '' ); ?>><a class="menu-tab-link" href="<?php echo add_query_arg('customlink-tab', 'all', remove_query_arg($removed_args)); ?>#tabs-panel-all-custom"><?php _e('View All'); ?></a></li> 
    368373                </ul> 
    369374 
    370375                <div class="tabs-panel <?php  
    371376                        echo ( 'create' == $current_tab ? 'tabs-panel-active' : 'tabs-panel-inactive' ); 
    372377                ?>" id="tabs-panel-create-custom"> 
    373                         <input type="hidden" value="custom" name="menu-item[<?php echo $_placeholder; ?>][menu-item-type]" /> 
     378                        <input type="hidden" value="custom" name="menu-item[<?php echo $_nav_menu_placeholder; ?>][menu-item-type]" /> 
    374379                        <p id="menu-item-url-wrap"> 
    375380                                <label class="howto" for="custom-menu-item-url"> 
    376381                                        <span><?php _e('URL'); ?></span> 
    377                                         <input id="custom-menu-item-url" name="menu-item[<?php echo $_placeholder; ?>][menu-item-url]" type="text" class="code menu-item-textbox" value="http://" /> 
     382                                        <input id="custom-menu-item-url" name="menu-item[<?php echo $_nav_menu_placeholder; ?>][menu-item-url]" type="text" class="code menu-item-textbox" value="http://" /> 
    378383                                </label> 
    379384                        </p> 
    380385 
    381386                        <p id="menu-item-name-wrap"> 
    382387                                <label class="howto" for="custom-menu-item-name"> 
    383388                                        <span><?php _e('Text'); ?></span> 
    384                                         <input id="custom-menu-item-name" name="menu-item[<?php echo $_placeholder; ?>][menu-item-title]" type="text" class="regular-text menu-item-textbox" value="<?php echo esc_attr( __('Menu Item') ); ?>" /> 
     389                                        <input id="custom-menu-item-name" name="menu-item[<?php echo $_nav_menu_placeholder; ?>][menu-item-title]" type="text" class="regular-text menu-item-textbox" value="<?php echo esc_attr( __('Menu Item') ); ?>" /> 
    385390                                </label> 
    386391                        </p> 
    387392                </div><!-- /.tabs-panel --> 
    388393 
    389                 <div class="tabs-panel <?php  
    390                         echo ( 'all' == $current_tab ? 'tabs-panel-active' : 'tabs-panel-inactive' ); 
    391                 ?>" id="tabs-panel-all-custom"> 
    392                         <ul id="customlinkchecklist" class="list:customlink customlinkchecklist form-no-clear"> 
    393                                 <?php 
    394                                 $args['walker'] = new Walker_Nav_Menu_Checklist; 
    395                                 echo walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', $links), 0, (object) $args ); 
    396                                 ?> 
    397                         </ul> 
    398                 </div><!-- /.tabs-panel --> 
    399  
    400394                <p class="button-controls"> 
    401395                        <span class="add-to-menu"> 
    402396                                <input type="submit" class="button-secondary" value="<?php esc_attr_e('Add to Menu'); ?>" name="add-custom-menu-item" /> 
     
    433427                'suppress_filters' => true,  
    434428        ); 
    435429 
     430        if ( isset( $post_type['args']->_default_query ) ) 
     431                $args = array_merge($args, (array) $post_type['args']->_default_query ); 
     432 
    436433        // @todo transient caching of these results with proper invalidation on updating of a post of this type 
    437434        $get_posts = new WP_Query; 
    438435        $posts = $get_posts->query( $args ); 
     
    810807} 
    811808 
    812809/** 
     810 * Adds custom arguments to some of the meta box object types. 
     811 * 
     812 * @since 3.0.0 
     813 *  
     814 * @access private 
     815 * 
     816 * @param object $object The post type or taxonomy meta-object. 
     817 * @return object The post type of taxonomy object. 
     818 */ 
     819function _wp_nav_menu_meta_box_object( $object = null ) { 
     820        if ( isset( $object->name ) ) { 
     821                // don't show media meta box 
     822                if ( 'attachment' == $object->name ) 
     823                        return false; 
     824         
     825                // pages should show most recent 
     826                if ( 'page' == $object->name ) { 
     827                        $object->_default_query = array( 
     828                                'orderby' => 'post_date', 
     829                                'order' => 'DESC', 
     830                                'post_status' => 'publish', 
     831                        ); 
     832 
     833                // posts should show only published items 
     834                } elseif ( 'post' == $object->name ) { 
     835                        $object->_default_query = array( 
     836                                'post_status' => 'publish', 
     837                        ); 
     838 
     839                // cats should be in reverse chronological order 
     840                } elseif ( 'category' == $object->name ) { 
     841                        $object->_default_query = array( 
     842                                'orderby' => 'id', 
     843                                'order' => 'DESC', 
     844                        ); 
     845                } 
     846        } 
     847         
     848        return $object; 
     849} 
     850 
     851/** 
    813852 * Returns the menu item formatted to edit. 
    814853 * 
    815854 * @since 3.0.0 
     
    818857 * @return string|WP_Error $output The menu formatted to edit or error object on failure. 
    819858 */ 
    820859function wp_get_nav_menu_to_edit( $menu_item_id = 0 ) { 
    821         static $_placeholder; 
    822          
    823860        $menu = wp_get_nav_menu_object( $menu_item_id ); 
    824861         
    825862        // If the menu exists, get its items. 
  • wp-admin/js/nav-menu.dev.js

     
    159159                if ( ! list ) 
    160160                        return; 
    161161 
    162                 var menuListItems = list.getElementsByTagName('li'), 
     162                var dummyListItem = document.getElementById(list.id + '-dummy-list-item'), 
     163                menuListItems = list.getElementsByTagName('li'), 
    163164                i = menuListItems.length; 
     165 
     166                if ( ! dummyListItem ) { 
     167                        dummyListItem = document.createElement('li'); 
     168                        dummyListItem.id = list.id + '-dummy-list-item'; 
     169                        list.appendChild(dummyListItem); 
     170                        this.setupListItemDragAndDrop(dummyListItem); 
     171                } 
    164172                 
    165173                while ( i-- ) 
    166174                        this.setupListItemDragAndDrop(menuListItems[i]); 
     
    234242                attachTabsPanelListeners : function() { 
    235243                        $('#menu-settings-column').bind('click', function(e) { 
    236244                                if ( e.target && e.target.className && -1 != e.target.className.indexOf('menu-tab-link') ) { 
    237                                         var i = e.target.parentNode, 
    238                                         activePanel, 
     245                                        var activePanel, 
    239246                                        panelIdMatch = /#(.*)$/.exec(e.target.href), 
    240                                         tabPanels; 
    241                                         while ( ! i.className || -1 == i.className.indexOf('inside') ) { 
    242                                                 i = i.parentNode; 
    243                                         } 
    244                                         $('.tabs-panel', i).each(function() { 
     247                                        tabPanels, 
     248                                        wrapper = getParentWrapper(e.target, 'inside'), 
     249                                        inputs = wrapper ? wrapper.getElementsByTagName('input') : [], 
     250                                        i = inputs.length; 
     251 
     252                                        // upon changing tabs, we want to uncheck all checkboxes 
     253                                        while( i-- )  
     254                                                inputs[i].checked = false; 
     255 
     256                                        $('.tabs-panel', wrapper).each(function() { 
    245257                                                if ( this.className ) 
    246258                                                        this.className = this.className.replace('tabs-panel-active', 'tabs-panel-inactive'); 
    247259                                        }); 
    248260 
    249                                         $('.tabs', i).each(function() { 
     261                                        $('.tabs', wrapper).each(function() { 
    250262                                                this.className = this.className.replace('tabs', ''); 
    251263                                        }); 
    252264 
     
    396408                                        if ( that != currentDropzone || ( ! activeHovering && that.className && -1 != that.className.indexOf('sortable-placeholder') ) ) { 
    397409                                                that.className = that.className.replace(/sortable-placeholder/g, ''); 
    398410                                        } 
    399                                 }, 500); 
     411                                }, 800); 
    400412                        })(dropEl); 
    401413                }, 
    402414 
     
    563575                        if ( ! req ) 
    564576                                req = {}; 
    565577                        var dropZone, 
     578                        dummyListItem = document.getElementById(menuList.id + '-dummy-list-item'), 
    566579                        i, 
    567580                        listElements, 
    568581                        wrap = document.createElement('ul'); 
     
    572585                        i = listElements.length; 
    573586                        while ( i-- ) { 
    574587                                this.setupListItemDragAndDrop(listElements[i]); 
    575                                 menuList.appendChild(listElements[i]); 
     588                                if ( dummyListItem ) 
     589                                        menuList.insertBefore(listElements[i], dummyListItem); 
     590                                else 
     591                                        menuList.appendChild(listElements[i]); 
    576592                        } 
    577593 
     594                        this.recalculateSortOrder(menuList); 
     595 
    578596                        /* set custom link form back to defaults */ 
    579597                        if ( customLinkNameInput && customLinkURLInput ) {  
    580598                                customLinkNameInput.value = customLinkNameDefault;