cache = Cache::for('dashboard', WEEK_IN_SECONDS)->connect('user');
if (JVB_TESTING) {
$this->cache->flush();
}
add_action('init', [$this, 'registerDashboard']);
$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
*/
public function registerDashboard():void
{
$plural = 'Dashboards';
$singular = 'Dashboard';
register_post_type(BASE.'dash', array(
'labels' => [
'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,
'show_in_menu' => true,
'show_in_admin_bar' => false,
'has_archive' => true,
'hierarchical' => true,
'rewrite' => array(
'slug' => 'dash',
'with_front' => false
),
'capability_type' => 'post',
'supports' => array('title', 'editor', 'custom-fields')
));
}
/**
* Redirect all non-admin users from wp-admin to custom dashboard
*/
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
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 are created
* @return void
*/
public function activate():void
{
$manageableContent = $this->getAllDashboardPages();
error_log('[DashboardManager]::buildDashboard Manageable Content: '.print_r($manageableContent, true));
foreach ($manageableContent as $slug => $page) {
if ($page === 'dash') {
continue;
}
$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 ($parentID > 0) {
$args['post_parent'] = $parentID;
}
return wp_insert_post($args);
}
/**
* 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();
$slug = sanitize_title($title);
$this->createDashboardPage($slug, $title, $parentID);
}
}
protected function getDescription(string $page):string
{
$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!';
break;
case 'metrics':
$description = 'See what kind of traffic you\'re getting. (coming soon)';
break;
case 'favourites':
$description = 'See what you favourited, and create, manage, and share lists.';
break;
case 'support':
$description = 'Sometimes we all need a hand. This is your direct access to the site admin - or text Jake at 825-823-9916';
break;
case 'settings':
$description = 'Control your privacy and email frequency.';
break;
}
}
return $description;
}
/**
* Hacking into the template_include to set our custom templates and protections
* @param string $template
*
* @return string
*/
public function dashboardTemplates(string $template):string
{
if (!is_singular(BASE.'dash') && !is_post_type_archive(BASE.'dash')) {
return $template;
}
// 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)));
// 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);
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->renderHeader();
// Pass to page handler
$constantSlug = $this->getConstantSlug($page);
echo apply_filters(
'jvbDashboardPage',
$this->renderPage($page),
$page,
$constantSlug
);
$this->renderFooter();
// return ob_get_clean();
return '';
// $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 '
Whoops
It seems this page isn\'t configured yet.
If this keeps happening, maybe contact the admin.
';
}
/**
* Enqueues necessary scripts
* @return void
*/
public function dashboardScripts():void
{
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');
$page = $this->getCurrentPageSlug();
switch ($page) {
case 'notifications':
if (Site::has('notifications')) {
wp_enqueue_script('jvb-notification-manager');
}
break;
case 'integrations':
wp_enqueue_script('jvb-integrations');
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
// ]
// );
// 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 (Site::has('favourites')) {
wp_enqueue_script('jvb-favourites');
wp_localize_script('jvb-favourites-manager', 'favouritesSettings', [
'strings' => [
'loadError' => 'Error loading favourites',
'saveError' => 'Error updating favourite',
'removeSuccess' => 'Removed from favourites',
'addSuccess' => 'Added to favourites'
]
]);
}
wp_enqueue_script('jvb-creator');
if (Site::has('forum')) {
wp_enqueue_script('jvb-news');
}
do_action('jvbDashScripts', $page);
}
protected function getCurrentPageTitle():string
{
if (is_post_type_archive(BASE.'dash')) {
return '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
{
?>
>
= Site::dashboardTitle()??'Dashboard | '.get_bloginfo('name') ?>
getUserAllowedPages();
foreach($pages as $page) {
$page = str_replace('_', '-', $page);
$link = ($page === 'dash') ? '/'.$page : "/dash/$page";
?>
= jvbDarkModeToggle() ?>
'core/site-logo',
'attrs' => [],
]);
}
?>
addClass('sidebar left')->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();
?>
getCurrentPageSlug());
?>
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 'Hey '.$name.'
';
echo 'Welcome back!
';
$pages = $this->getUserAllowedPages();
echo 'What would you like to do today?
';
echo '';
echo 'Everything saves auto-magically, so rest easy.
';
return ob_get_clean();
}
/**
* Similar to CRUD, except it only manages a single item, such as a user's profile or a shop
* @param string $type
*
* @return void
*/
protected function renderForm(string $type):void
{
wp_enqueue_script(
'jvb-bio-manager',
JVB_URL.'assets/js/min/bioManager.min.js',
array('jvb-queue', 'sortablejs', 'quill-js', 'jvb-selector'),
'1.0.0',
true
);
wp_localize_script('jvb-bio-manager', 'bioSettings', [
'type' => 'bio_update',
]);
jvbRenderSections($this->userLink, 'post', $type);
}
protected function renderSettings():void
{
wp_enqueue_script('jvb-form');
wp_enqueue_script(
'jvb-bio-manager',
JVB_URL.'assets/js/min/bioManager.min.js',
array('jvb-client-queue', 'sortablejs', 'quill-js', 'jvb-taxonomy-selector'),
'1.0.0',
true
);
wp_localize_script('jvb-bio-manager', 'bioSettings', [
'type' => 'user_settings',
]);
$content = apply_filters('jvbDashboardSettings', '');
if ($content !== '') {
echo $content;
} else {
jvbRenderSections($this->user->ID, 'user', jvbUserRole());
}
}
protected function getIntegrationsMenu():string
{
$integrations = JVB()->getAvailableServices(false);
$out = '';
if (!empty($integrations)) {
$out = '';
}
return $out;
}
protected function renderIntegrations(string $page):void
{
echo $this->getIntegrationsMenu();
$map = [
'google-my-business' => 'gmb',
'google-maps' => 'maps'
];
$connection = (array_key_exists($page, $map)) ? $map[$page] : $page;
if ($connection !== 'integrations') {
$userID = (Site::has('has_membership')) ? $this->user->ID : null;
$integration = JVB()->connect($connection, $userID);
echo 'Managing '.$integration->title.'
';
$integration->renderDefaults();
} else {
?>
getAvailableServices();
foreach ($all as $name) {
if (current_user_can('manage_options')) {
$userID = null;
} else {
$userID = $this->user->ID;
}
JVB()->connect($name, $userID)->renderConnection();
}
?>
ArtistsManage artists here
= jvbRenderToggleTextField(
'vertical',
'TAB NAV:',
'',
jvbDashIcon('caret-double-down'),
jvbDashIcon('caret-double-right'))?>
|
Actions |
$config) {
if (array_key_exists('quickEdit', $config)) {
$extra = '';
switch ($config['type']) {
case 'set':
case 'radio':
$extra = '( '.implode(', ', $config['options']).' )';
break;
case 'repeater':
$temp = [];
foreach ($config['fields'] as $f => $c) {
$temp[] = $c['label'];
}
$extra = '[ '.implode(', ', $temp).' ]';
break;
}
$extra = ($extra === '') ? '' : ''.$extra.'
';
if (!array_key_exists('label', $config)) {
error_log('No label set for: '.print_r($n, true));
}
?>
= $config['label'].$extra ?>
|
|
= jvbDashIcon('dots-six-vertical') ?>
|
= jvbRenderToggleTextField(
'public',
'',
'',
jvbDashIcon('eye'),
jvbDashIcon('eye-closed'))
?>
|
$config) {
if (array_key_exists('quickEdit', $config)) {
?>
|
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;
}
}