Изменение роли пользователя в 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()&&current_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="">'.__('&mdash; No role for this site &mdash;').'</option>';
  }else{
   echo '<option value="" selected="selected">'.__('&mdash; No role for this site &mdash;').'</option>';}
   echo '</select></div>';}}}}
add_action('show_user_profile','VAB_user_fields');
add_action('edit_user_profile','VAB_user_fields');

А вот обработчик писать даже и не пришлось. Этого хватило и все заработало. И оно в полне логично, ведь разметка от самих разработчиков. WordPress сам обрабатывает эту разметку.

Смотреть видео на ютуб канале «Изменение роли пользователя в WordPress multisite»


Кастомные поля