<?php
|
namespace JVBase\blocks;
|
|
use JVBase\managers\CacheManager;
|
use JVBase\forms\TaxonomySelector;
|
use WP_Block;
|
|
if (!defined('ABSPATH')) {
|
exit; // Exit if accessed directly
|
}
|
|
class FeedBlock
|
{
|
protected CacheManager $cache;
|
protected array $config;
|
protected string $path = JVB_DIR.'/build/feed';
|
|
public function __construct()
|
{
|
$this->cache = CacheManager::for('feed',WEEK_IN_SECONDS);
|
add_action('init', [$this, 'registerBlock']);
|
}
|
|
public function registerBlock()
|
{
|
register_block_type($this->path, [
|
'render_callback' => [$this, 'render']
|
]);
|
}
|
|
protected function buildParams(array $attributes):array
|
{
|
|
if (!jvbCheck('inheritQuery', $attributes)) {
|
return [
|
'title' => $attributes['title'],
|
'content' => $attributes['contentTypes'],
|
'taxonomies'=> $this->getTaxonomies($attributes['contentTypes'])
|
];
|
}
|
|
if (isJVBUserType()) {
|
return $this->buildProfileConfig();
|
} elseif (isJVBContentTax()) {
|
return $this->buildShopConfig();
|
} elseif (is_tax()) {
|
return $this->buildTaxonomyConfig();
|
}
|
|
return [];
|
}
|
|
protected function buildProfileConfig():array
|
{
|
$obj = get_queried_object();
|
$content = jvbGetUserContentTypes($obj->ID);
|
return [
|
'is_gallery' => true,
|
'content' => $content,
|
'context' => jvbNoBase($obj->post_type),
|
'taxonomies' => $this->getTaxonomies($content)
|
];
|
}
|
|
protected function buildShopConfig():array
|
{
|
$type = jvbNoBase(get_queried_object()->taxonomy);
|
$content = jvbContentTaxContent($type);
|
|
$context = [
|
'content' => $content,
|
'taxonomies' => $this->getTaxonomies($content),
|
'context' => $type,
|
];
|
unset($context['taxonomies'][array_search($type, $context['taxonomies'])]);
|
return $context;
|
}
|
|
protected function buildTaxonomyConfig():array
|
{
|
$type = jvbNoBase(get_queried_object()->taxonomy);
|
$content = jvbContentTaxContent($type);
|
return [
|
'content' => $content,
|
'taxonomies' => $this->getTaxonomies($content),
|
'context' => $type
|
];
|
}
|
|
protected function getTaxonomies(array $content):array
|
{
|
global $jvb_taxonomy_for;
|
$taxonomies = [];
|
foreach ($jvb_taxonomy_for as $taxonomy => $for) {
|
if (array_intersect($for, $content)) {
|
$taxonomies[] = $taxonomy;
|
}
|
}
|
return $taxonomies;
|
}
|
|
public function render(array $attributes, string $content, WP_Block $block)
|
{
|
$this->config = $this->buildParams($attributes);
|
|
return $this->cache->remember(
|
$this->config,
|
function() {
|
return $this->renderBlock();
|
}
|
);
|
}
|
|
protected function renderBlock():string
|
{
|
$work = isJVBUserType() ? ' id="work"' : '';
|
|
ob_start();
|
?>
|
<section<?= $work ?> class="feed-block"
|
data-source="<?= get_queried_object_id(); ?>"
|
<?= (array_key_exists('context', $this->config)) ? ' data-context="'.$this->config['context'].'"' : '' ?>
|
<?= (array_key_exists('is_gallery', $this->config)) ? ' data-gallery="true"' : ''?>>
|
<?php
|
$this->renderFilters();
|
$this->renderGrid();
|
$this->renderLoader();
|
$this->renderTemplates();
|
?>
|
</section>
|
<?php
|
return ob_get_clean();
|
}
|
|
protected function renderFilters():void
|
{
|
if (empty($this->config)) {
|
return;
|
}
|
$many = count($this->config['content']) > 1;
|
global $jvb_everything;
|
global $jvb_taxonomy_for;
|
?>
|
<form class="feed-filters" data-save="feed">
|
<details>
|
<summary class="row btw">
|
<span class="label">SHOWING: </span>
|
<?php
|
$labels = [];
|
foreach ($this->config['content'] as $i => $type) :
|
$checked = $i === 0 ? ' checked' : '';
|
|
$label = $jvb_everything[$type]['plural'];
|
?>
|
|
<input type="radio"
|
id="filter-<?= esc_attr($type) ?>"
|
class="btn"
|
name="content"
|
value="<?= esc_attr($type) ?>"
|
<?= $checked ?>>
|
<label for="filter-<?= esc_attr($type) ?>" title="Show <?= $label ?>" class="row">
|
<?= jvbIcon($type, ['title'=> $label]) ?>
|
<span class="screen-reader-text"><?= $label ?></span>
|
</label>
|
|
<?php
|
$labels['filter-'.$type] = $label;
|
endforeach;
|
?>
|
<ul class="filter-label">
|
<?php
|
$i = 0;
|
foreach ($labels as $id =>$label) {
|
$active = $i === 0 ? ' class="active"' : '';
|
?>
|
<li id="<?=$id?>"<?=$active?>>
|
<?=$label?>
|
</li>
|
<?php
|
$i++;
|
}
|
?>
|
</ul>
|
|
|
<?php if (is_user_logged_in()) : ?>
|
<input type="checkbox" id="favourites" class="btn" name="favourites" value="on">
|
<label for="favourites" title="Show Favourites" class="row">
|
<?= jvbIcon('heart', ['title' =>'Favourites']) ?>
|
<span class="screen-reader-text">Show Favourites Only</span>
|
</label>
|
<?php endif; ?>
|
|
<?php if ($many) {
|
echo '</summary>';
|
} ?>
|
|
<div class="filters">
|
<div class="filter-group">
|
<span class="label">FILTER BY:</span>
|
|
<?php
|
foreach ($jvb_taxonomy_for as $tax => $items) :
|
$hidden = !in_array($tax, $this->config['taxonomies']) ? ' hidden' : '';
|
if (in_array($tax, $this->config['taxonomies'])) {
|
$tax = new TaxonomySelector(
|
'feed-'.$tax,
|
$tax,
|
[
|
'update' => '.selected-items-section .selected-items',
|
'types' => $items,
|
'hidden'=> $hidden
|
]
|
);
|
echo $tax->render();
|
}
|
|
endforeach; ?>
|
</div>
|
<div class="selected-items-section">
|
<div class="selected-items row"></div>
|
<div class="filter-actions row">
|
<?= jvbRenderToggleTextField('match', 'Match', 'Filters', 'ALL', 'ANY') ?>
|
<button type="button" class="clear-filters row">
|
<?= jvbIcon('close', ['title' => 'Clear']) ?>
|
Clear All Filters
|
</button>
|
</div>
|
</div>
|
</div>
|
|
<div class="filter-group">
|
<div class="order-by">
|
<span class="label">ORDER BY:</span>
|
<input type="radio" id="order-title" class="btn" name="orderby" value="title" data-for="artist,shop" hidden>
|
<label for="order-title" title="Order by Name" class="row">
|
<?= jvbIcon('alphabetical') ?>
|
<span class="label">Name</span>
|
</label>
|
|
<input type="radio" id="order-date" class="btn" name="orderby" value="date" checked>
|
<label for="order-date" title="Order by Date" class="row">
|
<?= jvbIcon('calendar', ['title'=>'Date']) ?>
|
<span class="label">Date</span>
|
</label>
|
|
<input type="radio" id="order-random" class="btn" name="orderby" value="random">
|
<label for="order-random" title="Random Order" class="row">
|
<?= jvbIcon('random') ?>
|
<span class="label">Random</span>
|
</label>
|
</div>
|
|
<div class="order-direction radio-group-label" data-for-order="date,title">
|
<span class="label">ORDER:</span>
|
<input type="radio" id="order-desc" class="btn" name="order" value="desc" checked>
|
<label for="order-desc" title="Newest First" class="row">
|
<?= jvbIcon('desc') ?>
|
</label>
|
|
<input type="radio" id="order-asc" class="btn" name="order" value="asc">
|
<label for="order-asc" title="Oldest First" class="row">
|
<?= jvbIcon('asc') ?>
|
</label>
|
</div>
|
</div>
|
</details>
|
</form>
|
<?php
|
}
|
|
protected function renderGrid():void
|
{
|
?>
|
<div class="item-grid"></div>
|
<?php
|
}
|
|
protected function renderLoader():void
|
{
|
?>
|
<button type="button" class="load-more">
|
<?= jvbIcon('elbow-left-down', ['title' =>'More']) ?>
|
Show Me More
|
<?= jvbIcon('elbow-right-down', ['title'=> 'More']) ?>
|
</button>
|
|
<?= jvbLoadingScreen() ?>
|
<?php
|
if (array_key_exists('is_gallery', $this->config)) {
|
jvbRenderGallery();
|
}
|
}
|
|
protected function renderTemplates():void
|
{
|
echo '<template class="feed-item">
|
<details class="item feed" data-umami-event="view_feed">
|
<summary class="row btw">
|
<span class="handle">DETAILS</span>
|
<button class="favourite" title="Add to favourites" onclick="toggleFavourite(this)">
|
'.jvbIcon('heart')
|
.jvbIcon('heart', ['style'=>'fill']).'
|
</button>
|
<div class="feed-images">
|
<a>
|
<img width="300px" height="300px" loading="lazy" decoding="async">
|
</a>
|
</div>
|
</summary>
|
|
<div class="item-info">
|
<h3><a></a></h3>
|
<div class="item">
|
<span class="label"></span>
|
<a></a>
|
<p></p>
|
</div>
|
<div class="item-list">
|
<span class="label"></span>
|
<ul>
|
<li>
|
<a></a>
|
</li>
|
</ul>
|
</div>
|
</div>
|
</div>
|
</details>
|
</template>';
|
|
echo '<template class="emptyState">
|
<div class="feed-empty-state">
|
<h3>NOTHING HERE...</h3>
|
<p>Try tweaking those filters a bit.</p>
|
<p>Edmonton\'s got talent - let\'s find it.</p>
|
</div>
|
</template>';
|
|
echo '<template class="placeholderTemplate"><div class="placeholder"></div></template>';
|
}
|
}
|