diff --git a/lib/class-wp-rest-menu-items-controller.php b/lib/class-wp-rest-menu-items-controller.php index 8329e8772220e..2e82b5337d65d 100644 --- a/lib/class-wp-rest-menu-items-controller.php +++ b/lib/class-wp-rest-menu-items-controller.php @@ -410,7 +410,7 @@ protected function prepare_item_for_database( $request ) { 'menu-item-object-id' => 0, 'menu-item-object' => '', 'menu-item-parent-id' => 0, - 'menu-item-position' => 0, + 'menu-item-position' => 1, 'menu-item-type' => 'custom', 'menu-item-title' => '', 'menu-item-url' => '', @@ -524,51 +524,6 @@ protected function prepare_item_for_database( $request ) { } } - // If menu id is set, valid the value of menu item position and parent id. - if ( ! empty( $prepared_nav_item['menu-id'] ) ) { - // Check if nav menu is valid. - if ( ! is_nav_menu( $prepared_nav_item['menu-id'] ) ) { - return new WP_Error( 'invalid_menu_id', __( 'Invalid menu ID.', 'gutenberg' ), array( 'status' => 400 ) ); - } - - // If menu item position is set to 0, insert as the last item in the existing menu. - $menu_items = wp_get_nav_menu_items( $prepared_nav_item['menu-id'], array( 'post_status' => 'publish,draft' ) ); - if ( 0 === (int) $prepared_nav_item['menu-item-position'] ) { - if ( $menu_items ) { - $last_item = $menu_items[ count( $menu_items ) - 1 ]; - if ( $last_item && isset( $last_item->menu_order ) ) { - $prepared_nav_item['menu-item-position'] = $last_item->menu_order + 1; - } else { - $prepared_nav_item['menu-item-position'] = count( $menu_items ) - 1; - } - array_push( $menu_items, $last_item ); - } else { - $prepared_nav_item['menu-item-position'] = 1; - } - } - - // Check if existing menu position is already in use by another menu item. - $menu_item_ids = array(); - foreach ( $menu_items as $menu_item ) { - $menu_item_ids[] = $menu_item->ID; - if ( $menu_item->ID !== (int) $menu_item_db_id ) { - if ( (int) $prepared_nav_item['menu-item-position'] === (int) $menu_item->menu_order ) { - return new WP_Error( 'invalid_menu_order', __( 'Invalid menu position.', 'gutenberg' ), array( 'status' => 400 ) ); - } - } - } - - // Check if valid parent id is valid nav menu item in menu. - if ( $prepared_nav_item['menu-item-parent-id'] ) { - if ( ! is_nav_menu_item( $prepared_nav_item['menu-item-parent-id'] ) ) { - return new WP_Error( 'invalid_menu_item_parent', __( 'Invalid menu item parent.', 'gutenberg' ), array( 'status' => 400 ) ); - } - if ( ! $menu_item_ids || ! in_array( $prepared_nav_item['menu-item-parent-id'], $menu_item_ids, true ) ) { - return new WP_Error( 'invalid_item_parent', __( 'Invalid menu item parent.', 'gutenberg' ), array( 'status' => 400 ) ); - } - } - } - foreach ( array( 'menu-item-object-id', 'menu-item-parent-id' ) as $key ) { // Note we need to allow negative-integer IDs for previewed objects not inserted yet. $prepared_nav_item[ $key ] = (int) $prepared_nav_item[ $key ]; @@ -750,8 +705,13 @@ public function prepare_item_for_response( $post, $request ) { $base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name; if ( rest_is_field_included( $base, $fields ) ) { - $terms = get_the_terms( $post, $taxonomy->name ); - $data[ $base ] = $terms ? array_values( wp_list_pluck( $terms, 'term_id' ) ) : array(); + $terms = get_the_terms( $post, $taxonomy->name ); + $term_ids = $terms ? array_values( wp_list_pluck( $terms, 'term_id' ) ) : array(); + if ( 'nav_menu' === $taxonomy->name ) { + $data[ $base ] = $term_ids ? array_shift( $term_ids ) : 0; + } else { + $data[ $base ] = $term_ids; + } } } @@ -962,10 +922,11 @@ public function get_item_schema() { 'description' => __( 'The DB ID of the nav_menu_item that is this item\'s menu parent, if any, otherwise 0.', 'gutenberg' ), 'context' => array( 'view', 'edit', 'embed' ), 'type' => 'integer', - 'minimum' => 0, - 'default' => 0, + 'minimum' => 1, + 'default' => 1, ); - $schema['properties']['object'] = array( + + $schema['properties']['object'] = array( 'description' => __( 'The type of object originally represented, such as "category," "post", or "attachment."', 'gutenberg' ), 'context' => array( 'view', 'edit', 'embed' ), 'type' => 'string', diff --git a/packages/edit-navigation/src/store/actions.js b/packages/edit-navigation/src/store/actions.js index 91b2cc7500197..0eb641a12858f 100644 --- a/packages/edit-navigation/src/store/actions.js +++ b/packages/edit-navigation/src/store/actions.js @@ -65,7 +65,7 @@ export const createMissingMenuItems = serializeProcessing( function* ( post ) { data: { title: 'Placeholder', url: 'Placeholder', - menu_order: 0, + menu_order: 1, }, } ); diff --git a/packages/edit-navigation/src/store/test/actions.js b/packages/edit-navigation/src/store/test/actions.js index 0c2bf7c90f681..fc5ca7f5c4a65 100644 --- a/packages/edit-navigation/src/store/test/actions.js +++ b/packages/edit-navigation/src/store/test/actions.js @@ -77,7 +77,7 @@ describe( 'createMissingMenuItems', () => { data: { title: 'Placeholder', url: 'Placeholder', - menu_order: 0, + menu_order: 1, }, } ) ); @@ -200,7 +200,7 @@ describe( 'createMissingMenuItems', () => { data: { title: 'Placeholder', url: 'Placeholder', - menu_order: 0, + menu_order: 1, }, } ) ); diff --git a/phpunit/class-rest-nav-menu-items-controller-test.php b/phpunit/class-rest-nav-menu-items-controller-test.php index 34dd004e162fe..46c55d17653ec 100644 --- a/phpunit/class-rest-nav-menu-items-controller-test.php +++ b/phpunit/class-rest-nav-menu-items-controller-test.php @@ -277,39 +277,47 @@ public function test_create_item_invalid_term() { public function test_create_item_change_position() { wp_set_current_user( self::$admin_id ); $new_menu_id = wp_create_nav_menu( rand_str() ); + $expected = array(); + $actual = array(); for ( $i = 1; $i < 5; $i ++ ) { $request = new WP_REST_Request( 'POST', '/__experimental/menu-items' ); $request->add_header( 'content-type', 'application/x-www-form-urlencoded' ); $params = $this->set_menu_item_data( array( - 'menus' => $new_menu_id, + 'menu_order' => $i, + 'menus' => $new_menu_id, ) ); $request->set_body_params( $params ); $response = rest_get_server()->dispatch( $request ); $this->check_create_menu_item_response( $response ); $data = $response->get_data(); - $this->assertEquals( $data['menu_order'], $i ); + + $expected[] = $i; + $actual[] = $data['menu_order']; } + $this->assertEquals( $actual, $expected ); } /** * */ - public function test_create_item_invalid_position() { + public function test_menu_order_must_be_set() { wp_set_current_user( self::$admin_id ); $new_menu_id = wp_create_nav_menu( rand_str() ); - $request = new WP_REST_Request( 'POST', '/__experimental/menu-items' ); + + $request = new WP_REST_Request( 'POST', '/__experimental/menu-items' ); $request->add_header( 'content-type', 'application/x-www-form-urlencoded' ); $params = $this->set_menu_item_data( array( - 'menu_order' => 1, + 'menu_order' => 0, 'menus' => $new_menu_id, ) ); $request->set_body_params( $params ); $response = rest_get_server()->dispatch( $request ); - $this->check_create_menu_item_response( $response ); + $this->assertErrorResponse( 'rest_invalid_param', $response, 400 ); + $request = new WP_REST_Request( 'POST', '/__experimental/menu-items' ); $request->add_header( 'content-type', 'application/x-www-form-urlencoded' ); $params = $this->set_menu_item_data( @@ -320,8 +328,7 @@ public function test_create_item_invalid_position() { ); $request->set_body_params( $params ); $response = rest_get_server()->dispatch( $request ); - - $this->assertErrorResponse( 'invalid_menu_order', $response, 400 ); + $this->assertEquals( 201, $response->get_status() ); } /** @@ -380,43 +387,6 @@ public function test_create_item_invalid_parent() { $this->assertErrorResponse( 'rest_invalid_param', $response, 400 ); } - /** - * - */ - public function test_create_item_invalid_parent_menu_item() { - wp_set_current_user( self::$admin_id ); - $new_menu_id = wp_create_nav_menu( rand_str() ); - $request = new WP_REST_Request( 'POST', '/__experimental/menu-items' ); - $request->add_header( 'content-type', 'application/x-www-form-urlencoded' ); - $params = $this->set_menu_item_data( - array( - 'menus' => $new_menu_id, - 'parent' => $this->menu_item_id, - ) - ); - $request->set_body_params( $params ); - $response = rest_get_server()->dispatch( $request ); - $this->assertErrorResponse( 'invalid_item_parent', $response, 400 ); - } - - /** - * - */ - public function test_create_item_invalid_parent_post() { - wp_set_current_user( self::$admin_id ); - $post_id = self::factory()->post->create(); - $request = new WP_REST_Request( 'POST', '/__experimental/menu-items' ); - $request->add_header( 'content-type', 'application/x-www-form-urlencoded' ); - $params = $this->set_menu_item_data( - array( - 'parent' => $post_id, - ) - ); - $request->set_body_params( $params ); - $response = rest_get_server()->dispatch( $request ); - $this->assertErrorResponse( 'invalid_menu_item_parent', $response, 400 ); - } - /** * */ @@ -830,8 +800,13 @@ protected function check_menu_item_data( $post, $data, $context, $links ) { $this->assertTrue( isset( $data[ $taxonomy->rest_base ] ) ); $terms = wp_get_object_terms( $post->ID, $taxonomy->name, array( 'fields' => 'ids' ) ); sort( $terms ); - sort( $data[ $taxonomy->rest_base ] ); - $this->assertEquals( $terms, $data[ $taxonomy->rest_base ] ); + if ( 'nav_menu' === $taxonomy->name ) { + $term_id = $terms ? array_shift( $terms ) : 0; + $this->assertEquals( $term_id, $data[ $taxonomy->rest_base ] ); + } else { + sort( $data[ $taxonomy->rest_base ] ); + $this->assertEquals( $terms, $data[ $taxonomy->rest_base ] ); + } } // test links. @@ -908,7 +883,7 @@ protected function set_menu_item_data( $args = array() ) { $defaults = array( 'object_id' => 0, 'parent' => 0, - 'menu_order' => 0, + 'menu_order' => 1, 'menus' => $this->menu_id, 'type' => 'custom', 'title' => 'Custom Link Title',