post_type = $post_type;
parent::__construct($id, '', $config); // Empty taxonomy as we're using post type
}
protected function getAvailableTerms():array
{
$args = [
'post_type' => $this->post_type,
'posts_per_page' => 20, // Initial load amount
'orderby' => 'title',
'order' => 'ASC',
'fields' => 'id=>name'
];
// Add shop exclusion if shop_id is set
if (!empty($this->config['shop_id'])) {
$args['tax_query'] = [[
'taxonomy' => BASE.'shop',
'terms' => $this->config['shop_id'],
'operator' => 'NOT IN'
]];
}
$posts = get_posts($args);
return is_wp_error($posts) ? [] : array_combine(
array_map(function ($post) {
return $post->ID;
}, $posts),
array_map(function ($post) {
return $post->post_title;
}, $posts)
);
}
public function render(array $selected = []):string
{
$wrapper_classes = $this->getWrapperClasses();
ob_start();
?>
renderSelectedItems($selected); ?>
';
return;
}
echo '';
foreach ($selected as $id => $title) {
printf(
'
%s
',
esc_attr($id),
esc_html($title),
esc_attr($title)
);
}
echo '
';
}
public function renderSelectableItems():void
{
$posts = $this->getAvailableTerms();
echo '';
}
public function handleArtistSearch(WP_REST_Request $request):WP_REST_Response
{
$query = sanitize_text_field($request->get_param('query'));
$page = (int)$request->get_param('page') ?: 1;
$per_page = 30;
$args = [
'post_type' => BASE.'artist',
'posts_per_page' => $per_page,
'paged' => $page,
'orderby' => 'title',
'order' => 'ASC',
's' => $query
];
// Add shop exclusion if shop_id is set
if (!empty($this->config['shop_id'])) {
$args['tax_query'] = [[
'taxonomy' => BASE.'shop',
'terms' => $this->config['shop_id'],
'operator' => 'NOT IN'
]];
}
$key = $this->cache->generateKey($args);
$cache = $this->cache->get($key);
if ($cache) {
return new WP_REST_Response($cache);
}
$posts = new WP_Query($args);
$results = [];
foreach ($posts->posts as $post) {
$city_terms = wp_get_object_terms($post->ID, BASE.'city');
$city = !empty($city_terms) ? $city_terms[0]->name : '';
$results[] = [
'id' => $post->ID,
'title' => $post->post_title,
'thumbnail' => get_the_post_thumbnail_url($post->ID, 'thumbnail'),
'city' => $city,
'url' => get_permalink($post->ID)
];
}
$return = [
'results' => $results,
'hasMore' => $posts->max_num_pages > $page,
'total' => $posts->found_posts
];
$this->cache->set($key, $return);
return new WP_REST_Response($return);
}
protected function getWrapperClasses():string
{
$classes = [
'jvb-selector',
'selector-' . $this->post_type,
'post-selector'
];
if ($this->config['multiple'] ?? false) {
$classes[] = 'multiple';
}
if ($this->config['modal'] ?? false) {
$classes[] = 'has-modal';
}
return implode(' ', $classes);
}
}