PluginProbe
Gutenberg / 12.6.0
Gutenberg v12.6.0
23.9.1 23.9.0 23.8.0 23.7.2 23.7.1 23.7.0 23.6.1 23.6.2 23.6.0 23.5.3 23.5.2 23.5.1 23.5.0 23.4.0 23.3.2 23.3.1 23.3.0 23.2.0 23.2.1 23.2.2 23.1.1 23.1.0 23.0.1 12.6.0 7.4.0 All 402 releases
gutenberg / lib / class-wp-rest-menu-locations-controller.php

class-wp-rest-menu-locations-controller.php in Gutenberg 12.6.0, at lib/class-wp-rest-menu-locations-controller.php

277 lines 8.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * REST API: WP_REST_Menu_Locations_Controller class
4 *
5 * @subpackage REST_API
6 * @package WordPress
7 */
8
9 /**
10 * Core class used to access menu locations via the REST API.
11 *
12 * @see WP_REST_Controller
13 */
14 class WP_REST_Menu_Locations_Controller extends WP_REST_Controller {
15
16 /**
17 * Constructor.
18 */
19 public function __construct() {
20 $this->namespace = 'wp/v2';
21 $this->rest_base = 'menu-locations';
22 }
23
24 /**
25 * Registers the routes for the objects of the controller.
26 *
27 * @see register_rest_route()
28 */
29 public function register_routes() {
30 register_rest_route(
31 $this->namespace,
32 '/' . $this->rest_base,
33 array(
34 array(
35 'methods' => WP_REST_Server::READABLE,
36 'callback' => array( $this, 'get_items' ),
37 'permission_callback' => array( $this, 'get_items_permissions_check' ),
38 'args' => $this->get_collection_params(),
39 ),
40 'schema' => array( $this, 'get_public_item_schema' ),
41 )
42 );
43
44 register_rest_route(
45 $this->namespace,
46 '/' . $this->rest_base . '/(?P<location>[\w-]+)',
47 array(
48 'args' => array(
49 'location' => array(
50 'description' => __( 'An alphanumeric identifier for the menu location.', 'gutenberg' ),
51 'type' => 'string',
52 ),
53 ),
54 array(
55 'methods' => WP_REST_Server::READABLE,
56 'callback' => array( $this, 'get_item' ),
57 'permission_callback' => array( $this, 'get_item_permissions_check' ),
58 'args' => array(
59 'context' => $this->get_context_param( array( 'default' => 'view' ) ),
60 ),
61 ),
62 'schema' => array( $this, 'get_public_item_schema' ),
63 )
64 );
65 }
66
67 /**
68 * Checks whether a given request has permission to read menu locations.
69 *
70 * @param WP_REST_Request $request Full details about the request.
71 *
72 * @return WP_Error|bool True if the request has read access, WP_Error object otherwise.
73 */
74 public function get_items_permissions_check( $request ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
75 if ( ! current_user_can( 'edit_theme_options' ) ) {
76 return new WP_Error( 'rest_cannot_view', __( 'Sorry, you are not allowed to view menu locations.', 'gutenberg' ), array( 'status' => rest_authorization_required_code() ) );
77 }
78
79 return true;
80 }
81
82 /**
83 * Retrieves all menu locations, depending on user context.
84 *
85 * @param WP_REST_Request $request Full details about the request.
86 *
87 * @return WP_Error|WP_REST_Response Response object on success, or WP_Error object on failure.
88 */
89 public function get_items( $request ) {
90 $data = array();
91
92 foreach ( get_registered_nav_menus() as $name => $description ) {
93 $location = new stdClass();
94 $location->name = $name;
95 $location->description = $description;
96
97 $location = $this->prepare_item_for_response( $location, $request );
98 $data[ $name ] = $this->prepare_response_for_collection( $location );
99 }
100
101 return rest_ensure_response( $data );
102 }
103
104 /**
105 * Checks if a given request has access to read a menu location.
106 *
107 * @param WP_REST_Request $request Full details about the request.
108 *
109 * @return WP_Error|bool True if the request has read access for the item, WP_Error object otherwise.
110 */
111 public function get_item_permissions_check( $request ) {
112 if ( ! current_user_can( 'edit_theme_options' ) ) {
113 return new WP_Error( 'rest_cannot_view', __( 'Sorry, you are not allowed to view menu locations.', 'gutenberg' ), array( 'status' => rest_authorization_required_code() ) );
114 }
115 if ( ! array_key_exists( $request['location'], get_registered_nav_menus() ) ) {
116 return new WP_Error( 'rest_menu_location_invalid', __( 'Invalid menu location.', 'gutenberg' ), array( 'status' => 404 ) );
117 }
118
119 return true;
120 }
121
122 /**
123 * Retrieves a specific menu location.
124 *
125 * @param WP_REST_Request $request Full details about the request.
126 *
127 * @return WP_Error|WP_REST_Response 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.', 'gutenberg' ), 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 * Prepares a menu location object for serialization.
146 *
147 * @param stdClass $location Post status data.
148 * @param WP_REST_Request $request Full details about the request.
149 *
150 * @return WP_REST_Response Post status data.
151 */
152 public function prepare_item_for_response( $location, $request ) {
153 $locations = get_nav_menu_locations();
154 $menu = ( isset( $locations[ $location->name ] ) ) ? $locations[ $location->name ] : 0;
155
156 $fields = $this->get_fields_for_response( $request );
157 $data = array();
158
159 if ( rest_is_field_included( 'name', $fields ) ) {
160 $data['name'] = $location->name;
161 }
162
163 if ( rest_is_field_included( 'description', $fields ) ) {
164 $data['description'] = $location->description;
165 }
166
167 if ( rest_is_field_included( 'menu', $fields ) ) {
168 $data['menu'] = (int) $menu;
169 }
170
171 $context = ! empty( $request['context'] ) ? $request['context'] : 'view';
172 $data = $this->add_additional_fields_to_object( $data, $request );
173 $data = $this->filter_response_by_context( $data, $context );
174
175 $response = rest_ensure_response( $data );
176
177 $response->add_links( $this->prepare_links( $location ) );
178
179 /**
180 * Filters a menu location returned from the REST API.
181 *
182 * Allows modification of the menu location data right before it is
183 * returned.
184 *
185 * @param WP_REST_Response $response The response object.
186 * @param object $location The original status object.
187 * @param WP_REST_Request $request Request used to generate the response.
188 */
189 return apply_filters( 'rest_prepare_menu_location', $response, $location, $request );
190 }
191
192 /**
193 * Retrieves the menu location's schema, conforming to JSON Schema.
194 *
195 * @return array Item schema data.
196 */
197 public function get_item_schema() {
198 $schema = array(
199 '$schema' => 'http://json-schema.org/draft-04/schema#',
200 'title' => 'menu-location',
201 'type' => 'object',
202 'properties' => array(
203 'name' => array(
204 'description' => __( 'The name of the menu location.', 'gutenberg' ),
205 'type' => 'string',
206 'context' => array( 'embed', 'view', 'edit' ),
207 'readonly' => true,
208 ),
209 'description' => array(
210 'description' => __( 'The description of the menu location.', 'gutenberg' ),
211 'type' => 'string',
212 'context' => array( 'embed', 'view', 'edit' ),
213 'readonly' => true,
214 ),
215 'menu' => array(
216 'description' => __( 'The ID of the assigned menu.', 'gutenberg' ),
217 'type' => 'integer',
218 'context' => array( 'embed', 'view', 'edit' ),
219 'readonly' => true,
220 ),
221 ),
222 );
223
224 return $this->add_additional_fields_schema( $schema );
225 }
226
227 /**
228 * Retrieves the query params for collections.
229 *
230 * @return array Collection parameters.
231 */
232 public function get_collection_params() {
233 return array(
234 'context' => $this->get_context_param( array( 'default' => 'view' ) ),
235 );
236 }
237
238 /**
239 * Prepares links for the request.
240 *
241 * @param stdClass $location Menu location.
242 *
243 * @return array Links for the given menu location.
244 */
245 protected function prepare_links( $location ) {
246 $base = sprintf( '%s/%s', $this->namespace, $this->rest_base );
247
248 // Entity meta.
249 $links = array(
250 'self' => array(
251 'href' => rest_url( trailingslashit( $base ) . $location->name ),
252 ),
253 'collection' => array(
254 'href' => rest_url( $base ),
255 ),
256 );
257
258 $locations = get_nav_menu_locations();
259 $menu = ( isset( $locations[ $location->name ] ) ) ? $locations[ $location->name ] : 0;
260 if ( $menu ) {
261 $taxonomy_object = get_taxonomy( 'nav_menu' );
262 if ( $taxonomy_object->show_in_rest ) {
263 $rest_base = ! empty( $taxonomy_object->rest_base ) ? $taxonomy_object->rest_base : $taxonomy_object->name;
264 $namespace = ! empty( $taxonomy_object->rest_namespace ) ? $taxonomy_object->rest_namespace : '__experimental';
265 $url = rest_url( sprintf( '%s/%s/%d', $namespace, $rest_base, $menu ) );
266
267 $links['https://api.w.org/menu'][] = array(
268 'href' => $url,
269 'embeddable' => true,
270 );
271 }
272 }
273
274 return $links;
275 }
276 }
277