[ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * REST API: WP_REST_Menu_Locations_Controller class 4 * 5 * @package WordPress 6 * @subpackage REST_API 7 * @since 5.9.0 8 */ 9 10 /** 11 * Core class used to access menu locations via the REST API. 12 * 13 * @since 5.9.0 14 * 15 * @see WP_REST_Controller 16 */ 17 class WP_REST_Menu_Locations_Controller extends WP_REST_Controller { 18 19 /** 20 * Menu Locations Constructor. 21 * 22 * @since 5.9.0 23 */ 24 public function __construct() { 25 $this->namespace = 'wp/v2'; 26 $this->rest_base = 'menu-locations'; 27 } 28 29 /** 30 * Registers the routes for the objects of the controller. 31 * 32 * @since 5.9.0 33 * 34 * @see register_rest_route() 35 */ 36 public function register_routes() { 37 register_rest_route( 38 $this->namespace, 39 '/' . $this->rest_base, 40 array( 41 array( 42 'methods' => WP_REST_Server::READABLE, 43 'callback' => array( $this, 'get_items' ), 44 'permission_callback' => array( $this, 'get_items_permissions_check' ), 45 'args' => $this->get_collection_params(), 46 ), 47 'schema' => array( $this, 'get_public_item_schema' ), 48 ) 49 ); 50 51 register_rest_route( 52 $this->namespace, 53 '/' . $this->rest_base . '/(?P<location>[\w-]+)', 54 array( 55 'args' => array( 56 'location' => array( 57 'description' => __( 'An alphanumeric identifier for the menu location.' ), 58 'type' => 'string', 59 ), 60 ), 61 array( 62 'methods' => WP_REST_Server::READABLE, 63 'callback' => array( $this, 'get_item' ), 64 'permission_callback' => array( $this, 'get_item_permissions_check' ), 65 'args' => array( 66 'context' => $this->get_context_param( array( 'default' => 'view' ) ), 67 ), 68 ), 69 'schema' => array( $this, 'get_public_item_schema' ), 70 ) 71 ); 72 } 73 74 /** 75 * Checks whether a given request has permission to read menu locations. 76 * 77 * @since 5.9.0 78 * 79 * @param WP_REST_Request $request Full details about the request. 80 * @return true|WP_Error True if the request has read access, WP_Error object otherwise. 81 */ 82 public function get_items_permissions_check( $request ) { 83 return $this->check_has_read_only_access( $request ); 84 } 85 86 /** 87 * Retrieves all menu locations, depending on user context. 88 * 89 * @since 5.9.0 90 * 91 * @param WP_REST_Request $request Full details about the request. 92 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. 93 */ 94 public function get_items( $request ) { 95 $data = array(); 96 97 foreach ( get_registered_nav_menus() as $name => $description ) { 98 $location = new stdClass(); 99 $location->name = $name; 100 $location->description = $description; 101 102 $location = $this->prepare_item_for_response( $location, $request ); 103 $data[ $name ] = $this->prepare_response_for_collection( $location ); 104 } 105 106 return rest_ensure_response( $data ); 107 } 108 109 /** 110 * Checks if a given request has access to read a menu location. 111 * 112 * @since 5.9.0 113 * 114 * @param WP_REST_Request $request Full details about the request. 115 * @return true|WP_Error True if the request has read access for the item, WP_Error object otherwise. 116 */ 117 public function get_item_permissions_check( $request ) { 118 return $this->check_has_read_only_access( $request ); 119 } 120 121 /** 122 * Retrieves a specific menu location. 123 * 124 * @since 5.9.0 125 * 126 * @param WP_REST_Request $request Full details about the request. 127 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. 128 */ 129 public function get_item( $request ) { 130 $registered_menus = get_registered_nav_menus(); 131 if ( ! array_key_exists( $request['location'], $registered_menus ) ) { 132 return new WP_Error( 'rest_menu_location_invalid', __( 'Invalid menu location.' ), array( 'status' => 404 ) ); 133 } 134 135 $location = new stdClass(); 136 $location->name = $request['location']; 137 $location->description = $registered_menus[ $location->name ]; 138 139 $data = $this->prepare_item_for_response( $location, $request ); 140 141 return rest_ensure_response( $data ); 142 } 143 144 /** 145 * Checks whether the current user has read permission for the endpoint. 146 * 147 * @since 6.8.0 148 * 149 * @param WP_REST_Request $request Full details about the request. 150 * @return true|WP_Error True if the current user has permission, WP_Error object otherwise. 151 */ 152 protected function check_has_read_only_access( $request ) { 153 /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-menu-items-controller.php */ 154 $read_only_access = apply_filters( 'rest_menu_read_access', false, $request, $this ); 155 if ( $read_only_access ) { 156 return true; 157 } 158 159 if ( ! current_user_can( 'edit_theme_options' ) ) { 160 return new WP_Error( 161 'rest_cannot_view', 162 __( 'Sorry, you are not allowed to view menu locations.' ), 163 array( 'status' => rest_authorization_required_code() ) 164 ); 165 } 166 167 return true; 168 } 169 170 /** 171 * Prepares a menu location object for serialization. 172 * 173 * @since 5.9.0 174 * 175 * @param stdClass $item Post status data. 176 * @param WP_REST_Request $request Full details about the request. 177 * @return WP_REST_Response Menu location data. 178 */ 179 public function prepare_item_for_response( $item, $request ) { 180 // Restores the more descriptive, specific name for use within this method. 181 $location = $item; 182 183 $locations = get_nav_menu_locations(); 184 $menu = isset( $locations[ $location->name ] ) ? $locations[ $location->name ] : 0; 185 186 $fields = $this->get_fields_for_response( $request ); 187 $data = array(); 188 189 if ( rest_is_field_included( 'name', $fields ) ) { 190 $data['name'] = $location->name; 191 } 192 193 if ( rest_is_field_included( 'description', $fields ) ) { 194 $data['description'] = $location->description; 195 } 196 197 if ( rest_is_field_included( 'menu', $fields ) ) { 198 $data['menu'] = (int) $menu; 199 } 200 201 $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; 202 $data = $this->add_additional_fields_to_object( $data, $request ); 203 $data = $this->filter_response_by_context( $data, $context ); 204 205 $response = rest_ensure_response( $data ); 206 207 if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { 208 $response->add_links( $this->prepare_links( $location ) ); 209 } 210 211 /** 212 * Filters menu location data returned from the REST API. 213 * 214 * @since 5.9.0 215 * 216 * @param WP_REST_Response $response The response object. 217 * @param object $location The original location object. 218 * @param WP_REST_Request $request Request used to generate the response. 219 */ 220 return apply_filters( 'rest_prepare_menu_location', $response, $location, $request ); 221 } 222 223 /** 224 * Prepares links for the request. 225 * 226 * @since 5.9.0 227 * 228 * @param stdClass $location Menu location. 229 * @return array Links for the given menu location. 230 */ 231 protected function prepare_links( $location ) { 232 $base = sprintf( '%s/%s', $this->namespace, $this->rest_base ); 233 234 // Entity meta. 235 $links = array( 236 'self' => array( 237 'href' => rest_url( trailingslashit( $base ) . $location->name ), 238 ), 239 'collection' => array( 240 'href' => rest_url( $base ), 241 ), 242 ); 243 244 $locations = get_nav_menu_locations(); 245 $menu = isset( $locations[ $location->name ] ) ? $locations[ $location->name ] : 0; 246 if ( $menu ) { 247 $path = rest_get_route_for_term( $menu ); 248 if ( $path ) { 249 $url = rest_url( $path ); 250 251 $links['https://api.w.org/menu'][] = array( 252 'href' => $url, 253 'embeddable' => true, 254 ); 255 } 256 } 257 258 return $links; 259 } 260 261 /** 262 * Retrieves the menu location's schema, conforming to JSON Schema. 263 * 264 * @since 5.9.0 265 * 266 * @return array Item schema data. 267 */ 268 public function get_item_schema() { 269 if ( $this->schema ) { 270 return $this->add_additional_fields_schema( $this->schema ); 271 } 272 273 $this->schema = array( 274 '$schema' => 'http://json-schema.org/draft-04/schema#', 275 'title' => 'menu-location', 276 'type' => 'object', 277 'properties' => array( 278 'name' => array( 279 'description' => __( 'The name of the menu location.' ), 280 'type' => 'string', 281 'context' => array( 'embed', 'view', 'edit' ), 282 'readonly' => true, 283 ), 284 'description' => array( 285 'description' => __( 'The description of the menu location.' ), 286 'type' => 'string', 287 'context' => array( 'embed', 'view', 'edit' ), 288 'readonly' => true, 289 ), 290 'menu' => array( 291 'description' => __( 'The ID of the assigned menu.' ), 292 'type' => 'integer', 293 'context' => array( 'embed', 'view', 'edit' ), 294 'readonly' => true, 295 ), 296 ), 297 ); 298 299 return $this->add_additional_fields_schema( $this->schema ); 300 } 301 302 /** 303 * Retrieves the query params for collections. 304 * 305 * @since 5.9.0 306 * 307 * @return array Collection parameters. 308 */ 309 public function get_collection_params() { 310 return array( 311 'context' => $this->get_context_param( array( 'default' => 'view' ) ), 312 ); 313 } 314 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated : Fri Feb 21 08:20:01 2025 | Cross-referenced by PHPXref |