Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
34.48% covered (danger)
34.48%
20 / 58
20.00% covered (danger)
20.00%
1 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
WPCOM_REST_API_V2_Endpoint_Template_Loader
36.36% covered (danger)
36.36%
20 / 55
20.00% covered (danger)
20.00%
1 / 5
24.49
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 register_routes
100.00% covered (success)
100.00%
20 / 20
100.00% covered (success)
100.00%
1 / 1
1
 permissions_check
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
6
 validate_template_type
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
6
 get_item
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2/**
3 * REST API endpoint for resolving template.
4 *
5 * @package automattic/jetpack
6 */
7
8if ( ! defined( 'ABSPATH' ) ) {
9    exit( 0 );
10}
11
12/**
13 * Returns the correct template for the site's page based on the template type
14 */
15class WPCOM_REST_API_V2_Endpoint_Template_Loader extends WP_REST_Controller {
16    /**
17     * Constructor.
18     */
19    public function __construct() {
20        $this->namespace = 'wpcom/v2';
21        $this->rest_base = 'template-loader';
22
23        add_action( 'rest_api_init', array( $this, 'register_routes' ) );
24    }
25
26    /**
27     * Called automatically on `rest_api_init()`.
28     */
29    public function register_routes() {
30        register_rest_route(
31            $this->namespace,
32            sprintf(
33                '/%s/(?P<template_type>\w+)',
34                $this->rest_base
35            ),
36            array(
37                'methods'             => WP_REST_Server::READABLE,
38                'callback'            => array( $this, 'get_item' ),
39                'permission_callback' => array( $this, 'permissions_check' ),
40                'args'                => array(
41                    'template_type' => array(
42                        'description'       => __( 'The type of the template.', 'jetpack' ),
43                        'type'              => 'string',
44                        'required'          => true,
45                        'validate_callback' => array( $this, 'validate_template_type' ),
46                    ),
47                ),
48            )
49        );
50    }
51
52    /**
53     * Checks if the user has permissions to make the request.
54     *
55     * @return true|WP_Error True if the request has read access, WP_Error object otherwise.
56     */
57    public function permissions_check() {
58        // Verify if the current user has edit_theme_options capability.
59        // This capability is required to edit/view/delete templates.
60        if ( ! current_user_can( 'edit_theme_options' ) ) {
61            return new WP_Error(
62                'rest_cannot_manage_templates',
63                __( 'Sorry, you are not allowed to access the templates on this site.', 'jetpack' ),
64                array(
65                    'status' => rest_authorization_required_code(),
66                )
67            );
68        }
69
70        return true;
71    }
72
73    /**
74     * Validate the template type.
75     *
76     * @param string $template_type The template type.
77     * @return boolean True if the template type is valid.
78     */
79    public function validate_template_type( $template_type ) {
80        $template_types = array_keys( get_default_block_template_types() );
81        if ( ! in_array( $template_type, $template_types, true ) ) {
82            return new WP_Error(
83                'rest_invalid_param',
84                sprintf(
85                    /* translators: %s: The template type. */
86                    __( 'The template type %s are not allowed.', 'jetpack' ),
87                    $template_type
88                ),
89                array( 'status' => 400 )
90            );
91        }
92
93        return true;
94    }
95
96    /**
97     * Retrieves the template by specified type.
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        $template_type = $request['template_type'];
104
105        // A list of template candidates, in descending order of priority.
106        $templates      = apply_filters( "{$template_type}_template_hierarchy", array( "{$template_type}.php" ) );
107        $template       = locate_template( $templates );
108        $block_template = resolve_block_template( $template_type, $templates, $template );
109
110        if ( empty( $block_template ) ) {
111            return new WP_Error( 'not_found', 'Template not found', array( 'status' => 404 ) );
112        }
113
114        return rest_ensure_response(
115            array(
116                'type' => $block_template->type,
117                'id'   => $block_template->id,
118            )
119        );
120    }
121}
122
123wpcom_rest_api_v2_load_plugin( 'WPCOM_REST_API_V2_Endpoint_Template_Loader' );