wp/wp-includes/rest-api/endpoints/class-wp-rest-navigation-fallback-controller.php
changeset 21 48c4eec2b7e6
equal deleted inserted replaced
20:7b1b88e27a20 21:48c4eec2b7e6
       
     1 <?php
       
     2 /**
       
     3  * WP_REST_Navigation_Fallback_Controller class
       
     4  *
       
     5  * REST Controller to create/fetch a fallback Navigation Menu.
       
     6  *
       
     7  * @package WordPress
       
     8  * @subpackage REST_API
       
     9  * @since 6.3.0
       
    10  */
       
    11 
       
    12 /**
       
    13  * REST Controller to fetch a fallback Navigation Block Menu. If needed it creates one.
       
    14  *
       
    15  * @since 6.3.0
       
    16  */
       
    17 class WP_REST_Navigation_Fallback_Controller extends WP_REST_Controller {
       
    18 
       
    19 	/**
       
    20 	 * The Post Type for the Controller
       
    21 	 *
       
    22 	 * @since 6.3.0
       
    23 	 *
       
    24 	 * @var string
       
    25 	 */
       
    26 	private $post_type;
       
    27 
       
    28 	/**
       
    29 	 * Constructs the controller.
       
    30 	 *
       
    31 	 * @since 6.3.0
       
    32 	 */
       
    33 	public function __construct() {
       
    34 		$this->namespace = 'wp-block-editor/v1';
       
    35 		$this->rest_base = 'navigation-fallback';
       
    36 		$this->post_type = 'wp_navigation';
       
    37 	}
       
    38 
       
    39 	/**
       
    40 	 * Registers the controllers routes.
       
    41 	 *
       
    42 	 * @since 6.3.0
       
    43 	 */
       
    44 	public function register_routes() {
       
    45 
       
    46 		// Lists a single nav item based on the given id or slug.
       
    47 		register_rest_route(
       
    48 			$this->namespace,
       
    49 			'/' . $this->rest_base,
       
    50 			array(
       
    51 				array(
       
    52 					'methods'             => WP_REST_Server::READABLE,
       
    53 					'callback'            => array( $this, 'get_item' ),
       
    54 					'permission_callback' => array( $this, 'get_item_permissions_check' ),
       
    55 					'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::READABLE ),
       
    56 				),
       
    57 				'schema' => array( $this, 'get_item_schema' ),
       
    58 			)
       
    59 		);
       
    60 	}
       
    61 
       
    62 	/**
       
    63 	 * Checks if a given request has access to read fallbacks.
       
    64 	 *
       
    65 	 * @since 6.3.0
       
    66 	 *
       
    67 	 * @param WP_REST_Request $request Full details about the request.
       
    68 	 * @return true|WP_Error True if the request has read access, WP_Error object otherwise.
       
    69 	 */
       
    70 	public function get_item_permissions_check( $request ) {
       
    71 
       
    72 		$post_type = get_post_type_object( $this->post_type );
       
    73 
       
    74 		// Getting fallbacks requires creating and reading `wp_navigation` posts.
       
    75 		if ( ! current_user_can( $post_type->cap->create_posts ) || ! current_user_can( 'edit_theme_options' ) || ! current_user_can( 'edit_posts' ) ) {
       
    76 			return new WP_Error(
       
    77 				'rest_cannot_create',
       
    78 				__( 'Sorry, you are not allowed to create Navigation Menus as this user.' ),
       
    79 				array( 'status' => rest_authorization_required_code() )
       
    80 			);
       
    81 		}
       
    82 
       
    83 		if ( 'edit' === $request['context'] && ! current_user_can( $post_type->cap->edit_posts ) ) {
       
    84 			return new WP_Error(
       
    85 				'rest_forbidden_context',
       
    86 				__( 'Sorry, you are not allowed to edit Navigation Menus as this user.' ),
       
    87 				array( 'status' => rest_authorization_required_code() )
       
    88 			);
       
    89 		}
       
    90 
       
    91 		return true;
       
    92 	}
       
    93 
       
    94 	/**
       
    95 	 * Gets the most appropriate fallback Navigation Menu.
       
    96 	 *
       
    97 	 * @since 6.3.0
       
    98 	 *
       
    99 	 * @param WP_REST_Request $request Full details about the request.
       
   100 	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
       
   101 	 */
       
   102 	public function get_item( $request ) {
       
   103 		$post = WP_Navigation_Fallback::get_fallback();
       
   104 
       
   105 		if ( empty( $post ) ) {
       
   106 			return rest_ensure_response( new WP_Error( 'no_fallback_menu', __( 'No fallback menu found.' ), array( 'status' => 404 ) ) );
       
   107 		}
       
   108 
       
   109 		$response = $this->prepare_item_for_response( $post, $request );
       
   110 
       
   111 		return $response;
       
   112 	}
       
   113 
       
   114 	/**
       
   115 	 * Retrieves the fallbacks' schema, conforming to JSON Schema.
       
   116 	 *
       
   117 	 * @since 6.3.0
       
   118 	 *
       
   119 	 * @return array Item schema data.
       
   120 	 */
       
   121 	public function get_item_schema() {
       
   122 		if ( $this->schema ) {
       
   123 			return $this->add_additional_fields_schema( $this->schema );
       
   124 		}
       
   125 
       
   126 		$this->schema = array(
       
   127 			'$schema'    => 'http://json-schema.org/draft-04/schema#',
       
   128 			'title'      => 'navigation-fallback',
       
   129 			'type'       => 'object',
       
   130 			'properties' => array(
       
   131 				'id' => array(
       
   132 					'description' => __( 'The unique identifier for the Navigation Menu.' ),
       
   133 					'type'        => 'integer',
       
   134 					'context'     => array( 'view', 'edit', 'embed' ),
       
   135 					'readonly'    => true,
       
   136 				),
       
   137 			),
       
   138 		);
       
   139 
       
   140 		return $this->add_additional_fields_schema( $this->schema );
       
   141 	}
       
   142 
       
   143 	/**
       
   144 	 * Matches the post data to the schema we want.
       
   145 	 *
       
   146 	 * @since 6.3.0
       
   147 	 *
       
   148 	 * @param WP_Post         $item    The wp_navigation Post object whose response is being prepared.
       
   149 	 * @param WP_REST_Request $request Request object.
       
   150 	 * @return WP_REST_Response $response The response data.
       
   151 	 */
       
   152 	public function prepare_item_for_response( $item, $request ) {
       
   153 		$data = array();
       
   154 
       
   155 		$fields = $this->get_fields_for_response( $request );
       
   156 
       
   157 		if ( rest_is_field_included( 'id', $fields ) ) {
       
   158 			$data['id'] = (int) $item->ID;
       
   159 		}
       
   160 
       
   161 		$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
       
   162 		$data    = $this->add_additional_fields_to_object( $data, $request );
       
   163 		$data    = $this->filter_response_by_context( $data, $context );
       
   164 
       
   165 		$response = rest_ensure_response( $data );
       
   166 
       
   167 		if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
       
   168 			$links = $this->prepare_links( $item );
       
   169 			$response->add_links( $links );
       
   170 		}
       
   171 
       
   172 		return $response;
       
   173 	}
       
   174 
       
   175 	/**
       
   176 	 * Prepares the links for the request.
       
   177 	 *
       
   178 	 * @since 6.3.0
       
   179 	 *
       
   180 	 * @param WP_Post $post the Navigation Menu post object.
       
   181 	 * @return array Links for the given request.
       
   182 	 */
       
   183 	private function prepare_links( $post ) {
       
   184 		return array(
       
   185 			'self' => array(
       
   186 				'href'       => rest_url( rest_get_route_for_post( $post->ID ) ),
       
   187 				'embeddable' => true,
       
   188 			),
       
   189 		);
       
   190 	}
       
   191 }