From ef33fd1841097cb4de122742b414f190595ffca7 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Fri, 4 Nov 2016 07:23:49 +0000 Subject: [PATCH] Customize: Ensure page/post stubs are included in listings and searches for available nav menu items. Include the customized state in the Ajax requests to load items and search items. See #38573. Fixes #38122. git-svn-id: https://develop.svn.wordpress.org/trunk@39138 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/js/customize-nav-menus.js | 14 ++-- .../class-wp-customize-nav-menus.php | 65 +++++++++++++------ tests/phpunit/tests/ajax/CustomizeMenus.php | 18 ++++- 3 files changed, 72 insertions(+), 25 deletions(-) diff --git a/src/wp-admin/js/customize-nav-menus.js b/src/wp-admin/js/customize-nav-menus.js index c51cff32cc..5e4e5f9056 100644 --- a/src/wp-admin/js/customize-nav-menus.js +++ b/src/wp-admin/js/customize-nav-menus.js @@ -302,12 +302,14 @@ $section.addClass( 'loading' ); self.loading = true; - params = { + + params = api.previewer.query( { excludeCustomizedSaved: true } ); + _.extend( params, { 'customize-menus-nonce': api.settings.nonce['customize-menus'], 'wp_customize': 'on', 'search': self.searchTerm, 'page': page - }; + } ); self.currentRequest = wp.ajax.post( 'search-available-menu-items-customizer', params ); @@ -378,7 +380,7 @@ * @returns {void} */ loadItems: function( itemTypes, deprecated ) { - var self = this, _itemTypes, requestItemTypes = [], request, itemTemplate, availableMenuItemContainers = {}; + var self = this, _itemTypes, requestItemTypes = [], params, request, itemTemplate, availableMenuItemContainers = {}; itemTemplate = wp.template( 'available-menu-item' ); if ( _.isString( itemTypes ) && _.isString( deprecated ) ) { @@ -408,12 +410,16 @@ } self.loading = true; - request = wp.ajax.post( 'load-available-menu-items-customizer', { + + params = api.previewer.query( { excludeCustomizedSaved: true } ); + _.extend( params, { 'customize-menus-nonce': api.settings.nonce['customize-menus'], 'wp_customize': 'on', 'item_types': requestItemTypes } ); + request = wp.ajax.post( 'load-available-menu-items-customizer', params ); + request.done(function( data ) { var typeInner; _.each( data.items, function( typeItems, name ) { diff --git a/src/wp-includes/class-wp-customize-nav-menus.php b/src/wp-includes/class-wp-customize-nav-menus.php index 89b5b02a4a..37a8de8cb6 100644 --- a/src/wp-includes/class-wp-customize-nav-menus.php +++ b/src/wp-includes/class-wp-customize-nav-menus.php @@ -174,13 +174,25 @@ final class WP_Customize_Nav_Menus { ); } - $posts = get_posts( array( + // Prepend posts with nav_menus_created_posts on first page. + $posts = array(); + if ( 0 === $page && $this->manager->get_setting( 'nav_menus_created_posts' ) ) { + foreach ( $this->manager->get_setting( 'nav_menus_created_posts' )->value() as $post_id ) { + $auto_draft_post = get_post( $post_id ); + if ( $post_type->name === $auto_draft_post->post_type ) { + $posts[] = $auto_draft_post; + } + } + } + + $posts = array_merge( $posts, get_posts( array( 'numberposts' => 10, 'offset' => 10 * $page, 'orderby' => 'date', 'order' => 'DESC', 'post_type' => $object, - ) ); + ) ) ); + foreach ( $posts as $post ) { $post_title = $post->post_title; if ( '' === $post_title ) { @@ -305,27 +317,42 @@ final class WP_Customize_Nav_Menus { $query['s'] = $args['s']; } + $posts = array(); + + // Prepend list of posts with nav_menus_created_posts search results on first page. + $nav_menus_created_posts_setting = $this->manager->get_setting( 'nav_menus_created_posts' ); + if ( 1 === $args['pagenum'] && $nav_menus_created_posts_setting && count( $nav_menus_created_posts_setting ) > 0 ) { + $stub_post_query = new WP_Query( array_merge( + $query, + array( + 'post_status' => 'auto-draft', + 'post__in' => $nav_menus_created_posts_setting->value(), + 'posts_per_page' => -1, + ) + ) ); + $posts = array_merge( $posts, $stub_post_query->posts ); + } + // Query posts. $get_posts = new WP_Query( $query ); + $posts = array_merge( $posts, $get_posts->posts ); - // Check if any posts were found. - if ( $get_posts->post_count ) { - foreach ( $get_posts->posts as $post ) { - $post_title = $post->post_title; - if ( '' === $post_title ) { - /* translators: %d: ID of a post */ - $post_title = sprintf( __( '#%d (no title)' ), $post->ID ); - } - $items[] = array( - 'id' => 'post-' . $post->ID, - 'title' => html_entity_decode( $post_title, ENT_QUOTES, get_bloginfo( 'charset' ) ), - 'type' => 'post_type', - 'type_label' => $post_type_objects[ $post->post_type ]->labels->singular_name, - 'object' => $post->post_type, - 'object_id' => intval( $post->ID ), - 'url' => get_permalink( intval( $post->ID ) ), - ); + // Create items for posts. + foreach ( $posts as $post ) { + $post_title = $post->post_title; + if ( '' === $post_title ) { + /* translators: %d: ID of a post */ + $post_title = sprintf( __( '#%d (no title)' ), $post->ID ); } + $items[] = array( + 'id' => 'post-' . $post->ID, + 'title' => html_entity_decode( $post_title, ENT_QUOTES, get_bloginfo( 'charset' ) ), + 'type' => 'post_type', + 'type_label' => $post_type_objects[ $post->post_type ]->labels->singular_name, + 'object' => $post->post_type, + 'object_id' => intval( $post->ID ), + 'url' => get_permalink( intval( $post->ID ) ), + ); } // Query taxonomy terms. diff --git a/tests/phpunit/tests/ajax/CustomizeMenus.php b/tests/phpunit/tests/ajax/CustomizeMenus.php index 5013701d28..fef7831dfc 100644 --- a/tests/phpunit/tests/ajax/CustomizeMenus.php +++ b/tests/phpunit/tests/ajax/CustomizeMenus.php @@ -322,6 +322,7 @@ class Tests_Ajax_CustomizeMenus extends WP_Ajax_UnitTestCase { * @param array $post_args POST args. */ function test2_ajax_load_available_items_structure( $post_args ) { + do_action( 'customize_register', $this->wp_customize ); $expected_keys = array( 'id', @@ -336,6 +337,9 @@ class Tests_Ajax_CustomizeMenus extends WP_Ajax_UnitTestCase { // Create some terms and pages. self::factory()->term->create_many( 5 ); self::factory()->post->create_many( 5, array( 'post_type' => 'page' ) ); + $auto_draft_post = $this->wp_customize->nav_menus->insert_auto_draft_post( array( 'post_title' => 'Test Auto Draft', 'post_type' => 'post' ) ); + $this->wp_customize->set_post_value( 'nav_menus_created_posts', array( $auto_draft_post->ID ) ); + $this->wp_customize->get_setting( 'nav_menus_created_posts' )->preview(); $_POST = array_merge( array( 'action' => 'load-available-menu-items-customizer', @@ -371,6 +375,9 @@ class Tests_Ajax_CustomizeMenus extends WP_Ajax_UnitTestCase { } } } + } elseif ( 'post' === $test_item['object'] ) { + $item_ids = wp_list_pluck( $response['data']['items']['post_type:post'], 'id' ); + $this->assertContains( 'post-' . $auto_draft_post->ID, $item_ids ); } } @@ -497,8 +504,13 @@ class Tests_Ajax_CustomizeMenus extends WP_Ajax_UnitTestCase { * @param array $expected_results Expected results. */ function test_ajax_search_available_items_results( $post_args, $expected_results ) { + do_action( 'customize_register', $this->wp_customize ); self::factory()->post->create_many( 5, array( 'post_title' => 'Test Post' ) ); + $included_auto_draft_post = $this->wp_customize->nav_menus->insert_auto_draft_post( array( 'post_title' => 'Test Included Auto Draft', 'post_type' => 'post' ) ); + $excluded_auto_draft_post = $this->wp_customize->nav_menus->insert_auto_draft_post( array( 'post_title' => 'Excluded Auto Draft', 'post_type' => 'post' ) ); + $this->wp_customize->set_post_value( 'nav_menus_created_posts', array( $included_auto_draft_post->ID, $excluded_auto_draft_post->ID ) ); + $this->wp_customize->get_setting( 'nav_menus_created_posts' )->preview(); $_POST = array_merge( array( 'action' => 'search-available-menu-items-customizer', @@ -511,11 +523,13 @@ class Tests_Ajax_CustomizeMenus extends WP_Ajax_UnitTestCase { if ( isset( $post_args['search'] ) && 'test' === $post_args['search'] ) { $this->assertsame( true, $response['success'] ); - $this->assertSame( 5, count( $response['data']['items'] ) ); + $this->assertSame( 6, count( $response['data']['items'] ) ); + $item_ids = wp_list_pluck( $response['data']['items'], 'id' ); + $this->assertContains( 'post-' . $included_auto_draft_post->ID, $item_ids ); + $this->assertNotContains( 'post-' . $excluded_auto_draft_post->ID, $item_ids ); } else { $this->assertSame( $expected_results, $response ); } - } /**