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/DashboardManager.php |  139 ++++++++++++++++++++-------------------------
 1 files changed, 62 insertions(+), 77 deletions(-)

diff --git a/inc/managers/DashboardManager.php b/inc/managers/DashboardManager.php
index 49a3762..1b5cb1c 100644
--- a/inc/managers/DashboardManager.php
+++ b/inc/managers/DashboardManager.php
@@ -5,7 +5,7 @@
 use JVBase\managers\CRUD;
 use JVBase\meta\Form;
 use JVBase\meta\Meta;
-use JVBase\utility\Features;
+use JVBase\registrar\Registrar;use JVBase\utility\Features;
 use JVBase\ui\Navigation;
 use WP_User;
 
@@ -139,14 +139,14 @@
 	}
 
 
-	protected function getConfig(string $page):array
+	protected function getConfig(string $page):Registrar|false
 	{
 		$pages = $this->getAllDashboardPages();
 		$key = array_search($page, $pages);
 		if ($key === false || is_numeric($key)) {
-			return [];
+			return false;
 		}
-		return Features::getConfig($key);
+		return Registrar::getInstance($key)??false;
 	}
 
 	/**
@@ -166,9 +166,9 @@
 
 	protected function getTitle(string $slug):string
 	{
-		$config = $this->getConfig($slug);
-		if (!empty($config)) {
-			return $config['dash_title']??$config['plural'];
+		$registrar = $this->getConfig($slug);
+		if ($registrar) {
+			return $registrar->getConfig('dashboard')['title']??$registrar->getPlural();
 		}
 		return ucwords(str_replace('-', ' ', str_replace('_', ' ', $slug)));
 	}
@@ -292,9 +292,9 @@
 
     protected function getDescription(string $page):string
     {
-		$config = $this->getConfig($page);
-        if (!empty($config)) {
-            $description = (array_key_exists('dash_description', $config)) ? $config['dash_description'] : '';
+		$registrar = $this->getConfig($page);
+        if ($registrar) {
+            $description =  $registrar->getConfig('dashboard')['description']??'';
         } else {
 			$description = apply_filters('jvbDashboardDescription', $page);
             switch ($page) {
@@ -342,10 +342,10 @@
 
         // Get current page/section
         $page = $this->getCurrentPageTitle();
-		$config = $this->getConfig($page);
-		if(!empty($config)) {
-			add_filter('jvbLoadingIcon', function() use ($config) {
-				return $config['icon'];
+		$registrar = $this->getConfig($page);
+		if($registrar) {
+			add_filter('jvbLoadingIcon', function() use ($registrar) {
+				return $registrar->getIcon();
 			});
 		}
 		$integrationSlugs = array_map(function($name) {
@@ -383,6 +383,7 @@
 		$this->renderHeader();
 		// Pass to page handler
 		$constantSlug = $this->getConstantSlug($page);
+
         echo apply_filters(
 			'jvbDashboardPage',
 			$this->renderPage($page),
@@ -621,10 +622,11 @@
 		return $this->cache->remember('icon_'.sanitize_title($page), function() use ($slug, $page) {
 			$icon = sanitize_title($page);
 			if (!is_numeric($slug)) {
-				$config = Features::getConfig($slug);
-				if (array_key_exists('icon', $config)) {
-					$icon = $config['icon'];
+				$registrar =Registrar::getInstance($slug);
+				if ($registrar) {
+				return $registrar->getIcon();
 				}
+
 			}
 			return $icon;
 		});
@@ -743,7 +745,7 @@
 			//content types
 				//Taxonomies
 		$availableContent = array_filter($pages, function($page, $key) {
-			return !is_numeric($key) && array_key_exists($key, JVB_CONTENT);
+			return !is_numeric($key) && array_key_exists($key, Registrar::getRegistered('post'));
 		}, ARRAY_FILTER_USE_BOTH);
 		if (!empty ($availableContent)){
 			$content = $menu->addItem('Your Content', jvbDashIcon('book-bookmark'))
@@ -751,18 +753,18 @@
 				->defaultMenuClasses($menuClasses)
 				->defaultItemClasses($itemClasses);
 			foreach ($availableContent as $slug => $page) {
-				$config = JVB_CONTENT[$slug];
-				$item = $content->addItem($page, jvbDashIcon($config['icon']))
+				$registrar = Registrar::getInstance($slug);
+
+				$item = $content->addItem($page, $registrar->getIcon())
 					->url($this->baseURL.'/'.$slug);
 
-				$taxonomies = array_filter(JVB_TAXONOMY, function ($value, $key) use ($slug) {
-					return in_array($slug, $value['for_content']);
-				},1);
+				$taxonomies = $registrar->registrar->taxonomies;
 				if (!empty ($taxonomies)) {
 					//TODO: If we add a dedicated 'create item' page, remove this from the empty check
 					$itemMenu = $item->submenu($slug);
-					foreach ($taxonomies as $s => $config) {
-						$itemMenu->addItem($config['plural'], $config['icon'])
+					foreach ($taxonomies as $s) {
+						$taxRegistrar = Registrar::getInstance($s);
+						$itemMenu->addItem($taxRegistrar->getPlural(), $taxRegistrar->getIcon())
 							->url($this->baseURL.'/'.$s);
 					}
 				}
@@ -971,7 +973,7 @@
 		$connection = (array_key_exists($page, $map)) ? $map[$page] : $page;
 		if ($connection !== 'integrations') {
 
-			$userID = (jvbSiteHasMembership()) ? $this->user->ID : null;
+			$userID = (Features::forSite()->has('has_membership')) ? $this->user->ID : null;
 			$integration = JVB()->connect($connection, $userID);
 
 			echo '<h1>Managing '.$integration->title.'</h1>';
@@ -1078,20 +1080,19 @@
         <nav class="tabs row start" role="tablist">
         <?php
         $i=1;
-        $content = JVB_CONTENT;
-        $contentTax = array_filter(JVB_TAXONOMY, function ($tax) {
-            return jvbCheck('is_content', $tax);
-        });
-        $taxonomies = JVB_TAXONOMY;
-        foreach($contentTax as $key => $config) {
-            unset($taxonomies[$key]);
+        $content = Registrar::getRegistered('post');
+        $contentTax = Registrar::getFeatured('is_content', 'term');
+        $taxonomies = Registrar::getRegistered('term');
+        foreach($contentTax as $index => $tax) {
+            unset($taxonomies[$index]);
         }
         $content = array_merge($content, $contentTax);
-        foreach ($content as $type => $settings) {
+        foreach ($content as $type) {
+			$registrar = Registrar::getInstance($type);
             $active = ($i === 1) ? ' active' : '';
             ?>
             <button type="button" class="tab<?=$active?>" data-tab="<?=$type?>" role="tab" aria-selected="<?= ($active !== '') ? 'true' : 'false'?>">
-                <h2><?=jvbDashIcon($settings['icon']??$key)?> <?= $settings['plural'] ?></h2>
+                <h2><?=jvbDashIcon($registrar->getIcon())?> <?= $registrar->getPlural() ?></h2>
             </button>
             <?php
             $i++;
@@ -1102,8 +1103,9 @@
             <option> ... Taxonomy</option>
             <?php
 
-            foreach ($taxonomies as $type => $settings) {
-                echo '<option value="'.$type.'">'.$settings['plural'].'</option>';
+            foreach ($taxonomies as $type) {
+				$taxRegistrar = Registrar::getInstance($type);
+                echo '<option value="'.$type.'">'.$taxRegistrar->getPlural().'</option>';
             }
             ?>
         </select>
@@ -1127,10 +1129,10 @@
 
     <?php
 
-    $jvb_everything = array_merge(JVB_CONTENT, JVB_TAXONOMY);
 
-    foreach ($jvb_everything as $type => $settings) {
-        $fields = jvbGetFields($type);
+
+    foreach (Registrar::getRegistered() as $type) {
+        $fields = Registrar::getFieldsFor($type);
         ?>
         <template class="<?= $type ?>Table">
             <table>
@@ -1272,7 +1274,7 @@
 				$pages[] = 'Favourites';
 			}
 
-			if (Features::anyContentHas('karma') || Features::anyTaxonomyHas('karma') || Features::anyUserHas('karma')) {
+			if (!empty(Registrar::getFeatured('karma'))) {
 				$pages[] = 'Karmic Score';
 			}
 
@@ -1289,12 +1291,14 @@
 			}
 
 			// Add all content types (with config keys)
-			foreach (JVB_CONTENT as $slug => $config) {
-				$pages[$slug] = $config['plural'];
+			foreach (Registrar::getRegistered('post') as $slug) {
+				$registrar = Registrar::getInstance($slug);
+				$pages[$slug] = $registrar->getPlural();
 			}
 
-			foreach (JVB_TAXONOMY as $slug=>$config) {
-				$pages[$slug] = $config['plural'];
+			foreach (Registrar::getRegistered('term') as $slug) {
+				$registrar = Registrar::getInstance($slug);
+				$pages[$slug] = $registrar->getPlural();
 			}
 
 			// Allow filtering
@@ -1321,7 +1325,7 @@
 	{
 		$role = jvbNoBase($role);
 
-		if (!array_key_exists($role, JVB_USER)) {
+		if (!Registrar::getInstance($role)){
 			return [];
 		}
 
@@ -1366,21 +1370,22 @@
 				//Default to Remove pages
 				$remove = true;
 				if (!is_numeric($key)) {
-					$type  = Features::getType($key);
+					$registrar = Registrar::getInstance($key);
+					$type  = $registrar? $registrar->getType() : false;
 					if ($type) {
-						$permission = RoleManager::getPlural($key);
+						$permission = JVB()->roles()->getPermission('edit', $key);
 					}
 					switch ($type) {
 						case 'content':
-							if (user_can($userID, "edit_{$permission}")) {
+							if (user_can($userID, $permission)) {
 								$remove = false;
 							}
 							break;
 						case 'taxonomy':
-							$config = Features::getConfig($key, 'taxonomy');
-							if (array_key_exists('is_content', $config) && $config['is_content'] && (user_can($userID, "own_{$key}") || user_can($userID, "manage_{$key}"))) {
+							$registrar = Registrar::getInstance($key);
+							if ($registrar && $registrar->hasFeature('is_content') && (!empty(JVB()->roles()->getOwnedTerms($userID, $key)) || !empty(JVB()->roles()->getManagedTerms($userID, $key)))){
 								$remove = false;
-							} else if (count(array_intersect($config['for_content'], array_keys($pages))) > 0) {
+							} else if (count(array_intersect($registrar->registrar->for, array_keys($pages))) > 0) {
 								$remove = false;
 							}
 							break;
@@ -1402,7 +1407,8 @@
 								}
 							}
 							if ($remove) {
-								if ($canSkip || array_key_exists('invitable', $config)) {
+								//TODO: Figure out what $config was supposed to be
+								if ($canSkip || ($registrar && $registrar->hasFeature('invitable'))) {
 									$remove = false;
 								}
 							}
@@ -1449,11 +1455,8 @@
 							foreach ($roles as $role) {
 								$contents = Features::forUser($role)->getCreatableContent();
 								if (!empty($contents)) {
-									foreach($contents as $content) {
-										if (Features::forContent($content)->has('karma')) {
-											$remove = false;
-										}
-									}
+									$hasKarma = Registrar::getFeatured('karma');
+									$remove = empty(array_intersect($contents, $hasKarma));
 								}
 							}
 							break;
@@ -1513,9 +1516,7 @@
 	 */
 	protected function getRolesWithDashboard():array
 	{
-		return array_keys(array_filter(JVB_USER, function ($role) {
-			return Features::forUser(array_search($role, JVB_USER))->has('has_dashboard');
-		}));
+		return Registrar::getFeatured('has_dashboard', 'user');
 	}
 
 	/**
@@ -1535,20 +1536,4 @@
 		return count(array_intersect($dashboardRoles, $userRoles)) > 0;
 	}
 
-	/**
-	 * Get the capability needed to access a content type
-	 * @param string $type
-	 * @return string
-	 */
-	protected function getPermissionForType(string $type):string
-	{
-		// Check if it's a registered content type
-		if (array_key_exists($type, JVB_CONTENT)) {
-			$plural = JVB_CONTENT[$type]['plural'];
-			return 'edit_'.$plural;
-		}
-
-		// Default to edit_{type}s
-		return 'edit_'.$type.'s';
-	}
 }

--
Gitblit v1.10.0