Make WordPress Core

Changeset 53504


Ignore:
Timestamp:
06/15/2022 10:18:02 AM (4 years ago)
Author:
spacedmonkey
Message:

REST API: Prime caches for linked objects in menu item REST API controller.

Add a new parameter to WP_Query called update_menu_item_cache that when set to true, primes the caches for linked terms and posts for menu item post objects. This change moves logic
found in wp_get_nav_menu_items into a new function called update_menu_item_cache. Update the menu item REST API controller, to pass the update_menu_item_cache parameter to the
arguments used for the WP_Query run to get menu items.

Props furi3r, TimothyBlynJacobs, spacedmonkey, peterwilsoncc, mitogh.
Fixes #55620.

--This line, and those below, will be ignored--

M src/wp-includes/class-wp-query.php
M src/wp-includes/nav-menu.php
M src/wp-includes/rest-api/endpoints/class-wp-rest-menu-items-controller.php
M tests/phpunit/tests/post/nav-menu.php

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-wp-query.php

    r53483 r53504  
    757757         *     @type bool            $update_post_meta_cache  Whether to update the post meta cache. Default true.
    758758         *     @type bool            $update_post_term_cache  Whether to update the post term cache. Default true.
     759         *     @type bool            $update_menu_item_cache  Whether to update the menu item cache. Default false.
    759760         *     @type bool            $lazy_load_term_meta     Whether to lazy-load term meta. Setting to false will
    760761         *                                                    disable cache priming for term meta, so that each
     
    18721873                }
    18731874
     1875                if ( ! isset( $q['update_menu_item_cache'] ) ) {
     1876                        $q['update_menu_item_cache'] = false;
     1877                }
     1878
    18741879                if ( ! isset( $q['lazy_load_term_meta'] ) ) {
    18751880                        $q['lazy_load_term_meta'] = $q['update_post_term_cache'];
     
    31463151                        /** @var WP_Post[] */
    31473152                        $this->posts = array_map( 'get_post', $this->posts );
     3153                }
     3154
     3155                if ( ! empty( $this->posts ) && $q['update_menu_item_cache'] ) {
     3156                        update_menu_item_cache( $this->posts );
    31483157                }
    31493158
  • trunk/src/wp-includes/nav-menu.php

    r53455 r53504  
    692692        }
    693693
    694         static $fetched = array();
    695 
    696694        if ( ! taxonomy_exists( 'nav_menu' ) ) {
    697695                return false;
     
    699697
    700698        $defaults = array(
    701                 'order'       => 'ASC',
    702                 'orderby'     => 'menu_order',
    703                 'post_type'   => 'nav_menu_item',
    704                 'post_status' => 'publish',
    705                 'output'      => ARRAY_A,
    706                 'output_key'  => 'menu_order',
    707                 'nopaging'    => true,
    708                 'tax_query'   => array(
     699                'order'                  => 'ASC',
     700                'orderby'                => 'menu_order',
     701                'post_type'              => 'nav_menu_item',
     702                'post_status'            => 'publish',
     703                'output'                 => ARRAY_A,
     704                'output_key'             => 'menu_order',
     705                'nopaging'               => true,
     706                'update_menu_item_cache' => true,
     707                'tax_query'              => array(
    709708                        array(
    710709                                'taxonomy' => 'nav_menu',
     
    721720        }
    722721
    723         // Prime posts and terms caches.
    724         if ( empty( $fetched[ $menu->term_id ] ) ) {
    725                 $fetched[ $menu->term_id ] = true;
    726                 $post_ids                  = array();
    727                 $term_ids                  = array();
    728                 foreach ( $items as $item ) {
    729                         $object_id = get_post_meta( $item->ID, '_menu_item_object_id', true );
    730                         $type      = get_post_meta( $item->ID, '_menu_item_type', true );
    731 
    732                         if ( 'post_type' === $type ) {
    733                                 $post_ids[] = (int) $object_id;
    734                         } elseif ( 'taxonomy' === $type ) {
    735                                 $term_ids[] = (int) $object_id;
    736                         }
    737                 }
    738 
    739                 if ( ! empty( $post_ids ) ) {
    740                         _prime_post_caches( $post_ids, false );
    741                 }
    742                 unset( $post_ids );
    743 
    744                 if ( ! empty( $term_ids ) ) {
    745                         _prime_term_caches( $term_ids );
    746                 }
    747                 unset( $term_ids );
    748         }
    749 
    750722        $items = array_map( 'wp_setup_nav_menu_item', $items );
    751723
     
    779751         */
    780752        return apply_filters( 'wp_get_nav_menu_items', $items, $menu, $args );
     753}
     754
     755/**
     756 * Prime all linked objects to menu items.
     757 *
     758 * @since 6.1.0
     759 *
     760 * @param WP_Post[] $menu_items Array post objects of menu items.
     761 */
     762function update_menu_item_cache( $menu_items ) {
     763        $post_ids = array();
     764        $term_ids = array();
     765
     766        foreach ( $menu_items as $menu_item ) {
     767                if ( 'nav_menu_item' !== $menu_item->post_type ) {
     768                        continue;
     769                }
     770                $object_id = get_post_meta( $menu_item->ID, '_menu_item_object_id', true );
     771                $type      = get_post_meta( $menu_item->ID, '_menu_item_type', true );
     772
     773                if ( 'post_type' === $type ) {
     774                        $post_ids[] = (int) $object_id;
     775                } elseif ( 'taxonomy' === $type ) {
     776                        $term_ids[] = (int) $object_id;
     777                }
     778        }
     779
     780        if ( ! empty( $post_ids ) ) {
     781                _prime_post_caches( $post_ids, false );
     782        }
     783
     784        if ( ! empty( $term_ids ) ) {
     785                _prime_term_caches( $term_ids );
     786        }
    781787}
    782788
  • trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-menu-items-controller.php

    r53455 r53504  
    999999                }
    10001000
     1001                $query_args['update_menu_item_cache'] = true;
     1002
    10011003                return $query_args;
    10021004        }
  • trunk/tests/phpunit/tests/post/nav-menu.php

    r52389 r53504  
    204204
    205205        /**
     206         * @ticket 55620
     207         */
     208        public function test_update_menu_item_cache_primed_post() {
     209                $post_id = self::factory()->post->create();
     210                wp_update_nav_menu_item(
     211                        $this->menu_id,
     212                        0,
     213                        array(
     214                                'menu-item-type'      => 'post_type',
     215                                'menu-item-object'    => 'post',
     216                                'menu-item-object-id' => $post_id,
     217                                'menu-item-status'    => 'publish',
     218                        )
     219                );
     220
     221                $posts_query  = new WP_Query();
     222                $query_result = $posts_query->query( array( 'post_type' => 'nav_menu_item' ) );
     223
     224                wp_cache_delete( $post_id, 'posts' );
     225                $action = new MockAction();
     226                add_filter( 'update_post_metadata_cache', array( $action, 'filter' ), 10, 2 );
     227
     228                update_menu_item_cache( $query_result );
     229
     230                $args = $action->get_args();
     231                $last = end( $args );
     232                $this->assertEqualSets( array( $post_id ), $last[1], '_prime_post_caches was not executed.' );
     233        }
     234
     235        /**
     236         * @ticket 55620
     237         */
     238        public function test_update_menu_item_cache_primed_terms() {
     239                register_taxonomy( 'wptests_tax', 'post', array( 'hierarchical' => true ) );
     240                $term_id = self::factory()->term->create( array( 'taxonomy' => 'wptests_tax' ) );
     241                wp_update_nav_menu_item(
     242                        $this->menu_id,
     243                        0,
     244                        array(
     245                                'menu-item-type'      => 'taxonomy',
     246                                'menu-item-object'    => 'wptests_tax',
     247                                'menu-item-object-id' => $term_id,
     248                                'menu-item-status'    => 'publish',
     249                        )
     250                );
     251
     252                $posts_query  = new WP_Query();
     253                $query_result = $posts_query->query( array( 'post_type' => 'nav_menu_item' ) );
     254
     255                wp_cache_delete( $term_id, 'terms' );
     256                $action = new MockAction();
     257                add_filter( 'update_term_metadata_cache', array( $action, 'filter' ), 10, 2 );
     258
     259                update_menu_item_cache( $query_result );
     260
     261                $args = $action->get_args();
     262                $last = end( $args );
     263                $this->assertEqualSets( array( $term_id ), $last[1], '_prime_term_caches was not executed.' );
     264        }
     265
     266        /**
    206267         * @ticket 13910
    207268         */
Note: See TracChangeset for help on using the changeset viewer.