From 2bb9aaaf24b794b528e3894ee9f9c42ca6d7fe93 Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Thu, 01 Jan 2026 21:08:58 +0000
Subject: [PATCH] =FeedRoutes: extractTaxonomies added
---
inc/registry/PostTypeRegistrar.php | 168 +++++++++++++++++++++++++++++++++++++++----------------
1 files changed, 119 insertions(+), 49 deletions(-)
diff --git a/inc/registry/PostTypeRegistrar.php b/inc/registry/PostTypeRegistrar.php
index 9bd39c6..cd753c4 100644
--- a/inc/registry/PostTypeRegistrar.php
+++ b/inc/registry/PostTypeRegistrar.php
@@ -1,6 +1,9 @@
<?php
namespace JVBase\registry;
+use JVBase\forms\TaxonomySelector;
+use JVBase\managers\CRUD;
+use JVBase\utility\Features;
use WP_Post;
use JVBase\meta\MetaRegistry;
use JVBase\managers\CacheManager;
@@ -31,6 +34,13 @@
$singular = $this->config['singular'] ?? ucfirst($this->slug);
$plural = $this->config['plural'] ?? $singular . 's';
$loweredPlural = strtolower($plural);
+ $capsMap = $this->config['capability_type']??[];
+ if (empty($capsMap)){
+ $capsMap = [
+ $this->slug,
+ str_replace('-', '_',sanitize_title($loweredPlural))
+ ];
+ }
$args = [
'labels' => $this->buildLabels($singular, $plural),
'public' => $this->config['public'] ?? true,
@@ -40,16 +50,16 @@
'show_in_menu' => $this->config['show_in_menu'] ?? true,
'query_var' => $this->config['query_var'] ?? true,
'rewrite' => $this->config['rewrite'] ?? ['slug' => $this->slug, 'with_front' => false],
- 'capability_type' => [$this->slug, $loweredPlural],
+ 'capability_type' => $capsMap,
'capabilities' => [
'edit_post' => "edit_{$this->slug}",
'read_post' => "read_{$this->slug}",
'delete_post' => "delete_{$this->slug}",
- 'edit_posts' => "edit_{$loweredPlural}",
- 'edit_others_posts' => "edit_others_{$loweredPlural}",
- 'publish_posts' => "publish_{$loweredPlural}",
- 'read_private_posts' => "read_private_{$loweredPlural}",
- 'create_posts' => "edit_{$loweredPlural}",
+ 'edit_posts' => "edit_{$capsMap[1]}",
+ 'edit_others_posts' => "edit_others_{$capsMap[1]}",
+ 'publish_posts' => "publish_{$capsMap[1]}",
+ 'read_private_posts' => "read_private_{$capsMap[1]}",
+ 'create_posts' => "edit_{$capsMap[1]}",
],
'has_archive' => $this->config['has_archive'] ?? true,
'hierarchical' => $this->config['hierarchical'] ?? false,
@@ -58,12 +68,18 @@
'show_in_rest' => $this->config['show_in_rest'] ?? true,
];
- if (jvbCheck('is_calendar', $this->config)) {
+ if ($this->config['is_calendar']??false) {
$args['rewrite']['slug'] = $args['rewrite']['slug']??$this->slug.'/%eyear%/%emonth%/%eday%';
}
- if (isset($this->config['icon'])) {
+ if ($this->config['rewrite_taxonomy']??false && array_key_exists($this->config['rewrite_taxonomy'], JVB_TAXONOMY)) {
+ $args['rewrite']['slug'] = "{$this->slug}/%{$this->config['rewrite_taxonomy']}%";
+ }
+ if ($this->config['icon']??false) {
$args['menu_icon'] = jvbCSSIcon($this->config['icon']);
}
+ if ($this->config['is_timeline']??false) {
+
+ }
register_post_type($this->post_type, $args);
@@ -103,50 +119,17 @@
}
}
- $postType = $this->post_type;
- add_action("save_post_{$this->post_type}", function($post_id, $post, $update) use ($postType) {
- if (jvbNoSaveIt($post_id, $post)) {
- return;
- }
- $this->invalidatePostCache($postType, $post, $update ? 'update' : 'create');
- }, 10, 3);
+ add_filter('jvbDashboardPage', [$this, 'renderDashPage'], 10, 3);
- add_action("delete_post", function($post_id, $post) use ($postType) {
- $post = get_post($post_id);
- if ($post && $post->post_type === $postType) {
- $this->invalidatePostCache($postType, $post, 'delete');
- }
- }, 10, 2);
-
- add_action("transition_post_status", function($new_status, $old_status, $post) use ($postType) {
- if ($post->post_type === $postType && $new_status !== $old_status) {
- $this->invalidatePostCache($postType, $post, 'status_change');
- }
- }, 10, 3);
- }
-
- protected function invalidatePostCache(string $type, $post, string $action) {
- error_log('Clearing Cache for '.print_r($type, true));
-
- $cache = new CacheManager(jvbNoBase($type));
- $cache->delete($post->ID);
-
- // Clear specific cache groups
- CacheManager::invalidateGroup($type);
-
- CacheManager::invalidateGroup("user_content_{$post->post_author}");
-
- // Clear related caches (taxonomies attached to this post)
- $taxonomies = get_object_taxonomies($post->post_type);
- foreach ($taxonomies as $taxonomy) {
- $terms = wp_get_post_terms($post->ID, $taxonomy, ['fields' => 'ids']);
- if (!empty($terms)) {
- CacheManager::invalidateGroup($taxonomy);
- }
+ if ($this->config['hide_children'] ?? false) {
+ add_action('template_redirect', [$this, 'redirectChildToParent']);
}
- // Trigger custom action for additional handling
- do_action("jvb_cache_invalidated_{$type}", $post, $action);
+ if (array_key_exists('rewrite_taxonomy', $this->config) && array_key_exists($this->config['rewrite_taxonomy'], JVB_TAXONOMY)) {
+ add_action('init', [$this, 'addRewriteRules'], 20);
+ add_action('post_type_link', [$this, 'rewriteTaxonomySingle'], 15, 2);
+ add_filter('post_type_archive_link', [$this, 'rewriteTaxonomyArchive'], 15, 2);
+ }
}
public function hideFromPublic(bool $is_viewable): bool
@@ -180,4 +163,91 @@
return get_post_type_archive_link($post->post_type);
}
+ public function addRewriteRules(): void
+ {
+ $type = $this->config['rewrite_taxonomy'];
+ $taxonomy = jvbCheckBase($type);
+
+ // Rule 1: Post type archive - /faq/
+ add_rewrite_rule(
+ "{$this->slug}/?$",
+ "index.php?post_type={$this->post_type}",
+ 'top'
+ );
+
+ // Rule 2: Single posts with taxonomy - /faq/section/post/
+ add_rewrite_rule(
+ "{$this->slug}/([^/]+)/([^/]+)/?$",
+ "index.php?post_type={$this->post_type}&name=\$matches[2]&{$taxonomy}=\$matches[1]",
+ 'top'
+ );
+
+ // Rule 3: Un-sectioned posts - /faq/post/
+ // Use 'bottom' priority so taxonomy rules match first
+ add_rewrite_rule(
+ "{$this->slug}/([^/]+)/?$",
+ "index.php?post_type={$this->post_type}&name=\$matches[1]",
+ 'bottom'
+ );
+ }
+ public function rewriteTaxonomySingle(string $url, \WP_Post $post): string
+ {
+ if ($post->post_type === $this->post_type) {
+ $type = $this->config['rewrite_taxonomy'];
+ $taxonomy = jvbCheckBase($type);
+ $terms = wp_get_post_terms($post->ID, $taxonomy);
+ if (!empty($terms) && !is_wp_error($terms)) {
+ $path = TaxonomySelector::getTermPath($terms[0], true);
+ $path = implode('/', array_map(function($term) {
+ return sanitize_title($term);
+ }, $path));
+ return str_replace("%{$type}%", $path, $url);
+ }
+ return str_replace("/%{$type}%", '', $url);
+ }
+ return $url;
+ }
+
+ public function rewriteTaxonomyArchive(string $url, string $post_type):string
+ {
+ if ($post_type === $this->post_type) {
+ $url = get_home_url(null, "/{$this->slug}/");
+ }
+ return $url;
+ }
+
+ /**
+ * Redirect child timeline posts to their parent post
+ */
+ public function redirectChildToParent(): void
+ {
+ if (!is_singular($this->post_type)) {
+ return;
+ }
+
+ global $post;
+
+ // If this post has a parent, redirect to parent
+ if ($post->post_parent) {
+ $parent_url = get_permalink($post->post_parent);
+
+ // Add anchor or query param to indicate which child was accessed
+ $redirect_url = add_query_arg('update', $post->ID, $parent_url);
+
+ wp_redirect($redirect_url, 301);
+ exit;
+ }
+ }
+
+ public function renderDashPage(string $content, string $page, string $slug):string
+ {
+ if ($slug === $this->slug) {
+ ob_start();
+ $crud = new CRUD($slug);
+ $crud->render();
+ return ob_get_clean();
+ }
+
+ return $content;
+ }
}
--
Gitblit v1.10.0