/** * Grant a user virtual caps they'll need to access certain menu items. * * @param array $capabilities All capabilities belonging to the current user, cap => true/false. * @param array $required_caps The required capabilities. * @param array $args The capability passed to current_user_can, the current user's ID, and other args. * @return array Filtered list of capabilities. */ function grant_virtual_caps_to_user($capabilities, $required_caps, $args) { $wp_menu_editor = $this->wp_menu_editor; if ($this->disable_virtual_caps) { return $capabilities; } $virtual_caps = $wp_menu_editor->get_virtual_caps(); //The second entry of the $args array should be the user ID if (count($args) < 2) { return $capabilities; } $user_id = intval($args[1]); //We can avoid a potentially costly call chain and object initialization //by retrieving the current user directly if the ID matches (as it usually will). $current_user = wp_get_current_user(); if ($user_id == intval($current_user->ID)) { $user = $current_user; } else { $user = get_user_by('id', $user_id); } $grant_keys = array(); if ($user) { if (isset($user->user_login)) { $grant_keys[] = 'user:'******'role:' . $role_id; } } } //is_super_admin() will call has_cap on single-site installs. $this->disable_virtual_caps = true; if (is_multisite() && is_super_admin($user->ID)) { $grant_keys[] = 'special:super_admin'; } $this->disable_virtual_caps = false; foreach ($grant_keys as $grant) { if (isset($virtual_caps[$grant])) { $capabilities = array_merge($capabilities, $virtual_caps[$grant]); } } return $capabilities; }
/** * Check if a plugin is visible to the current user. * * Goals: * - You can easily hide a plugin from everyone, including new roles. See: isVisibleByDefault * - You can configure a role so that new plugins are hidden by default. See: grantAccessByDefault * - You can change visibility per role and per user, just like with admin menus. * - Roles that don't have access to plugins are not considered when deciding visibility. * - Precedence order: user > super admin > all roles. * * @param string $pluginFileName Plugin file name as returned by plugin_basename(). * @param WP_User $user Current user. * @return bool */ private function isPluginVisible($pluginFileName, $user = null) { //TODO: Can we refactor this to be shorter? static $isMultisite = null; if (!isset($isMultisite)) { $isMultisite = is_multisite(); } if ($user === null) { $user = wp_get_current_user(); } $settings = $this->getSettings(); //Do we have custom settings for this plugin? if (isset($settings['plugins'][$pluginFileName])) { $isVisibleByDefault = $settings['plugins'][$pluginFileName]['isVisibleByDefault']; $grantAccess = $settings['plugins'][$pluginFileName]['grantAccess']; if ($isVisibleByDefault) { $grantAccess = array_merge($settings['grantAccessByDefault'], $grantAccess); } } else { $isVisibleByDefault = true; $grantAccess = $settings['grantAccessByDefault']; } //User settings take precedence over everything else. $userActor = 'user:'******'user_login'); if (isset($grantAccess[$userActor])) { return $grantAccess[$userActor]; } //Super Admin is next. if ($isMultisite && is_super_admin($user->ID)) { //By default the Super Admin has access to everything. return ameUtils::get($grantAccess, 'special:super_admin', true); } //Finally, the user can see the plugin if at least one of their roles can. $roles = $this->menuEditor->get_user_roles($user); foreach ($roles as $roleId) { if (ameUtils::get($grantAccess, 'role:' . $roleId, $isVisibleByDefault && $this->canManagePlugins($roleId))) { return true; } } return false; }