From 2127b1bdd73ecd2423e443992da4b442f5a3c1a3 Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Wed, 04 Feb 2026 21:19:25 +0000
Subject: [PATCH] =Major overhaul of MetaManager.php -> Meta.php and RestRouteManager.php -> Rest.php. Seems to work for JakeVan
---
inc/managers/DashboardManager.php | 339 +++++++++++++++++++++++++++++++++++++++-----------------
1 files changed, 234 insertions(+), 105 deletions(-)
diff --git a/inc/managers/DashboardManager.php b/inc/managers/DashboardManager.php
index 69e485e..c2867aa 100644
--- a/inc/managers/DashboardManager.php
+++ b/inc/managers/DashboardManager.php
@@ -1,9 +1,12 @@
<?php
namespace JVBase\managers;
-use JVBase\forms\TaxonomySelector;use JVBase\managers\CRUD;
-use JVBase\meta\MetaManager;
+use JVBase\forms\TaxonomySelector;
+use JVBase\managers\CRUD;
+use JVBase\meta\Form;
+use JVBase\meta\Meta;
use JVBase\utility\Features;
+use JVBase\ui\Navigation;
use WP_User;
if (!defined('ABSPATH')) {
@@ -16,13 +19,14 @@
class DashboardManager
{
protected WP_User $user;
- protected CacheManager $cache;
+ protected Cache $cache;
protected string $role;
+ protected string $baseURL;
protected int $userLink;
public function __construct()
{
- $this->cache = CacheManager::for('dashboard', WEEK_IN_SECONDS);
+ $this->cache = Cache::for('dashboard', WEEK_IN_SECONDS)->connect('user');
add_action('init', [$this, 'registerDashboard']);
if (!$this->isRegistered()) {
add_action('init', [$this, 'buildDashboard']);
@@ -30,15 +34,30 @@
$this->user = wp_get_current_user();
$this->role = jvbUserRole($this->user->ID);
$this->userLink = (int)get_user_meta($this->user->ID, BASE.'link', true);
-
+ $this->baseURL = get_home_url(null, '/dash');
add_action('template_redirect', [$this, 'handleRedirects']);
add_action('template_include', [$this, 'dashboardTemplates']);
add_action('admin_init', [$this, 'redirectFromAdmin']);
add_action('wp_enqueue_scripts', [$this, 'dashboardScripts'], 50);
add_filter('jvbDashboardPage', [$this, 'renderIndex'], 10, 2);
+
+ add_filter('the_seo_framework_sitemap_exclude_ids', [$this, 'excludeDashboard'], 10, 1);
}
+ public function excludeDashboard(array $ids):array {
+ $cached = $this->cache->remember(
+ 'dashboardIDs',
+ function() {
+ return get_posts([
+ 'post_type' => BASE.'dash',
+ 'posts_per_page' => -1,
+ 'fields' => 'ids',
+ ]);
+ });
+ return array_merge($ids, $cached);
+ }
+
/**
* Registers the custom post type that handles the dashboard
* @return void
@@ -50,18 +69,21 @@
$singular = 'Dashboard';
register_post_type(BASE.'dash', array(
'labels' => [
- 'name' => $plural,
- 'singular_name' => $singular,
- 'menu_name' => $plural,
- 'add_new' => "Add New {$singular}",
- 'add_new_item' => "Add New {$singular}",
- 'edit_item' => "Edit {$singular}",
- 'new_item' => "New {$singular}",
- 'view_item' => "View {$singular}",
- 'search_items' => "Search {$plural}",
- 'not_found' => "No {$plural} found",
- 'not_found_in_trash' => "No {$plural} found in Trash"
- ],
+ 'name' => $plural,
+ 'singular_name' => $singular,
+ 'menu_name' => $plural,
+ 'name_admin_bar' => $singular,
+ 'add_new' => "Add New",
+ 'add_new_item' => "Add New {$singular}",
+ 'new_item' => "New {$singular}",
+ 'edit_item' => "Edit {$singular}",
+ 'view_item' => "View {$singular}",
+ 'all_items' => "All {$plural}",
+ 'search_items' => "Search {$plural}",
+ 'parent_item_colon' => "Parent {$plural}:",
+ 'not_found' => "No {$plural} found.",
+ 'not_found_in_trash' => "No {$plural} found in Trash.",
+ ],
'menu_icon' => jvbCSSIcon('gauge'),
'public' => true,
'publicly_queryable' => true,
@@ -83,12 +105,24 @@
*/
public function redirectFromAdmin()
{
+ // Skip if already processing a redirect
+ if (defined('DOING_AJAX') && DOING_AJAX) {
+ return;
+ }
+
+ // Ensure user is fully loaded
+ if (!did_action('wp_loaded')) {
+ return;
+ }
+
// Allow admins to access wp-admin if needed
if (current_user_can('manage_options')) {
return;
}
// Redirect to custom dashboard
- $this->redirectToDashboard();
+ if (is_user_logged_in() && isOurPeople()) {
+ $this->redirectToDashboard();
+ }
}
protected function redirectToLogin():void
@@ -178,10 +212,10 @@
$page = $this->getCurrentPageTitle();
// Check if page exists in allowed pages
$allowedPages = $this->getUserAllowedPages();
+
if (!in_array($page, $allowedPages)) {
error_log("User not allowed to access page: {$page}");
$this->redirectToDashboard();
- return;
}
}
}
@@ -322,14 +356,14 @@
// Pass along to the Integrations template handler which knows to check for subpages
$page = 'integrations';
}
- echo $this->renderDashboard($page);
- //TODO: Reenable
-// echo $this->cache->remember(
-// $page,
-// function() use ($page) {
-// return $this->renderDashboard($page);
-// }
-// );
+// echo $this->renderDashboard($page);
+
+ echo $this->cache->remember(
+ $page,
+ function() use ($page) {
+ return $this->renderDashboard($page);
+ }
+ );
return '';
}
@@ -482,12 +516,13 @@
if (!is_singular(BASE.'dash') && !is_post_type_archive(BASE.'dash')) {
return;
}
+ wp_enqueue_style('jvb-icons-dash');
+ wp_enqueue_style('jvb-icons-forms');
wp_enqueue_script('jvb-form');
wp_enqueue_script('jvb-selector');
wp_enqueue_script('jvb-uploader');
wp_enqueue_script('jvb-content');
- wp_enqueue_script('jvb-crud');
$page = $this->getCurrentPageSlug();
@@ -526,6 +561,12 @@
);
}
break;
+ case 'seo':
+ wp_enqueue_script('jvb-schema');
+ break;
+ default:
+ wp_enqueue_script('jvb-crud');
+ break;
}
if (Features::forSite()->has('favourites')) {
wp_enqueue_script('jvb-favourites');
@@ -559,8 +600,7 @@
if (!$post) {
return '';
}
-
- return $post->post_title;
+ return html_entity_decode($post->post_title);
}
protected function getCurrentPageSlug():string
{
@@ -629,7 +669,7 @@
$checked = (is_user_logged_in() && current_user_can('prefers_dark_theme', true)) ? ' checked' : '';
$title = ($checked == '') ? 'Toggle Dark Mode' : 'Toggle Light Mode';
echo '<label title="'.$title.'" id="theme-switch" class="toggle-switch" for="theme-switcher">
- <input class="theme-switch row" id="theme-switcher" type="checkbox"'.$checked.' data-setting="theme" data-theme role="switch" name="dark-mode"><span class="slider">'.
+ <input class="theme-switch row" id="theme-switcher" name="theme-switcher" type="checkbox"'.$checked.' data-setting="theme" data-theme role="switch" name="dark-mode" aria-label="Toggle dark mode"><span class="slider">'.
jvbIcon('sun-dim', ['title'=> 'Light Mode']).
jvbIcon('moon', ['title'=>'Dark Mode']).
'</span></label>';
@@ -656,6 +696,7 @@
<ul>
<?= jvbNotificationMenu() ?>
<?= jvbHelpMenu() ?>
+ <li><a href="<?=wp_logout_url(get_home_url())?>" title="Logout"><?=jvbIcon('sign-out')?></a></li>
</ul>
</nav>
</header>
@@ -668,39 +709,133 @@
{
?>
</section>
+
+ <?php
+ $menu = new Navigation('sidebar');
+ $menuClasses = ['col', 'a-start', 'nowrap'];
+ $itemClasses = ['col'];
+ $menu->addClass('col a-start')->hasToggle()->defaultMenuClasses($menuClasses);
+ $menu->defaultItemClasses($itemClasses);
+ $pages = $this->getUserAllowedPages()?:[];
+ //Dashboard
+ //Referrals
+ $dashboard = $menu->addItem('Dashboard',jvbDashIcon('door'))
+ ->url($this->baseURL);
+// ->submenu('dashboard')
+// ->defaultMenuClasses($menuClasses)
+// ->defaultItemClasses($itemClasses);
+ //notifications
+ if (in_array('Notifications', $pages)) {
+ $menu->addItem('Notifications',jvbDashIcon('bell'))
+ ->url($this->baseURL.'/notifications');
+ }
+ if (in_array('Referrals', $pages)) {
+ $menu->addItem('Referrals', jvbDashIcon('hand-heart'))
+ ->url($this->baseURL.'/referrals');
+ }
+ if (in_array('Favourites', $pages)) {
+ $menu->addItem('Favourites', jvbDashIcon('heart'))
+ ->url($this->baseURL.'/favourites');
+ }
+
+ //Content
+ //content types
+ //Taxonomies
+ $availableContent = array_filter($pages, function($page, $key) {
+ return !is_numeric($key) && array_key_exists($key, JVB_CONTENT);
+ }, ARRAY_FILTER_USE_BOTH);
+ if (!empty ($availableContent)){
+ $content = $menu->addItem('Your Content', jvbDashIcon('book-bookmark'))
+ ->submenu('content')
+ ->defaultMenuClasses($menuClasses)
+ ->defaultItemClasses($itemClasses);
+ foreach ($availableContent as $slug => $page) {
+ $config = JVB_CONTENT[$slug];
+ $item = $content->addItem($page, jvbDashIcon($config['icon']))
+ ->url($this->baseURL.'/'.$slug);
+
+ $taxonomies = array_filter(JVB_TAXONOMY, function ($value, $key) use ($slug) {
+ return in_array($slug, $value['for_content']);
+ },1);
+ 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'])
+ ->url($this->baseURL.'/'.$s);
+ }
+ }
+
+ }
+ }
+
+ //Settings
+ $settings = $menu->addItem('Settings', jvbDashIcon('faders'))
+ ->submenu('settings')
+ ->defaultItemClasses($itemClasses)
+ ->defaultMenuClasses($menuClasses);
+
+ //SEO
+ if (in_array('SEO', $pages)) {
+ $settings->addItem('SEO', jvbDashIcon('robot'))
+ ->url($this->baseURL.'/seo');
+ }
+ //Integrations
+ if (in_array('Integrations', $pages)) {
+ $settings->addItem('Integrations', jvbDashIcon('plugs-connected'))
+ ->url($this->baseURL.'/integrations');
+ }
+ //Account
+ $account = $menu->addItem('Account', jvbDashIcon('user-circle'))
+ ->url($this->baseURL.'/account')
+ ->submenu('account')
+ ->defaultMenuClasses($menuClasses)
+ ->defaultItemClasses($itemClasses);
+ $account->addItem('Reset Password', jvbDashIcon('password'))
+ ->url($this->baseURL.'/reset-password');
+ //name + contact
+ //reset password
+
+ if (in_array('notifications', $pages)) {
+ $account->addItem('Permissions', jvbDashIcon('keyhole'))
+ ->url($this->baseURL.'/permissions');
+ }
+
+ echo $menu->render();
+ ?>
+
<footer class="col">
<?= jvbLoadingScreen() ?>
<?= TaxonomySelector::outputSelectorModal() ?>
- <nav class="dashboard-nav">
+<!-- <nav class="dashboard-nav">-->
<?php
- $current_page = $this->getCurrentPageSlug();
- $pages = $this->getUserAllowedPages()?:[];
-
- echo '<ul>';
- foreach ($pages as $slug => $page) {
- $slug = $this->getSlug($slug, $page);
- $icon = $this->getIcon($slug, $page);
- // Add data-page attribute for the navigator
- $active = ($current_page == $slug) ? ' class="current"' : '';
- $current = ($current_page == $slug) ? ' aria-current="page"' : '';
-
-
- $link = ($page === 'dash') ? '/'.$page : "/dash/$slug";
- printf(
- '<li%s><a href="%s"%s data-page="%s" data-dash title="%s">%s<span>%s</span></a></li>',
- $active,
- get_home_url(null, $link),
- $current,
- $slug,
- $page,
- jvbIcon($icon, ['title'=> $page]),
- $page
- );
- }
-
- echo '</ul>';
+// $current_page = $this->getCurrentPageSlug();
+// $pages = $this->getUserAllowedPages()?:[];
+// echo '<ul>';
+// foreach ($pages as $slug => $page) {
+// $slug = $this->getSlug($slug, $page);
+// $icon = $this->getIcon($slug, $page);
+// // Add data-page attribute for the navigator
+// $active = ($current_page == $slug) ? ' class="current"' : '';
+// $current = ($current_page == $slug) ? ' aria-current="page"' : '';
+//
+//
+// $link = ($page === 'dash') ? '/'.$page : "/dash/$slug";
+// printf(
+// '<li%s><a href="%s"%s data-page="%s" data-dash title="%s">%s<span>%s</span></a></li>',
+// $active,
+// get_home_url(null, $link),
+// $current,
+// $slug,
+// $page,
+// jvbDashIcon($icon, ['title'=> $page]),
+// $page
+// );
+// }
+//
+// echo '</ul>';
?>
- </nav>
+<!-- </nav>-->
</footer>
@@ -720,6 +855,14 @@
if ($page !== '' && $page !== 'dash') {
return $content;
}
+
+ if (Features::forSite()->has('referrals')) {
+ $whatever = JVB()->referrals()->getReferralWelcomeMessage($this->user->ID);
+ if (!empty($whatever)) {
+ return $whatever;
+ }
+ }
+
ob_start();
$name = ($this->user->first_name !== '') ? $this->user->first_name : $this->user->display_name;
@@ -730,7 +873,7 @@
echo '<h2>What would you like to do today?</h2>';
- echo '<ul>';
+ echo '<ul class="dashboard">';
foreach ($pages as $slug => $page) {
if ($page === 'dash') {
continue;
@@ -743,7 +886,7 @@
$icon = $this->getIcon($slug, $page);
if ($title !== '') {
echo '<li><p><a href="'.get_home_url(null, '/dash/'.$slug.'/').'"
- data-page="'.$slug.'" data-dash>'.jvbIcon($icon).ucwords($title).'</a></p></li>';
+ data-page="'.$slug.'" data-dash>'.jvbDashIcon($icon).ucwords($title).'</a></p></li>';
}
}
@@ -804,13 +947,13 @@
$out = '<nav class="integrations"><ul>';
$url = get_home_url(null, '/dash/integrations/');
- $out .= '<li><a href="'.$url.'">'.jvbIcon('plugs-connected').'Integrations</a></li>';
+ $out .= '<li><a href="'.$url.'">'.jvbDashIcon('plugs-connected').'Integrations</a></li>';
foreach ($integrations as $name=> $integration) {
if (!JVB()->userCanConnect($name, $this->user->ID) || !$integration->hasDefaults()) {
continue;
}
$link = sanitize_title(str_replace('_', '-',$name));
- $out .= '<li><a href="'.$url.$link.'">'.jvbIcon($integration->icon).$integration->getTitle().'</a></li>';
+ $out .= '<li><a href="'.$url.$link.'">'.jvbDashIcon($integration->icon).$integration->getTitle().'</a></li>';
}
$out .= '</ul></nav>';
}
@@ -861,16 +1004,16 @@
<div class="approvals container">
<nav class="tabs row start" role="tablist">
<button type="button" class="tab active" data-tab="summary" role="tab" aria-selected="true">
- <h2><?= jvbIcon('infinity')?>All</h2>
+ <h2><?= jvbDashIcon('infinity')?>All</h2>
</button>
<button type="button" class="tab" data-tab="artists" role="tab" aria-selected="false">
- <h2><?= jvbIcon('users-three')?>Artists</h2>
+ <h2><?= jvbDashIcon('users-three')?>Artists</h2>
</button>
<button type="button" class="tab" data-tab="terms" role="tab" aria-selected="false">
- <h2><?= jvbIcon('hash')?>Terms</h2>
+ <h2><?= jvbDashIcon('hash')?>Terms</h2>
</button>
<button type="button" class="tab" data-tab="yours" role="tab" aria-selected="false">
- <h2><?= jvbIcon('user')?>Yours</h2>
+ <h2><?= jvbDashIcon('user')?>Yours</h2>
</button>
</nav>
</div>
@@ -947,7 +1090,7 @@
$active = ($i === 1) ? ' active' : '';
?>
<button type="button" class="tab<?=$active?>" data-tab="<?=$type?>" role="tab" aria-selected="<?= ($active !== '') ? 'true' : 'false'?>">
- <h2><?=jvbIcon($settings['icon']??$key)?> <?= $settings['plural'] ?></h2>
+ <h2><?=jvbDashIcon($settings['icon']??$key)?> <?= $settings['plural'] ?></h2>
</button>
<?php
$i++;
@@ -974,8 +1117,8 @@
'vertical',
'TAB NAV:',
'',
- jvbIcon('caret-double-down'),
- jvbIcon('caret-double-right'))?>
+ jvbDashIcon('caret-double-down'),
+ jvbDashIcon('caret-double-right'))?>
</div>
<div class="items-container">
@@ -986,7 +1129,6 @@
$jvb_everything = array_merge(JVB_CONTENT, JVB_TAXONOMY);
foreach ($jvb_everything as $type => $settings) {
- $meta = new MetaManager(null, 'form');
$fields = jvbGetFields($type);
?>
<template class="<?= $type ?>Table">
@@ -1034,18 +1176,18 @@
<template class="<?= $type ?>Row">
<tr>
<td>
- <?= jvbIcon('dots-six-vertical') ?>
+ <?= jvbDashIcon('dots-six-vertical') ?>
</td>
<td data-id="actions" class="col">
<?= jvbRenderToggleTextField(
'public',
'',
'',
- jvbIcon('eye'),
- jvbIcon('eye-closed'))
+ jvbDashIcon('eye'),
+ jvbDashIcon('eye-closed'))
?>
<button type="button" data-action="edit">
- <?= jvbIcon('pencil-simple') ?>
+ <?= jvbDashIcon('pencil-simple') ?>
</button>
</td>
<?php
@@ -1056,7 +1198,7 @@
<?php
$config['type'] = 'text';
$config['description'] = '';
- $meta->render('form', $n, $config);
+ Form::render($n, null, $config);
?>
</td>
<?php
@@ -1071,10 +1213,9 @@
echo jvbNewModal(
'edit-modal '.$type,
'Edit '.ucfirst($type),
- $meta->renderForm('admin', [], $fields)
+ jvbRenderForm('admin', $fields)
);
}
-
return ob_get_clean();
}
@@ -1104,7 +1245,7 @@
$pages = $this->cache->get($cacheKey);
if ($pages === false || JVB_TESTING) {
$pages = [];
-
+ $pages[] = 'SEO';
// Add feature-dependent pages (non-config)
if (Features::forSite()->has('referrals')) {
$pages[] = 'Referrals';
@@ -1205,15 +1346,15 @@
return [];
}
- $cacheKey = "user_pages_{$userID}";
- $pages = $this->cache->get($cacheKey);
+
+ $pages = $this->cache->get($userID);
if ($pages === false || JVB_TESTING) {
if (user_can($userID, 'manage_options')) {
// Admin gets all pages as flat array
$pages = $this->getAllDashboardPages();
// Extract just the values (slugs)
- $this->cache->set($cacheKey, $pages, WEEK_IN_SECONDS);
+ $this->cache->set($userID, $pages, WEEK_IN_SECONDS);
return $pages;
}
$roles = array_map('jvbNoBase', $user->roles);
@@ -1230,7 +1371,7 @@
}
switch ($type) {
case 'content':
- if (!user_can($userID, "edit_{$permission}")) {
+ if (user_can($userID, "edit_{$permission}")) {
$remove = false;
}
break;
@@ -1238,12 +1379,14 @@
$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}"))) {
$remove = false;
+ } else if (count(array_intersect($config['for_content'], array_keys($pages))) > 0) {
+ $remove = false;
}
break;
}
} else {
switch ($slug) {
- case 'integrations':
+ case 'Integrations':
foreach($roles as $role) {
if (Features::hasAnyIntegration('user', $role)) {
$remove = false;
@@ -1263,7 +1406,7 @@
}
}
break;
- case 'approvals':
+ case 'Approvals':
$canApprove = false;
if (Features::forMembership()->has('term_approval')) {
if (array_key_exists('can_approve', JVB_MEMBERSHIP)) {
@@ -1313,6 +1456,8 @@
}
}
break;
+ case 'dash':
+ case 'Referrals':
case 'favourites':
case 'notifications':
case 'support':
@@ -1321,9 +1466,9 @@
default:
break;
}
- if ($remove) {
- unset($pages[$key]);
- }
+ }
+ if ($remove) {
+ unset($pages[$key]);
}
}
@@ -1331,7 +1476,7 @@
$pages = apply_filters('jvbUserDashboardPages', $pages, $user->roles, $userID);
$pages = array_unique($pages);
- $this->cache->set($cacheKey, $pages, WEEK_IN_SECONDS);
+ $this->cache->set($userID, $pages, WEEK_IN_SECONDS);
}
return $pages;
@@ -1405,20 +1550,4 @@
// Default to edit_{type}s
return 'edit_'.$type.'s';
}
-
- /**
- * Invalidate dashboard page cache for a user or all users
- * Call this when user roles or permissions change
- * @param int|null $userID Specific user to invalidate, null for all
- * @return void
- */
- public function invalidatePagesCache(?int $userID = null):void
- {
- if ($userID !== null) {
- $this->cache->delete("user_pages_{$userID}");
- } else {
- // Invalidate all user caches by invalidating the group
- $this->cache->invalidate();
- }
- }
}
--
Gitblit v1.10.0