Make WordPress Core

Changeset 53504


Ignore:
Timestamp:
06/15/2022 10:18:02 AM (2 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.