cache = CacheManager::for('feed_block', WEEK_IN_SECONDS); // Set up cache connections for all feed content types $this->setupCacheConnections(); add_action('init', [$this, 'registerBlock']); } /** * Set up cache connections for feed content */ protected function setupCacheConnections(): void { // Connect to all content types that show in feed $contentTypes = Features::getTypesWithFeature('show_feed', 'content'); foreach ($contentTypes as $type) { CacheManager::for('feed_content')->connectTo('post', $type); } // Connect to all taxonomies that show in feed $taxonomies = Features::getTypesWithFeature('show_feed', 'taxonomy'); foreach ($taxonomies as $tax) { CacheManager::for('feed_taxonomy')->connectTo('taxonomy', $tax); } } 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']) ]; } $config = [ 'is_gallery' => false, 'content' => '', 'taxonomies' => [] ]; $type = get_queried_object(); if (is_post_type_archive() || is_singular()) { $content = is_singular() ? jvbNoBase($type->post_type) : jvbNoBase($type->name); $mainConfig = JVB_CONTENT[$content]??false; if ($mainConfig && array_key_exists('feed', $mainConfig) && array_key_exists('config', $mainConfig['feed'])){ $config = array_merge($config, $mainConfig['feed']['config']); } else { $config['content'] = $content; $config['icon'] = JVB_CONTENT[$content]['icon']??['logo-triangle']; } if (is_singular()) { $config['source'] = $type->ID; } $config['taxonomies'] = $this->getTaxonomies([$content]); } elseif (is_tax()) { $content = jvbNoBase($type->taxonomy); $mainConfig = JVB_TAXONOMY[$content]??false; if ($mainConfig) { $config['content'] = $mainConfig['for_content']; $config['context'] = $content; // ← ADD THIS $config['taxonomies'] = $this->getTaxonomies($mainConfig['for_content']); if (array_key_exists('feed', $mainConfig) && array_key_exists('config', $mainConfig['feed'])){ $config = array_merge($config, $mainConfig['feed']['config']); } } $config['source'] = $type->term_id; } if (!is_array($config['content'])) { $config['content'] = [$config['content']]; } return $config; } /** * Get taxonomies for given content types * Uses Checker instead of globals */ protected function getTaxonomies(array $content): array { $checker = Checker::getInstance(); $taxonomies = []; foreach ($content as $contentType) { $contentTaxonomies = $checker->getTaxonomiesForContent($contentType); $contentTaxonomies = array_filter($contentTaxonomies, function($taxonomy) { return array_key_exists('show_feed', JVB_TAXONOMY[$taxonomy]) && JVB_TAXONOMY[$taxonomy]['show_feed']; }); $taxonomies = array_merge($taxonomies, $contentTaxonomies); } return array_unique($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 { $ids = (array_key_exists('ids', $this->config) && !empty($this->config['ids'])) ? ' id="'.implode(' ',$this->config['ids']).'"' : ''; $classes = (array_key_exists('classes', $this->config) && !empty($this->config['classes'])) ? ' class="'.implode(' ',$this->config['classes']).'"' : ''; $source = (array_key_exists('source', $this->config)) ? ' data-source="'.$this->config['source'].'"' : ''; $context = (array_key_exists('context', $this->config)) ? ' data-context="'.$this->config['context'].'"' : ''; $icons = (array_key_exists('icon', $this->config)) ? ' data-icon="'.$this->config['icon'].'"' : ' data-icon="logo-triangle"'; $gallery = (array_key_exists('is_gallery', $this->config) && $this->config['is_gallery']) ? ' data-gallery' : ''; $content = (array_key_exists('content', $this->config)) ? ' data-content="'.implode(',',$this->config['content']).'"' : ''; ob_start(); ?> class="feed-block"> renderFilters(); $this->renderGrid(); $this->renderLoader(); $this->renderTemplates(); echo TaxonomySelector::outputSelectorModal(); ?> config)) { return; } $feedContent = $this->getFeedContent(); $hasMany = count($this->config['content']) > 1; ?>
SHOWING: config['content'] as $i => $type) : $checked = $i === 0 ? ' checked' : ''; $label = $feedContent[$type]['plural'] ?? ucfirst($type); ?> >
    $label) { $active = $i === 0 ? ' class="active"' : ''; ?>
  • >
has('favourites') && is_user_logged_in()) : ?>
FILTER BY: config['taxonomies'] as $tax) : $taxConfig = JVB_TAXONOMY[$tax] ?? null; if (!$taxConfig) continue; $contentForTax = $checker->getContentForTaxonomy($tax); $hidden = empty($contentForTax) ? ' hidden' : ''; $taxSelector = new TaxonomySelector( 'feed-'.$tax, $tax, [ 'icon' => $taxConfig['icon']??'logo-triangle', 'update' => '.selected-items-section .selected-items', 'types' => $contentForTax, 'autocomplete' => false, 'hidden' => $hidden, 'output' => 'minimal' ] ); echo $taxSelector->render(); endforeach; ?>
'match']) ?>
ORDER BY:
ORDER:
config['content']) - 1; for ($i = 1; $i <= 36; $i++) { $rand = rand(0, $total); $config = Features::getConfig($this->config['content'][$rand]); $icon = jvbIcon($config['icon']??'logo-triangle'); ?>
config)) { jvbRenderGallery(); } } protected function renderTemplates(): void { echo ''; echo ''; echo ''; } /** * Get feed content using Features instead of get_option * Returns array of slug => config for types that show in feed */ public function getFeedContent(): array { return JVB()->routes('feed')->getFeedTypesConfig(); } }