| | |
| | | exit; |
| | | } |
| | | |
| | | use JVBase\utility\Features; |
| | | use WP_Block; |
| | | use WP_Query; |
| | | |
| | | class DirectoryManager |
| | | { |
| | | protected array $directories; |
| | | protected array $directoryPageIDs; |
| | | protected array $directoryList; |
| | | protected static string $type = BASE.'for_type'; |
| | | protected static string $slug = BASE.'for_type_slug'; |
| | | protected CacheManager $cache; |
| | | |
| | | public function __construct() |
| | | { |
| | | $this->directories = jvbGlobalDirectoryInfo(); |
| | | if (empty(jvbGlobalDirectories())) { |
| | | $this->directories = $this->getDirectories(); |
| | | if (empty($this->directories)) { |
| | | return; |
| | | } |
| | | $this->cache = CacheManager::for('directory', WEEK_IN_SECONDS); |
| | | foreach(['content','taxonomy','user'] as $key) { |
| | | if (array_key_exists($key, $this->directories)) { |
| | | $this->cache->connectTo($key); |
| | | } |
| | | } |
| | | |
| | | add_action('init', [$this, 'registerDirectories']); |
| | | jvb_register_do_once('directories_registered', [$this, 'activate']); |
| | | |
| | | add_action('render_block', [$this, 'renderBlock'], 99, 3); |
| | | add_action('render_block', [$this, 'renderBlock'], 99999, 3); |
| | | } |
| | | |
| | | public function registerDirectories() |
| | |
| | | )); |
| | | } |
| | | |
| | | 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'; |
| | | } |
| | | } |
| | | } |
| | | if(Features::anyTaxonomyHas('show_directory')) { |
| | | foreach (JVB_TAXONOMY as $key=>$config) { |
| | | if (Features::forTaxonomy($key)->has('show_directory')) { |
| | | $directories[$key] = 'taxonomy'; |
| | | } |
| | | } |
| | | } |
| | | if (Features::anyUserHas('show_directory')) { |
| | | foreach(JVB_USER as $key=>$config) { |
| | | if (Features::forUser($key)->has('show_directory')) { |
| | | $directories[$key] = 'user'; |
| | | } |
| | | } |
| | | } |
| | | |
| | | update_option(BASE.'directories', $directories); |
| | | } |
| | | 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() |
| | | { |
| | | $created = []; |
| | | $directories = []; |
| | | |
| | | foreach (jvbGlobalDirectories() as $directory => $type) { |
| | | switch ($type) { |
| | | case 'content': |
| | | $config = JVB_CONTENT; |
| | | break; |
| | | case 'tax': |
| | | $config = JVB_TAXONOMY; |
| | | break; |
| | | case 'user': |
| | | $config = JVB_USER; |
| | | break; |
| | | } |
| | | $title = $config[$directory]['directory']??$config[$directory]['plural']; |
| | | $excerpt = implode(' ', $config[$directory]['description']??[]); |
| | | $ID = wp_insert_post([ |
| | | 'post_type' => BASE.'directory', |
| | | 'post_title'=> $title, |
| | | 'post_status'=> 'publish', |
| | | 'post_excerpt' => $excerpt, |
| | | 'slug' => sanitize_title($title) |
| | | ]); |
| | | if (!is_wp_error($ID)) { |
| | | add_post_meta($ID, self::$type, $type); |
| | | add_post_meta($ID, self::$slug, $directory); |
| | | $created[$directory] = (int)$ID; |
| | | $slug = sanitize_title($title); |
| | | $directories[$directory] = [ |
| | | 'slug' => $slug, |
| | | 'title' => $title, |
| | | 'ID' => $ID, |
| | | 'url' => get_home_url(null, '/directory/'.$slug), |
| | | 'page' => $title, |
| | | 'description' =>$config[$directory]['description']??[], |
| | | 'type' => $type, |
| | | 'extra' => $config[$directory]['directory_extra'] ??[], |
| | | ]; |
| | | } |
| | | foreach($this->directories as $directory => $type) { |
| | | $config = $this->getConfigFromType($directory); |
| | | $title = $config['directory']??$config['plural']; |
| | | $excerpt = implode(' ', $config['description']??[]); |
| | | $ID = wp_insert_post([ |
| | | 'post_type' => BASE.'directory', |
| | | 'post_title' => $title, |
| | | 'post_status' => 'publish', |
| | | 'post_excerpt' => $excerpt, |
| | | 'slug' => sanitize_title($title) |
| | | ]); |
| | | if (!is_wp_error($ID)) { |
| | | add_post_meta($ID, self::$type, $type); |
| | | add_post_meta($ID, self::$slug, $directory); |
| | | $created[$directory] = (int)$ID; |
| | | $slug = sanitize_title($title); |
| | | $directories[$directory] = [ |
| | | 'slug' => $slug, |
| | | 'title' => $title, |
| | | 'ID' => $ID, |
| | | 'url' => get_home_url(null, '/directory/'.$slug), |
| | | 'page' => $title, |
| | | 'description' =>$config[$directory]['description']??[], |
| | | 'type' => $type, |
| | | '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) { |
| | | $title = $title.', but Grouped'; |
| | | $slug = sanitize_title($title).'-grouped'; |
| | | $excerpt = $config['groupedDescription']??'Too many options? This is grouped by type.'; |
| | | $ID = wp_insert_post([ |
| | | 'post_type' => BASE.'directory', |
| | | 'post_title' => $title, |
| | | 'post_status' => 'publish', |
| | | 'post_excerpt' => $excerpt, |
| | | 'slug' => $slug, |
| | | ]); |
| | | if (!is_wp_error($ID)) { |
| | | add_post_meta($ID, self::$type, $type); |
| | | add_post_meta($ID, self::$slug, $directory.'-grouped'); |
| | | add_post_meta($ID, BASE.'grouped_directory', 'yup'); |
| | | $created[$directory.'-grouped'] = (int)$ID; |
| | | $directories[$directory.'-grouped'] = [ |
| | | 'slug' => $slug, |
| | | 'title' => $title, |
| | | 'ID' => $ID, |
| | | 'url' => get_home_url(null, '/directory/'.$slug), |
| | | 'page' => $title, |
| | | 'description' =>$config[$directory]['description']??[], |
| | | 'type' => $type, |
| | | 'extra' => $config[$directory]['directory_extra'] ??[], |
| | | ]; |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | if (jvbCheck('isGrouped', $config[$directory])) { |
| | | $title = $title. ', but Grouped'; |
| | | $excerpt = 'Too many options in the list? This is grouped by type, nested deep, man.'; |
| | | $slug = sanitize_title(str_replace(', but', '', $title)); |
| | | $ID = wp_insert_post([ |
| | | 'post_type' => BASE.'directory', |
| | | 'post_title'=> $title, |
| | | 'post_status'=> 'publish', |
| | | 'post_excerpt' => $excerpt, |
| | | 'slug' => $slug |
| | | ]); |
| | | if (!is_wp_error($ID)) { |
| | | add_post_meta($ID, self::$type, $type); |
| | | add_post_meta($ID, self::$slug, $directory.'-grouped'); |
| | | add_post_meta($ID, BASE.'grouped_directory', 'yup'); |
| | | $created[$directory.'-grouped'] = (int)$ID; |
| | | $directories[$directory.'-grouped'] = [ |
| | | 'slug' => $slug, |
| | | 'title' => $title, |
| | | 'ID' => $ID, |
| | | 'url' => get_home_url(null, '/directory/'.$slug), |
| | | 'page' => $title, |
| | | 'description' =>$config[$directory]['description']??[], |
| | | 'type' => $type, |
| | | 'extra' => $config[$directory]['directory_extra'] ??[], |
| | | ]; |
| | | } |
| | | } |
| | | |
| | | } |
| | | if (jvbCheck('has_map', JVB_SITE)) { |
| | | if (Features::forSite()->has('has_map')) { |
| | | $ID = wp_insert_post([ |
| | | 'post_type' => BASE.'directory', |
| | | 'post_title' => 'Map', |
| | |
| | | } |
| | | } |
| | | |
| | | public function getDirectoryPageIDs():array |
| | | { |
| | | if (empty($this->directoryPageIDs)) { |
| | | $this->directoryPageIDs = get_option(BASE.'directory_ids', []); |
| | | } |
| | | return $this->directoryPageIDs; |
| | | } |
| | | public function getDirectoryList():array |
| | | { |
| | | if (empty($this->directoryList)) { |
| | | $this->directoryList = get_option(BASE.'directory_list', []); |
| | | } |
| | | return $this->directoryList; |
| | | } |
| | | |
| | | public static function getConfig(int $ID):array |
| | | { |
| | | $type = get_post_meta($ID, self::$type, true); |
| | | $slug = get_post_meta($ID, self::$slug, true); |
| | | switch ($type) { |
| | | case 'content': |
| | | return JVB_CONTENT[$slug]; |
| | | case 'taxonomy': |
| | | return JVB_TAXONOMY[$slug]; |
| | | case 'user': |
| | | return JVB_USER[$slug]; |
| | | } |
| | | return []; |
| | | } |
| | | return match ($type) { |
| | | 'content' => JVB_CONTENT[$slug], |
| | | 'taxonomy' => JVB_TAXONOMY[$slug], |
| | | 'user' => JVB_USER[$slug], |
| | | default => [], |
| | | }; |
| | | } |
| | | |
| | | public function letters():array |
| | | { |
| | |
| | | ]; |
| | | } |
| | | |
| | | protected function alphabetizeMe( |
| | | public function alphabetizeMe( |
| | | array $list, |
| | | string $name = '', |
| | | string $url = '', |
| | |
| | | return $list; |
| | | } |
| | | |
| | | public function directories(string $search = 'all'):array |
| | | { |
| | | $directories = $this->getDirectories(); |
| | | if ($search === 'all') { |
| | | return $directories; |
| | | } |
| | | return $directories[$search]??[]; |
| | | } |
| | | |
| | | public function isDirectory():bool |
| | | { |
| | | return (is_post_type_archive(BASE.'directory') || is_singular(BASE.'directory')); |
| | | } |
| | | |
| | | private function renderArchive(): string |
| | | { |
| | | $this->getDirectoryList(); |
| | | return $this->cache->remember( |
| | | 'archive', |
| | | function() { |
| | | $cache = '<h1>Directory of Directories</h1> |
| | | <p>You like lists? We\'ve got \'em!</p> |
| | | <section class="directories item-grid">'; |
| | | foreach ($this->directories as $slug => $directory) { |
| | | foreach ($this->directoryList as $slug => $directory) { |
| | | $config = $this->getConfigFromType($slug); |
| | | $aOpen = '<a href="'.$directory['url'].'" title="See our list of '.$directory['title'].'">'; |
| | | $aClose = '</a>'; |
| | | $cache .= '<div class="directory col start"> |
| | | '.$aOpen.jvbIcon($slug).$aClose. |
| | | '.$aOpen.jvbIcon($config['icon']).$aClose. |
| | | '<h2>'.$aOpen.$directory['title'].$aClose.'</h2>'; |
| | | if (!empty($directory['description'])) { |
| | | $cache .= '<div class="description">'; |
| | |
| | | $cache = $this->cache->remember( |
| | | 'index', |
| | | function() { |
| | | $cache = '<nav class="directory"><ul>'; |
| | | foreach (jvbDirectories() as $slug => $directory) { |
| | | $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']??''); |
| | | $cache .= '<li id="'.$slug.'"> |
| | | <a href="'.$directory['url'].'">'. |
| | | jvbIcon(str_replace('-grouped', '', $slug)).$directory['title'].' |
| | | <a href="'.$directory['url'].'" class="'.$actualSlug.'">'. |
| | | $icon.$directory['title'].' |
| | | </a> |
| | | </li>'; |
| | | } |
| | |
| | | return $cache; |
| | | } |
| | | ); |
| | | if ($current !== '' && array_key_exists($current, jvbDirectories())) { |
| | | if ($current !== '' && array_key_exists($current, $this->directories())) { |
| | | $open = ($open) ? ' open' : ''; |
| | | $cache = '<details'.$open.'><summary class="row btw">Other Directories:</summary>'. |
| | | str_replace('id="'.$current.'"', 'id="'.$current.'" class="current"', $cache) |
| | |
| | | if ($slug === '') { |
| | | return ''; |
| | | } |
| | | $this->directories(); |
| | | return $this->cache->remember( |
| | | $slug, |
| | | function() use ($slug) { |
| | | $out = '<h1>'.$this->directories[$slug]['title'].'</h1>'; |
| | | $config = $this->getConfigFromType($slug); |
| | | $out = '<h1>'.$config['directory'].'</h1>'; |
| | | $out .= '<div class="description">'; |
| | | |
| | | foreach ($this->directories[$slug]['description']??[] as $p) { |
| | | foreach ($config[$slug]['description']??[] as $p) { |
| | | $out .= '<p>'.$p.'</p>'; |
| | | } |
| | | $out .= '</div>'; |
| | | $out .= $this->renderIndex($slug); |
| | | |
| | | $data = $this->directories[$slug]; |
| | | $type = $this->directories[$slug]; |
| | | $list = []; |
| | | switch ($data['type']) { |
| | | switch ($type) { |
| | | case 'content': |
| | | $get = new WP_Query([ |
| | | 'post_type' => jvbCheckBase($slug), |
| | |
| | | 'order' => 'ASC' |
| | | ]); |
| | | |
| | | $hasExtra = Features::forContent($slug)->has('directory_extra'); |
| | | if ($get->have_posts()) { |
| | | while ( $get->have_posts() ) { |
| | | $get->the_post(); |
| | | $extra = []; |
| | | foreach ( $data['extra'] as $item ) { |
| | | $item = jvbCheckBase( $item ); |
| | | if ($hasExtra) { |
| | | foreach ($config['directory_extra'] as $item ) { |
| | | $item = jvbCheckBase( $item ); |
| | | |
| | | $terms = get_the_terms( get_the_ID(), jvbCheckBase( $item ) ); |
| | | 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, |
| | | 'url' => get_term_link( $term->term_id, $item ), |
| | | 'id' => $term->term_id, |
| | | 'type' => $item, |
| | | ]; |
| | | $terms = get_the_terms( get_the_ID(), jvbCheckBase( $item ) ); |
| | | 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, |
| | | 'url' => get_term_link( $term->term_id, $item ), |
| | | 'id' => $term->term_id, |
| | | 'type' => $item, |
| | | ]; |
| | | |
| | | } |
| | | } |
| | | $list = $this->alphabetizeMe( |
| | | $list, |
| | | get_the_title(), |
| | | get_the_permalink(), |
| | | get_the_ID(), |
| | | $extra |
| | | ); |
| | | } |
| | | $list = $this->alphabetizeMe( |
| | | $list, |
| | | get_the_title(), |
| | | get_the_permalink(), |
| | | get_the_ID(), |
| | | $extra |
| | | ); |
| | | } |
| | | } |
| | | wp_reset_postdata(); |
| | | break; |
| | | case 'tax': |
| | | case 'taxonomy': |
| | | $get = get_terms([ |
| | | 'taxonomy' => jvbCheckBase($slug), |
| | | 'hide_empty' => true, |
| | |
| | | ]); |
| | | |
| | | if ($get && !is_wp_error($get)) { |
| | | $extra = false; |
| | | $extra = []; |
| | | foreach ($get as $term) { |
| | | |
| | | $list = $this->alphabetizeMe( |
| | |
| | | ]); |
| | | |
| | | break; |
| | | default: |
| | | $list = []; |
| | | break; |
| | | } |
| | | |
| | | $out .= '<section class="directory-list '.$slug.'">'; |
| | |
| | | } |
| | | return $this->cache->remember( |
| | | $slug.'_group', |
| | | function() { |
| | | function() use ($slug){ |
| | | $out = '<h1>'.$this->directories[$slug]['title'].'</h1>'; |
| | | $out .= '<div class="description">'; |
| | | |
| | |
| | | |
| | | $out = '<ul class="list-none">'; |
| | | foreach ($list as $letter => $items) { |
| | | $out .= '<li id="starts-with-'.$letter.'" class="row a-start btw"><h3>'.strtoupper($letter).'</h3><ul>'; |
| | | $out .= '<li id="starts-with-'.$letter.'" class="row a-start btw nowrap"><h3>'.strtoupper($letter).'</h3><ul>'; |
| | | foreach ($items as $item) { |
| | | $extra = ''; |
| | | if (!empty($item['extra'])) { |
| | |
| | | return $content; |
| | | } |
| | | |
| | | |
| | | // For archive page |
| | | if (is_post_type_archive(BASE.'directory') && $block['blockName'] === 'core/group') { |
| | | return ($block['attrs']['tagName']??false === 'main') ? '<main>'.$this->renderArchive().'</main>' : $content; |
| | | return ($block['attrs']['tagName']??'' === 'main') ? '<main>'.$this->renderArchive().'</main>' : $content; |
| | | } |
| | | |
| | | // For single directory posts |
| | | if ($block['blockName'] === 'core/group') { |
| | | |
| | | switch (get_post_meta(get_the_ID(), BASE.'grouped_directory', true)) { |
| | | case '': |
| | | return '<main>' . $this->renderDirectory() . '</main>'; |
| | |
| | | return $content; |
| | | } |
| | | } |
| | | |
| | | new DirectoryManager(); |
| | | |
| | | function jvbDirectoryConfig():array |
| | | { |
| | | $ID = get_the_ID(); |
| | | if ($ID) { |
| | | return DirectoryManager::getConfig($ID); |
| | | } |
| | | return []; |
| | | } |
| | | |