first
This commit is contained in:
@ -0,0 +1,89 @@
|
||||
<?php
|
||||
/**
|
||||
* WPSEO plugin file.
|
||||
*
|
||||
* @package WPSEO\Admin\Capabilities
|
||||
*/
|
||||
|
||||
/**
|
||||
* Abstract Capability Manager shared code.
|
||||
*/
|
||||
abstract class WPSEO_Abstract_Capability_Manager implements WPSEO_Capability_Manager {
|
||||
|
||||
/**
|
||||
* Registered capabilities.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $capabilities = [];
|
||||
|
||||
/**
|
||||
* Registers a capability.
|
||||
*
|
||||
* @param string $capability Capability to register.
|
||||
* @param array $roles Roles to add the capability to.
|
||||
* @param bool $overwrite Optional. Use add or overwrite as registration method.
|
||||
*/
|
||||
public function register( $capability, array $roles, $overwrite = false ) {
|
||||
if ( $overwrite || ! isset( $this->capabilities[ $capability ] ) ) {
|
||||
$this->capabilities[ $capability ] = $roles;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Combine configurations.
|
||||
$this->capabilities[ $capability ] = array_merge( $roles, $this->capabilities[ $capability ] );
|
||||
|
||||
// Remove doubles.
|
||||
$this->capabilities[ $capability ] = array_unique( $this->capabilities[ $capability ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of registered capabilitities.
|
||||
*
|
||||
* @return string[] Registered capabilities.
|
||||
*/
|
||||
public function get_capabilities() {
|
||||
return array_keys( $this->capabilities );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of WP_Role roles.
|
||||
*
|
||||
* The string array of role names are converted to actual WP_Role objects.
|
||||
* These are needed to be able to use the API on them.
|
||||
*
|
||||
* @param array $roles Roles to retrieve the objects for.
|
||||
*
|
||||
* @return WP_Role[] List of WP_Role objects.
|
||||
*/
|
||||
protected function get_wp_roles( array $roles ) {
|
||||
$wp_roles = array_map( 'get_role', $roles );
|
||||
|
||||
return array_filter( $wp_roles );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter capability roles.
|
||||
*
|
||||
* @param string $capability Capability to filter roles for.
|
||||
* @param array $roles List of roles which can be filtered.
|
||||
*
|
||||
* @return array Filtered list of roles for the capability.
|
||||
*/
|
||||
protected function filter_roles( $capability, array $roles ) {
|
||||
/**
|
||||
* Filter: Allow changing roles that a capability is added to.
|
||||
*
|
||||
* @api array $roles The default roles to be filtered.
|
||||
*/
|
||||
$filtered = apply_filters( $capability . '_roles', $roles );
|
||||
|
||||
// Make sure we have the expected type.
|
||||
if ( ! is_array( $filtered ) ) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $filtered;
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
/**
|
||||
* WPSEO plugin file.
|
||||
*
|
||||
* @package WPSEO\Admin\Capabilities
|
||||
*/
|
||||
|
||||
/**
|
||||
* Capability Manager Factory.
|
||||
*/
|
||||
class WPSEO_Capability_Manager_Factory {
|
||||
|
||||
/**
|
||||
* Returns the Manager to use.
|
||||
*
|
||||
* @param string $plugin_type Whether it's Free or Premium.
|
||||
*
|
||||
* @return WPSEO_Capability_Manager Manager to use.
|
||||
*/
|
||||
public static function get( $plugin_type = 'free' ) {
|
||||
static $manager = [];
|
||||
|
||||
if ( ! array_key_exists( $plugin_type, $manager ) ) {
|
||||
if ( function_exists( 'wpcom_vip_add_role_caps' ) ) {
|
||||
$manager[ $plugin_type ] = new WPSEO_Capability_Manager_VIP();
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'wpcom_vip_add_role_caps' ) ) {
|
||||
$manager[ $plugin_type ] = new WPSEO_Capability_Manager_WP();
|
||||
}
|
||||
}
|
||||
|
||||
return $manager[ $plugin_type ];
|
||||
}
|
||||
}
|
@ -0,0 +1,119 @@
|
||||
<?php
|
||||
/**
|
||||
* WPSEO plugin file.
|
||||
*
|
||||
* @package WPSEO\Admin\Capabilities
|
||||
*/
|
||||
|
||||
/**
|
||||
* Integrates Yoast SEO capabilities with third party role manager plugins.
|
||||
*
|
||||
* Integrates with: Members
|
||||
* Integrates with: User Role Editor
|
||||
*/
|
||||
class WPSEO_Capability_Manager_Integration implements WPSEO_WordPress_Integration {
|
||||
|
||||
/**
|
||||
* Capability manager to use.
|
||||
*
|
||||
* @var WPSEO_Capability_Manager
|
||||
*/
|
||||
public $manager;
|
||||
|
||||
/**
|
||||
* WPSEO_Capability_Manager_Integration constructor.
|
||||
*
|
||||
* @param WPSEO_Capability_Manager $manager The capability manager to use.
|
||||
*/
|
||||
public function __construct( WPSEO_Capability_Manager $manager ) {
|
||||
$this->manager = $manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the hooks.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register_hooks() {
|
||||
add_filter( 'members_get_capabilities', [ $this, 'get_capabilities' ] );
|
||||
add_action( 'members_register_cap_groups', [ $this, 'action_members_register_cap_group' ] );
|
||||
|
||||
add_filter( 'ure_capabilities_groups_tree', [ $this, 'filter_ure_capabilities_groups_tree' ] );
|
||||
add_filter( 'ure_custom_capability_groups', [ $this, 'filter_ure_custom_capability_groups' ], 10, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Yoast SEO capabilities.
|
||||
* Optionally append them to an existing array.
|
||||
*
|
||||
* @param array $caps Optional existing capability list.
|
||||
* @return array
|
||||
*/
|
||||
public function get_capabilities( array $caps = [] ) {
|
||||
if ( ! did_action( 'wpseo_register_capabilities' ) ) {
|
||||
do_action( 'wpseo_register_capabilities' );
|
||||
}
|
||||
|
||||
return array_merge( $caps, $this->manager->get_capabilities() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add capabilities to its own group in the Members plugin.
|
||||
*
|
||||
* @see members_register_cap_group()
|
||||
*/
|
||||
public function action_members_register_cap_group() {
|
||||
if ( ! function_exists( 'members_register_cap_group' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Register the yoast group.
|
||||
$args = [
|
||||
'label' => esc_html__( 'Yoast SEO', 'wordpress-seo' ),
|
||||
'caps' => $this->get_capabilities(),
|
||||
'icon' => 'dashicons-admin-plugins',
|
||||
'diff_added' => true,
|
||||
];
|
||||
members_register_cap_group( 'wordpress-seo', $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds Yoast SEO capability group in the User Role Editor plugin.
|
||||
*
|
||||
* @see URE_Capabilities_Groups_Manager::get_groups_tree()
|
||||
*
|
||||
* @param array $groups Current groups.
|
||||
*
|
||||
* @return array Filtered list of capabilty groups.
|
||||
*/
|
||||
public function filter_ure_capabilities_groups_tree( $groups = [] ) {
|
||||
$groups = (array) $groups;
|
||||
|
||||
$groups['wordpress-seo'] = [
|
||||
'caption' => 'Yoast SEO',
|
||||
'parent' => 'custom',
|
||||
'level' => 3,
|
||||
];
|
||||
|
||||
return $groups;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds capabilities to the Yoast SEO group in the User Role Editor plugin.
|
||||
*
|
||||
* @see URE_Capabilities_Groups_Manager::get_cap_groups()
|
||||
*
|
||||
* @param array $groups Current capability groups.
|
||||
* @param string $cap_id Capability identifier.
|
||||
*
|
||||
* @return array List of filtered groups.
|
||||
*/
|
||||
public function filter_ure_custom_capability_groups( $groups = [], $cap_id = '' ) {
|
||||
if ( in_array( $cap_id, $this->get_capabilities(), true ) ) {
|
||||
$groups = (array) $groups;
|
||||
$groups[] = 'wordpress-seo';
|
||||
}
|
||||
|
||||
return $groups;
|
||||
}
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
/**
|
||||
* WPSEO plugin file.
|
||||
*
|
||||
* @package WPSEO\Admin\Capabilities
|
||||
*/
|
||||
|
||||
/**
|
||||
* VIP implementation of the Capability Manager.
|
||||
*/
|
||||
final class WPSEO_Capability_Manager_VIP extends WPSEO_Abstract_Capability_Manager {
|
||||
|
||||
/**
|
||||
* Adds the registered capabilities to the system.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function add() {
|
||||
$role_capabilities = [];
|
||||
foreach ( $this->capabilities as $capability => $roles ) {
|
||||
$role_capabilities = $this->get_role_capabilities( $role_capabilities, $capability, $roles );
|
||||
}
|
||||
|
||||
foreach ( $role_capabilities as $role => $capabilities ) {
|
||||
wpcom_vip_add_role_caps( $role, $capabilities );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the registered capabilities from the system
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function remove() {
|
||||
// Remove from any role it has been added to.
|
||||
$roles = wp_roles()->get_names();
|
||||
$roles = array_keys( $roles );
|
||||
|
||||
$role_capabilities = [];
|
||||
foreach ( array_keys( $this->capabilities ) as $capability ) {
|
||||
// Allow filtering of roles.
|
||||
$role_capabilities = $this->get_role_capabilities( $role_capabilities, $capability, $roles );
|
||||
}
|
||||
|
||||
foreach ( $role_capabilities as $role => $capabilities ) {
|
||||
wpcom_vip_remove_role_caps( $role, $capabilities );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the roles which the capability is registered on.
|
||||
*
|
||||
* @param array $role_capabilities List of all roles with their capabilities.
|
||||
* @param string $capability Capability to filter roles for.
|
||||
* @param array $roles List of default roles.
|
||||
*
|
||||
* @return array List of capabilities.
|
||||
*/
|
||||
protected function get_role_capabilities( $role_capabilities, $capability, $roles ) {
|
||||
// Allow filtering of roles.
|
||||
$filtered_roles = $this->filter_roles( $capability, $roles );
|
||||
|
||||
foreach ( $filtered_roles as $role ) {
|
||||
if ( ! isset( $add_role_caps[ $role ] ) ) {
|
||||
$role_capabilities[ $role ] = [];
|
||||
}
|
||||
|
||||
$role_capabilities[ $role ][] = $capability;
|
||||
}
|
||||
|
||||
return $role_capabilities;
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
/**
|
||||
* WPSEO plugin file.
|
||||
*
|
||||
* @package WPSEO\Admin\Capabilities
|
||||
*/
|
||||
|
||||
/**
|
||||
* Default WordPress capability manager implementation.
|
||||
*/
|
||||
final class WPSEO_Capability_Manager_WP extends WPSEO_Abstract_Capability_Manager {
|
||||
|
||||
/**
|
||||
* Adds the capabilities to the roles.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function add() {
|
||||
foreach ( $this->capabilities as $capability => $roles ) {
|
||||
$filtered_roles = $this->filter_roles( $capability, $roles );
|
||||
|
||||
$wp_roles = $this->get_wp_roles( $filtered_roles );
|
||||
foreach ( $wp_roles as $wp_role ) {
|
||||
$wp_role->add_cap( $capability );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters the capabilities from the system.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function remove() {
|
||||
// Remove from any roles it has been added to.
|
||||
$roles = wp_roles()->get_names();
|
||||
$roles = array_keys( $roles );
|
||||
|
||||
foreach ( $this->capabilities as $capability => $_roles ) {
|
||||
$registered_roles = array_unique( array_merge( $roles, $this->capabilities[ $capability ] ) );
|
||||
|
||||
// Allow filtering of roles.
|
||||
$filtered_roles = $this->filter_roles( $capability, $registered_roles );
|
||||
|
||||
$wp_roles = $this->get_wp_roles( $filtered_roles );
|
||||
foreach ( $wp_roles as $wp_role ) {
|
||||
$wp_role->remove_cap( $capability );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/**
|
||||
* WPSEO plugin file.
|
||||
*
|
||||
* @package WPSEO\Admin\Capabilities
|
||||
*/
|
||||
|
||||
/**
|
||||
* Capability Manager interface.
|
||||
*/
|
||||
interface WPSEO_Capability_Manager {
|
||||
|
||||
/**
|
||||
* Registers a capability.
|
||||
*
|
||||
* @param string $capability Capability to register.
|
||||
* @param array $roles Roles to add the capability to.
|
||||
* @param bool $overwrite Optional. Use add or overwrite as registration method.
|
||||
*/
|
||||
public function register( $capability, array $roles, $overwrite = false );
|
||||
|
||||
/**
|
||||
* Adds the registerd capabilities to the system.
|
||||
*/
|
||||
public function add();
|
||||
|
||||
/**
|
||||
* Removes the registered capabilities from the system.
|
||||
*/
|
||||
public function remove();
|
||||
|
||||
/**
|
||||
* Returns the list of registered capabilities.
|
||||
*
|
||||
* @return string[] List of registered capabilities.
|
||||
*/
|
||||
public function get_capabilities();
|
||||
}
|
@ -0,0 +1,100 @@
|
||||
<?php
|
||||
/**
|
||||
* WPSEO plugin file.
|
||||
*
|
||||
* @package WPSEO\Admin\Capabilities
|
||||
*/
|
||||
|
||||
/**
|
||||
* Capability Utils collection.
|
||||
*/
|
||||
class WPSEO_Capability_Utils {
|
||||
|
||||
/**
|
||||
* Checks if the user has the proper capabilities.
|
||||
*
|
||||
* @param string $capability Capability to check.
|
||||
*
|
||||
* @return bool True if the user has the proper rights.
|
||||
*/
|
||||
public static function current_user_can( $capability ) {
|
||||
if ( $capability === 'wpseo_manage_options' ) {
|
||||
return self::has( $capability );
|
||||
}
|
||||
|
||||
return self::has_any( [ 'wpseo_manage_options', $capability ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the users that have the specified capability.
|
||||
*
|
||||
* @param string $capability The name of the capability.
|
||||
*
|
||||
* @return array The users that have the capability.
|
||||
*/
|
||||
public static function get_applicable_users( $capability ) {
|
||||
$applicable_roles = self::get_applicable_roles( $capability );
|
||||
|
||||
if ( $applicable_roles === [] ) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return get_users( [ 'role__in' => $applicable_roles ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the roles that have the specified capability.
|
||||
*
|
||||
* @param string $capability The name of the capability.
|
||||
*
|
||||
* @return array The names of the roles that have the capability.
|
||||
*/
|
||||
public static function get_applicable_roles( $capability ) {
|
||||
$roles = wp_roles();
|
||||
$role_names = $roles->get_names();
|
||||
|
||||
$applicable_roles = [];
|
||||
foreach ( array_keys( $role_names ) as $role_name ) {
|
||||
$role = $roles->get_role( $role_name );
|
||||
|
||||
if ( ! $role ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add role if it has the capability.
|
||||
if ( array_key_exists( $capability, $role->capabilities ) && $role->capabilities[ $capability ] === true ) {
|
||||
$applicable_roles[] = $role_name;
|
||||
}
|
||||
}
|
||||
|
||||
return $applicable_roles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the current user has at least one of the supplied capabilities.
|
||||
*
|
||||
* @param array $capabilities Capabilities to check against.
|
||||
*
|
||||
* @return bool True if the user has at least one capability.
|
||||
*/
|
||||
protected static function has_any( array $capabilities ) {
|
||||
foreach ( $capabilities as $capability ) {
|
||||
if ( self::has( $capability ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the user has a certain capability.
|
||||
*
|
||||
* @param string $capability Capability to check against.
|
||||
*
|
||||
* @return bool True if the user has the capability.
|
||||
*/
|
||||
protected static function has( $capability ) {
|
||||
return current_user_can( $capability );
|
||||
}
|
||||
}
|
@ -0,0 +1,111 @@
|
||||
<?php
|
||||
/**
|
||||
* WPSEO plugin file.
|
||||
*
|
||||
* @package WPSEO\Admin\Capabilities
|
||||
*/
|
||||
|
||||
/**
|
||||
* Capabilities registration class.
|
||||
*/
|
||||
class WPSEO_Register_Capabilities implements WPSEO_WordPress_Integration {
|
||||
|
||||
/**
|
||||
* Registers the hooks.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register_hooks() {
|
||||
add_action( 'wpseo_register_capabilities', [ $this, 'register' ] );
|
||||
|
||||
if ( is_multisite() ) {
|
||||
add_action( 'user_has_cap', [ $this, 'filter_user_has_wpseo_manage_options_cap' ], 10, 4 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Maybe add manage_privacy_options capability for wpseo_manager user role.
|
||||
*/
|
||||
add_filter( 'map_meta_cap', [ $this, 'map_meta_cap_for_seo_manager' ], 10, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the capabilities.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register() {
|
||||
$manager = WPSEO_Capability_Manager_Factory::get();
|
||||
|
||||
$manager->register( 'wpseo_bulk_edit', [ 'editor', 'wpseo_editor', 'wpseo_manager' ] );
|
||||
$manager->register( 'wpseo_edit_advanced_metadata', [ 'editor', 'wpseo_editor', 'wpseo_manager' ] );
|
||||
|
||||
$manager->register( 'wpseo_manage_options', [ 'administrator', 'wpseo_manager' ] );
|
||||
$manager->register( 'view_site_health_checks', [ 'wpseo_manager' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Revokes the 'wpseo_manage_options' capability from administrator users if it should
|
||||
* only be granted to network administrators.
|
||||
*
|
||||
* @param array $allcaps An array of all the user's capabilities.
|
||||
* @param array $caps Actual capabilities being checked.
|
||||
* @param array $args Optional parameters passed to has_cap(), typically object ID.
|
||||
* @param WP_User $user The user object.
|
||||
*
|
||||
* @return array Possibly modified array of the user's capabilities.
|
||||
*/
|
||||
public function filter_user_has_wpseo_manage_options_cap( $allcaps, $caps, $args, $user ) {
|
||||
|
||||
// We only need to do something if 'wpseo_manage_options' is being checked.
|
||||
if ( ! in_array( 'wpseo_manage_options', $caps, true ) ) {
|
||||
return $allcaps;
|
||||
}
|
||||
|
||||
// If the user does not have 'wpseo_manage_options' anyway, we don't need to revoke access.
|
||||
if ( empty( $allcaps['wpseo_manage_options'] ) ) {
|
||||
return $allcaps;
|
||||
}
|
||||
|
||||
// If the user does not have 'delete_users', they are not an administrator.
|
||||
if ( empty( $allcaps['delete_users'] ) ) {
|
||||
return $allcaps;
|
||||
}
|
||||
|
||||
$options = WPSEO_Options::get_instance();
|
||||
|
||||
if ( $options->get( 'access' ) === 'superadmin' && ! is_super_admin( $user->ID ) ) {
|
||||
unset( $allcaps['wpseo_manage_options'] );
|
||||
}
|
||||
|
||||
return $allcaps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maybe add manage_privacy_options capability for wpseo_manager user role.
|
||||
*
|
||||
* @param string[] $caps Primitive capabilities required of the user.
|
||||
* @param string[] $cap Capability being checked.
|
||||
*
|
||||
* @return string[] Filtered primitive capabilities required of the user.
|
||||
*/
|
||||
public function map_meta_cap_for_seo_manager( $caps, $cap ) {
|
||||
$user = wp_get_current_user();
|
||||
|
||||
// No multisite support.
|
||||
if ( is_multisite() ) {
|
||||
return $caps;
|
||||
}
|
||||
|
||||
// User must be of role wpseo_manager.
|
||||
if ( ! in_array( 'wpseo_manager', $user->roles, true ) ) {
|
||||
return $caps;
|
||||
}
|
||||
|
||||
// Remove manage_options cap requirement if requested cap is manage_privacy_options.
|
||||
if ( $cap === 'manage_privacy_options' ) {
|
||||
return array_diff( $caps, [ 'manage_options' ] );
|
||||
}
|
||||
|
||||
return $caps;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user