PluginProbe
Elementor Website Builder – more than just a page builder / 3.30.1
Elementor Website Builder – more than just a page builder v3.30.1
4.3.0-beta2 4.3.0-beta1 4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.5 4.2.0-beta2 4.2.0-dev2 4.2.0-beta1 4.1.4 4.1.3 4.1.2 4.1.1 4.1.0 4.1.0-beta3 4.1.0-dev3 4.0.9 4.1.0-beta2 4.1.0-dev2 4.0.8 4.1.0-beta1 4.1.0-dev1 4.0.7 All 451 releases
← All changes | modules/variables/classes/rest-api.php +30 -291 4.2.03.30.1 View file →
@@ -1,21 +1,20 @@
1 1 <?php
2 2
3 3 namespace Elementor\Modules\Variables\Classes;
4 4
5 -use Elementor\Modules\Variables\Storage\Exceptions\Type_Mismatch;
5 +use Exception;
6 6 use WP_Error;
7 -use Exception;
7 +use WP_REST_Response;
8 +use WP_REST_Request;
8 9 use WP_REST_Server;
9 -use WP_REST_Request;
10 +
10 11 use Elementor\Plugin;
11 -use WP_REST_Response;
12 -use Elementor\Modules\Variables\Services\Variables_Service;
13 -use Elementor\Modules\Variables\Module as Variables_Module;
12 +use Elementor\Modules\Variables\PropTypes\Color_Variable_Prop_Type;
13 +use Elementor\Modules\Variables\PropTypes\Font_Variable_Prop_Type;
14 +use Elementor\Modules\Variables\Storage\Repository as Variables_Repository;
14 15 use Elementor\Modules\Variables\Storage\Exceptions\VariablesLimitReached;
15 16 use Elementor\Modules\Variables\Storage\Exceptions\RecordNotFound;
16 -use Elementor\Modules\Variables\Storage\Exceptions\DuplicatedLabel;
17 -use Elementor\Modules\Variables\Storage\Exceptions\BatchOperationFailed;
18 17
19 18 if ( ! defined( 'ABSPATH' ) ) {
20 19 exit; // Exit if accessed directly.
21 20 }
@@ -22,42 +21,40 @@
22 21
23 22 class Rest_Api {
24 23 const API_NAMESPACE = 'elementor/v1';
25 24 const API_BASE = 'variables';
25 +
26 26 const HTTP_OK = 200;
27 27 const HTTP_CREATED = 201;
28 28 const HTTP_BAD_REQUEST = 400;
29 29 const HTTP_NOT_FOUND = 404;
30 30 const HTTP_SERVER_ERROR = 500;
31 +
31 32 const MAX_ID_LENGTH = 64;
32 33 const MAX_LABEL_LENGTH = 50;
33 34 const MAX_VALUE_LENGTH = 512;
34 35
35 - private Variables_Service $service;
36 + private Variables_Repository $variables_repository;
36 37
37 - public function __construct( Variables_Service $service ) {
38 - $this->service = $service;
38 + public function __construct( Variables_Repository $variables_repository ) {
39 + $this->variables_repository = $variables_repository;
39 40 }
40 41
41 - public function enough_permissions_to_perform_ro_action() {
42 + public function enough_permissions_to_perform_action() {
42 43 return current_user_can( 'edit_posts' );
43 44 }
44 45
45 - public function enough_permissions_to_perform_rw_action() {
46 - return current_user_can( 'manage_options' );
47 - }
48 -
49 46 public function register_routes() {
50 47 register_rest_route( self::API_NAMESPACE, '/' . self::API_BASE . '/list', [
51 48 'methods' => WP_REST_Server::READABLE,
52 49 'callback' => [ $this, 'get_variables' ],
53 - 'permission_callback' => [ $this, 'enough_permissions_to_perform_ro_action' ],
50 + 'permission_callback' => [ $this, 'enough_permissions_to_perform_action' ],
54 51 ] );
55 52
56 53 register_rest_route( self::API_NAMESPACE, '/' . self::API_BASE . '/create', [
57 54 'methods' => WP_REST_Server::CREATABLE,
58 55 'callback' => [ $this, 'create_variable' ],
59 - 'permission_callback' => [ $this, 'enough_permissions_to_perform_rw_action' ],
56 + 'permission_callback' => [ $this, 'enough_permissions_to_perform_action' ],
60 57 'args' => [
61 58 'type' => [
62 59 'required' => true,
63 60 'type' => 'string',
@@ -81,9 +78,9 @@
81 78
82 79 register_rest_route( self::API_NAMESPACE, '/' . self::API_BASE . '/update', [
83 80 'methods' => WP_REST_Server::EDITABLE,
84 81 'callback' => [ $this, 'update_variable' ],
85 - 'permission_callback' => [ $this, 'enough_permissions_to_perform_rw_action' ],
82 + 'permission_callback' => [ $this, 'enough_permissions_to_perform_action' ],
86 83 'args' => [
87 84 'id' => [
88 85 'required' => true,
89 86 'type' => 'string',
@@ -101,26 +98,15 @@
101 98 'type' => 'string',
102 99 'validate_callback' => [ $this, 'is_valid_variable_value' ],
103 100 'sanitize_callback' => [ $this, 'trim_and_sanitize_text_field' ],
104 101 ],
105 - 'order' => [
106 - 'required' => false,
107 - 'type' => 'integer',
108 - 'validate_callback' => [ $this, 'is_valid_order' ],
109 - ],
110 - 'type' => [
111 - 'required' => false,
112 - 'type' => 'string',
113 - 'validate_callback' => [ $this, 'is_valid_variable_type' ],
114 - 'sanitize_callback' => [ $this, 'trim_and_sanitize_text_field' ],
115 - ],
116 102 ],
117 103 ] );
118 104
119 105 register_rest_route( self::API_NAMESPACE, '/' . self::API_BASE . '/delete', [
120 - 'methods' => WP_REST_Server::EDITABLE,
106 + 'methods' => WP_REST_Server::DELETABLE,
121 107 'callback' => [ $this, 'delete_variable' ],
122 - 'permission_callback' => [ $this, 'enough_permissions_to_perform_rw_action' ],
108 + 'permission_callback' => [ $this, 'enough_permissions_to_perform_action' ],
123 109 'args' => [
124 110 'id' => [
125 111 'required' => true,
126 112 'type' => 'string',
@@ -132,9 +118,9 @@
132 118
133 119 register_rest_route( self::API_NAMESPACE, '/' . self::API_BASE . '/restore', [
134 120 'methods' => WP_REST_Server::EDITABLE,
135 121 'callback' => [ $this, 'restore_variable' ],
136 - 'permission_callback' => [ $this, 'enough_permissions_to_perform_rw_action' ],
122 + 'permission_callback' => [ $this, 'enough_permissions_to_perform_action' ],
137 123 'args' => [
138 124 'id' => [
139 125 'required' => true,
140 126 'type' => 'string',
@@ -140,50 +126,13 @@
140 126 'type' => 'string',
141 127 'validate_callback' => [ $this, 'is_valid_variable_id' ],
142 128 'sanitize_callback' => [ $this, 'trim_and_sanitize_text_field' ],
143 129 ],
144 - 'label' => [
145 - 'required' => false,
146 - 'type' => 'string',
147 - 'validate_callback' => [ $this, 'is_valid_variable_label' ],
148 - 'sanitize_callback' => [ $this, 'trim_and_sanitize_text_field' ],
149 - ],
150 - 'value' => [
151 - 'required' => false,
152 - 'type' => 'string',
153 - 'validate_callback' => [ $this, 'is_valid_variable_value' ],
154 - 'sanitize_callback' => [ $this, 'trim_and_sanitize_text_field' ],
155 - ],
156 - 'type' => [
157 - 'required' => false,
158 - 'type' => 'string',
159 - 'validate_callback' => [ $this, 'is_valid_variable_type' ],
160 - 'sanitize_callback' => [ $this, 'trim_and_sanitize_text_field' ],
161 - ],
162 130 ],
163 131 ] );
164 -
165 - register_rest_route( self::API_NAMESPACE, '/' . self::API_BASE . '/batch', [
166 - 'methods' => WP_REST_Server::CREATABLE,
167 - 'callback' => [ $this, 'process_batch' ],
168 - 'permission_callback' => [ $this, 'enough_permissions_to_perform_rw_action' ],
169 - 'args' => [
170 - 'watermark' => [
171 - 'required' => true,
172 - 'type' => 'integer',
173 - 'validate_callback' => [ $this, 'is_valid_watermark' ],
174 - ],
175 - 'operations' => [
176 - 'required' => true,
177 - 'type' => 'array',
178 - 'validate_callback' => [ $this, 'is_valid_operations_array' ],
179 - ],
180 - ],
181 - ] );
182 132 }
183 133
184 134 public function trim_and_sanitize_text_field( $value ) {
185 -
186 135 return trim( sanitize_text_field( $value ) );
187 136 }
188 137
189 138 public function is_valid_variable_id( $id ) {
@@ -197,9 +146,8 @@
197 146 }
198 147
199 148 if ( self::MAX_ID_LENGTH < strlen( $id ) ) {
200 149 return new WP_Error( 'invalid_variable_id_length', sprintf(
201 - /* translators: %d: Maximum ID length. */
202 150 __( 'ID cannot exceed %d characters', 'elementor' ),
203 151 self::MAX_ID_LENGTH
204 152 ) );
205 153 }
@@ -207,11 +155,12 @@
207 155 return true;
208 156 }
209 157
210 158 public function is_valid_variable_type( $type ) {
211 - $allowed_types = array_keys( Variables_Module::instance()->get_variable_types_registry()->all() );
212 -
213 - return in_array( $type, $allowed_types, true );
159 + return in_array( $type, [
160 + Color_Variable_Prop_Type::get_key(),
161 + Font_Variable_Prop_Type::get_key(),
162 + ], true );
214 163 }
215 164
216 165 public function is_valid_variable_label( $label ) {
217 166 $label = trim( $label );
@@ -224,9 +173,8 @@
224 173 }
225 174
226 175 if ( self::MAX_LABEL_LENGTH < strlen( $label ) ) {
227 176 return new WP_Error( 'invalid_variable_label_length', sprintf(
228 - /* translators: %d: Maximum label length. */
229 177 __( 'Label cannot exceed %d characters', 'elementor' ),
230 178 self::MAX_LABEL_LENGTH
231 179 ) );
232 180 }
@@ -233,19 +181,8 @@
233 181
234 182 return true;
235 183 }
236 184
237 - public function is_valid_order( $order ) {
238 - if ( ! is_numeric( $order ) || $order < 0 ) {
239 - return new WP_Error(
240 - 'invalid_order',
241 - __( 'Order must be a non-negative integer', 'elementor' )
242 - );
243 - }
244 -
245 - return true;
246 - }
247 -
248 185 public function is_valid_variable_value( $value ) {
249 186 $value = trim( $value );
250 187
251 188 if ( empty( $value ) ) {
@@ -256,9 +193,8 @@
256 193 }
257 194
258 195 if ( self::MAX_VALUE_LENGTH < strlen( $value ) ) {
259 196 return new WP_Error( 'invalid_variable_value_length', sprintf(
260 - /* translators: %d: Maximum value length. */
261 197 __( 'Value cannot exceed %d characters', 'elementor' ),
262 198 self::MAX_VALUE_LENGTH
263 199 ) );
264 200 }
@@ -282,9 +218,9 @@
282 218 $type = $request->get_param( 'type' );
283 219 $label = $request->get_param( 'label' );
284 220 $value = $request->get_param( 'value' );
285 221
286 - $result = $this->service->create( [
222 + $result = $this->variables_repository->create( [
287 223 'type' => $type,
288 224 'label' => $label,
289 225 'value' => $value,
290 226 ] );
@@ -308,28 +244,14 @@
308 244 private function update_existing_variable( WP_REST_Request $request ) {
309 245 $id = $request->get_param( 'id' );
310 246 $label = $request->get_param( 'label' );
311 247 $value = $request->get_param( 'value' );
312 - $order = $request->get_param( 'order' );
313 - $type = $request->get_param( 'type' );
314 248
315 - $update_data = [
249 + $result = $this->variables_repository->update( $id, [
316 250 'label' => $label,
317 251 'value' => $value,
318 - ];
252 + ] );
319 253
320 - if ( $type ) {
321 - $update_data['type'] = $type;
322 - }
323 -
324 - if ( null !== $order ) {
325 - $update_data['order'] = $order;
326 - }
327 -
328 - $result = $this->service->update( $id, $update_data );
329 -
330 - $this->clear_cache();
331 -
332 254 return $this->success_response( [
333 255 'variable' => $result['variable'],
334 256 'watermark' => $result['watermark'],
335 257 ] );
@@ -345,12 +267,10 @@
345 267
346 268 private function delete_existing_variable( WP_REST_Request $request ) {
347 269 $id = $request->get_param( 'id' );
348 270
349 - $result = $this->service->delete( $id );
271 + $result = $this->variables_repository->delete( $id );
350 272
351 - $this->clear_cache();
352 -
353 273 return $this->success_response( [
354 274 'variable' => $result['variable'],
355 275 'watermark' => $result['watermark'],
356 276 ] );
@@ -366,32 +286,10 @@
366 286
367 287 private function restore_existing_variable( WP_REST_Request $request ) {
368 288 $id = $request->get_param( 'id' );
369 289
370 - $overrides = [];
290 + $result = $this->variables_repository->restore( $id );
371 291
372 - $label = $request->get_param( 'label' );
373 -
374 - if ( $label ) {
375 - $overrides['label'] = $label;
376 - }
377 -
378 - $value = $request->get_param( 'value' );
379 -
380 - if ( $value ) {
381 - $overrides['value'] = $value;
382 - }
383 -
384 - $type = $request->get_param( 'type' );
385 -
386 - if ( $type ) {
387 - $overrides['type'] = $type;
388 - }
389 -
390 - $result = $this->service->restore( $id, $overrides );
391 -
392 - $this->clear_cache();
393 -
394 292 return $this->success_response( [
395 293 'variable' => $result['variable'],
396 294 'watermark' => $result['watermark'],
397 295 ] );
@@ -405,12 +303,12 @@
405 303 }
406 304 }
407 305
408 306 private function list_of_variables() {
409 - $db_record = $this->service->load();
307 + $db_record = $this->variables_repository->load();
410 308
411 309 return $this->success_response( [
412 - 'variables' => $db_record['data'] ?? [],
310 + 'variables' => $db_record['data'],
413 311 'total' => count( $db_record['data'] ),
414 312 'watermark' => $db_record['watermark'],
415 313 ] );
416 314 }
@@ -430,16 +328,8 @@
430 328 __( 'Reached the maximum number of variables', 'elementor' )
431 329 );
432 330 }
433 331
434 - if ( $e instanceof DuplicatedLabel ) {
435 - return $this->prepare_error_response(
436 - self::HTTP_BAD_REQUEST,
437 - 'duplicated_label',
438 - __( 'Variable label already exists', 'elementor' )
439 - );
440 - }
441 -
442 332 if ( $e instanceof RecordNotFound ) {
443 333 return $this->prepare_error_response(
444 334 self::HTTP_NOT_FOUND,
445 335 'variable_not_found',
@@ -446,16 +336,8 @@
446 336 __( 'Variable not found', 'elementor' )
447 337 );
448 338 }
449 339
450 - if ( $e instanceof Type_Mismatch ) {
451 - return $this->prepare_error_response(
452 - self::HTTP_BAD_REQUEST,
453 - 'type_mismatch',
454 - $e->getMessage()
455 - );
456 - }
457 -
458 340 return $this->prepare_error_response(
459 341 self::HTTP_SERVER_ERROR,
460 342 'unexpected_server_error',
461 343 __( 'Unexpected server error', 'elementor' )
@@ -469,149 +351,6 @@
469 351 'data' => [
470 352 'status' => $status_code,
471 353 ],
472 354 ], $status_code );
473 - }
474 -
475 - public function is_valid_watermark( $watermark ) {
476 - if ( ! is_numeric( $watermark ) || $watermark < 0 ) {
477 - return new WP_Error(
478 - 'invalid_watermark',
479 - __( 'Watermark must be a non-negative integer', 'elementor' )
480 - );
481 - }
482 -
483 - return true;
484 - }
485 -
486 - public function is_valid_operations_array( $operations ) {
487 - if ( ! is_array( $operations ) || empty( $operations ) ) {
488 - return new WP_Error(
489 - 'invalid_operations_empty',
490 - __( 'Operations array cannot be empty', 'elementor' )
491 - );
492 - }
493 -
494 - foreach ( $operations as $index => $operation ) {
495 - if ( ! is_array( $operation ) || ! isset( $operation['type'] ) ) {
496 - $sanitized_index = absint( $index );
497 - return new WP_Error(
498 - 'invalid_operation_structure',
499 - sprintf(
500 - /* translators: %d: operation index */
501 - __( 'Invalid operation structure at index %d', 'elementor' ),
502 - $sanitized_index
503 - )
504 - );
505 - }
506 -
507 - $allowed_types = [ 'create', 'update', 'delete', 'restore', 'reorder' ];
508 -
509 - if ( ! in_array( $operation['type'], $allowed_types, true ) ) {
510 - $sanitized_index = absint( $index );
511 - return new WP_Error(
512 - 'invalid_operation_type',
513 - sprintf(
514 - /* translators: %d: operation index */
515 - __( 'Invalid operation type at index %d', 'elementor' ),
516 - $sanitized_index
517 - )
518 - );
519 - }
520 - }
521 -
522 - return true;
523 - }
524 -
525 - public function process_batch( WP_REST_Request $request ) {
526 - try {
527 - return $this->process_batch_operations( $request );
528 - } catch ( Exception $e ) {
529 - return $this->batch_error_response( $e );
530 - }
531 - }
532 -
533 - private function process_batch_operations( WP_REST_Request $request ) {
534 - $operations = $request->get_param( 'operations' );
535 -
536 - $result = $this->service->process_batch( $operations );
537 -
538 - $this->clear_cache();
539 -
540 - return $this->success_response( $result );
541 - }
542 -
543 -
544 - private function batch_error_response( Exception $e ) {
545 - if ( $e instanceof BatchOperationFailed ) {
546 - $error_details = $e->getErrorDetails();
547 - $batch_error_context = $this->determine_batch_error_context( $error_details );
548 -
549 - return new WP_REST_Response( [
550 - 'success' => false,
551 - 'code' => $batch_error_context['code'],
552 - 'message' => $batch_error_context['message'],
553 - 'data' => $batch_error_context['filtered_errors'],
554 - ], self::HTTP_BAD_REQUEST );
555 - }
556 -
557 - return $this->error_response( $e );
558 - }
559 -
560 - private function determine_batch_error_context( array $error_details ) {
561 - $error_config = [
562 - 'invalid_variable_limit_reached' => [
563 - 'batch_code' => 'batch_variables_limit_reached',
564 - 'batch_message' => __( 'Batch operation failed: Reached the maximum number of variables', 'elementor' ),
565 - 'status' => self::HTTP_BAD_REQUEST,
566 - 'message' => __( 'Reached the maximum number of variables', 'elementor' ),
567 - ],
568 - 'duplicated_label' => [
569 - 'batch_code' => 'batch_duplicated_label',
570 - 'batch_message' => __( 'Batch operation failed: Variable labels already exist', 'elementor' ),
571 - 'status' => self::HTTP_BAD_REQUEST,
572 - 'message' => __( 'Variable label already exists', 'elementor' ),
573 - ],
574 - 'variable_not_found' => [
575 - 'batch_code' => 'batch_variables_not_found',
576 - 'batch_message' => __( 'Batch operation failed: Variables not found', 'elementor' ),
577 - 'status' => self::HTTP_NOT_FOUND,
578 - 'message' => __( 'Variable not found', 'elementor' ),
579 - ],
580 - ];
581 -
582 - $grouped_errors = [];
583 -
584 - foreach ( $error_details as $id => $error_detail ) {
585 - $error_code = $error_detail['code'] ?? '';
586 -
587 - if ( isset( $error_config[ $error_code ] ) ) {
588 - $config = $error_config[ $error_code ];
589 - $grouped_errors[ $error_code ][ $id ] = [
590 - 'status' => $config['status'],
591 - 'message' => $config['message'],
592 - ];
593 - } else {
594 - $grouped_errors['unknown'][ $id ] = [
595 - 'status' => self::HTTP_SERVER_ERROR,
596 - 'message' => $error_detail['message'] ?? __( 'Unexpected error', 'elementor' ),
597 - ];
598 - }
599 - }
600 -
601 - foreach ( $error_config as $error_code => $config ) {
602 - if ( ! empty( $grouped_errors[ $error_code ] ) ) {
603 - return [
604 - 'code' => $config['batch_code'],
605 - 'message' => $config['batch_message'],
606 - 'filtered_errors' => $grouped_errors[ $error_code ],
607 - ];
608 - }
609 - }
610 -
611 - return [
612 - 'code' => 'batch_operation_failed',
613 - 'message' => __( 'Batch operation failed', 'elementor' ),
614 - 'filtered_errors' => $grouped_errors['unknown'] ?? [],
615 - ];
616 355 }
617 356 }