From 772462eeca3002a1d52508aeba485aab2b4742ad Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Tue, 03 Mar 2026 19:06:19 +0000
Subject: [PATCH] =MAJOR OVERHAUL. Likely should have made a new branch ages ago. Key changes: Registrar.php is the base for custom post types, taxonomies, and user roles. Replaces JVB_CONTENT, JVB_TAXONOMY, and JVB_USER constants, eliminates most of Features.php (except for JVB_SITE, JVB_MEMBERSHIP), and has built in sanitizing and validation via sub-classes. Also started a major overhaul of the Schema output. Created a shit ton of property traits and classes to help sanitize and ensure proper data for different schema types. Still a bunch to do, but better to be starting committing changes here on this other branch.

---
 inc/managers/CRUDManager.php |  120 +++++++++++++++---------------------------------------------
 1 files changed, 30 insertions(+), 90 deletions(-)

diff --git a/inc/managers/CRUDManager.php b/inc/managers/CRUDManager.php
index cec8688..3cbf9a7 100644
--- a/inc/managers/CRUDManager.php
+++ b/inc/managers/CRUDManager.php
@@ -1,8 +1,8 @@
 <?php
 namespace JVBase\managers;
 
+use JVBase\registrar\Registrar;
 use JVBase\ui\CRUDSkeleton;
