From 5b5f37de365ff84fc231e414a719d1b2ff4ceff6 Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Thu, 01 Jan 2026 22:38:58 +0000
Subject: [PATCH] =further feed block testing

---
 inc/registry/PostTypeRegistrar.php |  170 ++++++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 120 insertions(+), 50 deletions(-)

diff --git a/inc/registry/PostTypeRegistrar.php b/inc/registry/PostTypeRegistrar.php
index e6f7272..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,25 +34,32 @@
 		$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,
-			'publicly_queryable'  => $this->config['publicly_queryable'] ?? true,
+			'publicly_queryable'  => $this->config['publicly_queryable'] ?? $this->config['public'] ?? true,
 			'show_ui'             => $this->config['show_ui'] ?? true,
 //			'show_in_menu'        => false,
 			'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