PluginProbe
Elementor Website Builder – more than just a page builder / 4.2.0
Elementor Website Builder – more than just a page builder v4.2.0
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 / wp-rest / base / query.php

query.php in Elementor Website Builder – more than just a page builder 4.2.0, at modules/wp-rest/base/query.php

170 lines 4.5 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\WpRest\Base;
4
5 use Elementor\Core\Utils\Api\Error_Builder;
6 use Elementor\Core\Utils\Collection;
7
8 if ( ! defined( 'ABSPATH' ) ) {
9 exit; // Exit if accessed directly.
10 }
11
12 abstract class Query {
13 const NAMESPACE = 'elementor/v1';
14 const NONCE_KEY = 'x_wp_nonce';
15
16 const KEYS_CONVERSION_MAP_KEY = 'keys_conversion_map';
17 const IS_PUBLIC_KEY = 'is_public';
18 const TAX_QUERY_KEY = 'tax_query';
19 const META_QUERY_KEY = 'meta_query';
20
21 const MAX_RESPONSE_COUNT = 100;
22 const ITEMS_COUNT_KEY = 'items_count';
23
24 const INCLUDED_TYPE_KEY = 'included_types';
25 const EXCLUDED_TYPE_KEY = 'excluded_types';
26 const HIDE_EMPTY_KEY = 'hide_empty';
27
28 const SEARCH_TERM_KEY = 'term';
29 const SEARCH_FILTER_PRIORITY = 10;
30
31 /**
32 * @param \WP_REST_Request $request
33 * @return \WP_REST_Response
34 **/
35 abstract protected function get( \WP_REST_Request $request );
36
37 abstract protected static function get_allowed_param_keys(): array;
38
39 abstract protected static function get_keys_to_encode(): array;
40
41 abstract protected function get_endpoint_registration_args(): array;
42
43 abstract protected function permission_check( \WP_REST_Request $request ): bool;
44
45 public function register( $endpoint, bool $override_existing_endpoints = false ): void {
46 register_rest_route( self::NAMESPACE, $endpoint, [
47 [
48 'methods' => \WP_REST_Server::READABLE,
49 'permission_callback' => fn ( \WP_REST_Request $request ) => $this->validate_access_permission( $request ),
50 'args' => $this->get_endpoint_registration_args(),
51 'callback' => fn ( \WP_REST_Request $request ) => $this->send( fn () => $this->get( $request ) ),
52 ],
53 ], $override_existing_endpoints );
54 }
55
56 /**
57 * @param array $item The input array with original keys.
58 * @param array $dictionary An associative array mapping old keys to new keys.
59 * @return array The array with translated keys.
60 */
61 public function translate_keys( array $item, array $dictionary ): array {
62 if ( empty( $dictionary ) ) {
63 return $item;
64 }
65
66 $replaced = [];
67
68 foreach ( $item as $key => $value ) {
69 if ( ! isset( $dictionary[ $key ] ) ) {
70 continue;
71 }
72
73 $replaced[ $dictionary[ $key ] ] = $value;
74 }
75
76 return $replaced;
77 }
78
79 /**
80 * @param array<string>|string $input The input data, expected to be an array or JSON-encoded string.
81 * @return array The sanitized array of strings.
82 */
83 public static function sanitize_string_array( $input ) {
84 if ( ! is_array( $input ) ) {
85 $raw = sanitize_text_field( $input );
86 $decoded = json_decode( $raw, true );
87 if ( is_array( $decoded ) ) {
88 $input = $decoded;
89 } else {
90 $input = false !== strpos( $raw, ',' ) ? explode( ',', $raw ) : ( '' !== $raw ? [ $raw ] : [] );
91 }
92 }
93
94 return Collection::make( $input )
95 ->reduce( function ( $carry, $value, $key ) {
96 if ( $value ) {
97 $carry[ $key ] = is_array( $value ) ? self::sanitize_string_array( $value ) : sanitize_text_field( $value );
98 }
99
100 return $carry;
101 }, [] );
102 }
103
104
105 protected function validate_access_permission( \WP_REST_Request $request ): bool {
106 $nonce = $request->get_header( self::NONCE_KEY );
107
108 return $this->permission_check( $request ) && wp_verify_nonce( $nonce, 'wp_rest' );
109 }
110
111 protected function filter_keys_conversion_map( array $requested_map, array $allowed_map ): array {
112 $sanitized_map = [];
113
114 foreach ( $requested_map as $source_key => $destination_key ) {
115 if ( ! isset( $allowed_map[ $source_key ] ) ) {
116 continue;
117 }
118
119 $sanitized_map[ $source_key ] = $destination_key;
120 }
121
122 return ! empty( $sanitized_map ) ? $sanitized_map : $allowed_map;
123 }
124
125 /**
126 * @param callable $cb The route callback.
127 * @return \WP_REST_Response | \WP_Error
128 */
129 private function send( callable $cb ) {
130 try {
131 $response = $cb();
132 } catch ( \Exception $e ) {
133 return Error_Builder::make( $e->getCode() )
134 ->set_message( $e->getMessage() )
135 ->build();
136 }
137
138 return $response;
139 }
140
141 /**
142 * @param $args array{
143 * excluded_types: array,
144 * included_types: array,
145 * keys_conversion_map: array,
146 * } The query parameters
147 * @return array The query parameters.
148 */
149 public static function build_query_params( array $args ): array {
150 $allowed_keys = static::get_allowed_param_keys();
151 $keys_to_encode = static::get_keys_to_encode();
152 $params = [];
153
154 foreach ( $args as $key => $value ) {
155 if ( ! in_array( $key, $allowed_keys, true ) || ! isset( $value ) ) {
156 continue;
157 }
158
159 if ( ! in_array( $key, $keys_to_encode, true ) ) {
160 $params[ $key ] = $value;
161 continue;
162 }
163
164 $params[ $key ] = wp_json_encode( $value );
165 }
166
167 return $params;
168 }
169 }
170