Изменение роли пользователя в WordPress multisite
В одном из очередных обновлений WordPress в сети multisite пропала настройка управления ролями пользователя. Долго искать решение в интернете я не стал. В таких случаях, как правило, решают вопрос с помощью плагина. Но так как я не всегда отдаю предпочтение плагину, решил заглянуть под капот движка. В папке wp-admin есть файл user-edit.php и уже в нем можно найти примерно такие строчки кода
... // Compare user role against currently editable roles. $user_roles = array_intersect( array_values( $profileuser->roles ), array_keys( get_editable_roles() ) ); $user_role = reset( $user_roles ); // Print the full list of roles with the primary one selected. wp_dropdown_roles( $user_role ); ...
Они то и выводят выпадающий список ролей пользователей на экран. Не думаю, что было бы верно предположить, что это было случайностью. Ведь все это было обернуто условиями:
if ( ! IS_PROFILE_PAGE && ! is_network_admin() && current_user_can( 'promote_user', $profileuser->ID ) ) :
! is_network_admin() — таким образом выпадающий список был скрыт из разметки при условии, что user находится в настройках сети сайтов.
Не долго думая я решил взять эту разметку и продублировать в собитиях show_user_profile и edit_user_profile, но при этом изменить условие в противоположном направлении. Используем как обычно для вывода поля два события: show_user_profile и edit_user_profile. А для обработки данных personal_options_update и edit_user_profile_update. Вот, что в результате получилось
if(!function_exists('VAB_user_fields')){
function VAB_user_fields($user){
global $pagenow;
if(is_multisite()&&isset($_GET['user_id'])){
$user_id=(int)$_GET['user_id'];$profileuser=get_user_to_edit($user_id);
if(!IS_PROFILE_PAGE&&is_network_admin()&¤t_user_can('promote_user',$profileuser->ID)&&$pagenow=='user-edit.php'){
echo'<div><label for="role"><big class="user-role-wrap">'.__('Role').'</big></label><select name="role" id="role">';
$user_roles=array_intersect(array_values($profileuser->roles),array_keys(get_editable_roles()));<br /> $user_role=reset($user_roles);
wp_dropdown_roles($user_role);
if($user_role){
echo '<option value="">'.__('— No role for this site —').'</option>';
}else{
echo '<option value="" selected="selected">'.__('— No role for this site —').'</option>';}
echo '</select></div>';}}}}
add_action('show_user_profile','VAB_user_fields');
add_action('edit_user_profile','VAB_user_fields');
А вот обработчик писать даже и не пришлось. Этого хватило и все заработало. И оно в полне логично, ведь разметка от самих разработчиков. WordPress сам обрабатывает эту разметку.