WP Custom Site Roles appear to be a bit ‘flaky’ at best but this particular solution worked for me (created a custom plugin for it).
$result = add_role(
'org_site_owner',
__( 'Site Owner' ),
array(
'activate_plugins' => false,
'create_users' => true,
'customize' => true,
'delete_others_pages' => true,
'delete_others_posts' => true,
'delete_pages' => true,
'delete_plugins' => false,
'delete_posts' => true,
'delete_private_pages' => true,
'delete_private_posts' => true,
'delete_published_pages' => true,
'delete_published_posts' => true,
'delete_site' => false,
'delete_themes' => false,
'delete_users' => true,
'edit_dashboard' => false,
'edit_files' => true,
'edit_others_pages' => true,
'edit_others_posts' => true,
'edit_pages' => true,
'edit_plugins' => false,
'edit_posts' => true,
'edit_private_pages' => true,
'edit_private_posts' => true,
'edit_published_pages' => true,
'edit_published_posts' => true,
'edit_theme_options' => true,
'edit_themes' => false,
'edit_users' => true,
'export' => false,
'import' => false,
'install_plugins' => false,
'install_themes' => false,
'list_users' => true,
'manage_categories' => true,
'manage_links' => true,
'manage_options' => true,
'moderate_comments' => true,
'promote_users' => false,
'publish_pages' => true,
'publish_posts' => true,
'read' => true,
'read_private_pages' => true,
'read_private_posts' => true,
'remove_users' => true,
'switch_themes' => false,
'unfiltered_html' => false,
'update_core' => false,
'update_plugins' => false,
'update_themes' => false,
'upload_files' => true,
'upload_plugins' => false,
'upload_themes' => false,
)
);
// Allow site owners to see Appearance and Settings menus
$role_object = get_role( 'org_site_owner' );
$role_object->add_cap( 'edit_theme_options' );
$role_object->add_cap( 'manage_options' );
function hide_appearance_options() {
// Hide theme selection page
remove_submenu_page( 'themes.php', 'themes.php' );
// Hide media settings page
remove_submenu_page( 'options-general.php', 'options-media.php' );
// Hide permalinks
remove_submenu_page( 'options-general.php', 'options-permalink.php' );
// Hide featured image column
remove_submenu_page( 'options-general.php', 'featured-image-column' );
//Hide SSO/SAML configuration settings
remove_submenu_page( 'options-general.php', 'onelogin_saml_configuration' );
}
function org_site_owner_menu_pages()
{
$user_role = wp_get_current_user();
$allowed_roles = array('org_site_owner');
if( array_intersect($allowed_roles, $user_role->roles ) )
{
remove_menu_page('plugins.php'); // Plugins
remove_menu_page('tools.php'); // Tools
remove_menu_page('edit.php?post_type=acf'); // ACF Fields
remove_menu_page('admin.php?page=searchandfilter-settings'); // Search and filter plugin
add_action('admin_head', 'hide_appearance_options');
}
}
add_action( 'admin_init' , 'org_site_owner_menu_pages' );