ult' === $capability ) { continue; } $enabled = in_array( 'aioseo_' . aioseo()->helpers->toSnakeCase( $capability ), array_keys( $value[ $wpRole ]['capabilities'] ), true ); if ( $useDefault && $enabled !== $options->accessControl->$role->getDefault( $capability ) ) { $useDefault = false; } $options->accessControl->$role->$capability = $enabled; } $options->accessControl->$role->useDefault = $useDefault; } // Update dynamic role. if ( $dynamicOptions->accessControl->has( $role ) ) { $useDefault = true; foreach ( $dynamicOptions->accessControl->$role->all() as $capability => $enabled ) { if ( 'useDefault' === $capability ) { continue; } $enabled = in_array( 'aioseo_' . aioseo()->helpers->toSnakeCase( $capability ), array_keys( $value[ $wpRole ]['capabilities'] ), true ); if ( $useDefault && $enabled !== $dynamicOptions->accessControl->$role->getDefault( $capability ) ) { $useDefault = false; } $dynamicOptions->accessControl->$role->$capability = $enabled; } $dynamicOptions->accessControl->$role->useDefault = $useDefault; } } // Re-init the WordPress roles before we use it again. wp_roles()->for_site(); // Run our method again so it will ensure all our capabilities are right. $this->addCapabilities(); } /** * Checks if the current user has the capability. * * @since 4.0.0 * * @param string $capability The capability to check against. * @param string|null $checkRole A role to check against. * @return bool Whether or not the user has this capability. */ public function hasCapability( $capability, $checkRole = null ) { // Administrators always have access. if ( $this->isAdmin( $checkRole ) ) { return true; } static $isAllowed = []; $capabilityName = aioseo()->helpers->toCamelCase( str_replace( 'aioseo_', '', $capability ) ); $hasCapability = false; $options = aioseo()->options->noConflict(); $dynamicOptions = aioseo()->dynamicOptions->noConflict(); foreach ( $this->roles as $wpRole => $role ) { // Skip other roles if is checking for a specific role. if ( $checkRole && $checkRole !== $role ) { continue; } if ( ! $checkRole && ! current_user_can( $wpRole ) ) { continue; } if ( isset( $isAllowed[ $role ][ $capability ] ) ) { return $isAllowed[ $role ][ $capability ]; } if ( $options->accessControl->has( $role ) ) { // Check for default role. $hasCapability = $options->accessControl->{ $role }->{ $capabilityName }; if ( $options->accessControl->$role->useDefault ) { $hasCapability = $options->accessControl->{ $role }->getDefault( $capabilityName ); } } elseif ( $dynamicOptions->accessControl->has( $role ) ) { // Check for dynamic role. $hasCapability = $dynamicOptions->accessControl->{ $role }->{ $capabilityName }; if ( $dynamicOptions->accessControl->$role->useDefault ) { $hasCapability = $dynamicOptions->accessControl->{ $role }->getDefault( $capabilityName ); } } $isAllowed[ $role ][ $capability ] = $hasCapability; if ( $hasCapability ) { return true; } } return $hasCapability; } /** * Adds capabilities into WordPress for the current user. * Only on activation or settings saved. * * @since 4.0.0 * * @return void */ public function addCapabilities() { parent::addCapabilities(); foreach ( $this->roles as $wpRole => $role ) { // Role doesn't exist, let's add it in. if ( in_array( $wpRole, [ 'aioseo_manager', 'aioseo_editor' ], true ) ) { add_role( $wpRole, ucwords( str_replace( 'aioseo_', 'SEO ', $wpRole ) ), [ 'edit_others_posts' => true, 'edit_others_pages' => true, 'edit_pages' => true, 'edit_posts' => true, 'edit_private_pages' => true, 'edit_private_posts' => true, 'edit_published_pages' => true, 'edit_published_posts' => true, 'manage_categories' => true, 'read_private_pages' => true, 'read_private_posts' => true, 'read' => true ] ); } $roleObject = get_role( $wpRole ); if ( ! is_object( $roleObject ) ) { continue; } foreach ( $this->getAllCapabilities( $role ) as $capability => $enabled ) { if ( $enabled ) { $roleObject->add_cap( $capability ); } else { $roleObject->remove_cap( $capability ); } } } // Let addons add their own Access Control. aioseo()->addons->doAddonFunction( 'access', 'addCapabilities' ); } /** * Checks if the current user can manage AIOSEO. * * @since 4.0.0 * * @param string|null $checkRole A role to check against. * @return bool Whether or not the user can manage AIOSEO. */ public function canManage( $checkRole = null ) { // Administrators always can manage. if ( $this->isAdmin( $checkRole ) ) { return true; } foreach ( $this->roles as $wpRole => $role ) { // Skip other roles if is checking for a specific role. if ( $checkRole && $checkRole !== $role ) { continue; } if ( ! $checkRole && ! current_user_can( $wpRole ) ) { continue; } $isCustomRole = aioseo()->dynamicOptions->accessControl->has( $role ); if ( ! aioseo()->options->accessControl->has( $role ) && ! $isCustomRole ) { continue; } $roleSettings = $isCustomRole ? aioseo()->dynamicOptions->accessControl->$role->all() : aioseo()->options->accessControl->$role->all(); // If is set to use default settings, let's get the default values. if ( true === $roleSettings['useDefault'] ) { foreach ( $roleSettings as $capability => $enabled ) { $roleSettings[ $capability ] = $isCustomRole ? aioseo()->dynamicOptions->accessControl->$role->getDefault( $capability ) : aioseo()->options->accessControl->$role->getDefault( $capability ); } } unset( $roleSettings['useDefault'] ); foreach ( $roleSettings as $capability => $enabled ) { // We are not looking for page settings here. if ( false !== strpos( $capability, 'page' ) ) { continue; } if ( $enabled ) { return true; } } } return false; } /** * Gets all options that the user does not have access to manage. * * @since 4.1.3 * * @param string $role The given role. * @return array An array with the option names. */ public function getNotAllowedOptions( $role = null ) { return $this->getNotAllowedOnList( $this->capabilityOptions, $role ); } /** * Gets all page fields that the user does not have access to manage. * * @since 4.1.3 * * @param string $role The given role. * @return array An array with the field names. */ public function getNotAllowedPageFields( $role = null ) { return $this->getNotAllowedOnList( $this->capabilityPage, $role ); } /** * Helper function to get all options user does not have access on the given mapped list. * * @since 4.1.3 * * @param array $mappedCapabilities The mapped capabilities/options list. * @param string $role The given role. * @return array An array with the option names. */ private function getNotAllowedOnList( $mappedCapabilities, $role = null ) { $allCapabilities = $this->getAllCapabilities( $role ); $trueCapabilities = array_filter( $allCapabilities ); $falseCapabilities = array_diff_key( $mappedCapabilities, $trueCapabilities ); if ( empty( $falseCapabilities ) ) { return []; } $notAllowedOptions = call_user_func_array( 'array_merge', array_values( $falseCapabilities ) ); return array_combine( $notAllowedOptions, $notAllowedOptions ); } }