<?php
|
namespace JVBase\forms;
|
|
use JVBase\forms\TaxonomySelector;
|
use JVBase\JVBIcons;
|
use JVBase\managers\CacheManager;
|
use WP_REST_Request;
|
use WP_REST_Response;
|
use WP_Term;
|
use WP_Query;
|
|
if (!defined('ABSPATH')) {
|
exit; // Exit if accessed directly
|
}
|
class PostSelectorOld extends TaxonomySelector
|
{
|
protected string $post_type;
|
|
public function __construct(int $id, string $post_type, array $config = [])
|
{
|
$this->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();
|
?>
|
<div class="<?= esc_attr($wrapper_classes); ?>"
|
id="<?= esc_attr($this->id); ?>"
|
data-post-type="<?= esc_attr($this->post_type); ?>"
|
data-config='<?= esc_attr(wp_json_encode($this->getFrontendConfig())); ?>'>
|
|
<div class="selector-wrapper">
|
<?php $this->renderSelectedItems($selected); ?>
|
|
<dialog class="selector-modal">
|
<div class="wrap col">
|
<header class="modal-header">
|
<h3><?= esc_html($this->config['title'] ?? 'Search Artists'); ?></h3>
|
<button type="button" class="cancel" aria-label="Close">×</button>
|
</header>
|
|
|
<div class="items-container">
|
<?php $this->renderSelectableItems(); ?>
|
<div class="scroll-sentinel"></div>
|
</div>
|
|
<?php if ($this->config['modal']) : ?>
|
<div class="pending-section" hidden>
|
<h4>Pending Approvals</h4>
|
<div class="pending-list" role="list"></div>
|
</div>
|
<?php endif; ?>
|
</div>
|
<?= jvbSearch() ?>
|
</dialog>
|
</div>
|
</div>
|
<?php
|
return ob_get_clean();
|
}
|
|
protected function renderSelectedItems(array $selected = []):void
|
{
|
if (empty($selected)) {
|
echo '<div class="selected-items"></div>';
|
return;
|
}
|
|
echo '<div class="selected-items">';
|
foreach ($selected as $id => $title) {
|
printf(
|
'<div class="selected-item" data-id="%s">
|
<span class="item-name">%s</span>
|
<button type="button"
|
class="remove-item"
|
aria-label="Remove %s">×</button>
|
</div>',
|
esc_attr($id),
|
esc_html($title),
|
esc_attr($title)
|
);
|
}
|
echo '</div>';
|
}
|
|
public function renderSelectableItems():void
|
{
|
$posts = $this->getAvailableTerms();
|
|
echo '<div class="wrap"><ul class="flat items">';
|
foreach ($posts as $ID => $name) {
|
echo '<li>';
|
?>
|
<input id="<?= $this->id.'-'.esc_attr($ID); ?>"
|
type="<?= $this->config['multiple'] ? 'checkbox' : 'radio'; ?>"
|
name="<?= esc_attr($this->id); ?>"
|
value="<?= esc_attr($ID); ?>">
|
<label class="selectable-item" for="<?= $this->id.'-'.esc_attr($ID); ?>">
|
<?= esc_html($name); ?>
|
</label>
|
<?php
|
echo '</li>';
|
}
|
|
echo '</ul></div>';
|
}
|
|
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);
|
}
|
}
|