PluginProbe
Performance Lab / 4.1.0
Performance Lab v4.1.0
trunk 1.0.0 1.0.0-beta.1 1.0.0-beta.2 1.0.0-beta.3 1.0.0-rc.1 1.1.0 1.2.0 1.3.0 1.4.0 1.5.0 1.6.0 1.7.0 1.8.0 1.9.0 2.0.0 2.1.0 2.2.0 2.3.0 2.4.0 2.5.0 2.6.0 2.6.1 2.7.0 2.8.0 All 44 releases
performance-lab / includes / admin / rest-api.php

rest-api.php in Performance Lab 4.1.0, at includes/admin/rest-api.php

186 lines 5.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * REST API integration for the plugin.
4 *
5 * @package performance-lab
6 * @since 3.6.0
7 */
8
9 // @codeCoverageIgnoreStart
10 if ( ! defined( 'ABSPATH' ) ) {
11 exit; // Exit if accessed directly.
12 }
13 // @codeCoverageIgnoreEnd
14
15 /**
16 * Namespace for performance-lab REST API.
17 *
18 * @since 3.6.0
19 * @var string
20 */
21 const PERFLAB_REST_API_NAMESPACE = 'performance-lab/v1';
22
23 /**
24 * Route for activating plugin/feature.
25 *
26 * Note the `:activate` art of the endpoint follows Google's guidance in AIP-136 for the use of the POST method in a way
27 * that does not strictly follow the standard usage.
28 *
29 * @since 3.6.0
30 * @link https://google.aip.dev/136
31 * @var string
32 */
33 const PERFLAB_FEATURES_ACTIVATE_ROUTE = '/features/(?P<slug>[a-z0-9_-]+):activate';
34
35 /**
36 * Route for fetching plugin/feature information.
37 *
38 * @since 3.6.0
39 * @var string
40 */
41 const PERFLAB_FEATURES_INFORMATION_ROUTE = '/features/(?P<slug>[a-z0-9_-]+)';
42
43 /**
44 * Registers endpoint for performance-lab REST API.
45 *
46 * @since 3.6.0
47 * @access private
48 */
49 function perflab_register_endpoint(): void {
50 register_rest_route(
51 PERFLAB_REST_API_NAMESPACE,
52 PERFLAB_FEATURES_ACTIVATE_ROUTE,
53 array(
54 'methods' => 'POST',
55 'args' => array(
56 'slug' => array(
57 'type' => 'string',
58 'description' => __( 'Plugin slug of the Performance Lab feature to be activated.', 'performance-lab' ),
59 'required' => true,
60 'validate_callback' => 'perflab_validate_slug_endpoint_arg',
61 ),
62 ),
63 'callback' => 'perflab_handle_feature_activation',
64 'permission_callback' => static function () {
65 // Important: The endpoint calls perflab_install_and_activate_plugin() which does more granular capability checks.
66 if ( current_user_can( 'activate_plugins' ) ) {
67 return true;
68 }
69
70 return new WP_Error( 'cannot_activate', __( 'Sorry, you are not allowed to activate this feature.', 'performance-lab' ) );
71 },
72 )
73 );
74
75 register_rest_route(
76 PERFLAB_REST_API_NAMESPACE,
77 PERFLAB_FEATURES_INFORMATION_ROUTE,
78 array(
79 'methods' => 'GET',
80 'args' => array(
81 'slug' => array(
82 'type' => 'string',
83 'description' => __( 'Plugin slug of plugin/feature whose information is needed.', 'performance-lab' ),
84 'required' => true,
85 'validate_callback' => 'perflab_validate_slug_endpoint_arg',
86 ),
87 ),
88 'callback' => 'perflab_handle_get_feature_information',
89 'permission_callback' => static function () {
90 if ( current_user_can( 'manage_options' ) ) {
91 return true;
92 }
93
94 return new WP_Error( 'cannot_access_plugin_settings_url', __( 'Sorry, you are not allowed to access plugin/feature information on this site.', 'performance-lab' ) );
95 },
96 )
97 );
98 }
99 add_action( 'rest_api_init', 'perflab_register_endpoint' );
100
101 /**
102 * Validates whether the provided plugin slug is a valid Performance Lab plugin.
103 *
104 * Note that an enum is not being used because additional PHP files have to be required to access the necessary functions,
105 * and this would not be ideal to do at rest_api_init.
106 *
107 * @since 3.6.0
108 * @access private
109 *
110 * @param string $slug Plugin slug.
111 * @return bool Whether valid.
112 */
113 function perflab_validate_slug_endpoint_arg( string $slug ): bool {
114 require_once ABSPATH . 'wp-admin/includes/plugin.php';
115 require_once PERFLAB_PLUGIN_DIR_PATH . 'includes/admin/load.php';
116 require_once PERFLAB_PLUGIN_DIR_PATH . 'includes/admin/plugins.php';
117 return in_array( $slug, perflab_get_standalone_plugins(), true );
118 }
119
120 /**
121 * Handles REST API request to activate plugin/feature.
122 *
123 * @since 3.6.0
124 * @access private
125 *
126 * @phpstan-param WP_REST_Request<array<string, mixed>> $request
127 *
128 * @param WP_REST_Request $request Request.
129 * @return WP_REST_Response|WP_Error Response.
130 */
131 function perflab_handle_feature_activation( WP_REST_Request $request ) {
132 require_once ABSPATH . 'wp-admin/includes/file.php';
133 require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
134 require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
135 require_once ABSPATH . 'wp-admin/includes/class-wp-ajax-upgrader-skin.php';
136
137 // Install and activate the plugin/feature and its dependencies.
138 $result = perflab_install_and_activate_plugin( $request['slug'] );
139 if ( is_wp_error( $result ) ) {
140 switch ( $result->get_error_code() ) {
141 case 'cannot_install_plugin':
142 case 'cannot_activate_plugin':
143 $response_code = rest_authorization_required_code();
144 break;
145 case 'plugin_not_found':
146 $response_code = 404;
147 break;
148 default:
149 $response_code = 500;
150 }
151 return new WP_Error(
152 $result->get_error_code(),
153 $result->get_error_message(),
154 array( 'status' => $response_code )
155 );
156 }
157
158 return new WP_REST_Response(
159 array(
160 'success' => true,
161 )
162 );
163 }
164
165 /**
166 * Handles REST API request to get plugin/feature information.
167 *
168 * @since 3.6.0
169 * @access private
170 *
171 * @phpstan-param WP_REST_Request<array<string, mixed>> $request
172 *
173 * @param WP_REST_Request $request Request.
174 * @return WP_REST_Response Response.
175 */
176 function perflab_handle_get_feature_information( WP_REST_Request $request ): WP_REST_Response {
177 $plugin_settings_url = perflab_get_plugin_settings_url( $request['slug'] );
178
179 return new WP_REST_Response(
180 array(
181 'slug' => $request['slug'],
182 'settingsUrl' => $plugin_settings_url,
183 )
184 );
185 }
186