diff --git a/composer.json b/composer.json index 0c743040..2dd63ca4 100644 --- a/composer.json +++ b/composer.json @@ -71,6 +71,7 @@ "menu item add-post", "menu item add-term", "menu item delete", + "menu item get", "menu item list", "menu item update", "menu list", diff --git a/features/menu-item.feature b/features/menu-item.feature index ca4109d4..494e0dfd 100644 --- a/features/menu-item.feature +++ b/features/menu-item.feature @@ -194,3 +194,61 @@ Feature: Manage WordPress menu items | type | title | position | link | | custom | First | 1 | https://first.com | | custom | Third | 2 | https://third.com | + + Scenario: Get menu item details + When I run `wp menu create "Sidebar Menu"` + Then STDOUT should not be empty + + When I run `wp menu item add-custom sidebar-menu Apple https://apple.com --porcelain` + Then save STDOUT as {ITEM_ID} + + When I run `wp menu item get {ITEM_ID}` + Then STDOUT should be a table containing rows: + | Field | Value | + | db_id | {ITEM_ID} | + | type | custom | + | title | Apple | + | link | https://apple.com | + | position | 1 | + + When I run `wp menu item get {ITEM_ID} --format=json` + Then STDOUT should be JSON containing: + """ + { + "db_id": {ITEM_ID}, + "type": "custom", + "title": "Apple", + "link": "https://apple.com" + } + """ + + When I run `wp menu item get {ITEM_ID} --field=title` + Then STDOUT should be: + """ + Apple + """ + + When I run `wp menu item get {ITEM_ID} --fields=db_id,title,type --format=csv` + Then STDOUT should be CSV containing: + | Field | Value | + | db_id | {ITEM_ID} | + | title | Apple | + | type | custom | + + When I try `wp menu item get 99999999` + Then STDERR should be: + """ + Error: Invalid menu item. + """ + And the return code should be 1 + + When I run `wp post create --post_title='Test Post' --porcelain` + Then save STDOUT as {POST_ID} + + When I try `wp menu item get {POST_ID}` + Then STDERR should be: + """ + Error: Invalid menu item. + """ + And the return code should be 1 + diff --git a/src/Menu_Item_Command.php b/src/Menu_Item_Command.php index 9ee9c835..c1444d9d 100644 --- a/src/Menu_Item_Command.php +++ b/src/Menu_Item_Command.php @@ -120,6 +120,118 @@ function ( $item ) { $formatter->display_items( $items ); } + /** + * Gets details about a menu item. + * + * ## OPTIONS + * + * + * : Database ID for the menu item. + * + * [--field=] + * : Instead of returning the whole menu item, returns the value of a single field. + * + * [--fields=] + * : Limit the output to specific fields. Defaults to all fields. + * + * [--format=] + * : Render output in a particular format. + * --- + * default: table + * options: + * - table + * - csv + * - json + * - yaml + * --- + * + * ## AVAILABLE FIELDS + * + * These fields are available: + * + * * db_id + * * type + * * title + * * link + * * position + * * menu_item_parent + * * object_id + * * object + * * type_label + * * target + * * attr_title + * * description + * * classes + * * xfn + * + * ## EXAMPLES + * + * # Get details about a menu item with ID 45 + * $ wp menu item get 45 + * +-------------+----------------------------------+ + * | Field | Value | + * +-------------+----------------------------------+ + * | db_id | 45 | + * | type | custom | + * | title | WordPress | + * | link | https://wordpress.org | + * | position | 1 | + * +-------------+----------------------------------+ + * + * # Get a specific field from a menu item + * $ wp menu item get 45 --field=title + * WordPress + * + * # Get menu item data in JSON format + * $ wp menu item get 45 --format=json + * {"db_id":45,"type":"custom","title":"WordPress","link":"https://wordpress.org","position":1} + */ + public function get( $args, $assoc_args ) { + + $db_id = $args[0]; + + $menu_item = get_post( $db_id ); + + if ( ! $menu_item || 'nav_menu_item' !== $menu_item->post_type ) { + WP_CLI::error( 'Invalid menu item.' ); + } + + /** + * @var object{title: string, url: string, description: string, object: string, object_id: int, menu_item_parent: int, attr_title: string, target: string, classes: string[], xfn: string, type: string, type_label: string, menu_order: int, db_id: int, post_type: string} $menu_item + */ + $menu_item = wp_setup_nav_menu_item( $menu_item ); + + // Correct position inconsistency and protected `url` param in WP-CLI + // @phpstan-ignore property.notFound + $menu_item->position = $menu_item->menu_order; + // @phpstan-ignore property.notFound + $menu_item->link = $menu_item->url; + + if ( empty( $assoc_args['fields'] ) ) { + $assoc_args['fields'] = [ + 'db_id', + 'menu_item_parent', + 'object_id', + 'object', + 'type', + 'type_label', + 'title', + 'url', + 'link', + 'description', + 'attr_title', + 'target', + 'classes', + 'xfn', + 'menu_order', + 'position', + 'post_type', + ]; + } + $formatter = $this->get_formatter( $assoc_args ); + $formatter->display_item( $menu_item ); + } + /** * Adds a post as a menu item. *