Jake Vanderwerf
4 days ago 5a6906f710e9333507486df3cbb545a67a040881
inc/managers/DirectoryManager.php
@@ -5,8 +5,8 @@
   exit;
}
use JVBase\registry\PostTypeRegistrar;
use JVBase\utility\Features;
use JVBase\registrar\Registrar;
use JVBase\base\Site;
use WP_Block;
use WP_Query;
@@ -18,7 +18,7 @@
   protected int $perPage;
    protected static string $type = BASE.'for_type';
    protected static string $slug = BASE.'for_type_slug';
    protected CacheManager $cache;
    protected Cache $cache;
    public function __construct($perPage = 100)
    {
@@ -27,27 +27,25 @@
            return;
        }
      $this->perPage = $perPage;
        $this->cache = CacheManager::for('directory', WEEK_IN_SECONDS);
        $this->cache = Cache::for('directory', WEEK_IN_SECONDS);
      $this->cache->connect('post', true)
         ->connect('taxonomy', true)
         ->connect('user', true);
      if (JVB_TESTING) {
         $this->cache->clear();
         $this->cache->flush();
      }
      foreach(['content','taxonomy','user'] as $key) {
         if (array_key_exists($key, $this->directories)) {
            $this->cache->connectTo($key);
         }
      }
      jvb_register_do_once('buildDirectories', [$this, 'activate']);
      add_action('init', [$this, 'registerDirectories']);
      jvb_register_do_once('directories_registered', [$this, 'activate']);
        add_action('render_block', [$this, 'renderBlock'], 99999, 3);
        add_filter('render_block', [$this, 'renderBlock'], 998, 3);
    }
    public function registerDirectories():void
    {
      $singular = (array_key_exists('directory_label', JVB_SITE)) ? JVB_SITE['directory_label'][0] : 'Directory';
      $plural = (array_key_exists('directory_label', JVB_SITE)) ? JVB_SITE['directory_label'][1] : 'Directories';
      $singular = Site::getDirectorySingular()??'Directory';
      $plural = Site::getDirectoryPlural()??'Directories';
      $config = [
         'labels' => [
            'name'               => $plural,
@@ -68,7 +66,7 @@
         'public'              => true,
         'menu_icon'    => jvbCSSIcon('list-dashes'),
         'publicly_queryable'    => true,
         'show_in_menu'          => false,
         'show_in_menu'          => true,
         'show_in_admin_bar'     => false,
         'has_archive'           => true,
         'hierarchical'       => true,
@@ -87,28 +85,29 @@
   public function getDirectories():array
   {
      $directories = get_option(BASE.'directories');
      if (!$directories) {
         $directories = [];
         //content
         if(Features::anyContentHas('show_directory')) {
            foreach (JVB_CONTENT as $key => $config) {
               if (Features::forContent($key)->has('show_directory')) {
                  $directories[$key] = 'content';
               }
         $content = Registrar::getFeatured('show_directory', 'post');
         if(!empty($content)) {
            foreach ($content as $key) {
               $directories[$key] = 'content';
            }
         }
         if(Features::anyTaxonomyHas('show_directory')) {
            foreach (JVB_TAXONOMY as $key=>$config) {
               if (Features::forTaxonomy($key)->has('show_directory')) {
                  $directories[$key] = 'taxonomy';
               }
         $taxonomies = Registrar::getFeatured('show_directory', 'term');
         if(!empty($taxonomies)) {
            foreach ($taxonomies as $key) {
               $directories[$key] = 'taxonomy';
            }
         }
         if (Features::anyUserHas('show_directory')) {
            foreach(JVB_USER as $key=>$config) {
               if (Features::forUser($key)->has('show_directory')) {
                  $directories[$key] = 'user';
               }
         $users = Registrar::getFeatured('show_directory', 'user');
         if(!empty($users)) {
            foreach ($users as $key) {
               $directories[$key] = 'user';
            }
         }
@@ -116,37 +115,53 @@
      }
      return $directories;
   }
   protected function getConfigFromType(string $type):array
   {
      if (!array_key_exists($type, $this->directories)) {
         return [];
      }
      return match ($this->directories[$type]) {
         'content' => JVB_CONTENT[$type],
         'taxonomy' => JVB_TAXONOMY[$type],
         'user' => JVB_USER[$type],
         default => [],
      };
   }
    public function activate()
    public function activate():void
    {
      $this->registerDirectories();
//    $tmp = new self();
//    $this->registerDirectories();
        $created = [];
        $directories = [];
      $this->getDirectories();
      foreach($this->directories as $directory => $type) {
         $config = $this->getConfigFromType($directory);
         $title = $this->directoryTitle($config);
         $registrar = Registrar::getInstance($directory);
         if (!$registrar){
            error_log('Could not find registrar for making directory for '.$directory);
            continue;
         }
         $config = $registrar->getConfig('directory');
         $title = $config['title'];
         //Bail early if we've already created the page
         $existing = new WP_Query([
            'post_type' => BASE.'directory',
            'name'   => sanitize_title($title),
            'posts_per_page'  => 1,
         ]);
         if ($existing->have_posts()) {
            $existing = $existing->posts[0];
            $created[$directory] = $existing->ID;
            $directories[$directory] = [
               'slug'   => $existing->post_name,
               'title'  => $existing->post_title,
               'ID'  => $existing->ID,
               'url' => get_the_permalink($existing->ID),
               'page'   => $existing->post_title,
               'description'=> $existing->post_excerpt,
               'type'   => $type,
               'extra'  => $config[$directory]['directory_extra']??[],
            ];
            continue;
         }
         $excerpt = implode(' ', $config['description']??[]);
         $ID = wp_insert_post([
            'post_type' => BASE.'directory',
            'post_type'    => BASE.'directory',
            'post_title'   => $title,
            'post_status'  => 'publish',
            'post_excerpt' => $excerpt,
            'slug'         => sanitize_title($title)
            'post_name'       => sanitize_title($title)
         ]);
         if (!is_wp_error($ID)) {
            add_post_meta($ID, self::$type, $type);
@@ -164,13 +179,7 @@
               'extra'    => $config[$directory]['directory_extra'] ??[],
            ];
         }
         $isGrouped = match ($type) {
            'content' => Features::forContent($directory)->has('isGrouped'),
            'taxonomy' => Features::forTaxonomy($directory)->has('isGrouped'),
            'user' => Features::forUser($directory)->has('isGrouped'),
            default => false,
         };
         if ($isGrouped) {
         if ($config['isGrouped']) {
            $title = $title.', but Grouped';
            $slug = sanitize_title($title).'-grouped';
            $excerpt = $config['groupedDescription']??'Too many options? This is grouped by type.';
@@ -200,7 +209,7 @@
         }
      }
//        if (Features::forSite()->has('has_map')) {
//        if (Site::has('has_map')) {
//            $ID = wp_insert_post([
//                'post_type'     => BASE.'directory',
//                'post_title'    => 'Map',
@@ -220,7 +229,6 @@
//                ];
//            }
//        }
        if (!empty($created)) {
            update_option(BASE.'directory_ids', $created);
        }
@@ -229,6 +237,36 @@
        }
    }
   protected function buildDirectoryList():array
   {
      $saved = get_option(BASE.'directory_list', []);
      if (empty($saved)) {
         $all = new WP_Query([
            'post_type' => BASE.'directory',
            'post_status'  => 'publish',
            'posts_per_page'  => -1,
         ]);
         foreach($all->posts as $post) {
            $config = Registrar::getInstance($post->post_name)->getConfig('directory')??false;
            $saved[$post->post_name] = [
               'slug'   => $post->post_name,
               'title'  => $post->post_title,
               'ID'  => $post->ID,
               'url' => get_the_permalink($post->ID),
               'page'   => $post->post_title,
               'description'  => ($config) ?$config['description'] :'',
               'type'   => get_post_meta($post->ID, self::$type,true),
               'extra'  => ($config) ?$config['directory_extra'] : [],
            ];
         }
         update_option(BASE.'directory_list', $saved);
         wp_reset_postdata();
      }
      return $saved;
   }
   public function getDirectoryPageIDs():array
   {
      if (empty($this->directoryPageIDs)) {
@@ -239,21 +277,15 @@
   public function getDirectoryList():array
   {
      if (empty($this->directoryList)) {
         $this->directoryList = get_option(BASE.'directory_list', []);
         $this->directoryList = $this->buildDirectoryList();
      }
      return $this->directoryList;
   }
    public static function getConfig(int $ID):array
    public static function getConfig(int $ID):Registrar|false
    {
        $type = get_post_meta($ID, self::$type, true);
        $slug = get_post_meta($ID, self::$slug, true);
      return match ($type) {
         'content' => JVB_CONTENT[$slug],
         'taxonomy' => JVB_TAXONOMY[$slug],
         'user' => JVB_USER[$slug],
         default => [],
      };
      return Registrar::getInstance($slug);
   }
    public function letters():array
@@ -317,7 +349,7 @@
   public function directories(string $search = 'all'):array
   {
      $directories = $this->getDirectories();
      $directories = $this->getDirectoryList();
      if ($search === 'all') {
         return $directories;
      }
@@ -339,11 +371,11 @@
                <p>You like lists? We\'ve got \'em!</p>
                <ul class="directories">';
            foreach ($this->directoryList as $slug => $directory) {
               $config = $this->getConfigFromType($slug);
               $config = Registrar::getInstance($slug);
               $aOpen = '<a href="'.$directory['url'].'" title="See our list of '.$directory['title'].'">';
               $aClose = '</a>';
               $cache .= '<li class="directory col start">
                  '. $aOpen.jvbIcon(array_key_exists('icon', $config) ? $config['icon']:'list-dashes').$directory['title'].$aClose;
               $cache .= '<li class="directory col left">
                  '. $aOpen.jvbIcon($config->getIcon() !== '' ? $config->getIcon() :'list-dashes').$directory['title'].$aClose;
               if (!empty($directory['description'])) {
                  $cache .= '<div class="description">';
                  foreach ($directory['description'] as $description) {
@@ -367,8 +399,8 @@
            $cache = '<nav class="directory condensed"><ul>';
            foreach ($this->getDirectoryList() as $slug => $directory) {
               $actualSlug = str_replace('-grouped', '', $slug);
               $config = $this->getConfigFromType($actualSlug);
               $icon = jvbIcon($config['icon']??'');
               $config = Registrar::getInstance($actualSlug);
               $icon = $config->getIcon() !== '' ? jvbIcon($config->getIcon()) : '';
               $cache .= '<li id="'.$slug.'">
                    <a href="'.$directory['url'].'" class="'.$actualSlug.'">'.
                  $icon.$directory['title'].'
@@ -381,7 +413,7 @@
      );
        if ($current !== '' && array_key_exists($current, $this->directories())) {
            $open = ($open) ? ' open' : '';
            $cache = '<details'.$open.'><summary class="row btw">Other '.$this->referAs(true).':</summary>'.
            $cache = '<details'.$open.'><summary class="row x-btw">Other '.$this->referAs(true).':</summary>'.
                     str_replace('id="'.$current.'"', 'id="'.$current.'" class="current"', $cache)
                     .'</details>';
        }
@@ -396,7 +428,8 @@
   }
   $type = $this->directories[$slug];
   $config = $this->getConfigFromType($slug);
   $registrar = Registrar::getInstance($slug);
   $config = $registrar->getConfig('directory');
   $paged = isset($_GET['page']) ? max(1, (int)$_GET['page']) : 1;
@@ -404,10 +437,10 @@
   return $this->cache->remember(
      $cacheKey,
      function() use ($slug, $type, $config, $paged) {
         $out = '<h1>' . $this->directoryTitle($config) . '</h1>';
      function() use ($slug, $type, $registrar, $config, $paged) {
         $out = '<h1>' . $this->directoryTitle($registrar) . '</h1>';
         $out .= '<div class="description">';
         foreach ($config[$slug]['description'] ?? [] as $p) {
         foreach ($config['description'] ?? [] as $p) {
            $out .= '<p>' . $p . '</p>';
         }
         $out .= '</div>';
@@ -426,13 +459,14 @@
                  'order' => 'ASC'
               ];
               if (Features::forContent($slug)->has('is_timeline')) {
               if ($registrar->hasFeature('is_timeline')) {
                  $args['post_parent'] = 0;
               }
               $get = new WP_Query($args);
                  $hasExtra = Features::forContent($slug)->has('directory_extra');
                  $hasExtra = $registrar->hasFeature('directory_extra');
                  if ($get->have_posts()) {
                     while ( $get->have_posts() ) {
                        $get->the_post();
@@ -445,7 +479,7 @@
                              if ( $terms && ! is_wp_error( $terms ) ) {
                                 $term    = $terms[0];
                                 $extra[] = [
                                    'name' => (get_term_meta( $term->term_id, BASE . 'singular', true ) !== '') ? get_term_meta( $term->term_id, BASE . 'singular', true ) : $term->name,
                                    'name' => (get_term_meta( $term->term_id, BASE . 'singular', true ) !== '') ? get_term_meta( $term->term_id, BASE . 'singular', true ) : html_entity_decode($term->name),
                                    'url'  => get_term_link( $term->term_id, $item ),
                                    'id'   => $term->term_id,
                                    'type' => $item,
@@ -489,7 +523,7 @@
                        $list = $this->alphabetizeMe(
                           $list,
                           $term->name,
                           html_entity_decode($term->name),
                           get_term_link( $term->term_id, jvbCheckBase( $slug ) ),
                           $term->term_id,
                           $extra
@@ -580,11 +614,11 @@
         $children =$this->renderListChunk($taxonomy, $term->term_id);
         $out .= '<li>';
         if ($children !== '') {
            $out .= '<details class="term"><summary class="row btw"><a href="'.get_term_link($term->term_id, $term->taxonomy).'" title="See more '.$term->name.'">'.$term->name.'</a></summary>';
            $out .= '<details class="term"><summary class="row x-btw"><a href="'.get_term_link($term->term_id, $term->taxonomy).'" title="See more '.html_entity_decode($term->name).'">'.$term->name.'</a></summary>';
            $out .= $children;
            $out .= '</details>';
         } else {
            $out .= '<a href="'.get_term_link($term->term_id, $term->taxonomy).'" title="See more '.$term->name.'">'.$term->name.'</a>';
            $out .= '<a href="'.get_term_link($term->term_id, $term->taxonomy).'" title="See more '.$term->name.'">'.html_entity_decode($term->name).'</a>';
         }
         $out .= '</li>';
        }
@@ -635,7 +669,7 @@
        $out = '<ul class="list-none">';
        foreach ($list as $letter => $items) {
            $out .= '<li id="starts-with-'.$letter.'" class="row a-start btw nowrap"><h3>'.strtoupper($letter).'</h3><ul>';
            $out .= '<li id="starts-with-'.$letter.'" class="row top x-btw nowrap"><h3>'.strtoupper($letter).'</h3><ul>';
            foreach ($items as $item) {
                $extra = '';
                if (!empty($item['extra'])) {
@@ -650,7 +684,7 @@
            $item_html = apply_filters('jvb_directory_render_item', '', $item, $type, $extra);
            if (empty($item_html)) {
               $item_html = '<li class="row btw">
               $item_html = '<li class="row x-btw">
                    <a href="'.$item['url'].'" title="More about '.$item['name'].'">
                        '.$item['name'].'</a>'.$extra.'
                </li>';
@@ -673,6 +707,7 @@
            return $content;
        }
      error_log('Still working on directory manager...');
        // For archive page
        if (is_post_type_archive(BASE.'directory') && $block['blockName'] === 'core/group') {
            return ($block['attrs']['tagName']??'' === 'main') ? '<main>'.$this->renderArchive().'</main>' : $content;
@@ -691,17 +726,15 @@
        return $content;
    }
   protected function directoryTitle(array $config):string
   protected function directoryTitle(Registrar $registrar):string
   {
      return array_key_exists('directory', $config) ? $config['directory'] : $config['plural'];
      $config = $registrar->getConfig('directory');
      return $config['title']?: $registrar->getPlural();
   }
   public function referAs($plural = false):string
   {
      if (!empty(JVB_SITE) && array_key_exists('directory_label', JVB_SITE)) {
         return ($plural) ? JVB_SITE['directory_label'][1] : JVB_SITE['directory_label'][0];
      }
      return ($plural) ? 'Directories' : 'Directory';
      return ($plural) ? Site::getDirectoryPlural()??'Directories' : Site::getDirectorySingular()??'Directory';
   }
   /*****************************************************
@@ -802,14 +835,14 @@
         $slug . '_letter_page_map',
         function() use ($type, $slug) {
            $titles = [];
            $registrar = Registrar::getInstance($slug);
            switch ($type) {
               case 'content':
                  global $wpdb;
                  $post_type = jvbCheckBase($slug);
                  $where = $wpdb->prepare("post_type = %s AND post_status = 'publish'", $post_type);
                  if (Features::forContent($slug)->has('is_timeline')) {
                  if ($registrar && $registrar->hasFeature('is_timeline')) {
                     $where .= " AND post_parent = 0";
                  }