Jake Vanderwerf
2026-03-29 275c0d74cd68677622a5431505c5c870c473063d
inc/registrar/Registrar.php
@@ -1,8 +1,10 @@
<?php
namespace JVBase\registrar;
use JVBase\managers\Cache;
use JVBase\managers\CRUD;
use JVBase\managers\IconsManager;
use JVBase\meta\Meta;
use JVBase\registrar\config\Breadcrumbs;
use JVBase\registrar\config\Dashboard;
use JVBase\registrar\config\Directory;
@@ -15,6 +17,7 @@
use JVBase\registrar\helpers\MakeTrackChanges;
use JVBase\registrar\helpers\MakeVerification;
use JVBase\utility\Features;
use WP_Query;
if (!defined('ABSPATH')) {
   exit;
@@ -36,6 +39,8 @@
   protected ?string $upload_title = null;
   protected int|false $page = false;
   protected static array $allFlags = [
      //Shared Flags
      'favouritable', 'karma', 'show_feed', 'show_directory', 'approve_new', 'has_responses', 'invitable',
@@ -181,8 +186,10 @@
   private static array $instances = [];
   protected string $based;
   private function __construct(string $slug, string $singular, string $plural, string $type) {
      $this->slug = $slug;
      $this->based = jvbCheckBase($slug);
      $this->type = $type;
      $this->singular = $singular;
      $this->plural = $plural;
@@ -281,6 +288,11 @@
      return $this->fields;
   }
   public function args():array
   {
      return $this->args;
   }
   public function setFields():void
   {
      $this->fields = new Fields($this->type, $this);
@@ -373,6 +385,11 @@
      return $this->slug;
   }
   public function getBased():string
   {
      return $this->based;
   }
   public function setTimeline(bool $set):self
   {
      $this->is_timeline = $set;
@@ -401,6 +418,11 @@
      });
      foreach ($flags as $flag) {
         $this->$flag = true;
         switch ($flag) {
            case 'is_content':
               add_action('init', [$this, 'setupContent'], 20);
               break;
         }
      }
      return $this;
   }
@@ -639,4 +661,140 @@
      return $content;
   }
   public function setupContent():void
   {
      if (!$this->is_content) return;
      //We need a pseudo-archive page for this content taxonomy. We create a post with the plural name
      $this->page = get_option(BASE.$this->slug.'_archive', false);
      if (!$this->page || !(bool)get_post((int)$this->page)) {
         $exists = new WP_Query([
            'post_type' => 'page',
            'title'=> $this->plural,
            'posts_per_page'  => 1,
            'post_status'  => 'publish',
            'fields' => 'ids',
         ]);
         if ($exists->have_posts()) {
            $page = $exists->posts[0];
         } else {
            $page = wp_insert_post([
               'post_type'    => 'page',
               'post_title'   => $this->plural,
               'post_content' => '',
               'post_status'  => 'publish',
            ]);
         }
         if ($page && !is_wp_error($page)) {
            update_post_meta($page, BASE.'for_type', $this->slug);
            update_option(BASE.$this->slug.'_archive', $page);
            $this->page = $page;
         }
         wp_reset_postdata();
      }
      add_filter('jvb_post_content_output', [$this, 'renderContent'], 20, 2);
      //Add a date published and date modified fields, and auto-update them on term creation/modification
      $this->fields()->addField('date_published', [
         'type'   => 'datetime',
         'label'  => 'Published',
         'hidden' => true,
      ]);
      $this->fields()->addField('date_modified', [
         'type'   => 'datetime',
         'label'  => 'Modified',
         'hidden' => true,
      ]);
      add_action('created_'.$this->based, [$this, 'addTermCreatedMeta']);
      add_action('edited_'.$this->based, [$this, 'addTermUpdatedMeta']);
   }
      public function addTermCreatedMeta(int $termId):void
      {
         $meta = Meta::forTerm($termId);
         $meta->set('date_published', date('Y-m-d H:i:s'));
      }
      public function handleContentTermMetaChange(int $meta_id, int $term_id, string $meta_key, $meta_value):void
      {
         $term = get_term($term_id);
         $taxonomy = $term->taxonomy;
         if ($taxonomy === $this->based && $meta_key !== BASE . 'date_modified') {
            $meta = Meta::forTerm($term_id);
            $meta->set('date_modified', date('Y-m-d H:i:s'));
         }
      }
      public function addTermUpdatedMeta(int $termId):void
      {
         $meta = Meta::forTerm($termId);
         $meta->set('date_modified', date('Y-m-d H:i:s'));
      }
   public function renderContent(string $content, array $block):string
   {
      if (!is_page($this->page)) {
         return $content;
      }
      if ($block['blockName'] !== 'core/post-content') {
         return $content;
      }
      if (JVB_TESTING) {
         Cache::for($this->slug)->flush();
      }
      $out = Cache::for($this->slug)->remember(
         get_the_ID(),
         function() {
            $items = get_terms([
               'taxonomy'  => jvbCheckBase($this->slug),
//                'hide_empty' => true,
               'fields' => 'ids',
            ]);
            $out = [];
            if ($items && !is_wp_error($items)) {
               foreach ($items as $item) {
                  $meta = Meta::forTerm($item);
                  $slug = sanitize_title($meta->get('name'));
                  $item = sprintf(
                     '<li id="%s"><h2><a href="%s">%s</a></h2><p>%s</p><ul class="item-grid">',
                     $slug,
                     get_term_link($item, jvbCheckBase($this->slug))??'',
                     $meta->get('name'),
                     $meta->get('description')
                  );
                     $postTypes = array_map(function($type) { return jvbCheckBase($type);}, $this->registrar->for);
                     $posts = new WP_Query([
                        'post_type'    => $postTypes,
                        'post_status'  => 'publish',
                        'posts_per_page'  => 3,
                        'fields' => 'ids',
                     ]);
                     if ($posts->have_posts()) {
                        while($posts->have_posts()) {
                           $posts->the_post();
                           $ID = get_the_id();
                           $postMeta = Meta::forPost($ID);
                           $img = $postMeta->get('post_thumbnail');
                           $img = !empty($img) ? jvbFormatImage((int)$img, 'tiny', 'medium') : '';
                           $item .= sprintf(
                              '<li id="%s" class="item"><h3><a href="%s">%s</a></h3>%s</li>',
                              $slug.'-'.sanitize_title(get_the_title($ID)),
                              get_the_permalink($ID),
                              $postMeta->get('post_title'),
                              $img
                           );
                        }
                     }
                     wp_reset_postdata();
                  $item .= '</ul></li>';
                  $out[] = $item;
               }
            }
            return empty($out) ? '' : '<ul class="content-term-list">'.implode('',$out).'</ul>';
         }
      );
      error_log('Built the '.$this->slug.' page content.');
      return $content . $out;
   }
}