cache = Cache::for('dashboard', WEEK_IN_SECONDS)->connect('user'); add_action('init', [$this, 'registerDashboard']); if (!$this->isRegistered()) { add_action('init', [$this, 'buildDashboard']); } $this->cache->flush(); $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 */ 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 buildDashboard():void { $manageableContent = $this->getAllDashboardPages(); foreach ($manageableContent as $slug => $page) { if ($page === 'dash') { continue; } $slug = $this->getSlug($slug, $page); $existing = get_page_by_path($slug, OBJECT, BASE.'dash'); if ($existing) { continue; } $title = $page; $ID = wp_insert_post(array( 'post_title' => $title, 'post_name' => $slug, 'post_type' => BASE.'dash', 'post_status' => 'publish', )); if ($title === 'Integrations') { $this->buildIntegrationPages($ID); } } update_option(BASE.'dashboard_registered', true); remove_action('init', [$this, 'buildDashboard']); } /** * 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); // Check if integration page already exists $existing = get_posts([ 'post_type' => BASE.'dash', 'name' => $slug, 'post_parent' => $parentID, 'posts_per_page' => 1, ]); if (!empty($existing)) { continue; // Skip if exists } wp_insert_post([ 'post_title' => $title, 'post_name' => $slug, 'post_type' => BASE.'dash', 'post_status' => 'publish', 'post_parent' => $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; } /** * 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 * @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(); // $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 (!Features::hasAnyIntegration('user', $this->role)) { // $this->redirectToDashboard(); // } // } else { // if (!Features::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 (Features::forSite()->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 (Features::forSite()->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 (Features::forSite()->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 { ?> > <?= (array_key_exists('dashboard_title', JVB_SITE)) ? JVB_SITE['dashboard_title'] : 'Dashboard | '.get_bloginfo('name') ?> getUserAllowedPages(); foreach($pages as $page) { $page = str_replace('_', '-', $page); $link = ($page === 'dash') ? '/'.$page : "/dash/$page"; ?>
'. jvbIcon('sun-dim', ['title'=> 'Light Mode']). jvbIcon('moon', ['title'=>'Dark Mode']). ''; ?>

0) { $url = wp_get_attachment_image_url( $icon); if ($url) { $out = ''; } } if ($out == '') { $out =jvbIcon('house'); } ?>

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, Registrar::getRegistered('post')); }, 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); $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); $itemMenu->addItem($taxRegistrar->getPlural(), $taxRegistrar->getIcon()) ->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(); ?> getCurrentPageSlug()); ?> 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 '

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 = (Features::forSite()->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(); } ?>
Name Requester Actions
Name Requester Actions

ArtistsManage artists here

cache->get($cacheKey); if ($pages === false || JVB_TESTING) { $pages = []; $pages[] = 'SEO'; // Add feature-dependent pages (non-config) if (Features::forSite()->has('referrals')) { $pages[] = 'Referrals'; } if (Features::forMembership()->has('can_invite')) { $pages[] = 'Invites'; } if (Features::forMembership()->has('term_approval')) { $pages[] = 'Approvals'; } if (Features::forMembership()->has('forum')) { $pages[] = 'News'; } if (Features::forMembership()->has('member_content')) { $pages[] = 'Metrics'; } if (Features::forSite()->has('favourites')) { $pages[] = 'Favourites'; } if (!empty(Registrar::getFeatured('karma'))) { $pages[] = 'Karmic Score'; } if (Features::forSite()->has('notifications')) { $pages[] = 'Notifications'; } if (Features::forSite()->has('support')) { $pages[] = 'Support'; } if (Features::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 available to a specific role * @param string $role The role slug (with or without BASE prefix) * @return array */ protected function getRolePages(string $role):array { $role = jvbNoBase($role); if (!Registrar::getInstance($role)){ return []; } return Features::forUser($role)->getDashboardPages(); } /** * 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); $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 (Features::hasAnyIntegration('user', $role)) { $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 (Features::forMembership()->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(Features::forUser($role)->getCreatableContent())) { $remove = false; } } break; case 'karmic-score': foreach ($roles as $role) { $contents = Features::forUser($role)->getCreatableContent(); 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 = Features::forUser($role)->getCreatableContent(); $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; } }