-use JVBase\utility\Features;
 
 if (!defined('ABSPATH')) {
 	exit;
@@ -15,29 +15,19 @@
 class CRUD {
 	protected CRUDSkeleton $skeleton;
 	protected Cache $cache;
-	protected array $config;
 	protected string $content;
 	protected array $taxonomies = [];
 	protected int $user_id;
-	protected ?string $type = null;
-	protected ?array $constant = null;
+	protected Registrar $registrar;
 
 	public function __construct(string $content) {
-		if (array_key_exists($content, JVB_CONTENT)) {
-			$this->type = 'post';
-			$this->constant = JVB_CONTENT;
-		} elseif (array_key_exists($content, JVB_TAXONOMY)) {
-			$this->type = 'term';
-			$this->constant = JVB_TAXONOMY;
-		} elseif (array_key_exists($content, JVB_USER)) {
-			$this->type = 'user';
-			$this->constant = JVB_USER;
-		} else {
+		$this->registrar = Registrar::getInstance($content);
+
+		if (!$this->registrar) {
 			return;
 		}
 
 		$this->user_id = get_current_user_id();
-		$this->config = $this->constant[$content];
 		$this->content = $content;
 		$this->cache = Cache::for('crud')->connect('post')->connect('taxonomy');
 
@@ -56,33 +46,32 @@
 	protected function configure(): void {
 		// Basic info
 		$this->skeleton
-			->content($this->content, $this->config['singular'], $this->config['plural'])
+			->content($this->content, $this->registrar->getSingular(), $this->registrar->getPlural())
 			->title(
-				'Your ' . $this->config['plural'],
-				$this->config['page_description'] ?? ''
+				$this->registrar->config('dashboard')->getTitle(),
+				$this->registrar->config('dashboard')->getDescription()?? ''
 			);
 
 		// Initialize meta
 		$this->skeleton->addSearch();
 
 		// Timeline if applicable
-		if (Features::forContent($this->content)->has('is_timeline')) {
+		if ($this->registrar && $this->registrar->hasFeature('is_timeline')) {
 			$this->skeleton->setTimeline();
 		}
 
 		// Fields and sections
-		$this->skeleton->setFields($this->config['fields']);
+		$this->skeleton->setFields($this->registrar->getFields());
 
-		$sections = array_key_exists('sections', $this->config) ? $this->config['sections'] : [];
-		foreach ($sections as $id => $config) {
-			$this->skeleton->addSection($id, $config);
+		foreach ($this->registrar->getSections() as $config) {
+			$this->skeleton->addSection($config['id'], $config);
 		}
 
 		// Taxonomies
 		$this->initTaxonomies();
 
 		// Statuses
-		if (Features::forContent($this->content)->has('is_calendar')) {
+		if ($this->registrar && $this->registrar->hasFeature('is_calendar')) {
 			$this->skeleton->setCalendar();
 		}
 
@@ -104,7 +93,7 @@
 		// Capabilities
 		$this->skeleton->addCapabilities(['view', 'edit', 'create', 'delete']);
 
-		$plural = strtolower($this->config['plural'] ?? $this->content . 's');
+		$plural = strtolower($this->registrar->getPlural() ?? $this->content . 's');
 		$canPublish = jvbUserIsVerified() && user_can($this->user_id, "publish_{$plural}");
 		$this->skeleton->userCanPublish($canPublish);
 
@@ -112,7 +101,10 @@
 		$this->skeleton->addBulkActions(['edit', 'publish', 'draft', 'trash']);
 
 		// Uploader
-		$this->setupUploader();
+		if ($this->registrar->getType() === 'post') {
+			$this->setupUploader();
+		}
+
 
 		// Sticky fields
 		$stuck = ['post_title', 'term_name'];
@@ -129,29 +121,30 @@
 	 * Setup uploader configuration
 	 */
 	protected function setupUploader(): void {
-		$isSingleImage = jvbCheck('single_image', $this->config);
+
+		$isSingleImage = $this->registrar->hasFeature('single_image');
 
 		$config = [
 			'type' => 'upload',
 			'subtype' => 'image',
 			'mode' => $isSingleImage ? 'direct' : 'selection',
 			'create_new' => true,
-			'label' => $this->config['upload_title'] ?? 'Bulk Upload ' . $this->config['plural'],
+			'label' => $this->registrar->getUploadTitle(),
 			'content' => $this->content,
-			'singular' => $this->config['singular'],
-			'plural' => $this->config['plural'],
+			'singular' => $this->registrar->getSingular(),
+			'plural' => $this->registrar->getPlural(),
 			'multiple' => true,
 			'destination' => $isSingleImage ? 'post' : 'post_group'
 		];
 
 		if (!$isSingleImage) {
-			$config['upload_text'] = '<p>Drag images into groups. Each group becomes its own ' . $this->config['singular'] . '.</p>
+			$config['upload_text'] = '<p>Drag images into groups. Each group becomes its own ' . $this->registrar->getSingular() . '.</p>
 				<p>You can also select multiple images and click the "Add to Group" button.</p>
-				<p>If a ' . $this->config['singular'] . ' has multiple images, you can select the ' . jvbDashIcon('star') . ' to set an image as the main one.</p>
-				<p>Images left ungrouped will become individual ' . $this->config['plural'] . '</p>
+				<p>If a ' . $this->registrar->getSingular() . ' has multiple images, you can select the ' . jvbDashIcon('star') . ' to set an image as the main one.</p>
+				<p>Images left ungrouped will become individual ' . $this->registrar->getPlural() . '</p>
 				<p>Once finished, click the \'Save Changes\' button to send to server for processing.</p>';
 		} else {
-			$config['description'] = 'Each image will become its own ' . $this->config['singular'] . '.';
+			$config['description'] = 'Each image will become its own ' . $this->registrar->getSingular() . '.';
 		}
 
 		$this->skeleton->addUploader($config);
@@ -161,60 +154,7 @@
 	 * Initialize taxonomies from WordPress config
 	 */
 	protected function initTaxonomies(): void {
-		$this->taxonomies = array_filter(JVB_TAXONOMY, function ($config) {
-			return in_array($this->content, $config['for_content']);
-		});
-	}
-
-	/**
-	 * Get statuses - calendar or standard
-	 */
-	protected function getStatuses(): array {
-		return array_key_exists('is_calendar', $this->config) ?
-			[
-				'all' => [
-					'icon' => 'calendar',
-					'label' => 'Everything',
-				],
-				'future' => [
-					'label' => 'Upcoming',
-					'icon' => 'clock-clockwise',
-				],
-				'past' => [
-					'label' => 'Past',
-					'icon' => 'clock-counter-clockwise',
-				],
-				'repeat' => [
-					'label' => 'Recurring',
-					'icon' => 'repeat',
-				],
-				'draft' => [
-					'icon' => 'eye-closed',
-					'label' => 'Hidden',
-				],
-				'trash' => [
-					'label' => 'Scrapped',
-					'icon' => 'trash',
-				],
-			] :
-			[
-				'all' => [
-					'icon' => 'infinity',
-					'label' => 'Everything',
-				],
-				'publish' => [
-					'icon' => 'eye',
-					'label' => 'Live',
-				],
-				'draft' => [
-					'icon' => 'eye-closed',
-					'label' => 'Hidden',
-				],
-				'trash' => [
-					'label' => 'Scrapped',
-					'icon' => 'trash',
-				],
-			];
+		$this->taxonomies = $this->registrar->registrar->taxonomies;
 	}
 
 	/**
@@ -222,9 +162,9 @@
 	 */
 	public function createItem(array $actions): array {
 		$actions[] = [
-			'button' => '<button type="button" class="create-item row" title="Create New ' . $this->config['singular'] . '">'
+			'button' => '<button type="button" class="create-item row" title="Create New ' . $this->registrar->getSingular() . '">'
 				. jvbDashIcon('plus-square')
-				. '<span class="screen-reader-text">Create New ' . $this->config['singular'] . '</span></button>',
+				. '<span class="screen-reader-text">Create New ' . $this->registrar->getSingular() . '</span></button>',
 			'content' => '', // Modal is rendered by skeleton
 		];
 

--
Gitblit v1.10.0