WordPress.org

Make WordPress Core

Ticket #32769: 32769.4.diff

File 32769.4.diff, 12.1 KB (added by westonruter, 5 years ago)
  • src/wp-includes/class-wp-customize-nav-menus.php

    diff --git src/wp-includes/class-wp-customize-nav-menus.php src/wp-includes/class-wp-customize-nav-menus.php
    index 3ff1961..75fb5b5 100644
    final class WP_Customize_Nav_Menus { 
    493493                        $menu_items = (array) wp_get_nav_menu_items( $menu_id );
    494494
    495495                        foreach ( array_values( $menu_items ) as $i => $item ) {
    496 
    497496                                // Create a setting for each menu item (which doesn't actually manage data, currently).
    498497                                $menu_item_setting_id = 'nav_menu_item[' . $item->ID . ']';
    499                                 $this->manager->add_setting( new WP_Customize_Nav_Menu_Item_Setting( $this->manager, $menu_item_setting_id ) );
     498
     499                                $value = (array) $item;
     500                                $value['nav_menu_term_id'] = $menu_id;
     501                                $this->manager->add_setting( new WP_Customize_Nav_Menu_Item_Setting( $this->manager, $menu_item_setting_id, array(
     502                                        'value' => $value,
     503                                ) ) );
    500504
    501505                                // Create a control for each menu item.
    502506                                $this->manager->add_control( new WP_Customize_Nav_Menu_Item_Control( $this->manager, $menu_item_setting_id, array(
  • src/wp-includes/class-wp-customize-setting.php

    diff --git src/wp-includes/class-wp-customize-setting.php src/wp-includes/class-wp-customize-setting.php
    index 7f14187..b585692 100644
    class WP_Customize_Nav_Menu_Item_Setting extends WP_Customize_Setting { 
    701701         *
    702702         * A negative value represents a placeholder ID for a new menu not yet saved.
    703703         *
    704          * @todo Should this be $db_id, and also use this for WP_Customize_Nav_Menu_Setting::$term_id
    705          *
    706704         * @since 4.3.0
    707705         * @access public
    708706         * @var int
    class WP_Customize_Nav_Menu_Item_Setting extends WP_Customize_Setting { 
    710708        public $post_id;
    711709
    712710        /**
     711         * Storage of pre-setup menu item to prevent wasted calls to wp_setup_nav_menu_item().
     712         *
     713         * @since 4.3.0
     714         * @access protected
     715         * @var array
     716         */
     717        protected $value;
     718
     719        /**
    713720         * Previous (placeholder) post ID used before creating a new menu item.
    714721         *
    715722         * This value will be exported to JS via the customize_save_response filter
    class WP_Customize_Nav_Menu_Item_Setting extends WP_Customize_Setting { 
    806813                }
    807814
    808815                $this->post_id = intval( $matches['id'] );
    809 
    810                 $menu = $this->value();
    811                 $this->original_nav_menu_term_id = $menu['nav_menu_term_id'];
     816                add_action( 'wp_update_nav_menu_item', array( $this, 'flush_cached_value' ), 10, 2 );
    812817
    813818                parent::__construct( $manager, $id, $args );
     819
     820                // Ensure that an initially-supplied value is valid.
     821                if ( isset( $this->value ) ) {
     822                        $this->populate_value();
     823                        foreach ( array_diff( array_keys( $this->default ), array_keys( $this->value ) ) as $missing ) {
     824                                throw new Exception( "Supplied nav_menu_item value missing property: $missing" );
     825                        }
     826                }
     827
     828        }
     829
     830        /**
     831         * Clear the cached value when a nav menu item is updated.
     832         *
     833         * @since 4.3.0
     834         * @access public
     835         *
     836         * @param int $menu_id       The term ID for the menu.
     837         * @param int $menu_item_id  The post ID for the menu item.
     838         */
     839        public function flush_cached_value( $menu_id, $menu_item_id ) {
     840                unset( $menu_id );
     841                if ( $menu_item_id === $this->post_id ) {
     842                        $this->value = null;
     843                }
    814844        }
    815845
    816846        /**
    class WP_Customize_Nav_Menu_Item_Setting extends WP_Customize_Setting { 
    821851         *
    822852         * @see wp_setup_nav_menu_item()
    823853         *
    824          * @return array Instance data.
     854         * @return array|false Instance data array, or false if the item is marked for deletion.
    825855         */
    826856        public function value() {
    827857                if ( $this->is_previewed && $this->_previewed_blog_id === get_current_blog_id() ) {
    class WP_Customize_Nav_Menu_Item_Setting extends WP_Customize_Setting { 
    833863                        } else {
    834864                                $value = $post_value;
    835865                        }
     866                } else if ( isset( $this->value ) ) {
     867                        $value = $this->value;
    836868                } else {
    837869                        $value = false;
    838870
    class WP_Customize_Nav_Menu_Item_Setting extends WP_Customize_Setting { 
    840872                        if ( $this->post_id > 0 ) {
    841873                                $post = get_post( $this->post_id );
    842874                                if ( $post && self::POST_TYPE === $post->post_type ) {
    843                                         $item  = wp_setup_nav_menu_item( $post );
    844                                         $value = wp_array_slice_assoc(
    845                                                 (array) $item,
    846                                                 array_keys( $this->default )
    847                                         );
    848                                         $value['position']       = $item->menu_order;
    849                                         $value['status']         = $item->post_status;
    850                                         $value['original_title'] = '';
    851 
    852                                         $menus = wp_get_post_terms( $post->ID, WP_Customize_Nav_Menu_Setting::TAXONOMY, array(
    853                                                 'fields' => 'ids',
    854                                         ) );
    855 
    856                                         if ( ! empty( $menus ) ) {
    857                                                 $value['nav_menu_term_id'] = array_shift( $menus );
    858                                         } else {
    859                                                 $value['nav_menu_term_id'] = 0;
    860                                         }
    861 
    862                                         if ( 'post_type' === $value['type'] ) {
    863                                                 $original_title = get_the_title( $value['object_id'] );
    864                                         } elseif ( 'taxonomy' === $value['type'] ) {
    865                                                 $original_title = get_term_field( 'name', $value['object_id'], $value['object'], 'raw' );
    866                                                 if ( is_wp_error( $original_title ) ) {
    867                                                         $original_title = '';
    868                                                 }
    869                                         }
    870 
    871                                         if ( ! empty( $original_title ) ) {
    872                                                 $value['original_title'] = html_entity_decode( $original_title, ENT_QUOTES, get_bloginfo( 'charset' ) );
    873                                         }
     875                                        $value = (array) wp_setup_nav_menu_item( $post );
    874876                                }
    875877                        }
    876878
    877879                        if ( ! is_array( $value ) ) {
    878880                                $value = $this->default;
    879881                        }
     882
     883                        // Cache the value for future calls to avoid having to re-call wp_setup_nav_menu_item().
     884                        $this->value = $value;
     885                        $this->populate_value();
     886                        $value = $this->value;
    880887                }
    881888
    882                 if ( is_array( $value ) ) {
    883                         foreach ( array( 'object_id', 'menu_item_parent', 'nav_menu_term_id' ) as $key ) {
    884                                 $value[ $key ] = intval( $value[ $key ] );
     889                return $value;
     890        }
     891
     892        /**
     893         * Ensure that the value is fully populated with the necessary properties.
     894         *
     895         * Translates some properties added by {@see wp_setup_nav_menu_item()} and
     896         * removes others.
     897         *
     898         * @since 4.3.0
     899         * @access protected
     900         *
     901         * @see WP_Customize_Nav_Menu_Item_Setting::value()
     902         */
     903        protected function populate_value() {
     904                if ( ! is_array( $this->value ) ) {
     905                        return;
     906                }
     907
     908                if ( isset( $this->value['menu_order'] ) ) {
     909                        $this->value['position'] = $this->value['menu_order'];
     910                        unset( $this->value['menu_order'] );
     911                }
     912                if ( isset( $this->value['post_status'] ) ) {
     913                        $this->value['status'] = $this->value['post_status'];
     914                        unset( $this->value['post_status'] );
     915                }
     916
     917                if ( ! isset( $this->value['original_title'] ) ) {
     918                        $original_title = '';
     919                        if ( 'post_type' === $this->value['type'] ) {
     920                                $original_title = get_the_title( $this->value['object_id'] );
     921                        } elseif ( 'taxonomy' === $this->value['type'] ) {
     922                                $original_title = get_term_field( 'name', $this->value['object_id'], $this->value['object'], 'raw' );
     923                                if ( is_wp_error( $original_title ) ) {
     924                                        $original_title = '';
     925                                }
    885926                        }
     927                        $this->value['original_title'] = html_entity_decode( $original_title, ENT_QUOTES, get_bloginfo( 'charset' ) );
    886928                }
    887929
    888                 return $value;
     930                if ( ! isset( $this->value['nav_menu_term_id'] ) && $this->post_id > 0 ) {
     931                        $menus = wp_get_post_terms( $this->post_id, WP_Customize_Nav_Menu_Setting::TAXONOMY, array(
     932                                'fields' => 'ids',
     933                        ) );
     934                        if ( ! empty( $menus ) ) {
     935                                $this->value['nav_menu_term_id'] = array_shift( $menus );
     936                        } else {
     937                                $this->value['nav_menu_term_id'] = 0;
     938                        }
     939                }
     940
     941                foreach ( array( 'object_id', 'menu_item_parent', 'nav_menu_term_id' ) as $key ) {
     942                        if ( ! is_int( $this->value[ $key ] ) ) {
     943                                $this->value[ $key ] = intval( $this->value[ $key ] );
     944                        }
     945                }
     946
     947                // Remove remaining properties available on a setup nav_menu_item post object which aren't relevant to the setting value.
     948                $irrelevant_properties = array(
     949                        'ID',
     950                        'comment_count',
     951                        'comment_status',
     952                        'db_id',
     953                        'filter',
     954                        'guid',
     955                        'ping_status',
     956                        'pinged',
     957                        'post_author',
     958                        'post_content',
     959                        'post_content_filtered',
     960                        'post_date',
     961                        'post_date_gmt',
     962                        'post_excerpt',
     963                        'post_mime_type',
     964                        'post_modified',
     965                        'post_modified_gmt',
     966                        'post_name',
     967                        'post_parent',
     968                        'post_password',
     969                        'post_title',
     970                        'post_type',
     971                        'to_ping',
     972                        'type_label',
     973                );
     974                foreach ( $irrelevant_properties as $property ) {
     975                        unset( $this->value[ $property ] );
     976                }
    889977        }
    890978
    891979        /**
    class WP_Customize_Nav_Menu_Item_Setting extends WP_Customize_Setting { 
    10431131                $item->menu_order = $item->position;
    10441132                unset( $item->position );
    10451133
    1046                 $item->post_author = get_current_user_id();
    1047 
    10481134                if ( $item->title ) {
    10491135                        $item->post_title = $item->title;
    10501136                }
    10511137
    10521138                $item->ID = $this->post_id;
     1139                $item->db_id = $this->post_id;
    10531140                $post = new WP_Post( (object) $item );
    1054                 $post = wp_setup_nav_menu_item( $post );
    10551141
     1142                if ( empty( $post->post_author ) ) {
     1143                        $post->post_author = get_current_user_id();
     1144                }
     1145
     1146                if ( ! isset( $post->type_label ) ) {
     1147                        $post->type_label = null;
     1148                }
    10561149                return $post;
    10571150        }
    10581151
    class WP_Customize_Nav_Menu_Item_Setting extends WP_Customize_Setting { 
    11601253                $is_placeholder   = ( $this->post_id < 0 );
    11611254                $is_delete        = ( false === $value );
    11621255
     1256                // Update the cached value.
     1257                $this->value = $value;
     1258
    11631259                add_filter( 'customize_save_response', array( $this, 'amend_customize_save_response' ) );
    11641260
    11651261                if ( $is_delete ) {
  • src/wp-includes/nav-menu.php

    diff --git src/wp-includes/nav-menu.php src/wp-includes/nav-menu.php
    index 16213f1..9061ace 100644
    function wp_get_nav_menu_items( $menu, $args = array() ) { 
    658658 * Decorates a menu item object with the shared navigation menu item properties.
    659659 *
    660660 * Properties:
    661  * - db_id:             The DB ID of this item as a nav_menu_item object, if it exists (0 if it doesn't exist).
    662  * - object_id:         The DB ID of the original object this menu item represents, e.g. ID for posts and term_id for categories.
    663  * - type:              The family of objects originally represented, such as "post_type" or "taxonomy."
    664  * - object:            The type of object originally represented, such as "category," "post", or "attachment."
    665  * - type_label:        The singular label used to describe this type of menu item.
    666  * - post_parent:       The DB ID of the original object's parent object, if any (0 otherwise).
    667  * - menu_item_parent:  The DB ID of the nav_menu_item that is this item's menu parent, if any. 0 otherwise.
    668  * - url:               The URL to which this menu item points.
    669  * - title:             The title of this menu item.
    670  * - target:            The target attribute of the link element for this menu item.
    671  * - attr_title:        The title attribute of the link element for this menu item.
    672  * - classes:           The array of class attribute values for the link element of this menu item.
    673  * - xfn:               The XFN relationship expressed in the link of this menu item.
    674  * - description:       The description of this menu item.
     661 * - ID:               The term_id if the menu item represents a taxonomy term.
     662 * - attr_title:       The title attribute of the link element for this menu item.
     663 * - classes:          The array of class attribute values for the link element of this menu item.
     664 * - db_id:            The DB ID of this item as a nav_menu_item object, if it exists (0 if it doesn't exist).
     665 * - description:      The description of this menu item.
     666 * - menu_item_parent: The DB ID of the nav_menu_item that is this item's menu parent, if any. 0 otherwise.
     667 * - object:           The type of object originally represented, such as "category," "post", or "attachment."
     668 * - object_id:        The DB ID of the original object this menu item represents, e.g. ID for posts and term_id for categories.
     669 * - post_parent:      The DB ID of the original object's parent object, if any (0 otherwise).
     670 * - post_title:       A "no title" label if menu item represents a post that lacks a title.
     671 * - target:           The target attribute of the link element for this menu item.
     672 * - title:            The title of this menu item.
     673 * - type:             The family of objects originally represented, such as "post_type" or "taxonomy."
     674 * - type_label:       The singular label used to describe this type of menu item.
     675 * - url:              The URL to which this menu item points.
     676 * - xfn:              The XFN relationship expressed in the link of this menu item.
     677 * - _invalid:         Whether the menu item represents an object that no longer exists.
    675678 *
    676679 * @since 3.0.0
    677680 *