Skip to content

Incorrect error handling when converting classic to block menus #52481

@dlh01

Description

@dlh01

Description

Some errors that can occur when Gutenberg_Navigation_Fallback::create_classic_menu_fallback() calls Gutenberg_Classic_To_Block_Menu_Converter::convert() aren't handled as accurately as they could be.

  1. ::convert() can return a WP_Error object, but this error object won't be detected by the empty() check in ::create_classic_menu_fallback(). The WP_Error return type is also missing from the docs.
  2. ::convert() returns an array instead of a string when no menu items are returned by wp_get_nav_menu_items().

See here:

private static function create_classic_menu_fallback() {
// See if we have a classic menu.
$classic_nav_menu = static::get_fallback_classic_menu();
if ( ! $classic_nav_menu ) {
return new WP_Error( 'no_classic_menus', __( 'No Classic Menus found.', 'gutenberg' ) );
}
// If there is a classic menu then convert it to blocks.
$classic_nav_menu_blocks = Gutenberg_Classic_To_Block_Menu_Converter::convert( $classic_nav_menu );
if ( empty( $classic_nav_menu_blocks ) ) {
return new WP_Error( 'cannot_convert_classic_menu', __( 'Unable to convert Classic Menu to blocks.', 'gutenberg' ) );
}
// Create a new navigation menu from the classic menu.
$classic_menu_fallback = wp_insert_post(
array(
'post_content' => $classic_nav_menu_blocks,
'post_title' => $classic_nav_menu->name,
'post_name' => $classic_nav_menu->slug,
'post_status' => 'publish',
'post_type' => 'wp_navigation',
),
true // So that we can check whether the result is an error.
);
return $classic_menu_fallback;
}

and here:

/**
* Converts a Classic Menu to blocks.
*
* @param WP_Term $menu The Menu term object of the menu to convert.
* @return string the serialized and normalized parsed blocks.
*/
public static function convert( $menu ) {
if ( ! is_nav_menu( $menu ) ) {
return new WP_Error(
'invalid_menu',
__( 'The menu provided is not a valid menu.', 'gutenberg' )
);
}
$menu_items = wp_get_nav_menu_items( $menu->term_id, array( 'update_post_term_cache' => false ) );
if ( empty( $menu_items ) ) {
return array();
}
// Set up the $menu_item variables.
// Adds the class property classes for the current context, if applicable.
_wp_menu_item_classes_by_context( $menu_items );
$menu_items_by_parent_id = static::group_by_parent_id( $menu_items );
$first_menu_item = isset( $menu_items_by_parent_id[0] )
? $menu_items_by_parent_id[0]
: array();
$inner_blocks = static::to_blocks(
$first_menu_item,
$menu_items_by_parent_id
);
return serialize_blocks( $inner_blocks );
}

Step-by-step reproduction instructions

n/a

Screenshots, screen recording, code snippet

No response

Environment info

  • WordPress trunk
  • Gutenberg trunk

Please confirm that you have searched existing issues in the repo.

Yes

Please confirm that you have tested with all plugins deactivated except Gutenberg.

No

Metadata

Metadata

Assignees

No one assigned

    Labels

    Needs TestingNeeds further testing to be confirmed.[Block] NavigationAffects the Navigation Block[Status] StaleGives the original author opportunity to update before closing. Can be reopened as needed.[Type] BugAn existing feature does not function as intended

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions