From 894ec8a6f2ac62edbac7b3b6a88e3666f335c673 Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Fri, 15 May 2026 15:08:42 +0000
Subject: [PATCH] =Refactor of CustomBlocks.php to move a majority of the logic to the pre_render_field instead of render_field, and adding support for more blocks
---
inc/managers/DashboardManager.php | 1373 +++++++++++++++++++++++++++++++++++++++++++----------------
1 files changed, 1,001 insertions(+), 372 deletions(-)
diff --git a/inc/managers/DashboardManager.php b/inc/managers/DashboardManager.php
index e15be50..eea1901 100644
--- a/inc/managers/DashboardManager.php
+++ b/inc/managers/DashboardManager.php
@@ -1,9 +1,12 @@
<?php
namespace JVBase\managers;
-use JVBase\managers\CRUD;
-use JVBase\meta\MetaManager;
-use WP_User;
+use JVBase\forms\TaxonomySelector;
+use JVBase\base\Site;
+use JVBase\meta\Form;
+use JVBase\registrar\Registrar;
+use JVBase\ui\Navigation;
+use WP_Error;use WP_Query;use WP_User;
if (!defined('ABSPATH')) {
exit; // Exit if accessed directly
@@ -15,27 +18,45 @@
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 = new CacheManager('dashboard');
- $this->cache->invalidateGroup('dashboard');
+ $this->cache = Cache::for('dashboard', WEEK_IN_SECONDS)->connect('user');
add_action('init', [$this, 'registerDashboard']);
- if (!$this->isRegistered()) {
- add_action('init', [$this, 'buildDashboard']);
- }
- $this->user = wp_get_current_user();
- $this->role = jvbUserRole();
- $this->userLink = (int)get_user_meta($this->user->ID, BASE.'link', true);
+ $this->user = wp_get_current_user();
+ $this->role = jvbUserRole($this->user->ID);
+ $this->userLink = (int)get_user_meta($this->user->ID, BASE.'profile_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);
+
+ jvb_register_do_once('buildDashboard', [$this, 'activate']);
+
+ 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
@@ -47,18 +68,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,
@@ -80,89 +104,210 @@
*/
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
- wp_redirect(home_url('dash'));
- exit;
+ if (is_user_logged_in() && isOurPeople()) {
+ $this->redirectToDashboard();
+ }
}
+ protected function redirectToLogin():void
+ {
+ wp_redirect(wp_login_url(get_home_url(null, '/dash')));
+ exit;
+ }
+
+ protected function redirectToDashboard():void
+ {
+ wp_redirect(get_home_url(null, '/dash'));
+ exit;
+ }
+
+
+ protected function getConfig(string $page):Registrar|false
+ {
+ $pages = $this->getAllDashboardPages();
+ $key = array_search($page, $pages);
+ if ($key === false || is_numeric($key)) {
+ return false;
+ }
+ return Registrar::getInstance($key)??false;
+ }
+
+ /**
+ * Check if user can access page and redirect if not
+ * @param string $page
+ * @param int|null $userID
+ * @return void
+ */
+ protected function requirePageAccess(string $page, ?int $userID = null):void
+ {
+ $allowedPages = $this->getUserAllowedPages($userID);
+
+ if (!in_array($page, $allowedPages)) {
+ $this->redirectToDashboard();
+ }
+ }
+
+ protected function getTitle(string $slug):string
+ {
+ $registrar = $this->getConfig($slug);
+ if ($registrar) {
+ return $registrar->getConfig('dashboard')['title']??$registrar->getPlural();
+ }
+ return ucwords(str_replace('-', ' ', str_replace('_', ' ', $slug)));
+ }
+
+ public function handleRedirects():void
+ {
+ // Only process dashboard-related pages and 404s
+ if (!is_singular(BASE.'dash') && !is_post_type_archive(BASE.'dash') && !is_404()) {
+ return;
+ }
+
+ // Check if user is logged in first
+ if (!is_404() && !is_user_logged_in()) {
+ error_log('Redirecting to login - user not logged in');
+ $this->redirectToLogin();
+ return;
+ }
+
+ // If logged in but doesn't have dashboard access, redirect to home
+ if (!is_404() && !isOurPeople() && !current_user_can('manage_options')) {
+ error_log('Redirecting to home - user lacks dashboard access');
+ wp_redirect(home_url());
+ exit;
+ }
+
+ // Handle 404s that are trying to access dashboard URLs
+ global $wp;
+ if (is_404() && (str_starts_with($wp->request, 'dash/') || $wp->request === 'dash')) {
+ error_log('404 on dashboard URL, redirecting to dashboard home');
+ $this->redirectToDashboard();
+ return;
+ }
+
+ // For valid dashboard pages, check access permissions
+ if (!is_404()) {
+ $page = $this->getCurrentPageSlug();
+
+ // Dashboard home is always accessible (if authenticated)
+ if ($page === '' || $page === 'dash') {
+ return;
+ }
+ $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();
+ }
+ }
+ }
+
/**
- * Ensures the necessary pages ar created
+ * Ensures the necessary pages are created
* @return void
*/
- public function buildDashboard():void
+ public function activate():void
{
- $manageableContent = jvbGetAllDashboardPages();
- foreach ($manageableContent as $slug) {
- $title = $this->getTitle($slug);
- $slug = sanitize_title($title);
+ $manageableContent = $this->getAllDashboardPages();
+ error_log('[DashboardManager]::buildDashboard Manageable Content: '.print_r($manageableContent, true));
+ foreach ($manageableContent as $slug => $page) {
+ if ($page === 'dash') {
+ continue;
+ }
- $ID = wp_insert_post(array(
- 'post_title' => $title,
+ $ID = $this->createDashboardPage($slug, $page);
+
+
+ $registrar = Registrar::getInstance($slug);
+ if ($registrar) {
+ $create = [
+ 'new_' => 'Create New ',
+ 'edit_' => 'Edit '
+ ];
+ $parentID = (int)$ID;
+ foreach ($create as $s => $t) {
+ $s .= $slug;
+ $t .= $page;
+ $this->createDashboardPage($s, $t, $parentID);
+ }
+ }
+ if ($page === 'Integrations') {
+ $this->buildIntegrationPages($ID);
+ }
+ }
+ }
+ public function createDashboardPage(string $slug, string $page, int $parentID = 0):int|WP_Error
+ {
+ if (is_numeric($slug)) {
+ $slug = $this->getSlug($slug, $page);
+ }
+
+ $existing = new WP_Query([
+ 'post_type' => BASE.'dash',
+ 'name' => $slug,
+ 'fields' => 'ids',
+ 'posts_per_page' => 1,
+ ]);
+
+ if ($existing->have_posts()) {
+ return $existing->posts[0];
+ }
+
+
+ $args = [
+ 'post_title' => $page,
'post_name' => $slug,
'post_type' => BASE.'dash',
'post_status' => 'publish',
- ));
-
- if ($title === 'Integrations') {
- $integrations = ['BlueSky', 'Cloudflare', 'Facebook', 'Google Maps', 'Google My Business', 'Helcim', 'Instagram', 'Square', 'Umami'];
- foreach ($integrations as $integration) {
- $slug = sanitize_title($integration);
- wp_insert_post([
- 'post_title' => $integration,
- 'post_name' => $slug,
- 'post_type' => BASE.'dash',
- 'post_status' => 'publish',
- 'post_parent' => $ID
- ]);
- }
+ ];
+ if ($parentID > 0) {
+ $args['post_parent'] = $parentID;
}
- }
- update_option(BASE.'dashboard_registered', true);
- remove_action('init', [$this, 'buildDashboard']);
- }
+ return wp_insert_post($args);
+ }
- protected function getTitle(string $page):string
- {
- $content = JVB_CONTENT;
- $contentTax = array_filter(JVB_TAXONOMY, function ($tax) {
- return jvbCheck('is_content', $tax);
- });
- $content = array_merge($content, $contentTax);
- $title = '';
+ /**
+ * Build integration sub-pages
+ * @param int $parentID
+ * @return void
+ */
+ protected function buildIntegrationPages(int $parentID):void
+ {
+ $integrations = JVB()->getAvailableServices(false);
+ foreach ($integrations as $name => $integration) {
+ $title = $integration->getTitle();
- if (array_key_exists($page, $content)) {
- $config = $content[$page];
- $title = (array_key_exists('dash_title', $config)) ? $config['dash_title'] : $config['plural'];
- } else {
- switch ($page) {
- case 'admin':
- $title = 'Admin';
- break;
- default:
- $title = ucwords(str_replace('_', ' ', str_replace('-', ' ', $page)));
- }
- }
+ $slug = sanitize_title($title);
+ $this->createDashboardPage($slug, $title, $parentID);
+ }
+ }
- return $title;
- }
protected function getDescription(string $page):string
{
- $content = JVB_CONTENT;
- $contentTax = array_filter(JVB_TAXONOMY, function ($tax) {
- return jvbCheck('is_content', $tax);
- });
- $content = array_merge($content, $contentTax);
- if (array_key_exists($page, $content)) {
- $config = $content[$page];
- $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) {
case 'approval':
$description = 'See your approval requests for term creation, joining shops, or joining edmonton.ink. You can also help shape the community by approving other\'s requests!';
@@ -185,14 +330,6 @@
return $description;
}
- /**
- * Checks if we've already created the need pages
- * @return bool
- */
- protected function isRegistered():bool
- {
- return get_option(BASE.'dashboard_registered', false);
- }
/**
* Hacking into the template_include to set our custom templates and protections
@@ -205,81 +342,175 @@
if (!is_singular(BASE.'dash') && !is_post_type_archive(BASE.'dash')) {
return $template;
}
- if (!isOurPeople() && !current_user_can('manage_options')) {
- wp_redirect(wp_login_url(get_home_url(2, '/dash')));
- exit;
- }
// Get current page/section
+ $page = $this->getCurrentPageTitle();
+ $registrar = $this->getConfig($page);
+ if($registrar) {
+ add_filter('jvbLoadingIcon', function() use ($registrar) {
+ return $registrar->getIcon();
+ });
+ }
+ $integrationSlugs = array_map(function($name) {
+ return sanitize_title(str_replace('_', '-', $name));
+ }, array_keys(JVB()->getAvailableServices(false)));
- $page = $this->getCurrentPage();
+ // Check if this is an integration subpage
+ if (in_array($page, $integrationSlugs)) {
+ // Pass along to the Integrations template handler which knows to check for subpages
+ $page = 'integrations';
+ }
+// echo $this->renderDashboard($page);
- // Enqueue needed styles/scripts
+ echo $this->cache->remember(
+ $page,
+ function() use ($page) {
+ return $this->renderDashboard($page);
+ }
+ );
+
+ return '';
+ }
+
+ protected function getConstantSlug(string $page):string
+ {
+ $slug = array_search($page, $this->getAllDashboardPages());
+ return (is_numeric($slug)) ? '' : $slug;
+ }
+ protected function renderDashboard(string $page):string
+ {
+ ob_start();
jvbInlineStyles('nav');
jvbInlineStyles('dash');
jvbInlineStyles('forms');
- $this->cache->delete($page);
- echo $this->cache->remember(
+ $this->renderHeader();
+ // Pass to page handler
+ $constantSlug = $this->getConstantSlug($page);
+
+ echo apply_filters(
+ 'jvbDashboardPage',
+ $this->renderPage($page),
$page,
- function() use ($page) {
- ob_start();
- $this->renderHeader();
-
- switch ($page) {
- case 'dash':
- if (current_user_can('manage_options')) {
- $content = apply_filters('jvbAdminDashboard', '');
-
- if ($content !== '') {
- echo $content;
- }else {
- $this->renderAdmin();
- }
- } else {
- $this->renderIndex();
- }
-
- break;
- case 'admin':
- $this->renderAdmin();
- break;
- case 'bio':
- $this->renderForm(JVB_USER[$this->role]['profile']);
- break;
- case 'settings':
- $this->renderSettings();
- break;
- case 'integrations':
- case 'bluesky':
- case 'cloudflare':
- case 'facebook':
- case 'google-maps':
- case 'google-my-business':
- case 'helcim':
- case 'instagram':
- case 'square':
- case 'umami':
- $this->renderIntegrations($page);
- break;
- case 'approval':
- $this->renderApprovals();
- break;
- default:
- $this->renderCRUD($page);
- break;
- }
-
- echo jvbLoadingScreen();
- $this->renderFooter();
-
- // Get buffer contents and clean buffer
- return ob_get_clean();
- }
+ $constantSlug
);
- // Return empty string to prevent default template
- return '';
- }
+ $this->renderFooter();
+ return ob_get_clean();
+// $integrationSlugs = array_map(function($name) {
+// return sanitize_title(str_replace('_', '-', $name));
+// }, array_keys(JVB()->getAvailableServices(false)));
+//
+// if ($page === 'integrations' || in_array($page, $integrationSlugs)) {
+// // Check integration access
+// if ($page === 'integrations') {
+// if (!Site::hasAnyIntegration('user', $this->role)) {
+// $this->redirectToDashboard();
+// }
+// } else {
+// if (!Site::hasIntegration($page, 'user', $this->role)) {
+// $this->redirectToDashboard();
+// }
+// }
+// } elseif ($page === 'bio') {
+// // Bio page logic
+// $permission = JVB_USER[$this->role]['profile'] ?? false;
+// if (!$permission || (!current_user_can('manage_'.$permission) && !current_user_can('manage_options'))) {
+// $this->redirectToDashboard();
+// }
+// } elseif ($page === 'settings') {
+// // Settings page logic
+// if (!current_user_can('manage_settings') && !current_user_can('manage_options')) {
+// $this->redirectToDashboard();
+// }
+// } elseif ($page === 'approval') {
+// // Approval page logic
+// if (!current_user_can('skip_moderation')) {
+// $this->redirectToDashboard();
+// }
+// } elseif ($page !== 'dash') {
+// // Regular content type - check permission
+// $type = match($page) {
+// 'menu-item' => 'menu_item',
+// 'events' => 'event',
+// default => $page
+// };
+//
+// $permission = $this->getPermissionForType($type);
+// if (!current_user_can($permission)) {
+// $this->redirectToDashboard();
+// }
+// }
+// // Enqueue needed styles/scripts
+//
+// $this->cache->delete($page);
+// echo $this->cache->remember(
+// $page,
+// function() use ($page) {
+// ob_start();
+// $this->renderHeader();
+//
+// switch ($page) {
+// case 'dash':
+// if (current_user_can('manage_options')) {
+// $content = apply_filters('jvbAdminDashboard', '');
+//
+// if ($content !== '') {
+// echo $content;
+// }else {
+// $this->renderAdmin();
+// }
+// } else {
+// $this->renderIndex();
+// }
+//
+// break;
+// case 'admin':
+// $this->renderAdmin();
+// break;
+// case 'bio':
+// $this->renderForm(JVB_USER[$this->role]['profile']);
+// break;
+// case 'settings':
+// $this->renderSettings();
+// break;
+// case 'integrations':
+// case 'bluesky':
+// case 'cloudflare':
+// case 'facebook':
+// case 'google-maps':
+// case 'google-my-business':
+// case 'helcim':
+// case 'instagram':
+// case 'square':
+// case 'umami':
+// $this->renderIntegrations($page);
+// break;
+// case 'approval':
+// $this->renderApprovals();
+// break;
+// default:
+// $this->renderCRUD($page);
+// break;
+// }
+//
+// echo jvbLoadingScreen();
+// $this->renderFooter();
+//
+// // Get buffer contents and clean buffer
+// return ob_get_clean();
+// }
+// );
+//
+// // Return empty string to prevent default template
+// return '';
+ }
+
+ protected function renderPage(string $page):string
+ {
+ return '<h1>Whoops</h1>
+ <p>It seems this page isn\'t configured yet.</p>
+ <p>If this keeps happening, maybe contact the admin.</p>';
+ }
/**
* Enqueues necessary scripts
@@ -287,52 +518,22 @@
*/
public function dashboardScripts():void
{
- if (is_post_type_archive(BASE.'dash') || is_singular(BASE.'dash')) {
+ if (!is_singular(BASE.'dash') && !is_post_type_archive(BASE.'dash')) {
+ return;
+ }
+ IconsManager::for('forms')->enqueueIconStyles();
+ IconsManager::for('dash')->enqueueIconStyles();
+ wp_enqueue_script('jvb-form');
+ wp_enqueue_script('jvb-selector');
+ wp_enqueue_script('jvb-uploader');
+ wp_enqueue_script('jvb-content');
-// wp_enqueue_style('quill-css', 'https://cdn.quilljs.com/1.3.6/quill.snow.css');
-
-
- wp_enqueue_script('jvb-loading');
- wp_enqueue_script('jvb-form');
-
-
- // Consolidate all dashboard settings
- wp_localize_script('jvb-loading', 'dashboardSettings', array(
- 'loadingMessages' => array(
- 'default' => 'Loading...',
- 'error' => 'Failed to load page'
- ),
- 'strings' => array(
- 'deleteConfirm' => 'Are you sure you want to delete this item?',
- 'bulkDeleteConfirm' => 'Are you sure you want to delete these items?',
- 'deleteSuccess' => 'Item(s) deleted successfully',
- 'deleteError' => 'Error deleting item(s)',
- 'saveSuccess' => 'Changes saved successfully',
- 'saveError' => 'Error saving changes',
- 'loadError' => 'Error loading content'
- ),
- 'currentUser' => array(
- 'id' => $this->user->ID,
- 'name' => $this->user->display_name,
- 'role' => array_values($this->user->roles)[0] ?? '',
- 'type' => str_replace(BASE, '', array_values($this->user->roles)[0]),
- 'city' => '', // Add if needed,
- 'artistID' => $this->userLink,
- )
- ));
-
- wp_enqueue_script('jvb-selector');
- wp_enqueue_script('jvb-uploader');
- wp_enqueue_script('jvb-content');
- wp_enqueue_script('jvb-crud');
-// wp_enqueue_script('jvb-dashboard-navigator');
-
- $page = $this->getCurrentPage();
+ $page = $this->getCurrentPageSlug();
switch ($page) {
case 'notifications':
- if (jvbSiteHasNotifications()) {
+ if (Site::has('notifications')) {
wp_enqueue_script('jvb-notification-manager');
}
break;
@@ -342,31 +543,37 @@
break;
case 'admin':
case 'dash':
- if (current_user_can('manage_options') && apply_filters('jvbAdminDashboard', '') === '') {
- wp_enqueue_script(
- 'jvb-admin',
- JVB_URL . 'assets/js/min/admin.min.js',
- [
- 'jvb-queue',
- 'jvb-loading'
- ],
- [
- 'strategy' => 'defer',
- 'in_footer' => true
- ]
- );
+// if (current_user_can('manage_options') && apply_filters('jvbAdminDashboard', '') === '') {
+// wp_enqueue_script(
+// 'jvb-admin',
+// JVB_URL . 'assets/js/min/admin.min.js',
+// [
+// 'jvb-queue',
+//// 'jvb-loading'
+// ],
+// [
+// 'strategy' => 'defer',
+// 'in_footer' => true
+// ]
+// );
- wp_localize_script(
- 'jvb-admin',
- 'jvbAdmin',
- [
- 'nonce' => wp_create_nonce('itsme')
- ]
- );
- }
+// wp_localize_script(
+// 'jvb-admin',
+// 'jvbAdmin',
+// [
+// 'nonce' => wp_create_nonce('itsme')
+// ]
+// );
+// }
+ break;
+ case 'seo':
+ wp_enqueue_script('jvb-schema');
+ break;
+ default:
+ wp_enqueue_script('jvb-crud');
break;
}
- if (jvbSiteHasFavourites()) {
+ if (Site::has('favourites')) {
wp_enqueue_script('jvb-favourites');
wp_localize_script('jvb-favourites-manager', 'favouritesSettings', [
'strings' => [
@@ -382,23 +589,61 @@
wp_enqueue_script('jvb-creator');
- if (jvbSiteHasForum()) {
+ if (Site::has('forum')) {
wp_enqueue_script('jvb-news');
}
do_action('jvbDashScripts', $page);
- }
}
- protected function getCurrentPage():string
+ protected function getCurrentPageTitle():string
{
- global $wp;
- $dash = str_replace('dash/', '', $wp->request);
- if (str_starts_with($dash, 'integrations/')) {
- $dash = str_replace('integrations/', '', $dash);
+ if (is_post_type_archive(BASE.'dash')) {
+ return 'dash';
}
- return ($dash === '') ? 'dash' : $dash;
+ global $post;
+ if (!$post) {
+ return '';
+ }
+ return html_entity_decode($post->post_title);
}
+ protected function getCurrentPageSlug():string
+ {
+ if (is_post_type_archive(BASE.'dash')) {
+ return 'dash';
+ }
+
+ global $post;
+ if (!$post) {
+ return '';
+ }
+
+ return $post->post_name;
+ }
+ protected function getIcon(string $slug, string $page):string
+ {
+ return $this->cache->remember('icon_'.sanitize_title($page), function() use ($slug, $page) {
+ $icon = sanitize_title($page);
+ if (!is_numeric($slug)) {
+ $registrar =Registrar::getInstance($slug);
+ if ($registrar) {
+ return $registrar->getIcon();
+ }
+
+ }
+ return $icon;
+ });
+ }
+ protected function getSlug(string $slug, string $page):string
+ {
+ return $this->cache->remember('slug_'.sanitize_title($page), function() use ($slug, $page) {
+ if (!is_numeric($slug)) {
+ return $slug;
+ } else {
+ return sanitize_title($page);
+ }
+ });
+ }
protected function renderHeader():void
{
@@ -406,46 +651,47 @@
<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
- <title><?= (array_key_exists('dashboard_title', JVB_SITE)) ? JVB_SITE['dashboard_title'] : 'Dashboard | '.get_bloginfo('name') ?></title>
+ <title><?= Site::dashboardTitle()??'Dashboard | '.get_bloginfo('name') ?></title>
<meta charset="<?php bloginfo('charset'); ?>">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<?php
- $pages = jvbGetUserDashboardPages();
+ $pages = $this->getUserAllowedPages();
+
foreach($pages as $page) {
$page = str_replace('_', '-', $page);
$link = ($page === 'dash') ? '/'.$page : "/dash/$page";
?>
- <link rel="preconnect" href="<?= get_home_url(2, $link)?>"/>
+ <link rel="preconnect" href="<?= get_home_url(null, $link)?>"/>
<?php
}
?>
<link rel="preconnect" href="<?= get_home_url()?>"/>
<?php wp_head(); ?>
</head>
- <body class="dashboard<?= ' '.$this->getCurrentPage()?>">
+ <body class="dashboard<?= ' '.$this->getCurrentPageSlug()?>">
<?php jvbAccessibility();?>
<header>
- <?php
- $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.' role="switch" name="dark-mode"><span class="slider">'.
- jvbIcon('light').
- jvbIcon('dark').'</span></label>';
- ?>
- <p class="title">
- <a href="<?= get_home_url(); ?>" rel="home" title="Back to Site">
- <?= jvbIcon('logo-basic'); ?>
- </a>
- </p>
+ <?= jvbDarkModeToggle() ?>
+ <?php
+ $function = BASE.'render_core_site_logo';
+ if (function_exists($function)) {
+ echo $function([],'');
+ } else {
+ echo render_block( [
+ 'blockName' => 'core/site-logo',
+ 'attrs' => [],
+ ]);
+ }
+ ?>
- <nav>
- <ul>
- <?= jvbNotificationMenu() ?>
- <?= jvbHelpMenu() ?>
- </ul>
- </nav>
- </header>
+ <nav>
+ <ul>
+ <?= jvbNotificationMenu() ?>
+ <?= jvbHelpMenu() ?>
+ <li><a href="<?=wp_logout_url(get_home_url())?>" title="Logout"><?=jvbIcon('sign-out')?></a></li>
+ </ul>
+ </nav>
+ </header>
<main><section class="replace">
<?php
@@ -455,45 +701,149 @@
{
?>
</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
+ $all = array_merge(
+ Registrar::getRegistered('post'),
+ Registrar::getFeatured('is_content', 'term')
+ );
+ $availableContent = array_filter($pages, function($page, $key) use($all) {
+ return !is_numeric($key) && in_array($key, $all) && JVB()->roles()->checkRole($this->user, $key);
+ }, 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) {
+ $registrar = Registrar::getInstance($slug);
+
+ $item = $content->addItem($page, $registrar->getIcon())
+ ->url($this->baseURL.'/'.$slug);
+
+ if ($registrar->getType() === 'post') {
+ $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) {
+ $taxRegistrar = Registrar::getInstance($s);
+ if ($taxRegistrar) {
+ $itemMenu->addItem($taxRegistrar->getPlural(), $taxRegistrar->getIcon())
+ ->url($this->baseURL.'/'.$s);
+ }
+
+ }
+ }
+ }
+
+
+ }
+ }
+
+ //Taxonomies
+
+ //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">
- <nav class="dashboard-nav">
+ <?= jvbLoadingScreen() ?>
+ <?= TaxonomySelector::outputSelectorModal() ?>
+<!-- <nav class="dashboard-nav">-->
<?php
- $current_page = $this->getCurrentPage();
- $pages = jvbGetUserDashboardPages()?:[];
-
- global $jvb_everything;
- echo '<ul>';
- foreach ($pages as $page) {
- // Add data-page attribute for the navigator
- $active = ($current_page == $page) ? ' class="current"' : '';
- $current = ($current_page == $page) ? ' aria-current="page"' : '';
- $icon = (array_key_exists($page, $jvb_everything)) ? $jvb_everything[$page]['icon'] ?? $page : $page;
-
- $title = $this->getTitle($page);
- $page = str_replace('_', '-', $page);
-
- $link = ($page === 'dash') ? '/'.$page : "/dash/$page";
-
- printf(
- '<li%s><a href="%s"%s data-page="%s" data-dash title="%s">%s<span>%s</span></a></li>',
- $active,
- get_home_url(2, $link),
- $current,
- $page,
- $title,
- jvbIcon($icon, ['title'=> $title]),
- $title
- );
- }
-
- 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>
<?php
- do_action('jvbRenderDashboardSettings', $this->getCurrentPage());
+ do_action('jvbRenderDashboardSettings', $this->getCurrentPageSlug());
?>
<?php wp_footer(); ?>
@@ -503,37 +853,50 @@
<?php
}
- protected function renderIndex():void
+ public function renderIndex(string $content, string $page):string
{
- $name = get_post_meta($this->userLink, BASE.'firstname', true);
- $name = ($name === '') ? $this->user->display_name : $name;
+ if ($page !== '' && $page !== 'dash') {
+ return $content;
+ }
- echo '<h1 style="text-transform:none;margin-top:2em!important;">Hey '.$name.'</h1>';
+ if (Site::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;
+
+ echo '<h1>Hey '.$name.'</h1>';
echo '<p>Welcome back!</p>';
- $pages = jvbGetUserDashboardPages();
-
+ $pages = $this->getUserAllowedPages();
echo '<h2>What would you like to do today?</h2>';
- global $jvb_everything;
- echo '<ul>';
- foreach ($pages as $page) {
-
+ echo '<ul class="dashboard">';
+ foreach ($pages as $slug => $page) {
+ if ($page === 'dash') {
+ continue;
+ }
$title = $this->getTitle($page);
- $url = sanitize_title($title);
+
$description = $this->getDescription($page);
+ $slug = $this->getSlug($slug, $page);
+ $icon = $this->getIcon($slug, $page);
if ($title !== '') {
- echo '<li><p><a href="'.get_home_url(2, '/dash/'.$url.'/').'"
- data-page="'.$url.'" data-dash>'.jvbIcon($page).ucfirst($title).'</a></p>'.$description.'</li>';
+ echo '<li><p><a href="'.get_home_url(null, '/dash/'.$slug.'/').'"
+ data-page="'.$slug.'" data-dash>'.jvbDashIcon($icon).ucwords($title).'</a></p></li>';
}
}
echo '</ul>';
echo '<p>Everything saves auto-magically, so rest easy.</p>';
-
+ return ob_get_clean();
}
/**
* Similar to CRUD, except it only manages a single item, such as a user's profile or a shop
@@ -543,10 +906,7 @@
*/
protected function renderForm(string $type):void
{
- if (!current_user_can('manage_'.$type)) {
- wp_redirect(get_home_url(2, '/dash'));
- exit;
- }
+
wp_enqueue_script(
'jvb-bio-manager',
JVB_URL.'assets/js/min/bioManager.min.js',
@@ -562,10 +922,6 @@
protected function renderSettings():void
{
- if (!current_user_can('manage_options') && !current_user_can('manage_settings')) {
- wp_redirect(get_home_url(2, '/dash'));
- exit;
- }
wp_enqueue_script('jvb-form');
wp_enqueue_script(
'jvb-bio-manager',
@@ -581,7 +937,7 @@
if ($content !== '') {
echo $content;
} else {
- jvbRenderSections($this->user->ID, 'user', jvbUserRole());
+ jvbRenderSections($this->user->ID, 'user', jvbUserRole());
}
}
@@ -593,14 +949,14 @@
if (!empty($integrations)) {
$out = '<nav class="integrations"><ul>';
- $url = get_home_url(2, '/dash/integrations/');
- $out .= '<li><a href="'.$url.'">'.jvbIcon('plugs-connected').'Integrations</a></li>';
+ $url = get_home_url(null, '/dash/integrations/');
+ $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>';
}
@@ -609,12 +965,6 @@
protected function renderIntegrations(string $page):void
{
-
- //TODO: Make manage_integrations permission
-// if (!current_user_can('manage_integrations')) {
-// wp_redirect(get_home_url(2, '/dash'));
-// exit;
-// }
echo $this->getIntegrationsMenu();
$map = [
'google-my-business' => 'gmb',
@@ -623,7 +973,7 @@
$connection = (array_key_exists($page, $map)) ? $map[$page] : $page;
if ($connection !== 'integrations') {
- $userID = (jvbSiteHasMembership()) ? $this->user->ID : null;
+ $userID = (Site::has('has_membership')) ? $this->user->ID : null;
$integration = JVB()->connect($connection, $userID);
echo '<h1>Managing '.$integration->title.'</h1>';
@@ -653,24 +1003,20 @@
protected function renderApprovals():void
{
- if (!current_user_can('skip_moderation')) {
- wp_redirect(get_home_url(2, '/dash'));
- exit;
- }
?>
<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('all')?>All</h2>
+ <?= jvbDashIcon('infinity')?>All
</button>
<button type="button" class="tab" data-tab="artists" role="tab" aria-selected="false">
- <h2><?= jvbIcon('artists')?>Artists</h2>
+ <?= jvbDashIcon('users-three')?>Artists
</button>
<button type="button" class="tab" data-tab="terms" role="tab" aria-selected="false">
- <h2><?= jvbIcon('style')?>Terms</h2>
+ <?= jvbDashIcon('hash')?>Terms
</button>
<button type="button" class="tab" data-tab="yours" role="tab" aria-selected="false">
- <h2><?= jvbIcon('artist')?>Yours</h2>
+ <?= jvbDashIcon('user')?>Yours
</button>
</nav>
</div>
@@ -723,50 +1069,30 @@
}
- protected function renderCRUD(string $type):void
+
+ public function renderAdmin(string $content, string $page):string
{
- $type = match($type) {
- 'menu-item' => 'menu_item',
- 'events' => 'event',
- default => $type
- };
-
- $permission = JVB_CONTENT[$type]['plural']??$type.'s';
- if (!current_user_can('edit_'.$permission)) {
- wp_redirect(get_home_url(2, '/dash'));
- exit;
- }
- $crud = new CRUD($type);
- $crud->render();
-
- }
-
- protected function renderAdmin():void
- {
- //TODO: This has to be built from the settings from setup.php
- if (!current_user_can('manage_options')) {
- wp_redirect(get_home_url(2, '/dash'));
- exit;
- }
-
+ if ($page !== '' && $page !== 'dash') {
+ return $content;
+ }
+ ob_start();
?>
<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><?=jvbIcon($type)?> <?= $settings['plural'] ?></h2>
+ <h2><?=jvbDashIcon($registrar->getIcon())?> <?= $registrar->getPlural() ?></h2>
</button>
<?php
$i++;
@@ -777,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>
@@ -793,19 +1120,19 @@
'vertical',
'TAB NAV:',
'',
- jvbIcon('down'),
- jvbIcon('right'))?>
+ jvbDashIcon('caret-double-down'),
+ jvbDashIcon('caret-double-right'))?>
</div>
<div class="items-container">
</div>
<?php
- global $jvb_everything;
- foreach ($jvb_everything as $type => $settings) {
- $meta = new MetaManager(null, 'form');
- $fields = jvbGetFields($type);
+
+
+ foreach (Registrar::getRegistered() as $type) {
+ $fields = Registrar::getFieldsFor($type);
?>
<template class="<?= $type ?>Table">
<table>
@@ -852,18 +1179,18 @@
<template class="<?= $type ?>Row">
<tr>
<td>
- <?= jvbIcon('grab') ?>
+ <?= jvbDashIcon('dots-six-vertical') ?>
</td>
<td data-id="actions" class="col">
<?= jvbRenderToggleTextField(
'public',
'',
'',
- jvbIcon('show'),
- jvbIcon('hide'))
+ jvbDashIcon('eye'),
+ jvbDashIcon('eye-closed'))
?>
<button type="button" data-action="edit">
- <?= jvbIcon('edit') ?>
+ <?= jvbDashIcon('pencil-simple') ?>
</button>
</td>
<?php
@@ -874,7 +1201,7 @@
<?php
$config['type'] = 'text';
$config['description'] = '';
- $meta->render('form', $n, $config);
+ Form::render($n, null, $config);
?>
</td>
<?php
@@ -889,8 +1216,310 @@
echo jvbNewModal(
'edit-modal '.$type,
'Edit '.ucfirst($type),
- $meta->renderForm('admin', [], $fields)
+ jvbRenderForm('admin', $fields)
);
}
+ return ob_get_clean();
}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ /**
+ * Get all possible dashboard pages regardless of user
+ * Used during dashboard build process
+ * @return array
+ */
+ protected function getAllDashboardPages():array
+ {
+ $cacheKey = 'all_pages';
+ $pages = $this->cache->get($cacheKey);
+ if ($pages === false || JVB_TESTING) {
+ $pages = [];
+ $pages[] = 'SEO';
+ // Add feature-dependent pages (non-config)
+ if (Site::has('referrals')) {
+ $pages[] = 'Referrals';
+ }
+ $membership = Site::membership();
+ if ($membership && $membership->has('can_invite')) {
+ $pages[] = 'Invites';
+ }
+
+ if ($membership && $membership->has('term_approval')) {
+ $pages[] = 'Approvals';
+ }
+
+ if ($membership && $membership->has('forum')) {
+ $pages[] = 'News';
+ }
+
+ if ($membership && $membership->has('member_content')) {
+ $pages[] = 'Metrics';
+ }
+
+ if (Site::has('favourites')) {
+ $pages[] = 'Favourites';
+ }
+
+ if (!empty(Registrar::getFeatured('karma'))) {
+ $pages[] = 'Karmic Score';
+ }
+
+ if (Site::has('notifications')) {
+ $pages[] = 'Notifications';
+ }
+
+ if (Site::has('support')) {
+ $pages[] = 'Support';
+ }
+
+ if (Site::hasAnyIntegration()) {
+ $pages[] = 'Integrations';
+ }
+
+ // Add all content types (with config keys)
+ foreach (Registrar::getRegistered('post') as $slug) {
+ $registrar = Registrar::getInstance($slug);
+ $pages[$slug] = $registrar->getPlural();
+ }
+
+ foreach (Registrar::getRegistered('term') as $slug) {
+ $registrar = Registrar::getInstance($slug);
+ $pages[$slug] = $registrar->getPlural();
+ }
+
+ // Allow filtering
+ $pages = apply_filters('jvbAllDashboardPages', $pages);
+
+ // Remove duplicates while preserving keys
+ $pages = array_unique($pages);
+
+ // Dash home always first
+ array_unshift($pages, 'dash');
+
+ $this->cache->set($cacheKey, $pages, WEEK_IN_SECONDS);
+ }
+
+ return $pages;
+ }
+
+
+ /**
+ * Get pages that a specific user is allowed to access
+ * Filters based on capabilities and features
+ * @param int|null $userID Optional user ID (defaults to current user)
+ * @return array
+ */
+ public function getUserAllowedPages(?int $userID = null):array
+ {
+ if ($userID === null) {
+ $user = $this->user;
+ $userID = $user->ID;
+ } else {
+ $user = get_userdata($userID);
+ }
+
+ if (!$user || !$this->userHasDashboardAccess($user)) {
+ return [];
+ }
+
+
+ $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($userID, $pages, WEEK_IN_SECONDS);
+ return $pages;
+ }
+ $roles = array_map('jvbNoBase', $user->roles);
+ $pages = $this->getAllDashboardPages();
+
+ $canSkip = user_can($userID, 'skip_moderation');
+ foreach($pages as $key => $slug) {
+ //Default to Remove pages
+ $remove = true;
+ if (!is_numeric($key)) {
+ $registrar = Registrar::getInstance($key);
+ $membership = Site::membership();
+ $type = $registrar? $registrar->getType() : false;
+ if ($type) {
+ $permission = JVB()->roles()->getPermission('edit', $key);
+ }
+ switch ($type) {
+ case 'content':
+ if (user_can($userID, $permission)) {
+ $remove = false;
+ }
+ break;
+ case 'taxonomy':
+ $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($registrar->registrar->for, array_keys($pages))) > 0) {
+ $remove = false;
+ }
+ break;
+ }
+ } else {
+ switch ($slug) {
+ case 'Integrations':
+ foreach($roles as $role) {
+ if (Registrar::getInstance($role)->hasAnyIntegrations()) {
+ $remove = false;
+ }
+ }
+ break;
+ case 'invites':
+ $canInvite = JVB_MEMBERSHIP['can_invite']??[];
+ foreach ($roles as $role) {
+ if (array_key_exists($role, $canInvite)) {
+ $remove = false;
+ }
+ }
+ if ($remove) {
+ //TODO: Figure out what $config was supposed to be
+ if ($canSkip || ($registrar && $registrar->hasFeature('invitable'))) {
+ $remove = false;
+ }
+ }
+ break;
+ case 'Approvals':
+ $canApprove = false;
+ if ($membership && $membership->has('term_approval')) {
+ if (array_key_exists('can_approve', JVB_MEMBERSHIP)) {
+ foreach ($roles as $role) {
+ if (in_array($role, JVB_MEMBERSHIP['can_approve'])) {
+ $canApprove = true;
+ }
+ }
+ } else {
+ //Anyone can approve
+ $canApprove = true;
+ }
+ }
+ if ($canSkip && $canApprove) {
+ $remove = false;
+ }
+ break;
+ case 'news':
+ $canAccess = false;
+ if (array_key_exists('member_only', JVB_MEMBERSHIP)){
+ foreach ($roles as $role) {
+ if (in_array($role, JVB_MEMBERSHIP['member_only'])) {
+ $canAccess = true;
+ }
+ }
+ }
+ if ($canAccess && $canSkip) {
+ $remove = false;
+ }
+ break;
+ case 'metrics':
+ foreach ($roles as $role) {
+ if (!empty(Registrar::getInstance($role)?->getCreatable())) {
+ $remove = false;
+ }
+ }
+ break;
+ case 'karmic-score':
+ foreach ($roles as $role) {
+ $contents = Registrar::getInstance($role)?->getCreatable();
+ if (!empty($contents)) {
+ $hasKarma = Registrar::getFeatured('karma');
+ $remove = empty(array_intersect($contents, $hasKarma));
+ }
+ }
+ break;
+ case 'dash':
+ case 'Referrals':
+ case 'favourites':
+ case 'notifications':
+ case 'support':
+ $remove = false;
+ break;
+ default:
+ break;
+ }
+ }
+ if ($remove) {
+ unset($pages[$key]);
+ }
+ }
+
+ //Allow Filtering
+ $pages = apply_filters('jvbUserDashboardPages', $pages, $user->roles, $userID);
+ $pages = array_unique($pages);
+
+ $this->cache->set($userID, $pages, WEEK_IN_SECONDS);
+ }
+
+ return $pages;
+ }
+
+ /**
+ * Check if user can create content
+ * Replaces jvbUserCanCreate()
+ * @param int $userID
+ * @return bool
+ */
+ protected function userCanCreate(int $userID = 0):bool
+ {
+ $user = ($userID === 0) ? wp_get_current_user() : get_userdata($userID);
+ $roles = array_intersect(
+ $this->getRolesWithDashboard(),
+ array_map('jvbNoBase', $user->roles)
+ );
+
+ $creatable = [];
+ foreach ($roles as $role) {
+ $roleCreatable = Registrar::getInstance($role)?->getCreatable();
+ $creatable = array_merge($creatable, $roleCreatable);
+ }
+
+ return !empty($creatable);
+ }
+
+ /**
+ * Get user roles that have dashboard access
+ * Replaces jvbRolesWithDashboard()
+ * @return array
+ */
+ protected function getRolesWithDashboard():array
+ {
+ return Registrar::getFeatured('has_dashboard', 'user');
+ }
+
+ /**
+ * Check if user has dashboard access
+ * @param WP_User $user
+ * @return bool
+ */
+ protected function userHasDashboardAccess(WP_User $user):bool
+ {
+ if (user_can($user, 'manage_options')) {
+ return true;
+ }
+
+ $userRoles = array_map('jvbNoBase', $user->roles);
+ $dashboardRoles = $this->getRolesWithDashboard();
+
+ return count(array_intersect($dashboardRoles, $userRoles)) > 0;
+ }
+
}
--
Gitblit v1.10.0