getTerms(); } else if ($query == 'authors') { $data = $this->getAuthors(); } else { $data = $this->getPosts(); } wp_send_json_success($data); } catch (\Exception $e) { wp_send_json_error($e->getMessage()); } die(); } /** * Get Post Type * @return string */ protected function getPostType() { // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified in getSelectInputData() before this helper runs. return isset($_POST['post_type']) ? sanitize_text_field(wp_unslash($_POST['post_type'])) : ''; } /** * @return string[]|\WP_Post_Type[] */ protected function getAllPublicPostTypes() { return array_values(get_post_types(['public' => true])); } /** * @return string */ protected function getSearchQuery() { // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified in getSelectInputData() before this helper runs. return isset($_POST['search_text']) ? sanitize_text_field(wp_unslash($_POST['search_text'])) : ''; } /** * @return array|mixed */ protected function getselecedIds() { // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified in getSelectInputData() before this helper runs. return isset($_POST['ids']) ? sanitize_text_field(wp_unslash($_POST['ids'])) : []; } /** * @param string $taxonomy * * @return mixed|string */ public function getTaxonomyName($taxonomy = '') { $taxonomies = get_taxonomies(['public' => true], 'objects'); $taxonomies = array_column($taxonomies, 'label', 'name'); return isset($taxonomies[$taxonomy]) ? $taxonomies[$taxonomy] : ''; } /** * @return string[]|\WP_Taxonomy[] */ protected function getAllPublicTaxonomies() { return array_values(get_taxonomies(['public' => true])); } /** * Get Post Query Data * * @return array */ public function getPosts() { $include = $this->getselecedIds(); $searchText = $this->getSearchQuery(); $args = []; $args['post_status'] = 'publish'; $public_post_types = $this->getAllPublicPostTypes(); $requested_post_type = $this->getPostType(); // post_type comes straight from $_POST. Restrict it to the public post types this // control is meant to browse so it cannot be pointed at a private post type. if ($requested_post_type && in_array($requested_post_type, $public_post_types, true)) { $args['post_type'] = $requested_post_type; } else { $args['post_type'] = $public_post_types; } if (!empty($include)) { $args['post__in'] = $include; $args['posts_per_page'] = min(100, count($include)); } else { // Never run this unbounded: it is reachable by any 'edit_posts' user and // -1 returns every published post of every public post type. $args['posts_per_page'] = 50; } if ($searchText) { $args['s'] = $searchText; } $query = new \WP_Query($args); $results = []; foreach ($query->posts as $post) { $post_type_obj = get_post_type_object($post->post_type); if (!empty($data['include_type'])) { $text = $post_type_obj->labels->name . ': ' . $post->post_title; } else { $text = ($post_type_obj->hierarchical) ? $this->get_post_name_with_parents($post) : $post->post_title; } $results[] = [ 'id' => $post->ID, 'text' => esc_html($text), ]; } return $results; } private function get_post_name_with_parents($post, $max = 3) { if (0 === $post->post_parent) { return $post->post_title; } $separator = is_rtl() ? ' < ' : ' > '; $test_post = $post; $names = []; while ($test_post->post_parent > 0) { $test_post = get_post($test_post->post_parent); if (!$test_post) { break; } $names[] = $test_post->post_title; } $names = array_reverse($names); if (count($names) < ($max)) { return implode($separator, $names) . $separator . $post->post_title; } $name_string = ''; for ($i = 0; $i < ($max - 1); $i++) { $name_string .= $names[$i] . $separator; } return $name_string . '...' . $separator . $post->post_title; } /** * Get Terms query data * * @return array */ public function getTerms() { $search_text = $this->getSearchQuery(); $taxonomies = $this->getAllPublicTaxonomies(); $include = $this->getselecedIds(); if ($this->getPostType() == '_ultimate_post_kit_pro_related_post_type') { $post_type = $this->getAllPublicPostTypes(); } elseif ($this->getPostType()) { $post_type = $this->getPostType(); } $post_taxonomies = get_object_taxonomies($post_type); $taxonomies = array_intersect($post_taxonomies, $taxonomies); $data = []; if (empty($taxonomies)) { return $data; } $args = [ 'taxonomy' => $taxonomies, 'hide_empty' => true, ]; if (!empty($include)) { $args['include'] = $include; } if ($search_text) { $args['number'] = 20; $args['search'] = $search_text; } $terms = get_terms($args); if (is_wp_error($terms) || empty($terms)) { return $data; } foreach ($terms as $term) { $label = $term->name; $taxonomy_name = $this->getTaxonomyName($term->taxonomy); if ($taxonomy_name) { $label = "{$taxonomy_name}: {$label}"; } $data[] = [ 'id' => $term->term_taxonomy_id, 'text' => $label, ]; } return $data; } /** * Get Authors query Data * * @return array */ public function getAuthors() { $include = $this->getselecedIds(); $search_text = $this->getSearchQuery(); $args = [ 'fields' => ['ID', 'display_name'], 'orderby' => 'display_name', // Always bound the result set. Without this an empty search returns every // user on the site, unpaged. 'number' => 20, ]; // This endpoint is only capability-gated on 'edit_posts', so a Contributor can // reach it. WordPress core restricts callers without 'list_users' to users who // have published something (see WP_REST_Users_Controller::get_items), so match // that restriction rather than exposing the full user table. if (!current_user_can('list_users')) { $args['has_published_posts'] = true; } if (!empty($include)) { $args['include'] = $include; // Resolving already-selected values needs room for all of them, but still // bounded so a long id list cannot be used to dump the table. $args['number'] = min(100, max(20, count($include))); } if ($search_text) { $args['search'] = "*$search_text*"; // WP_User_Query searches user_email when the term contains "@", which turns // this into an address oracle. Core strips user_email from the searchable // columns for callers without 'list_users'; do the same here. $args['search_columns'] = ['ID', 'user_login', 'user_nicename', 'display_name']; } $users = get_users($args); $data = []; if (empty($users)) { return $data; } foreach ($users as $user) { $data[] = [ 'id' => $user->ID, 'text' => $user->display_name, ]; } return $data; } } function ultimatePostKit_dynamic_select_input_module() { return UltimatePostKit_Dynamic_Select_Input_Module::get_instance(); } ultimatePostKit_dynamic_select_input_module()->init();