PluginProbe
Elementor Website Builder – more than just a page builder / 3.31.2
Elementor Website Builder – more than just a page builder v3.31.2
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
elementor / modules / variables / classes / rest-api.php

rest-api.php in Elementor Website Builder – more than just a page builder 3.31.2, at modules/variables/classes/rest-api.php

400 lines 10.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Elementor\Modules\Variables\Classes;
4
5 use Elementor\Modules\Variables\Storage\Exceptions\DuplicatedLabel;
6 use Exception;
7 use WP_Error;
8 use WP_REST_Response;
9 use WP_REST_Request;
10 use WP_REST_Server;
11
12 use Elementor\Plugin;
13 use Elementor\Modules\Variables\PropTypes\Color_Variable_Prop_Type;
14 use Elementor\Modules\Variables\PropTypes\Font_Variable_Prop_Type;
15 use Elementor\Modules\Variables\Storage\Repository as Variables_Repository;
16 use Elementor\Modules\Variables\Storage\Exceptions\VariablesLimitReached;
17 use Elementor\Modules\Variables\Storage\Exceptions\RecordNotFound;
18
19 if ( ! defined( 'ABSPATH' ) ) {
20 exit; // Exit if accessed directly.
21 }
22
23 class Rest_Api {
24 const API_NAMESPACE = 'elementor/v1';
25 const API_BASE = 'variables';
26
27 const HTTP_OK = 200;
28 const HTTP_CREATED = 201;
29 const HTTP_BAD_REQUEST = 400;
30 const HTTP_NOT_FOUND = 404;
31 const HTTP_SERVER_ERROR = 500;
32
33 const MAX_ID_LENGTH = 64;
34 const MAX_LABEL_LENGTH = 50;
35 const MAX_VALUE_LENGTH = 512;
36
37 private Variables_Repository $variables_repository;
38
39 public function __construct( Variables_Repository $variables_repository ) {
40 $this->variables_repository = $variables_repository;
41 }
42
43 public function enough_permissions_to_perform_ro_action() {
44 return current_user_can( 'edit_posts' );
45 }
46
47 public function enough_permissions_to_perform_rw_action() {
48 return current_user_can( 'manage_options' );
49 }
50
51 public function register_routes() {
52 register_rest_route( self::API_NAMESPACE, '/' . self::API_BASE . '/list', [
53 'methods' => WP_REST_Server::READABLE,
54 'callback' => [ $this, 'get_variables' ],
55 'permission_callback' => [ $this, 'enough_permissions_to_perform_ro_action' ],
56 ] );
57
58 register_rest_route( self::API_NAMESPACE, '/' . self::API_BASE . '/create', [
59 'methods' => WP_REST_Server::CREATABLE,
60 'callback' => [ $this, 'create_variable' ],
61 'permission_callback' => [ $this, 'enough_permissions_to_perform_rw_action' ],
62 'args' => [
63 'type' => [
64 'required' => true,
65 'type' => 'string',
66 'validate_callback' => [ $this, 'is_valid_variable_type' ],
67 'sanitize_callback' => [ $this, 'trim_and_sanitize_text_field' ],
68 ],
69 'label' => [
70 'required' => true,
71 'type' => 'string',
72 'validate_callback' => [ $this, 'is_valid_variable_label' ],
73 'sanitize_callback' => [ $this, 'trim_and_sanitize_text_field' ],
74 ],
75 'value' => [
76 'required' => true,
77 'type' => 'string',
78 'validate_callback' => [ $this, 'is_valid_variable_value' ],
79 'sanitize_callback' => [ $this, 'trim_and_sanitize_text_field' ],
80 ],
81 ],
82 ] );
83
84 register_rest_route( self::API_NAMESPACE, '/' . self::API_BASE . '/update', [
85 'methods' => WP_REST_Server::EDITABLE,
86 'callback' => [ $this, 'update_variable' ],
87 'permission_callback' => [ $this, 'enough_permissions_to_perform_rw_action' ],
88 'args' => [
89 'id' => [
90 'required' => true,
91 'type' => 'string',
92 'validate_callback' => [ $this, 'is_valid_variable_id' ],
93 'sanitize_callback' => [ $this, 'trim_and_sanitize_text_field' ],
94 ],
95 'label' => [
96 'required' => true,
97 'type' => 'string',
98 'validate_callback' => [ $this, 'is_valid_variable_label' ],
99 'sanitize_callback' => [ $this, 'trim_and_sanitize_text_field' ],
100 ],
101 'value' => [
102 'required' => true,
103 'type' => 'string',
104 'validate_callback' => [ $this, 'is_valid_variable_value' ],
105 'sanitize_callback' => [ $this, 'trim_and_sanitize_text_field' ],
106 ],
107 ],
108 ] );
109
110 register_rest_route( self::API_NAMESPACE, '/' . self::API_BASE . '/delete', [
111 'methods' => WP_REST_Server::EDITABLE,
112 'callback' => [ $this, 'delete_variable' ],
113 'permission_callback' => [ $this, 'enough_permissions_to_perform_rw_action' ],
114 'args' => [
115 'id' => [
116 'required' => true,
117 'type' => 'string',
118 'validate_callback' => [ $this, 'is_valid_variable_id' ],
119 'sanitize_callback' => [ $this, 'trim_and_sanitize_text_field' ],
120 ],
121 ],
122 ] );
123
124 register_rest_route( self::API_NAMESPACE, '/' . self::API_BASE . '/restore', [
125 'methods' => WP_REST_Server::EDITABLE,
126 'callback' => [ $this, 'restore_variable' ],
127 'permission_callback' => [ $this, 'enough_permissions_to_perform_rw_action' ],
128 'args' => [
129 'id' => [
130 'required' => true,
131 'type' => 'string',
132 'validate_callback' => [ $this, 'is_valid_variable_id' ],
133 'sanitize_callback' => [ $this, 'trim_and_sanitize_text_field' ],
134 ],
135 'label' => [
136 'required' => false,
137 'type' => 'string',
138 'validate_callback' => [ $this, 'is_valid_variable_label' ],
139 'sanitize_callback' => [ $this, 'trim_and_sanitize_text_field' ],
140 ],
141 'value' => [
142 'required' => false,
143 'type' => 'string',
144 'validate_callback' => [ $this, 'is_valid_variable_value' ],
145 'sanitize_callback' => [ $this, 'trim_and_sanitize_text_field' ],
146 ],
147 ],
148 ] );
149 }
150
151 public function trim_and_sanitize_text_field( $value ) {
152 return trim( sanitize_text_field( $value ) );
153 }
154
155 public function is_valid_variable_id( $id ) {
156 $id = trim( $id );
157
158 if ( empty( $id ) ) {
159 return new WP_Error(
160 'invalid_variable_id_empty',
161 __( 'ID cannot be empty', 'elementor' )
162 );
163 }
164
165 if ( self::MAX_ID_LENGTH < strlen( $id ) ) {
166 return new WP_Error( 'invalid_variable_id_length', sprintf(
167 __( 'ID cannot exceed %d characters', 'elementor' ),
168 self::MAX_ID_LENGTH
169 ) );
170 }
171
172 return true;
173 }
174
175 public function is_valid_variable_type( $type ) {
176 return in_array( $type, [
177 Color_Variable_Prop_Type::get_key(),
178 Font_Variable_Prop_Type::get_key(),
179 ], true );
180 }
181
182 public function is_valid_variable_label( $label ) {
183 $label = trim( $label );
184
185 if ( empty( $label ) ) {
186 return new WP_Error(
187 'invalid_variable_label_empty',
188 __( 'Label cannot be empty', 'elementor' )
189 );
190 }
191
192 if ( self::MAX_LABEL_LENGTH < strlen( $label ) ) {
193 return new WP_Error( 'invalid_variable_label_length', sprintf(
194 __( 'Label cannot exceed %d characters', 'elementor' ),
195 self::MAX_LABEL_LENGTH
196 ) );
197 }
198
199 return true;
200 }
201
202 public function is_valid_variable_value( $value ) {
203 $value = trim( $value );
204
205 if ( empty( $value ) ) {
206 return new WP_Error(
207 'invalid_variable_value_empty',
208 __( 'Value cannot be empty', 'elementor' )
209 );
210 }
211
212 if ( self::MAX_VALUE_LENGTH < strlen( $value ) ) {
213 return new WP_Error( 'invalid_variable_value_length', sprintf(
214 __( 'Value cannot exceed %d characters', 'elementor' ),
215 self::MAX_VALUE_LENGTH
216 ) );
217 }
218
219 return true;
220 }
221
222 public function create_variable( WP_REST_Request $request ) {
223 try {
224 return $this->create_new_variable( $request );
225 } catch ( Exception $e ) {
226 return $this->error_response( $e );
227 }
228 }
229
230 protected function clear_cache() {
231 Plugin::$instance->files_manager->clear_cache();
232 }
233
234 private function create_new_variable( WP_REST_Request $request ) {
235 $type = $request->get_param( 'type' );
236 $label = $request->get_param( 'label' );
237 $value = $request->get_param( 'value' );
238
239 $result = $this->variables_repository->create( [
240 'type' => $type,
241 'label' => $label,
242 'value' => $value,
243 ] );
244
245 $this->clear_cache();
246
247 return $this->success_response( [
248 'variable' => $result['variable'],
249 'watermark' => $result['watermark'],
250 ], self::HTTP_CREATED );
251 }
252
253 public function update_variable( WP_REST_Request $request ) {
254 try {
255 return $this->update_existing_variable( $request );
256 } catch ( Exception $e ) {
257 return $this->error_response( $e );
258 }
259 }
260
261 private function update_existing_variable( WP_REST_Request $request ) {
262 $id = $request->get_param( 'id' );
263 $label = $request->get_param( 'label' );
264 $value = $request->get_param( 'value' );
265
266 $result = $this->variables_repository->update( $id, [
267 'label' => $label,
268 'value' => $value,
269 ] );
270
271 $this->clear_cache();
272
273 return $this->success_response( [
274 'variable' => $result['variable'],
275 'watermark' => $result['watermark'],
276 ] );
277 }
278
279 public function delete_variable( WP_REST_Request $request ) {
280 try {
281 return $this->delete_existing_variable( $request );
282 } catch ( Exception $e ) {
283 return $this->error_response( $e );
284 }
285 }
286
287 private function delete_existing_variable( WP_REST_Request $request ) {
288 $id = $request->get_param( 'id' );
289
290 $result = $this->variables_repository->delete( $id );
291
292 $this->clear_cache();
293
294 return $this->success_response( [
295 'variable' => $result['variable'],
296 'watermark' => $result['watermark'],
297 ] );
298 }
299
300 public function restore_variable( WP_REST_Request $request ) {
301 try {
302 return $this->restore_existing_variable( $request );
303 } catch ( Exception $e ) {
304 return $this->error_response( $e );
305 }
306 }
307
308 private function restore_existing_variable( WP_REST_Request $request ) {
309 $id = $request->get_param( 'id' );
310
311 $overrides = [];
312
313 $label = $request->get_param( 'label' );
314 if ( $label ) {
315 $overrides['label'] = $label;
316 }
317
318 $value = $request->get_param( 'value' );
319 if ( $value ) {
320 $overrides['value'] = $value;
321 }
322
323 $result = $this->variables_repository->restore( $id, $overrides );
324
325 $this->clear_cache();
326
327 return $this->success_response( [
328 'variable' => $result['variable'],
329 'watermark' => $result['watermark'],
330 ] );
331 }
332
333 public function get_variables() {
334 try {
335 return $this->list_of_variables();
336 } catch ( Exception $e ) {
337 return $this->error_response( $e );
338 }
339 }
340
341 private function list_of_variables() {
342 $db_record = $this->variables_repository->load();
343
344 return $this->success_response( [
345 'variables' => $db_record['data'],
346 'total' => count( $db_record['data'] ),
347 'watermark' => $db_record['watermark'],
348 ] );
349 }
350
351 private function success_response( $payload, $status_code = null ) {
352 return new WP_REST_Response( [
353 'success' => true,
354 'data' => $payload,
355 ], $status_code ?? self::HTTP_OK );
356 }
357
358 private function error_response( Exception $e ) {
359 if ( $e instanceof VariablesLimitReached ) {
360 return $this->prepare_error_response(
361 self::HTTP_BAD_REQUEST,
362 'invalid_variable_limit_reached',
363 __( 'Reached the maximum number of variables', 'elementor' )
364 );
365 }
366
367 if ( $e instanceof DuplicatedLabel ) {
368 return $this->prepare_error_response(
369 self::HTTP_BAD_REQUEST,
370 'duplicated_label',
371 __( 'Variable label already exists', 'elementor' )
372 );
373 }
374
375 if ( $e instanceof RecordNotFound ) {
376 return $this->prepare_error_response(
377 self::HTTP_NOT_FOUND,
378 'variable_not_found',
379 __( 'Variable not found', 'elementor' )
380 );
381 }
382
383 return $this->prepare_error_response(
384 self::HTTP_SERVER_ERROR,
385 'unexpected_server_error',
386 __( 'Unexpected server error', 'elementor' )
387 );
388 }
389
390 private function prepare_error_response( $status_code, $error, $message ) {
391 return new WP_REST_Response( [
392 'code' => $error,
393 'message' => $message,
394 'data' => [
395 'status' => $status_code,
396 ],
397 ], $status_code );
398 }
399 }
400