This commit is contained in:
2024-05-20 15:37:46 +03:00
commit 00b7dbd0b7
10404 changed files with 3285853 additions and 0 deletions

View File

@ -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;
}
}

View File

@ -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 ];
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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 );
}
}
}
}

View File

@ -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();
}

View File

@ -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 );
}
}

View File

@ -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;
}
}