PluginProbe
King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder / 51.1.78
King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder v51.1.78
51.1.83 51.1.82 51.1.81 51.1.79 51.1.78 51.1.77 51.1.76 51.1.74 51.1.75 51.1.65 51.1.64 51.1.63 trunk 51.1.14 51.1.2 51.1.35 51.1.36 51.1.37 51.1.38 51.1.39 51.1.44 51.1.45 51.1.46 51.1.47 51.1.49 All 37 releases
king-addons / includes / controls / Ajax_Select2 / Ajax_Select2_API.php

Ajax_Select2_API.php in King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder 51.1.78, at includes/controls/Ajax_Select2/Ajax_Select2_API.php

352 lines 10.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php /** @noinspection PhpUnused, SpellCheckingInspection, DuplicatedCode */
2
3 namespace King_Addons\AJAX_Select2;
4
5 use King_Addons\Core;
6 use WP_Query;
7 use WP_User_Query;
8
9 if (!defined('ABSPATH')) {
10 exit; // Exit if accessed directly.
11 }
12
13 class Ajax_Select2_API
14 {
15 private const ALLOWED_ACTIONS = [
16 'getElementorTemplates',
17 'getPostsByPostType',
18 'getPostTypeTaxonomies',
19 'getCustomMetaKeys',
20 'getUsers',
21 'getTaxonomies',
22 'getCustomMetaKeysProduct',
23 ];
24
25 public function __construct()
26 {
27 $this->init();
28 }
29
30 public function init(): void
31 {
32 add_action('rest_api_init', function () {
33 register_rest_route(
34 'kingaddons/v1/ajaxselect2',
35 '/(?P<action>\w+)/',
36 [
37 'methods' => 'GET',
38 'callback' => [$this, 'callback'],
39 'permission_callback' => [$this, 'canAccess'],
40 ]
41 );
42 });
43 }
44
45 public function canAccess($request): bool
46 {
47 $action = sanitize_key((string)($request['action'] ?? ''));
48 $allowed_actions = array_map('sanitize_key', self::ALLOWED_ACTIONS);
49
50 return current_user_can('edit_posts') && in_array($action, $allowed_actions, true);
51 }
52
53 public function callback($request)
54 {
55 $action = (string)($request['action'] ?? '');
56
57 if (!in_array($action, self::ALLOWED_ACTIONS, true) || !is_callable([$this, $action])) {
58 return new \WP_Error('king_addons_invalid_ajaxselect2_action', esc_html__('Invalid request.', 'king-addons'), ['status' => 400]);
59 }
60
61 return $this->{$action}($request);
62 }
63
64 public function getElementorTemplates($request): ?array
65 {
66 if (!current_user_can('edit_posts')) return null;
67
68 $args = [
69 'post_type' => 'elementor_library',
70 'post_status' => 'publish',
71 'meta_key' => '_elementor_template_type',
72 'meta_value' => ['page', 'section', 'container'],
73 'numberposts' => 10
74 ];
75
76 // Load specific templates by IDs (for pre-populating selected values)
77 if (isset($request['ids']) && !empty($request['ids'])) {
78 $ids = array_filter(array_map('intval', explode(',', $request['ids'])));
79 if (!empty($ids)) {
80 $args['post__in'] = $ids;
81 $args['numberposts'] = -1;
82 unset($args['meta_key'], $args['meta_value']); // Allow any template type when loading by ID
83 }
84 }
85
86 if (isset($request['s'])) {
87 $args['s'] = sanitize_text_field((string)$request['s']);
88 }
89
90 $options = [];
91 $the_query = new WP_Query($args);
92
93 if ($the_query->have_posts()) {
94 while ($the_query->have_posts()) {
95 $the_query->the_post();
96 $options[] = [
97 'id' => get_the_ID(),
98 'text' => wp_strip_all_tags(html_entity_decode(get_the_title())),
99 ];
100 }
101 }
102
103 wp_reset_postdata();
104
105 return ['results' => $options];
106 }
107
108 public function getPostsByPostType($request): ?array
109 {
110 if (!current_user_can('edit_posts')) return null;
111
112 $post_type = sanitize_key((string)($request['query_slug'] ?? ''));
113
114 $args = [
115 'post_type' => $post_type,
116 'post_status' => $post_type === 'attachment' ? 'any' : 'publish',
117 'posts_per_page' => 15,
118 ];
119
120 if (isset($request['ids'])) {
121 $args['post__in'] = array_filter(array_map('intval', explode(',', (string)$request['ids'])));
122 }
123
124 if (isset($request['s'])) {
125 $args['s'] = sanitize_text_field((string)$request['s']);
126 }
127
128 $query = new WP_Query($args);
129 $options = [];
130
131 if ($query->have_posts()) {
132 while ($query->have_posts()) {
133 $query->the_post();
134 $options[] = [
135 'id' => get_the_ID(),
136 'text' => wp_strip_all_tags(html_entity_decode(get_the_title())),
137 ];
138 }
139 }
140
141 wp_reset_postdata();
142 return ['results' => $options];
143 }
144
145 public function getPostTypeTaxonomies($request): ?array
146 {
147 if (!current_user_can('edit_posts')) return null;
148
149 $post_type = sanitize_key((string)($request['query_slug'] ?? ''));
150
151 $taxonomies = get_object_taxonomies($post_type, 'objects');
152 $options = [];
153
154 if ($taxonomies) {
155 foreach ($taxonomies as $taxonomy) {
156
157 if (isset($request['s']) && stripos($taxonomy->label, sanitize_text_field((string)$request['s'])) === false) {
158 continue;
159 }
160
161 if (isset($request['ids'])) {
162 $ids = array_map('sanitize_key', explode(',', (string)($request['ids'] ?: '99999999')));
163 if (!in_array($taxonomy->name, $ids)) {
164 continue;
165 }
166 }
167
168 $options[] = [
169 'id' => $taxonomy->name,
170 'text' => wp_strip_all_tags($taxonomy->label),
171 ];
172 }
173 }
174
175 return ['results' => $options];
176 }
177
178 public function getCustomMetaKeys($request)
179 {
180 if (!current_user_can('edit_posts')) return null;
181
182 $post_types = Core::getCustomTypes('post', false);
183 $data = [];
184
185 foreach ($post_types as $slug => $name) {
186 $posts = get_posts(['post_type' => $slug, 'posts_per_page' => -1]);
187 $metaKeys = [];
188
189 foreach ($posts as $post) {
190 $keys = get_post_custom_keys($post->ID) ?: [];
191 $keys = array_filter($keys, fn($k) => $k[0] !== '_');
192 $metaKeys = array_merge($metaKeys, $keys);
193 }
194
195 $data[$slug] = array_unique($metaKeys);
196 }
197
198 $mergedKeys = array_values(
199 array_unique(
200 array_merge([], ...array_values($data))
201 )
202 );
203
204 $filtered = array_filter($mergedKeys, function ($key) use ($request) {
205 return !isset($request['s']) || strpos($key, sanitize_text_field((string)$request['s'])) !== false;
206 });
207
208 $options = array_map(fn($k) => ['id' => $k, 'text' => wp_strip_all_tags($k)], $filtered);
209
210 return ['results' => $options];
211 }
212
213 public function getUsers($request)
214 {
215 if (!current_user_can('edit_posts')) return null;
216
217 $args = [
218 'number' => 15,
219 'blog_id' => 0,
220 ];
221
222 if (!empty($request['ids'])) {
223 $args['include'] = array_map('intval', explode(',', $request['ids']));
224 }
225
226 if (!empty($request['s'])) {
227 $args['search'] = '*' . sanitize_text_field((string)$request['s']) . '*';
228 }
229
230 $results = (new WP_User_Query($args))->get_results();
231
232 $options = array_map(
233 fn($user) => ['id' => $user->ID, 'text' => wp_strip_all_tags($user->display_name)],
234 $results ?: []
235 );
236
237 wp_reset_postdata();
238
239 return ['results' => $options];
240 }
241
242 public function getTaxonomies($request)
243 {
244 if (!current_user_can('edit_posts')) return null;
245
246 $tax = sanitize_key((string)($request['query_slug'] ?? ''));
247 $args = [
248 'orderby' => 'name',
249 'order' => 'DESC',
250 'hide_empty' => true,
251 'number' => 10,
252 ];
253
254 if (isset($request['ids'])) {
255 $args['include'] = array_filter(array_map('intval', explode(',', (string)($request['ids'] ?: '99999999'))));
256 }
257
258 if (!empty($request['s'])) {
259 $args['name__like'] = sanitize_text_field((string)$request['s']);
260 }
261
262 $terms = get_terms($tax, $args);
263 if (is_wp_error($terms)) {
264 return ['results' => []];
265 }
266
267 $options = array_map(function ($term) {
268 return [
269 'id' => $term->term_id,
270 'text' => wp_strip_all_tags($term->name),
271 ];
272 }, $terms);
273
274 wp_reset_postdata();
275
276 return ['results' => $options];
277 }
278
279 public function getCustomMetaKeysProduct($request)
280 {
281 if (!current_user_can('edit_posts')) return null;
282
283 $options = [];
284 $merged_meta_keys = [];
285 $post_types = Core::getCustomTypes('post', false);
286
287 foreach ($post_types as $slug => $name) {
288 $posts = get_posts(['post_type' => $slug, 'posts_per_page' => -1]);
289 foreach ($posts as $post) {
290 $meta_keys = get_post_custom_keys($post->ID);
291 if ($meta_keys) {
292 foreach ($meta_keys as $key) {
293 if ('_' !== substr($key, 0, 1)) {
294 $merged_meta_keys[] = $key;
295 }
296 }
297 }
298 }
299 }
300
301 $merged_meta_keys = array_values(array_unique($merged_meta_keys));
302 foreach ($merged_meta_keys as $key) {
303 if (empty($request['s']) || false !== strpos($key, sanitize_text_field((string)$request['s']))) {
304 $options[] = [
305 'id' => $key,
306 'text' => wp_strip_all_tags($key),
307 ];
308 }
309 }
310
311 $product_attributes = [];
312 $products_query = new WP_Query([
313 'post_type' => 'product',
314 'posts_per_page' => -1,
315 ]);
316
317 if ($products_query->have_posts()) {
318 while ($products_query->have_posts()) {
319 $products_query->the_post();
320
321 if (class_exists('WooCommerce')) {
322 if (function_exists('wc_get_product')) {
323 /** @noinspection PhpUndefinedFunctionInspection */
324
325 $product = wc_get_product(get_the_ID());
326
327 foreach ($product->get_attributes() as $attribute) {
328 $product_attributes[$attribute->get_name()] = true;
329 }
330
331 }
332 }
333
334 }
335 wp_reset_postdata();
336 }
337
338 foreach (array_keys($product_attributes) as $attribute_name) {
339 $options[] = [
340 'id' => $attribute_name,
341 'text' => wp_strip_all_tags($attribute_name),
342 ];
343 }
344
345 return [
346 'results' => $options,
347 ];
348 }
349
350 }
351
352 new Ajax_Select2_API();