Allow user to Edit specific Customizer Settings, blocking access to other areas
<?php
/**
* I like better this filter, because allow access to the customizer,
* but only to the desired capabilities given to the role.
*/
add_filter('user_has_cap', function($allcaps, $_, $args, $user) {
if(in_array('customize', $args) && in_array('custom_role', $user->roles)) {
return array_merge(['edit_theme_options' => true], $allcaps);
}
return $allcaps;
}, 13, 4);
<?php
/**
* Old school, not really nice because first gives access to
* a plethora of settings, then hides menus but they are
* available through knowing the script: i.e.: widgets.php
*/
// add capability edit_theme_options to user
/**
* Removes widget, nav_menus and AMP_customizer panels
*/
add_filter('customize_loaded_components', function($components) {
$user = wp_get_current_user();
if(in_array('custom_role', $user->roles)) {
add_action('customize_controls_init', function() {
global $wp_customize;
$wp_customize->remove_panel('amp_panel');
});
return array_filter($components, function($component) {
return !in_array($component, ['widgets', 'nav_menus']);
});
}
return $components;
});
add_action('admin_head', function(){
$user = wp_get_current_user();
if(in_array('custom_role', $user->roles)) {
remove_submenu_page('themes.php', 'themes.php');
remove_submenu_page('themes.php', 'widgets.php');
remove_submenu_page('themes.php', 'nav-menus.php');
global $submenu;
foreach($submenu['themes.php'] as $index => $slug) {
if(strpos($slug[2], 'amp_panel')) {
unset($submenu['themes.php'][$index]);
}
}
}
});