PluginProbe
seQura / 4.1.1
seQura v4.1.1
4.3.4 4.3.3 4.3.2 4.3.1 trunk 2.0.0 2.0.10 2.0.11 2.0.12 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 3.0.0 3.0.2 3.0.5 3.0.6 3.0.7 3.1.0 3.1.1 3.2.0 3.2.1 3.2.2 4.0.0 All 30 releases
sequra / src / Controllers / Rest / class-rest-controller.php

class-rest-controller.php in seQura 4.1.1, at src/Controllers/Rest/class-rest-controller.php

339 lines 10.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Helper for REST Controllers
4 *
5 * @package SeQura/WC
6 * @subpackage SeQura/WC/Controllers/Rest
7 */
8
9 namespace SeQura\WC\Controllers\Rest;
10
11 use SeQura\Core\BusinessLogic\AdminAPI\Response\Response;
12 use SeQura\Core\Infrastructure\Utility\RegexProvider;
13 use SeQura\WC\Services\Log\Interface_Logger_Service;
14 use WP;
15 use WP_Error;
16 use WP_REST_Request;
17 use WP_REST_Response;
18
19 /**
20 * Helper for REST Controllers
21 */
22 abstract class REST_Controller extends \WP_REST_Controller {
23
24 protected const PARAM_STORE_ID = 'storeId';
25 protected const PARAM_MERCHANT_ID = 'merchantId';
26
27 /**
28 * Logger service.
29 *
30 * @var Interface_Logger_Service
31 */
32 protected $logger;
33
34 /**
35 * RegEx service
36 *
37 * @var RegexProvider
38 */
39 protected $regex;
40
41 /**
42 * Constructor.
43 *
44 * @param Interface_Logger_Service $logger The logger service.
45 * @param RegexProvider $regex The regex provider.
46 */
47 public function __construct( Interface_Logger_Service $logger, RegexProvider $regex ) {
48 $this->logger = $logger;
49 $this->regex = $regex;
50 }
51
52 /**
53 * Check if the current user can manage options.
54 */
55 public function can_user_manage_options(): bool {
56 return \user_can( \get_current_user_id(), 'manage_options' );
57 }
58
59 /**
60 * Register GET endpoint.
61 *
62 * @param string $endpoint The endpoint.
63 * @param string $fun The function.
64 * @param mixed[] $args The arguments. See https://developer.wordpress.org/rest-api/extending-the-rest-api/adding-custom-endpoints/
65 * @param string $permission_callback The permission callback.
66 */
67 protected function register_get( $endpoint, $fun, $args = array(), $permission_callback = 'can_user_manage_options' ): void {
68 $this->register( \WP_REST_Server::READABLE, $endpoint, $fun, $args, $permission_callback );
69 }
70
71 /**
72 * Register POST endpoint.
73 *
74 * @param string $endpoint The endpoint.
75 * @param string $fun The function.
76 * @param mixed[] $args The arguments. See https://developer.wordpress.org/rest-api/extending-the-rest-api/adding-custom-endpoints/
77 * @param string $permission_callback The permission callback.
78 */
79 protected function register_post( $endpoint, $fun, $args = array(), $permission_callback = 'can_user_manage_options' ): void {
80 $this->register( \WP_REST_Server::CREATABLE, $endpoint, $fun, $args, $permission_callback );
81 }
82
83 /**
84 * Register DELETE endpoint.
85 *
86 * @param string $endpoint The endpoint.
87 * @param string $fun The function.
88 * @param mixed[] $args The arguments. See https://developer.wordpress.org/rest-api/extending-the-rest-api/adding-custom-endpoints/
89 * @param string $permission_callback The permission callback.
90 */
91 protected function register_delete( $endpoint, $fun, $args = array(), $permission_callback = 'can_user_manage_options' ): void {
92 $this->register( \WP_REST_Server::DELETABLE, $endpoint, $fun, $args, $permission_callback );
93 }
94
95 /**
96 * Register endpoint.
97 *
98 * @param string $methods The HTTP Verb.
99 * @param string $endpoint The endpoint.
100 * @param string $fun The function.
101 * @param mixed[] $arguments The arguments. See https://developer.wordpress.org/rest-api/extending-the-rest-api/adding-custom-endpoints/
102 * @param string $permission_callback The permission callback.
103 */
104 private function register( $methods, $endpoint, $fun, $arguments, $permission_callback ): void {
105 $args = array(
106 'methods' => $methods,
107 'callback' => array( $this, $fun ),
108 'permission_callback' => array( $this, $permission_callback ),
109 );
110 if ( ! empty( $arguments ) && is_array( $arguments ) ) {
111 $args['args'] = $arguments;
112 }
113 \register_rest_route( $this->namespace, "{$this->rest_base}/$endpoint", $args );
114 }
115
116 /**
117 * Validate if the parameter is not empty string.
118 *
119 * @param mixed $param The parameter.
120 * @param WP_REST_Request $request The request.
121 * @param string $key The key.
122 */
123 public function validate_not_empty_string( $param, $request, $key ): bool {
124 return is_string( $param ) && '' !== trim( $param );
125 }
126
127 /**
128 * Validate if the parameter is a boolean.
129 *
130 * @param mixed $param The parameter.
131 * @param WP_REST_Request $request The request.
132 * @param string $key The key.
133 */
134 public function validate_is_bool( $param, $request, $key ): bool {
135 return is_bool( $param );
136 }
137
138 /**
139 * Validate if the parameter is an integer.
140 *
141 * @param mixed $param The parameter.
142 * @param WP_REST_Request $request The request.
143 * @param string $key The key.
144 */
145 public function validate_is_int( $param, $request, $key ): bool {
146 return is_int( $param );
147 }
148
149 /**
150 * Validate id the parameter is an array of IP addresses.
151 *
152 * @param mixed $param The parameter.
153 * @param WP_REST_Request $request The request.
154 * @param string $key The key.
155 */
156 public function validate_ip_list( $param, $request, $key ): bool {
157 $ip_regex = $this->regex->getIpRegex();
158 if ( ! is_array( $param ) ) {
159 return false;
160 }
161 foreach ( $param as $ip ) {
162 if ( preg_match( $ip_regex, $ip ) !== 1 ) {
163 return false;
164 }
165 }
166 return true;
167 }
168
169 /**
170 * Check dates (yyyy-mm-dd) and time durations (PnYnMnDTnHnMnS). ISO 8061 regex to validate the date format.
171 *
172 * @param mixed $param The parameter.
173 * @param WP_REST_Request $request The request.
174 * @param string $key The key.
175 */
176 public function validate_time_duration( $param, $request, $key ): bool {
177 $regex = $this->regex->getDateOrDurationRegex();
178 return is_string( $param ) && preg_match( $regex, $param ) === 1 && 'P' !== $param && ! str_ends_with( $param, 'T' );
179 }
180
181 /**
182 * Sanitize boolean.
183 *
184 * @param mixed $param The parameter.
185 */
186 public function sanitize_bool( $param ): bool {
187 return (bool) $param;
188 }
189
190 /**
191 * Sanitize boolean.
192 *
193 * @param mixed $param The parameter.
194 */
195 public function sanitize_int( $param ): int {
196 return intval( $param );
197 }
198
199 /**
200 * Sanitize an array strings.
201 *
202 * @param mixed[] $param The parameter.
203 * @return mixed[]
204 */
205 public function sanitize_array_sanitize_text_field( $param ): array {
206 foreach ( $param as &$value ) {
207 $value = \sanitize_text_field( strval( $value ) );
208 }
209 return $param;
210 }
211
212 /**
213 * Get base argument structure.
214 *
215 * @param bool $required If the argument is required.
216 * @param mixed $default_value The default value. Null will be ignored.
217 * @return mixed[]
218 */
219 protected function get_arg( $required = true, $default_value = null ): array {
220 $arg = array( 'required' => $required );
221 if ( null !== $default_value ) {
222 $arg['default'] = $default_value;
223 }
224 return $arg;
225 }
226
227 /**
228 * Get argument structure for a boolean parameter.
229 *
230 * @param bool $required If the argument is required.
231 * @param mixed $default_value The default value. Null will be ignored.
232 * @return mixed[]
233 */
234 protected function get_arg_bool( $required = true, $default_value = null ): array {
235 return array_merge(
236 $this->get_arg( $required, $default_value ),
237 array(
238 'validate_callback' => array( $this, 'validate_is_bool' ),
239 'sanitize_callback' => array( $this, 'sanitize_bool' ),
240 )
241 );
242 }
243
244 /**
245 * Get argument structure for a integer parameter.
246 *
247 * @param bool $required If the argument is required.
248 * @param mixed $default_value The default value. Null will be ignored.
249 * @return mixed[]
250 */
251 protected function get_arg_int( $required = true, $default_value = null ): array {
252 return array_merge(
253 $this->get_arg( $required, $default_value ),
254 array(
255 'validate_callback' => array( $this, 'validate_is_int' ),
256 'sanitize_callback' => array( $this, 'sanitize_int' ),
257 )
258 );
259 }
260
261 /**
262 * Get argument structure for a boolean parameter.
263 *
264 * @param bool $required If the argument is required.
265 * @param mixed $default_value The default value. Null will be ignored.
266 * @param callable $validate The validate callback. Leave null to use the default.
267 * @param callable $sanitize The sanitize callback. Leave null to use the default.
268 * @return mixed[]
269 */
270 protected function get_arg_string( $required = true, $default_value = null, $validate = null, $sanitize = null ): array {
271 return array_merge(
272 $this->get_arg( $required, $default_value ),
273 array(
274 'validate_callback' => null === $validate ? array( $this, 'validate_not_empty_string' ) : $validate,
275 'sanitize_callback' => null === $sanitize ? 'sanitize_text_field' : $sanitize,
276 )
277 );
278 }
279
280 /**
281 * Get argument structure for an IP list.
282 *
283 * @param bool $required If the argument is required.
284 * @param mixed $default_value The default value. Null will be ignored.
285 * @param callable $validate The validate callback. Leave null to use the default.
286 * @param callable $sanitize The sanitize callback. Leave null to use the default.
287 * @return mixed[]
288 */
289 protected function get_arg_ip_list( $required = true, $default_value = null, $validate = null, $sanitize = null ): array {
290 return array_merge(
291 $this->get_arg( $required, $default_value ),
292 array(
293 'validate_callback' => null === $validate ? array( $this, 'validate_ip_list' ) : $validate,
294 'sanitize_callback' => null === $sanitize ? array( $this, 'sanitize_array_sanitize_text_field' ) : $sanitize,
295 )
296 );
297 }
298
299 /**
300 * Return a valid pattern to be used in a URL to match a parameter.
301 *
302 * @param string $param_name The URL parameter name.
303 * @param string $type The type of the parameter. Default is 'string'.
304 * Supported values are:
305 * - 'string'.
306 */
307 protected function url_param_pattern( $param_name, $type = 'string' ): string {
308 switch ( $type ) {
309 case 'string':
310 return '(?P<' . $param_name . '>[\w]+)';
311 default:
312 return '';
313 }
314 }
315
316 /**
317 * Build a valid response for the REST API
318 *
319 * @return WP_REST_Response|WP_Error
320 */
321 protected function build_response( Response $response ) {
322 return $this->build_response_from_array( $response->toArray(), $response->isSuccessful() );
323 }
324
325 /**
326 * Build a valid response for the REST API from an array
327 *
328 * @return WP_REST_Response|WP_Error
329 */
330 protected function build_response_from_array( array $response_array, bool $is_successful ) {
331 if ( ! $is_successful ) {
332 $code = strval( $response_array['statusCode'] ?? '500' );
333 $message = strval( $response_array['errorMessage'] ?? 'Unknown error' );
334 return new WP_Error( $code, $message );
335 }
336 return \rest_ensure_response( $response_array );
337 }
338 }
339