PluginProbe
Ultimate Store Kit / 3.1.0
Ultimate Store Kit v3.1.0
3.0.8 3.0.9 3.1.0 3.1.2 3.1.3 3.0.7 3.0.5 3.0.4 3.0.3 3.0.2 trunk 1.5.0 1.5.1 1.5.2 1.6.1 1.6.2 1.6.3 1.6.4 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 All 92 releases
ultimate-store-kit / includes / controls / select-input / dynamic-select-input-module.php

dynamic-select-input-module.php in Ultimate Store Kit 3.1.0, at includes/controls/select-input/dynamic-select-input-module.php

457 lines 9.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace UltimateStoreKit\Includes\Controls\SelectInput;
4
5 use Exception;
6 use WP_Query;
7
8 defined('ABSPATH') || die();
9
10 class Dynamic_Select_Input_Module {
11
12 const ACTION = '';
13
14 private static $instance = null;
15
16 /**
17 * Returns the instance.
18 *
19 * @return object
20 * @since 1.0.0
21 */
22 public static function get_instance() {
23 // If the single instance hasn't been set, set it now.
24 if (null == self::$instance) {
25 self::$instance = new self;
26 }
27
28 return self::$instance;
29 }
30
31 /**
32 * Init method
33 */
34
35 /**
36 * Constructor.
37 */
38 public function init() {
39 add_action('wp_ajax_ultimate_store_kit_dynamic_select_input_data', array($this, 'getSelectInputData'));
40 }
41
42 /**
43 * get Ajax Data
44 */
45 public function getSelectInputData() {
46 $nonce = isset($_POST['security']) ? sanitize_text_field(wp_unslash($_POST['security'])) : '';
47
48 try {
49 if (!wp_verify_nonce($nonce, 'usk_dynamic_select')) {
50 throw new Exception('Invalid request');
51 }
52
53 if (!current_user_can('edit_posts')) {
54 throw new Exception('Unauthorized request');
55 }
56
57 $query = isset($_POST['query']) ? sanitize_text_field(wp_unslash($_POST['query'])) : '';
58
59 switch ($query) {
60 case 'posts':
61 $data = $this->getPosts();
62 break;
63 case 'terms':
64 $data = $this->getTerms();
65 break;
66 case 'authors':
67 $data = $this->getAuthors();
68 break;
69 case 'authors_role':
70 $data = $this->getAuthorRoles();
71 break;
72 case 'only_post':
73 $data = $this->getOnlyPosts();
74 break;
75 case 'product_cat':
76 $data = $this->getProductTerms($query);
77 break;
78 case 'product_tag':
79 $data = $this->getProductTerms($query);
80 break;
81 case 'product_attributes':
82 $data = $this->getProductAttributes();
83 break;
84 case 'product_brand':
85 $data = $this->getProductTerms($query);
86 break;
87 default:
88 $data = $this->getPosts();
89 break;
90 }
91
92 wp_send_json_success($data);
93 } catch (Exception $e) {
94 wp_send_json_error($e->getMessage());
95 }
96
97 die();
98 }
99
100 /**
101 * Get Post Type
102 * @return string
103 */
104 protected function getPostType() {
105 // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Only reached from getSelectInputData(), which verifies the usk_dynamic_select nonce first.
106 return isset($_POST['post_type']) ? sanitize_text_field(wp_unslash($_POST['post_type'])) : '';
107 }
108
109 /**
110 * @return string[]|\WP_Post_Type[]
111 */
112 protected function getAllPublicPostTypes() {
113 return array_values(get_post_types(['public' => true]));
114 }
115
116 /**
117 * @return string
118 */
119 protected function getSearchQuery() {
120 // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Only reached from getSelectInputData(), which verifies the usk_dynamic_select nonce first.
121 return isset($_POST['search_text']) ? sanitize_text_field(wp_unslash($_POST['search_text'])) : '';
122 }
123
124 /**
125 * @return array|mixed
126 */
127 protected function getselecedIds() {
128
129 // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Only reached from getSelectInputData(), which verifies the usk_dynamic_select nonce first.
130 return isset($_POST['ids']) ? sanitize_text_field(wp_unslash($_POST['ids'])) : [];
131 }
132
133
134 /**
135 * @param string $taxonomy
136 *
137 * @return mixed|string
138 */
139 public function getTaxonomyName($taxonomy = '') {
140 $taxonomies = get_taxonomies(['public' => true], 'objects');
141 $taxonomies = array_column($taxonomies, 'label', 'name');
142
143 return isset($taxonomies[$taxonomy]) ? $taxonomies[$taxonomy] : '';
144 }
145
146 /**
147 * @return string[]|\WP_Taxonomy[]
148 */
149 public function getAllPublicTaxonomies() {
150 return array_values(get_taxonomies(['public' => true]));
151 }
152
153 /**
154 * Get Post Query Data
155 *
156 * @return array
157 */
158 public function getPosts() {
159
160 $include = $this->getselecedIds();
161 $searchText = $this->getSearchQuery();
162
163 $args = [];
164
165 if ($this->getPostType() && $this->getPostType() !== '_related_post_type') {
166 $args['post_type'] = $this->getPostType();
167 } else {
168 $args['post_type'] = $this->getAllPublicPostTypes();
169 }
170
171 if (!empty($include)) {
172 $args['post__in'] = $include;
173 $args['posts_per_page'] = count($include);
174 } else {
175 $args['posts_per_page'] = 20;
176 }
177
178 if ($searchText) {
179 $args['s'] = $searchText;
180 }
181
182 $query = new WP_Query($args);
183 $results = [];
184 foreach ($query->posts as $post) {
185 $post_type_obj = get_post_type_object($post->post_type);
186 if (!empty($data['include_type'])) {
187 $text = $post_type_obj->labels->name . ': ' . $post->post_title;
188 } else {
189 $text = ($post_type_obj->hierarchical) ? $this->get_post_name_with_parents($post) : $post->post_title;
190 }
191
192 $results[] = [
193 'id' => $post->ID,
194 'text' => esc_html($text),
195 ];
196 }
197
198 return $results;
199 }
200
201 public function getOnlyPosts() {
202 $include = $this->getselecedIds();
203 $searchText = $this->getSearchQuery();
204
205 $args = [];
206
207 $args['post_type'] = 'post';
208
209
210 if (!empty($include)) {
211 $args['post__in'] = $include;
212 $args['posts_per_page'] = count($include);
213 } else {
214 $args['posts_per_page'] = 20;
215 }
216
217 if ($searchText) {
218 $args['s'] = $searchText;
219 }
220
221 $query = new WP_Query($args);
222 $results = [];
223 foreach ($query->posts as $post) {
224 $post_type_obj = get_post_type_object($post->post_type);
225 if (!empty($data['include_type'])) {
226 $text = $post_type_obj->labels->name . ': ' . $post->post_title;
227 } else {
228 $text = ($post_type_obj->hierarchical) ? $this->get_post_name_with_parents($post) : $post->post_title;
229 }
230
231 $results[] = [
232 'id' => $post->ID,
233 'text' => esc_html($text),
234 ];
235 }
236
237 return $results;
238 }
239
240 private function get_post_name_with_parents($post, $max = 3) {
241 if (0 === $post->post_parent) {
242 return $post->post_title;
243 }
244 $separator = is_rtl() ? ' < ' : ' > ';
245 $test_post = $post;
246 $names = [];
247 while ($test_post->post_parent > 0) {
248 $test_post = get_post($test_post->post_parent);
249 if (!$test_post) {
250 break;
251 }
252 $names[] = $test_post->post_title;
253 }
254
255 $names = array_reverse($names);
256 if (count($names) < ($max)) {
257 return implode($separator, $names) . $separator . $post->post_title;
258 }
259
260 $name_string = '';
261 for ($i = 0; $i < ($max - 1); $i++) {
262 $name_string .= $names[$i] . $separator;
263 }
264
265 return $name_string . '...' . $separator . $post->post_title;
266 }
267
268 /**
269 * Get Terms query data
270 *
271 * @return array
272 */
273 public function getTerms() {
274 $search_text = $this->getSearchQuery();
275 $taxonomies = $this->getAllPublicTaxonomies();
276 $include = $this->getselecedIds();
277
278 if ($this->getPostType() == '_related_post_type') {
279 $post_type = 'any';
280 } elseif ($this->getPostType()) {
281 $post_type = $this->getPostType();
282 }
283 $post_taxonomies = get_object_taxonomies($post_type);
284 $taxonomies = array_intersect($post_taxonomies, $taxonomies);
285 $data = [];
286
287 if (empty($taxonomies)) {
288 return $data;
289 }
290
291 $args = [
292 'taxonomy' => $taxonomies,
293 'hide_empty' => true,
294 ];
295
296 if (!empty($include)) {
297 $args['include'] = $include;
298 }
299
300 if ($search_text) {
301 $args['number'] = 20;
302 $args['search'] = $search_text;
303 }
304 $terms = get_terms($args);
305
306 if (is_wp_error($terms) || empty($terms)) {
307 return $data;
308 }
309
310 foreach ($terms as $term) {
311 $label = $term->name;
312 $taxonomy_name = $this->getTaxonomyName($term->taxonomy);
313
314 if ($taxonomy_name) {
315 $label = "{$taxonomy_name}: {$label}";
316 }
317
318 $data[] = [
319 'id' => $term->term_taxonomy_id,
320 'text' => $label,
321 ];
322 }
323
324 return $data;
325 }
326
327 /**
328 * Get Authors query Data
329 *
330 * @return array
331 */
332 public function getAuthors() {
333 $include = $this->getselecedIds();
334 $search_text = $this->getSearchQuery();
335
336 $args = [
337 'fields' => ['ID', 'display_name'],
338 'orderby' => 'display_name',
339 ];
340
341 if (!empty($include)) {
342 $args['include'] = $include;
343 }
344
345 if ($search_text) {
346 $args['number'] = 20;
347 $args['search'] = "*$search_text*";
348 }
349
350 $users = get_users($args);
351
352 $data = [];
353
354 if (empty($users)) {
355 return $data;
356 }
357
358 foreach ($users as $user) {
359 $data[] = [
360 'id' => $user->ID,
361 'text' => $user->display_name,
362 ];
363 }
364
365 return $data;
366 }
367
368 /**
369 * Get Authors Roles query Data
370 *
371 * @return array
372 */
373 public function getAuthorRoles() {
374 global $wp_roles;
375
376 $all_roles = $wp_roles->roles;
377 $roles = [];
378 foreach ($all_roles as $key => $role) {
379 $roles[] = [
380 'id' => $key,
381 'text' => $role['name'],
382 ];
383 }
384
385 return $roles;
386 }
387
388 /**
389 * Get Product Categories query Data
390 *
391 * @return array
392 */
393 public function getProductTerms($taxonomy = 'product_cat') {
394 $include = $this->getselecedIds();
395 $search_text = $this->getSearchQuery();
396 $args = [
397 'taxonomy' => $taxonomy,
398 'hide_empty' => true,
399 ];
400
401 if (!empty($include)) {
402 $args['include'] = $include;
403 }
404
405 if ($search_text) {
406 $args['number'] = 20;
407 $args['search'] = $search_text;
408 }
409 $terms = get_terms($args);
410
411 if (is_wp_error($terms) || empty($terms)) {
412 return [];
413 }
414
415 foreach ($terms as $term) {
416 $data[] = [
417 'id' => $term->term_taxonomy_id,
418 'text' => $term->name,
419 ];
420 }
421 return $data;
422 }
423
424 /**
425 * Get Product Attributes query Data
426 *
427 * @return array
428 */
429 public function getProductAttributes(): array {
430 $search_text = $this->getSearchQuery();
431 // Get all global product attributes
432 $attribute_taxonomies = wc_get_attribute_taxonomies();
433
434 // Map the attributes to the desired structure
435 $data = [];
436
437 foreach ($attribute_taxonomies as $attribute) {
438 $data[] = [
439 'id' => $attribute->attribute_id,
440 'text' => $attribute->attribute_label,
441 ];
442 }
443
444 $data = array_filter($data, function ($item) use ($search_text) {
445 return stripos($item['text'], $search_text) !== false;
446 });
447 $data = array_slice($data, 0, 20); // Limit to 20 results
448 return $data;
449 }
450 }
451
452 function Dynamic_Select_Input_Module() {
453 return Dynamic_Select_Input_Module::get_instance();
454 }
455
456 Dynamic_Select_Input_Module()->init();
457