Изменение роли пользователя в 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 сам обрабатывает эту разметку.