Skip to content

Instantly share code, notes, and snippets.

@bhubbard
Created December 10, 2024 21:55
Show Gist options
  • Save bhubbard/2a49fb58a4793c9f6acb9fd21268978d to your computer and use it in GitHub Desktop.
Save bhubbard/2a49fb58a4793c9f6acb9fd21268978d to your computer and use it in GitHub Desktop.
Role-Scoped Listener Pattern • Description: Extends WordPress hooks by allowing specific actions or filters to execute only for users with defined roles or capabilities. Ideal for ensuring role-based access to functionality or modifying content dynamically based on user permissions.
<?php
/**
* Role-Scoped Listener Class
*
* Allows specific WordPress hooks to be executed only for users with designated roles.
*/
class Role_Scoped_Listener {
/**
* The name of the WordPress hook.
*
* @var string
*/
private $hook_name;
/**
* The callback function to execute.
*
* @var callable
*/
private $callback;
/**
* An array of allowed roles.
*
* @var array
*/
private $roles;
/**
* Constructor.
*
* @param string $hook_name The WordPress hook name.
* @param callable $callback The callback to execute.
* @param array $roles The roles allowed to trigger the callback.
*/
public function __construct( $hook_name, $callback, $roles ) {
$this->hook_name = $hook_name;
$this->callback = $callback;
$this->roles = $roles;
// Attach the listener to the specified hook.
add_action( $this->hook_name, [ $this, 'execute' ], 10, 2 );
}
/**
* Executes the callback if the user has the appropriate role.
*
* @param mixed ...$args Arguments passed by the hook.
*/
public function execute( ...$args ) {
if ( $this->user_has_role() ) {
call_user_func_array( $this->callback, $args );
}
}
/**
* Checks if the current user has any of the specified roles.
*
* @return bool True if the user has one of the roles, false otherwise.
*/
private function user_has_role() {
if ( ! is_user_logged_in() ) {
return false;
}
$user = wp_get_current_user();
foreach ( $this->roles as $role ) {
if ( in_array( $role, (array) $user->roles, true ) ) {
return true;
}
}
return false;
}
}
// Example Use Case: Display Custom Admin Notices for Specific Roles.
new Role_Scoped_Listener(
'admin_notices',
function() {
echo '<div class="notice notice-success"><p>' . esc_html__( 'Welcome, Admin! Here’s your custom notice.', 'text-domain' ) . '</p></div>';
},
[ 'administrator' ]
);
new Role_Scoped_Listener(
'admin_notices',
function() {
echo '<div class="notice notice-info"><p>' . esc_html__( 'Hello, Editor! You have special access to this feature.', 'text-domain' ) . '</p></div>';
},
[ 'editor' ]
);
// Example Use Case: Add Custom Styles for Specific Roles.
new Role_Scoped_Listener(
'wp_enqueue_scripts',
function() {
wp_enqueue_style( 'editor-style', get_template_directory_uri() . '/css/editor-style.css', [], '1.0.0' );
},
[ 'editor' ]
);
new Role_Scoped_Listener(
'wp_enqueue_scripts',
function() {
wp_enqueue_style( 'subscriber-style', get_template_directory_uri() . '/css/subscriber-style.css', [], '1.0.0' );
},
[ 'subscriber' ]
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment