diff options
Diffstat (limited to 'plugins/jetpack/json-endpoints/class.wpcom-json-api-menus-v1-1-endpoint.php')
-rw-r--r-- | plugins/jetpack/json-endpoints/class.wpcom-json-api-menus-v1-1-endpoint.php | 811 |
1 files changed, 606 insertions, 205 deletions
diff --git a/plugins/jetpack/json-endpoints/class.wpcom-json-api-menus-v1-1-endpoint.php b/plugins/jetpack/json-endpoints/class.wpcom-json-api-menus-v1-1-endpoint.php index be02c6c1..5f98f984 100644 --- a/plugins/jetpack/json-endpoints/class.wpcom-json-api-menus-v1-1-endpoint.php +++ b/plugins/jetpack/json-endpoints/class.wpcom-json-api-menus-v1-1-endpoint.php @@ -1,6 +1,19 @@ -<?php +<?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName + +// phpcs:disable Generic.Files.OneObjectStructurePerFile.MultipleFound + +/** + * Menus abstract endpoint class. + */ abstract class WPCOM_JSON_API_Menus_Abstract_Endpoint extends WPCOM_JSON_API_Endpoint { + /** + * Switch to blog and validate user. + * + * @param string $site - the site we want to validate. + * + * @return int + */ protected function switch_to_blog_and_validate_user( $site ) { $site_id = $this->api->switch_to_blog_and_validate_user( $this->api->get_blog_id( $site ) ); if ( is_wp_error( $site_id ) ) { @@ -18,13 +31,20 @@ abstract class WPCOM_JSON_API_Menus_Abstract_Endpoint extends WPCOM_JSON_API_End return $site_id; } - + /** + * Get the locations of the menus. + * + * @return array[] + */ protected function get_locations() { $locations = array(); - $menus = get_registered_nav_menus(); - if ( !empty( $menus ) ) { - foreach( $menus as $name => $description ) { - $locations[] = array( 'name' => $name, 'description' => $description ); + $menus = get_registered_nav_menus(); + if ( ! empty( $menus ) ) { + foreach ( $menus as $name => $description ) { + $locations[] = array( + 'name' => $name, + 'description' => $description, + ); } } @@ -32,58 +52,111 @@ abstract class WPCOM_JSON_API_Menus_Abstract_Endpoint extends WPCOM_JSON_API_End // Primary (first) location should have defaultState -> default, // all other locations (including widgets) should have defaultState -> empty. - for ( $i = 0; $i < count( $locations ); $i++ ) { + for ( $i = 0, $l = count( $locations ); $i < $l; $i++ ) { $locations[ $i ]['defaultState'] = $i ? 'empty' : 'default'; } return $locations; } + /** + * Simplify the menus. + * + * @param WP_Term|WP_Term[] $data - the menus we're simplifying. + * @return array|array[] Simplified menu data. + */ protected function simplify( $data ) { $simplifier = new WPCOM_JSON_API_Menus_Simplifier( $data ); return $simplifier->translate(); } + /** + * Complexify the menus. + * + * @param array[] $data - the menu data we're complexifying. + * @return array[]|WP_Error Complexified menu data, or WP_Error on error. + */ protected function complexify( $data ) { $complexifier = new WPCOM_JSON_API_Menus_Complexify( $data ); return $complexifier->translate(); } } +/** + * The menu translator class. + */ abstract class WPCOM_JSON_API_Menus_Translator { + /** + * A string identifying this class. + * + * @var string + */ protected $filter = ''; + /** + * List of filter method names. + * + * Filter methods are passed an array, and return a transformed array or WP_Error. + * + * @var array + */ protected $filters = array(); + /** + * Class constructor. + * + * @param mixed $menus - a menu or list of menus. + */ public function __construct( $menus ) { $this->is_single_menu = ! is_array( $menus ); - $this->menus = is_array( $menus ) ? $menus : array( $menus ); + $this->menus = is_array( $menus ) ? $menus : array( $menus ); } + /** + * Translate the menus. + * + * @return array|array[]|WP_Error + */ public function translate() { $result = $this->menus; foreach ( $this->filters as $f ) { $result = call_user_func( array( $this, $f ), $result ); - if ( is_wp_error($result ) ) { + if ( is_wp_error( $result ) ) { return $result; } } return $this->maybe_extract( $result ); } + /** + * Return a single menu or an array of menus. + * + * @param array $menus - the menu list. + * + * @return array|array[] + */ protected function maybe_extract( $menus ) { return $this->is_single_menu ? $menus[0] : $menus; } + /** + * See if we need to whitelist and rename. + * + * @param object|array $object - the object (or associative array) we're checking. + * @param array $dict Associative array holding the key whitelist and renaming/casting data. + * Keys are the keys from $object` to preserve. Values are the key to use in the output or an + * assoc where 'name' specifies the output key and 'type' specifies the PHP type to cast the value to. + * + * @return array + */ public function whitelist_and_rename_with( $object, $dict ) { - $keys = array_keys( $dict ); $return = array(); foreach ( (array) $object as $k => $v ) { - if ( in_array( $k, $keys ) ) { + if ( isset( $dict[ $k ] ) ) { if ( is_array( $dict[ $k ] ) ) { settype( $v, $dict[ $k ]['type'] ); $return[ $dict[ $k ]['name'] ] = $v; } else { - $new_k = $dict[ $k ]; + $new_k = $dict[ $k ]; $return[ $new_k ] = $v; } } @@ -92,9 +165,23 @@ abstract class WPCOM_JSON_API_Menus_Translator { } } +/** + * The simplifier class. + */ class WPCOM_JSON_API_Menus_Simplifier extends WPCOM_JSON_API_Menus_Translator { + + /** + * The simplify translator class. + * + * @var string + */ protected $filter = 'wpcom_menu_api_translator_simplify'; + /** + * The simplify filters. + * + * @var array + */ protected $filters = array( 'whitelist_and_rename_keys', 'add_locations', @@ -102,51 +189,128 @@ class WPCOM_JSON_API_Menus_Simplifier extends WPCOM_JSON_API_Menus_Translator { 'add_widget_locations', ); + /** + * The menu whitelist. + * + * @var array + */ protected $menu_whitelist = array( - 'term_id' => array( 'name' => 'id', 'type' => 'int' ), - 'name' => array( 'name' => 'name', 'type' => 'string' ), - 'description' => array( 'name' => 'description', 'type' => 'string' ), - 'items' => array( 'name' => 'items', 'type' => 'array' ), + 'term_id' => array( + 'name' => 'id', + 'type' => 'int', + ), + 'name' => array( + 'name' => 'name', + 'type' => 'string', + ), + 'description' => array( + 'name' => 'description', + 'type' => 'string', + ), + 'items' => array( + 'name' => 'items', + 'type' => 'array', + ), ); + /** + * The menu item whitelist. + * + * @var array + */ protected $menu_item_whitelist = array( - 'db_id' => array( 'name' => 'id', 'type' => 'int' ), - 'object_id' => array( 'name' => 'content_id', 'type' => 'int' ), - 'object' => array( 'name' => 'type', 'type' => 'string' ), - 'type' => array( 'name' => 'type_family', 'type' => 'string' ), - 'type_label' => array( 'name' => 'type_label', 'type' => 'string' ), - 'title' => array( 'name' => 'name', 'type' => 'string' ), - 'menu_order' => array( 'name' => 'order', 'type' => 'int' ), - 'menu_item_parent' => array( 'name' => 'parent', 'type' => 'int' ), - 'url' => array( 'name' => 'url', 'type' => 'string' ), - 'target' => array( 'name' => 'link_target', 'type' => 'string' ), - 'attr_title' => array( 'name' => 'link_title', 'type' => 'string' ), - 'description' => array( 'name' => 'description', 'type' => 'string' ), - 'classes' => array( 'name' => 'classes', 'type' => 'array' ), - 'xfn' => array( 'name' => 'xfn', 'type' => 'string' ), + 'db_id' => array( + 'name' => 'id', + 'type' => 'int', + ), + 'object_id' => array( + 'name' => 'content_id', + 'type' => 'int', + ), + 'object' => array( + 'name' => 'type', + 'type' => 'string', + ), + 'type' => array( + 'name' => 'type_family', + 'type' => 'string', + ), + 'type_label' => array( + 'name' => 'type_label', + 'type' => 'string', + ), + 'title' => array( + 'name' => 'name', + 'type' => 'string', + ), + 'menu_order' => array( + 'name' => 'order', + 'type' => 'int', + ), + 'menu_item_parent' => array( + 'name' => 'parent', + 'type' => 'int', + ), + 'url' => array( + 'name' => 'url', + 'type' => 'string', + ), + 'target' => array( + 'name' => 'link_target', + 'type' => 'string', + ), + 'attr_title' => array( + 'name' => 'link_title', + 'type' => 'string', + ), + 'description' => array( + 'name' => 'description', + 'type' => 'string', + ), + 'classes' => array( + 'name' => 'classes', + 'type' => 'array', + ), + 'xfn' => array( + 'name' => 'xfn', + 'type' => 'string', + ), ); /************************** * Filters methods **************************/ + /** + * Treeify the menus. + * + * @param array $menus - the menu list. + * + * @return array + */ public function treeify( $menus ) { return array_map( array( $this, 'treeify_menu' ), $menus ); } - // turn the flat item list into a tree of items + /** + * Turn the flat item list into a tree of items. + * + * @param array $menu - the menu. + * + * @return array + */ protected function treeify_menu( $menu ) { $indexed_nodes = array(); - $tree = array(); + $tree = array(); - foreach( $menu['items'] as &$item ) { + foreach ( $menu['items'] as &$item ) { $indexed_nodes[ $item['id'] ] = &$item; } - foreach( $menu['items'] as &$item ) { + foreach ( $menu['items'] as &$item ) { if ( $item['parent'] && isset( $indexed_nodes[ $item['parent'] ] ) ) { $parent_node = &$indexed_nodes[ $item['parent'] ]; - if ( !isset( $parent_node['items'] ) ) { + if ( ! isset( $parent_node['items'] ) ) { $parent_node['items'] = array(); } $parent_node['items'][ $item['order'] ] = &$item; @@ -162,20 +326,30 @@ class WPCOM_JSON_API_Menus_Simplifier extends WPCOM_JSON_API_Menus_Translator { return $menu; } - // recursively ensure item lists are contiguous + /** + * Recursively ensure item lists are contiguous. + * + * @param array $item - the item list. + */ protected function remove_item_keys( &$item ) { if ( ! isset( $item['items'] ) || ! is_array( $item['items'] ) ) { return; } - - foreach( $item['items'] as &$it ) { + foreach ( $item['items'] as &$it ) { $this->remove_item_keys( $it ); } $item['items'] = array_values( $item['items'] ); } + /** + * Whitelist and rename keys. + * + * @param (object|array)[] $menus - the menu list. + * + * @return array[] + */ protected function whitelist_and_rename_keys( $menus ) { $transformed_menus = array(); @@ -194,17 +368,31 @@ class WPCOM_JSON_API_Menus_Simplifier extends WPCOM_JSON_API_Menus_Translator { return $transformed_menus; } + /** + * Add menu locations. + * + * @param array $menus - the menu list. + * + * @return array[] + */ protected function add_locations( $menus ) { $menus_with_locations = array(); - foreach( $menus as $menu ) { - $menu['locations'] = array_keys( get_nav_menu_locations(), $menu['id'] ); + foreach ( $menus as $menu ) { + $menu['locations'] = array_keys( get_nav_menu_locations(), $menu['id'] ); // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict $menus_with_locations[] = $menu; } return $menus_with_locations; } + /** + * Add widget locations. + * + * @param array $menus - the menu list. + * + * @return array[] + */ protected function add_widget_locations( $menus ) { $nav_menu_widgets = WPCOM_JSON_API_Menus_Widgets::get(); @@ -217,7 +405,7 @@ class WPCOM_JSON_API_Menus_Simplifier extends WPCOM_JSON_API_Menus_Translator { foreach ( $nav_menu_widgets as $key => $widget ) { if ( is_array( $widget ) && isset( $widget['nav_menu'] ) && - $widget['nav_menu'] === $menu['id'] ) { + $widget['nav_menu'] === $menu['id'] ) { $widget_locations[] = 'nav_menu_widget-' . $key; } } @@ -228,61 +416,97 @@ class WPCOM_JSON_API_Menus_Simplifier extends WPCOM_JSON_API_Menus_Translator { } } +/** + * Complexify menu class. + */ class WPCOM_JSON_API_Menus_Complexify extends WPCOM_JSON_API_Menus_Translator { + + /** + * The complexify filter. + * + * @var string + */ protected $filter = 'wpcom_menu_api_translator_complexify'; + /** + * The filters. + * + * @var array + */ protected $filters = array( 'untreeify', 'set_locations', 'whitelist_and_rename_keys', ); + /** + * The menu whitelist. + * + * @var array + */ protected $menu_whitelist = array( - 'id' => 'term_id', - 'name' => 'menu-name', + 'id' => 'term_id', + 'name' => 'menu-name', 'description' => 'description', - 'items' => 'items', + 'items' => 'items', ); + /** + * The item whitelist. + * + * @var array + */ protected $menu_item_whitelist = array( - 'id' => 'menu-item-db-id', - 'content_id' => 'menu-item-object-id', - 'type' => 'menu-item-object', + 'id' => 'menu-item-db-id', + 'content_id' => 'menu-item-object-id', + 'type' => 'menu-item-object', 'type_family' => 'menu-item-type', - 'type_label' => 'menu-item-type-label', - 'name' => 'menu-item-title', - 'order' => 'menu-item-position', - 'parent' => 'menu-item-parent-id', - 'url' => 'menu-item-url', + 'type_label' => 'menu-item-type-label', + 'name' => 'menu-item-title', + 'order' => 'menu-item-position', + 'parent' => 'menu-item-parent-id', + 'url' => 'menu-item-url', 'link_target' => 'menu-item-target', - 'link_title' => 'menu-item-attr-title', - 'status' => 'menu-item-status', - 'tmp_id' => 'tmp_id', - 'tmp_parent' => 'tmp_parent', + 'link_title' => 'menu-item-attr-title', + 'status' => 'menu-item-status', + 'tmp_id' => 'tmp_id', + 'tmp_parent' => 'tmp_parent', 'description' => 'menu-item-description', - 'classes' => 'menu-item-classes', - 'xfn' => 'menu-item-xfn', + 'classes' => 'menu-item-classes', + 'xfn' => 'menu-item-xfn', ); /************************** * Filters methods **************************/ + /** + * Untreeify the menu. + * + * @param array $menus - the list of menus. + * + * @return array[] + */ public function untreeify( $menus ) { return array_map( array( $this, 'untreeify_menu' ), $menus ); } - // convert the tree of menu items to a flat list suitable for - // the nav_menu APIs + /** + * Convert the tree of menu items to a flat list suitable for the nav_menu APIs. + * + * @param array $menu - the menu we're untreeifying. + * + * @return array + */ protected function untreeify_menu( $menu ) { if ( empty( $menu['items'] ) ) { return $menu; } $items_list = array(); - $counter = 1; + $counter = 1; foreach ( $menu['items'] as &$item ) { - $item[ 'parent' ] = 0; + $item['parent'] = 0; } $this->untreeify_items( $menu['items'], $items_list, $counter ); $menu['items'] = $items_list; @@ -294,15 +518,15 @@ class WPCOM_JSON_API_Menus_Complexify extends WPCOM_JSON_API_Menus_Translator { * Recurse the items tree adding each item to a flat list and restoring * `order` and `parent` fields. * - * @param array $items item tree - * @param array &$items_list output flat list of items - * @param int &$counter for creating temporary IDs + * @param array $items item tree. + * @param array $items_list output flat list of items. + * @param int $counter for creating temporary IDs. */ protected function untreeify_items( $items, &$items_list, &$counter ) { - foreach( $items as $index => $item ) { + foreach ( $items as $index => $item ) { $item['order'] = $index + 1; - if( ! isset( $item['id'] ) ) { + if ( ! isset( $item['id'] ) ) { $this->set_tmp_id( $item, $counter++ ); } @@ -310,7 +534,7 @@ class WPCOM_JSON_API_Menus_Complexify extends WPCOM_JSON_API_Menus_Translator { foreach ( $item['items'] as &$i ) { $i['parent'] = $item['id']; } - $this->untreeify_items( $item[ 'items' ], $items_list, $counter ); + $this->untreeify_items( $item['items'], $items_list, $counter ); unset( $item['items'] ); } @@ -323,6 +547,9 @@ class WPCOM_JSON_API_Menus_Complexify extends WPCOM_JSON_API_Menus_Translator { * for all its children, to maintain the hierarchy. * These fields will be used when creating * new items with wp_update_nav_menu_item(). + * + * @param array $item - the item tree. + * @param string $tmp_id - the tmp ID. */ private function set_tmp_id( &$item, $tmp_id ) { $item['tmp_id'] = $tmp_id; @@ -334,6 +561,13 @@ class WPCOM_JSON_API_Menus_Complexify extends WPCOM_JSON_API_Menus_Translator { } } + /** + * Whitelist and rename keys. + * + * @param array $menus - the menus. + * + * @return array[] + */ protected function whitelist_and_rename_keys( $menus ) { $transformed_menus = array(); foreach ( $menus as $menu ) { @@ -347,17 +581,36 @@ class WPCOM_JSON_API_Menus_Complexify extends WPCOM_JSON_API_Menus_Translator { return $transformed_menus; } + /** + * Whitelist and rename item keys. + * + * @param array $item - the item. + * + * @return array + */ protected function whitelist_and_rename_item_keys( $item ) { $item = $this->implode_array_fields( $item ); $item = $this->whitelist_and_rename_with( $item, $this->menu_item_whitelist ); return $item; } - // all item fields are set as strings + /** + * All item fields are set as strings. + * + * @param array $menu_item - the menu item. + * @return array Item with fields imploded. + */ protected function implode_array_fields( $menu_item ) { return array_map( array( $this, 'implode_array_field' ), $menu_item ); } + /** + * Implode an array field. + * + * @param mixed $field - the field we're imploding. + * + * @return mixed The imploded string if `$field` was an array, otherwise `$field` unchanged. + */ protected function implode_array_field( $field ) { if ( is_array( $field ) ) { return implode( ' ', $field ); @@ -365,6 +618,13 @@ class WPCOM_JSON_API_Menus_Complexify extends WPCOM_JSON_API_Menus_Translator { return $field; } + /** + * Set the menu locations. + * + * @param array $menus - the menu list. + * + * @return array[]|WP_Error + */ protected function set_locations( $menus ) { foreach ( $menus as $menu ) { if ( isset( $menu['locations'] ) ) { @@ -377,13 +637,26 @@ class WPCOM_JSON_API_Menus_Complexify extends WPCOM_JSON_API_Menus_Translator { return array_map( array( $this, 'set_location' ), $menus ); } + /** + * Set the menu locations. + * + * @param array $menu - the menu. + * + * @return array + */ protected function set_location( $menu ) { $this->set_menu_at_locations( $menu['locations'], $menu['id'] ); return $menu; } + /** + * Set the menu at locations. + * + * @param array $locations - the locations. + * @param int $menu_id - the menu ID. + */ protected function set_menu_at_locations( $locations, $menu_id ) { - $location_map = get_nav_menu_locations(); + $location_map = get_nav_menu_locations(); $this->remove_menu_from_all_locations( $menu_id, $location_map ); if ( is_array( $locations ) ) { @@ -397,14 +670,26 @@ class WPCOM_JSON_API_Menus_Complexify extends WPCOM_JSON_API_Menus_Translator { $this->set_widget_menu_at_locations( $locations, $menu_id ); } + /** + * Remove from all locations. + * + * @param int $menu_id - the menu ID. + * @param array $location_map - the location map. + */ protected function remove_menu_from_all_locations( $menu_id, &$location_map ) { - foreach ( get_nav_menu_locations() as $existing_location => $existing_menu_id) { - if ( $existing_menu_id == $menu_id ) { - unset( $location_map[$existing_location] ); + foreach ( get_nav_menu_locations() as $existing_location => $existing_menu_id ) { + if ( $existing_menu_id === $menu_id ) { + unset( $location_map[ $existing_location ] ); } } } + /** + * Set widget menu at locations. + * + * @param array $locations - the locations. + * @param int $menu_id - the menu ID. + */ protected function set_widget_menu_at_locations( $locations, $menu_id ) { $nav_menu_widgets = get_option( 'widget_nav_menu' ); @@ -414,7 +699,7 @@ class WPCOM_JSON_API_Menus_Complexify extends WPCOM_JSON_API_Menus_Translator { // Remove menus from all custom menu widget locations foreach ( $nav_menu_widgets as &$widget ) { - if ( is_array( $widget ) && isset( $widget['nav_menu'] ) && $widget['nav_menu'] == $menu_id ) { + if ( is_array( $widget ) && isset( $widget['nav_menu'] ) && $widget['nav_menu'] === $menu_id ) { $widget['nav_menu'] = 0; } } @@ -423,7 +708,7 @@ class WPCOM_JSON_API_Menus_Complexify extends WPCOM_JSON_API_Menus_Translator { foreach ( $locations as $location ) { if ( preg_match( '/^nav_menu_widget-(\d+)/', $location, $matches ) ) { if ( isset( $matches[1] ) ) { - $nav_menu_widgets[$matches[1]]['nav_menu'] = $menu_id; + $nav_menu_widgets[ $matches[1] ]['nav_menu'] = $menu_id; } } } @@ -432,9 +717,16 @@ class WPCOM_JSON_API_Menus_Complexify extends WPCOM_JSON_API_Menus_Translator { update_option( 'widget_nav_menu', $nav_menu_widgets ); } + /** + * Check if the locations are valid. + * + * @param int|array $locations - the location we're checking. + * + * @return bool|WP_Error + */ protected function locations_are_valid( $locations ) { if ( is_int( $locations ) ) { - if ( $locations != 0) { + if ( $locations !== 0 ) { return new WP_Error( 'locations-int', 'Locations int must be 0.', 400 ); } else { return true; @@ -442,8 +734,11 @@ class WPCOM_JSON_API_Menus_Complexify extends WPCOM_JSON_API_Menus_Translator { } elseif ( is_array( $locations ) ) { foreach ( $locations as $location_name ) { if ( ! $this->location_name_exists( $location_name ) ) { - return new WP_Error( 'locations-array', - sprintf( "Location '%s' does not exist.", $location_name ), 404 ); + return new WP_Error( + 'locations-array', + sprintf( "Location '%s' does not exist.", $location_name ), + 404 + ); } } return true; @@ -451,6 +746,13 @@ class WPCOM_JSON_API_Menus_Complexify extends WPCOM_JSON_API_Menus_Translator { return new WP_Error( 'locations', 'Locations must be array or integer.', 400 ); } + /** + * Check if the location name exists. + * + * @param string $location_name - the location name. + * + * @return bool + */ protected function location_name_exists( $location_name ) { $widget_location_names = wp_list_pluck( WPCOM_JSON_API_Menus_Widgets::get(), 'name' ); @@ -462,37 +764,51 @@ class WPCOM_JSON_API_Menus_Complexify extends WPCOM_JSON_API_Menus_Translator { return array_key_exists( $location_name, get_registered_nav_menus() ) || array_key_exists( $location_name, $existing_locations ) || - in_array( $location_name, $widget_location_names ); + in_array( $location_name, $widget_location_names, true ); } } -new WPCOM_JSON_API_Menus_New_Menu_Endpoint( array ( - 'method' => 'POST', - 'description' => 'Create a new navigation menu.', - 'group' => 'menus', - 'stat' => 'menus:new-menu', - 'path' => '/sites/%s/menus/new', - 'path_labels' => array( - '$site' => '(int|string) Site ID or domain', - ), - 'request_format' => array( - 'name' => '(string) Name of menu', - ), - 'response_format' => array( - 'id' => '(int) Newly created menu ID', - ), - 'example_request' => 'https://public-api.wordpress.com/rest/v1.1/sites/82974409/menus/new', - 'example_request_data' => array( - 'headers' => array( 'authorization' => 'Bearer YOUR_API_TOKEN' ), - 'body' => array( - 'name' => 'Menu 1' - ) - ), -) ); +new WPCOM_JSON_API_Menus_New_Menu_Endpoint( + array( + 'method' => 'POST', + 'description' => 'Create a new navigation menu.', + 'group' => 'menus', + 'stat' => 'menus:new-menu', + 'path' => '/sites/%s/menus/new', + 'path_labels' => array( + '$site' => '(int|string) Site ID or domain', + ), + 'request_format' => array( + 'name' => '(string) Name of menu', + ), + 'response_format' => array( + 'id' => '(int) Newly created menu ID', + ), + 'example_request' => 'https://public-api.wordpress.com/rest/v1.1/sites/82974409/menus/new', + 'example_request_data' => array( + 'headers' => array( 'authorization' => 'Bearer YOUR_API_TOKEN' ), + 'body' => array( + 'name' => 'Menu 1', + ), + ), + ) +); +/** + * New menu endpoint class. + */ class WPCOM_JSON_API_Menus_New_Menu_Endpoint extends WPCOM_JSON_API_Menus_Abstract_Endpoint { - function callback( $path = '', $site = 0 ) { + + /** + * The API Callback. + * + * @param string $path - the path. + * @param int $site - the site ID. + * + * @return array|WP_Error + */ + public function callback( $path = '', $site = 0 ) { $site_id = $this->switch_to_blog_and_validate_user( $this->api->get_blog_id( $site ) ); if ( is_wp_error( $site_id ) ) { @@ -511,38 +827,53 @@ class WPCOM_JSON_API_Menus_New_Menu_Endpoint extends WPCOM_JSON_API_Menus_Abstra } } -new WPCOM_JSON_API_Menus_Update_Menu_Endpoint( array ( - 'method' => 'POST', - 'description' => 'Update a navigation menu.', - 'group' => 'menus', - 'stat' => 'menus:update-menu', - 'path' => '/sites/%s/menus/%d', - 'path_labels' => array( - '$site' => '(int|string) Site ID or domain', - '$menu_id' => '(int) Menu ID', - ), - 'request_format' => array( - 'name' => '(string) Name of menu', - 'items' => '(array) A list of menu item objects. +new WPCOM_JSON_API_Menus_Update_Menu_Endpoint( + array( + 'method' => 'POST', + 'description' => 'Update a navigation menu.', + 'group' => 'menus', + 'stat' => 'menus:update-menu', + 'path' => '/sites/%s/menus/%d', + 'path_labels' => array( + '$site' => '(int|string) Site ID or domain', + '$menu_id' => '(int) Menu ID', + ), + 'request_format' => array( + 'name' => '(string) Name of menu', + 'items' => '(array) A list of menu item objects. <br/><br/> Item objects contain fields relating to that item, e.g. id, type, content_id, but they can also contain other items objects - this nesting represents parents - and child items in the item tree.' - ), - 'response_format' => array( - 'menu' => '(object) Updated menu object', - ), - 'example_request' => 'https://public-api.wordpress.com/rest/v1.1/sites/82974409/menus/510604099', - 'example_request_data' => array( - 'headers' => array( 'authorization' => 'Bearer YOUR_API_TOKEN' ), - 'body' => array( - 'name' => 'Test Menu' - ), - ), -) ); + and child items in the item tree.', + ), + 'response_format' => array( + 'menu' => '(object) Updated menu object', + ), + 'example_request' => 'https://public-api.wordpress.com/rest/v1.1/sites/82974409/menus/510604099', + 'example_request_data' => array( + 'headers' => array( 'authorization' => 'Bearer YOUR_API_TOKEN' ), + 'body' => array( + 'name' => 'Test Menu', + ), + ), + ) +); +/** + * Update menu endpoint class. + */ class WPCOM_JSON_API_Menus_Update_Menu_Endpoint extends WPCOM_JSON_API_Menus_Abstract_Endpoint { - function callback( $path = '', $site = 0, $menu_id = 0 ) { + + /** + * The API Callback. + * + * @param string $path - the path. + * @param int $site - the site ID. + * @param int $menu_id - the menu ID. + * + * @return array|WP_Error + */ + public function callback( $path = '', $site = 0, $menu_id = 0 ) { $site_id = $this->switch_to_blog_and_validate_user( $this->api->get_blog_id( $site ) ); if ( is_wp_error( $site_id ) ) { @@ -553,9 +884,9 @@ class WPCOM_JSON_API_Menus_Update_Menu_Endpoint extends WPCOM_JSON_API_Menus_Abs return new WP_Error( 'menu-id', 'Menu ID must be greater than 0.', 400 ); } - $data = $this->input( true, false ); + $data = $this->input( true, false ); $data['id'] = $menu_id; - $data = $this->complexify( array( $data ) ); + $data = $this->complexify( array( $data ) ); if ( is_wp_error( $data ) ) { return $data; } @@ -573,13 +904,13 @@ class WPCOM_JSON_API_Menus_Update_Menu_Endpoint extends WPCOM_JSON_API_Menus_Abs } $delete_status = $this->delete_items_not_present( $menu_id, $data['items'] ); - if( is_wp_error( $delete_status ) ) { + if ( is_wp_error( $delete_status ) ) { return $delete_status; } foreach ( $data['items'] as $item ) { $item_id = isset( $item['menu-item-db-id'] ) ? $item['menu-item-db-id'] : 0; - $result = wp_update_nav_menu_item( $menu_id, $item_id, $item ); + $result = wp_update_nav_menu_item( $menu_id, $item_id, $item ); if ( is_wp_error( $result ) ) { return $result; } @@ -591,7 +922,7 @@ class WPCOM_JSON_API_Menus_Update_Menu_Endpoint extends WPCOM_JSON_API_Menus_Abs return $items; } - $menu = wp_get_nav_menu_object( $menu_id ); + $menu = wp_get_nav_menu_object( $menu_id ); $menu->items = $items; return array( 'menu' => $this->simplify( $menu ) ); @@ -604,12 +935,16 @@ class WPCOM_JSON_API_Menus_Update_Menu_Endpoint extends WPCOM_JSON_API_Menus_Abs * This function will create items that have a 'tmp_id' set, and * update any items with a 'tmp_parent' to use the * newly created item as a parent. + * + * @param array $data - the data we're checking. + * @param int $menu_id - the menu ID. + * @return array `$data` with new item IDs filled in. */ - function create_new_items( $data, $menu_id ) { + public function create_new_items( $data, $menu_id ) { $tmp_to_actual_ids = array(); foreach ( $data['items'] as &$item ) { if ( isset( $item['tmp_id'] ) ) { - $actual_id = wp_update_nav_menu_item( $menu_id, 0, $item ); + $actual_id = wp_update_nav_menu_item( $menu_id, 0, $item ); $tmp_to_actual_ids[ $item['tmp_id'] ] = $actual_id; unset( $item['tmp_id'] ); $item['menu-item-db-id'] = $actual_id; @@ -627,24 +962,32 @@ class WPCOM_JSON_API_Menus_Update_Menu_Endpoint extends WPCOM_JSON_API_Menus_Abs } /** - * remove any existing menu items not present in the supplied array. + * Remove any existing menu items not present in the supplied array. * returns wp_error if an item cannot be deleted. + * + * @param int $menu_id - the menu ID. + * @param array $menu_items - the menu items. + * + * @return bool|WP_Error */ - function delete_items_not_present( $menu_id, $menu_items ) { + public function delete_items_not_present( $menu_id, $menu_items ) { $existing_items = wp_get_nav_menu_items( $menu_id, array( 'update_post_term_cache' => false ) ); if ( ! is_array( $existing_items ) ) { return true; } - $existing_ids = wp_list_pluck( $existing_items, 'db_id' ); - $ids_to_keep = wp_list_pluck( $menu_items, 'menu-item-db-id' ); + $existing_ids = wp_list_pluck( $existing_items, 'db_id' ); + $ids_to_keep = wp_list_pluck( $menu_items, 'menu-item-db-id' ); $ids_to_remove = array_diff( $existing_ids, $ids_to_keep ); foreach ( $ids_to_remove as $id ) { if ( false === wp_delete_post( $id, true ) ) { - return new WP_Error( 'menu-item', - sprintf( 'Failed to delete menu item with id: %d.', $id ), 400 ); + return new WP_Error( + 'menu-item', + sprintf( 'Failed to delete menu item with id: %d.', $id ), + 400 + ); } } @@ -652,33 +995,47 @@ class WPCOM_JSON_API_Menus_Update_Menu_Endpoint extends WPCOM_JSON_API_Menus_Abs } } -new WPCOM_JSON_API_Menus_List_Menus_Endpoint( array ( - 'method'=> 'GET', - 'description' => 'Get a list of all navigation menus.', - 'group' => 'menus', - 'stat' => 'menus:list-menu', - 'path' => '/sites/%s/menus', - 'path_labels' => array( - '$site' => '(int|string) Site ID or domain', - ), - 'response_format' => array( - 'menus' => '(array) A list of menu objects.<br/><br/> +new WPCOM_JSON_API_Menus_List_Menus_Endpoint( + array( + 'method' => 'GET', + 'description' => 'Get a list of all navigation menus.', + 'group' => 'menus', + 'stat' => 'menus:list-menu', + 'path' => '/sites/%s/menus', + 'path_labels' => array( + '$site' => '(int|string) Site ID or domain', + ), + 'response_format' => array( + 'menus' => '(array) A list of menu objects.<br/><br/> A menu object contains a name, items, locations, etc. Check the example response for the full structure. <br/><br/> Item objects contain fields relating to that item, e.g. id, type, content_id, but they can also contain other items objects - this nesting represents parents and child items in the item tree.', - 'locations' => '(array) Locations where menus can be placed. List of objects, one per location.' - ), - 'example_request' => 'https://public-api.wordpress.com/rest/v1.1/sites/82974409/menus', - 'example_request_data' => array( - 'headers' => array( 'authorization' => 'Bearer YOUR_API_TOKEN' ), - ), -) ); + 'locations' => '(array) Locations where menus can be placed. List of objects, one per location.', + ), + 'example_request' => 'https://public-api.wordpress.com/rest/v1.1/sites/82974409/menus', + 'example_request_data' => array( + 'headers' => array( 'authorization' => 'Bearer YOUR_API_TOKEN' ), + ), + ) +); +/** + * List menus endpoint class. + */ class WPCOM_JSON_API_Menus_List_Menus_Endpoint extends WPCOM_JSON_API_Menus_Abstract_Endpoint { - function callback( $path = '', $site = 0 ) { + + /** + * The API Callback. + * + * @param string $path - the path. + * @param int $site - the site ID. + * + * @return array|WP_Error + */ + public function callback( $path = '', $site = 0 ) { $site_id = $this->switch_to_blog_and_validate_user( $this->api->get_blog_id( $site ) ); if ( is_wp_error( $site_id ) ) { @@ -705,37 +1062,55 @@ class WPCOM_JSON_API_Menus_List_Menus_Endpoint extends WPCOM_JSON_API_Menus_Abst return $this->get_locations(); } - return array( 'menus' => $menus, 'locations' => $this->get_locations() ); + return array( + 'menus' => $menus, + 'locations' => $this->get_locations(), + ); } } -new WPCOM_JSON_API_Menus_Get_Menu_Endpoint( array ( - 'method'=> 'GET', - 'description' => 'Get a single navigation menu.', - 'group' => 'menus', - 'stat' => 'menus:get-menu', - 'path' => '/sites/%s/menus/%d', - 'path_labels' => array( - '$site' => '(int|string) Site ID or domain', - '$menu_id' => '(int) Menu ID', - ), - 'response_format' => array( - 'menu' => '(object) A menu object.<br/><br/> +new WPCOM_JSON_API_Menus_Get_Menu_Endpoint( + array( + 'method' => 'GET', + 'description' => 'Get a single navigation menu.', + 'group' => 'menus', + 'stat' => 'menus:get-menu', + 'path' => '/sites/%s/menus/%d', + 'path_labels' => array( + '$site' => '(int|string) Site ID or domain', + '$menu_id' => '(int) Menu ID', + ), + 'response_format' => array( + 'menu' => '(object) A menu object.<br/><br/> A menu object contains a name, items, locations, etc. Check the example response for the full structure. <br/><br/> Item objects contain fields relating to that item, e.g. id, type, content_id, but they can also contain other items objects - this nesting represents parents - and child items in the item tree.' - ), - 'example_request' => 'https://public-api.wordpress.com/rest/v1.1/sites/82974409/menus/510604099', - 'example_request_data' => array( - 'headers' => array( 'authorization' => 'Bearer YOUR_API_TOKEN' ), - ), -) ); + and child items in the item tree.', + ), + 'example_request' => 'https://public-api.wordpress.com/rest/v1.1/sites/82974409/menus/510604099', + 'example_request_data' => array( + 'headers' => array( 'authorization' => 'Bearer YOUR_API_TOKEN' ), + ), + ) +); +/** + * Get menu endpoint class. + */ class WPCOM_JSON_API_Menus_Get_Menu_Endpoint extends WPCOM_JSON_API_Menus_Abstract_Endpoint { - function callback( $path = '', $site = 0, $menu_id = 0 ) { + + /** + * The API Callback. + * + * @param string $path - the path. + * @param int $site - the site ID. + * @param int $menu_id - the menu ID. + * + * @return array|WP_Error + */ + public function callback( $path = '', $site = 0, $menu_id = 0 ) { $site_id = $this->switch_to_blog_and_validate_user( $this->api->get_blog_id( $site ) ); if ( is_wp_error( $site_id ) ) { @@ -764,27 +1139,42 @@ class WPCOM_JSON_API_Menus_Get_Menu_Endpoint extends WPCOM_JSON_API_Menus_Abstra } } -new WPCOM_JSON_API_Menus_Delete_Menu_Endpoint( array ( - 'method' => 'POST', - 'description' => 'Delete a navigation menu', - 'group' => 'menus', - 'stat' => 'menus:delete-menu', - 'path' => '/sites/%s/menus/%d/delete', - 'path_labels' => array( - '$site' => '(int|string) Site ID or domain', - '$menu_id' => '(int) Menu ID', - ), - 'response_format' => array( - 'deleted' => '(bool) Has the menu been deleted?', - ), - 'example_request' => 'https://public-api.wordpress.com/rest/v1.1/sites/82974409/menus/$menu_id/delete', - 'example_request_data' => array( - 'headers' => array( 'authorization' => 'Bearer YOUR_API_TOKEN' ), - ), -) ); +new WPCOM_JSON_API_Menus_Delete_Menu_Endpoint( + array( + 'method' => 'POST', + 'description' => 'Delete a navigation menu', + 'group' => 'menus', + 'stat' => 'menus:delete-menu', + 'path' => '/sites/%s/menus/%d/delete', + 'path_labels' => array( + '$site' => '(int|string) Site ID or domain', + '$menu_id' => '(int) Menu ID', + ), + 'response_format' => array( + 'deleted' => '(bool) Has the menu been deleted?', + ), + 'example_request' => 'https://public-api.wordpress.com/rest/v1.1/sites/82974409/menus/$menu_id/delete', + 'example_request_data' => array( + 'headers' => array( 'authorization' => 'Bearer YOUR_API_TOKEN' ), + ), + ) +); +/** + * Delete menu endpoint class. + */ class WPCOM_JSON_API_Menus_Delete_Menu_Endpoint extends WPCOM_JSON_API_Menus_Abstract_Endpoint { - function callback( $path = '', $site = 0, $menu_id = 0 ) { + + /** + * The API Callback. + * + * @param string $path - the path. + * @param int $site - the site ID. + * @param int $menu_id - the menu ID. + * + * @return array|WP_Error + */ + public function callback( $path = '', $site = 0, $menu_id = 0 ) { $site_id = $this->switch_to_blog_and_validate_user( $this->api->get_blog_id( $site ) ); if ( is_wp_error( $site_id ) ) { @@ -804,9 +1194,17 @@ class WPCOM_JSON_API_Menus_Delete_Menu_Endpoint extends WPCOM_JSON_API_Menus_Abs } } +/** + * API Menus widgets class. + */ class WPCOM_JSON_API_Menus_Widgets { - static function get() { - $locations = array(); + /** + * Get the menu locations. + * + * @return array + */ + public static function get() { + $locations = array(); $nav_menu_widgets = get_option( 'widget_nav_menu' ); if ( ! is_array( $nav_menu_widgets ) ) { @@ -815,7 +1213,10 @@ class WPCOM_JSON_API_Menus_Widgets { foreach ( $nav_menu_widgets as $k => $v ) { if ( is_array( $v ) && isset( $v['title'] ) ) { - $locations[$k] = array( 'name' => 'nav_menu_widget-' . $k, 'description' => $v['title'] ); + $locations[ $k ] = array( + 'name' => 'nav_menu_widget-' . $k, + 'description' => $v['title'], + ); } } |