Skip to content

Instantly share code, notes, and snippets.

@frontycore
Last active April 4, 2022 23:52
Show Gist options
  • Save frontycore/12eacde61a1bdd2265d798c1add3d55e to your computer and use it in GitHub Desktop.
Save frontycore/12eacde61a1bdd2265d798c1add3d55e to your computer and use it in GitHub Desktop.
WP Role managing class
<?php
use App\Users\Role;
$role = new Role('special-role', 'Special role');
$role->allowDefaults(); // Admin dashboard
$role->allowCategory(3); // Allow edit all posts in category with term_id 3
$role->allowPage(4, false); // Allow edit page with ID 4, but not it's subpages
$role->allowPage(5, true); // Allow edit page with ID 5 including it's subpages
$role->addCap('publish_products'); // Add any other capability
<?php
namespace App\Users;
use WP_User;
use WP_Role;
use WP_Query;
use WP_Term_Query;
class Role {
const CAPS = [
'edit_dashboard', 'read'
];
/** @var WP_Role */
private $role;
/** @var WP_User */
private $user;
public function __construct(string $slug, string $title) {
$this->role = get_role($slug);
if (!$this->role) $this->role = add_role($slug, $title, self::CAPS);
$this->user = wp_get_current_user();
}
public function isInRole(): bool {
return in_array($this->role->name, (array)$this->user->roles);
}
public function addCap($caps, bool $allow = true): self {
$caps = (array)$caps;
foreach ($caps as $cap) {
$this->role->add_cap($cap, $allow);
}
return $this;
}
public function allowDefaults(): self {
$this->addCap(self::CAPS);
// Remove tools from menu
if ($this->isInRole()) {
add_action('admin_menu', function() {
remove_menu_page('tools.php');
});
}
return $this;
}
public function allowPage($ids, bool $includeSubpages = false): self {
$this->addCap(['publish_pages', 'edit_others_pages', 'edit_pages', 'edit_private_pages', 'edit_published_pages']);
if ($this->isInRole()) {
// Normalize ids, add subpages
$ids = $idsTmp = (array)$ids;
if ($includeSubpages) {
foreach ($idsTmp as $id) {
$subPages = get_pages(['child_of' => $id]);
foreach ($subPages as $subPage) {
$ids[] = $subPage->ID;
}
}
}
// Filter only allowed posts
add_action('pre_get_posts', function(WP_Query $query) use ($ids) {
if ($query->get('post_type') === 'page') {
$query->set('post__in', $ids);
return $query;
}
});
// Disable edit not-allowed pages
add_action('current_screen', function() use ($ids) {
$screen = get_current_screen();
if ($screen->post_type === 'page' && $screen->id === 'page' && !in_array(intval($_GET['post']), $ids)) {
wp_redirect(admin_url('/edit.php?post_type=page'));
exit();
}
});
}
return $this;
}
public function allowCategory(int $catId): self {
$this->addCap(['edit_others_posts', 'edit_posts', 'edit_private_posts', 'edit_published_posts', 'publish_posts', 'delete_posts', 'delete_published_posts', 'delete_others_posts', 'delete_private_posts']);
if ($this->isInRole()) {
// Filter only posts from allowed category
add_action('pre_get_posts', function(WP_Query $query) use ($catId) {
if ($query->get('post_type') === 'post') {
$query->set('category__in', $catId);
return $query;
}
});
// Filter category query
add_action('parse_term_query', function(WP_Term_Query $query) use ($catId) {
if ($query->query_vars['taxonomy'][0] === 'category') {
$query->query_vars['include'] = [$catId];
}
return $query;
});
// Remove comments from menu
add_action('admin_menu', function() {
remove_menu_page('edit-comments.php');
});
// Hide post category selection
add_action('admin_footer', function() {
?>
<style>
.editor-post-taxonomies__hierarchical-terms-choice {
display: none !important;
}
</style>
<?php
});
// Set post category
add_action('save_post', function(int $ID) use ($catId) {
wp_set_post_categories($ID, $catId, false);
});
// Disable editing other posts
add_action('current_screen', function() use ($catId) {
$screen = get_current_screen();
if ($screen->post_type === 'post' && $screen->id === 'post' && $_GET['post']) {
$id = intval($_GET['post']);
$cats = wp_get_post_categories($id);
if (!in_array($catId, $cats)) {
wp_redirect(admin_url('/edit.php'));
exit();
}
}
});
}
return $this;
}
public function allowGallery(int $galleryId): self {
$this->addCap('upload_files');
$this->allowPage($galleryId, true);
return $this;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment