Если текущий пользователь является администратором или редактором

104

Как я могу проверить, является ли текущий вошедший в систему пользователь администратором или редактором?

Я знаю, как сделать каждый в отдельности:

<?php if(current_user_can('editor')) { ?> 
    <!-- Stuff here for editors -->
<?php } ?>

<?php if(current_user_can('administrator')) { ?>
    <!-- Stuff here for administrators -->
<?php } ?>

Но как мне работать вместе? Т.е. пользователь это администратор или редактор?

Энди
источник
10
if( current_user_can('editor') || current_user_can('administrator') )
Шаззад

Ответы:

193

Первый ответ, не связанный с WordPress, потому что это всего лишь PHP: используйте логический оператор «ИЛИ»:

<?php if( current_user_can('editor') || current_user_can('administrator') ) {  ?>
    // Stuff here for administrators or editors
<?php } ?>

Если вы хотите проверить более двух ролей, вы можете проверить, находятся ли роли текущего пользователя в массиве ролей, например:

$user = wp_get_current_user();
$allowed_roles = array('editor', 'administrator', 'author');
<?php if( array_intersect($allowed_roles, $user->roles ) ) {  ?>
   // Stuff here for allowed roles
<?php } ?>

Однако current_user_canможет использоваться не только с именем пользователя, но и с его возможностями.

Таким образом, как только редакторы, так и администраторы могут редактировать страницы, ваша жизнь может быть проще, проверяя эти возможности:

<?php if( current_user_can('edit_others_pages') ) {  ?>
    // Stuff here for user roles that can edit pages: editors and administrators
<?php } ?>

Посмотрите здесь для получения дополнительной информации о возможностях.

gmazzap
источник
1
вам нужно проверить, если is_logged_in();?
RobBenz
3
@RobBenz нет, ни в одном из случаев. Потому что current_user_can()всегда возвращает false, если пользователь не вошел в систему, и wp_get_current_user()вернет пользователя без какой-либо роли, если пользователь не вошел в систему, поэтому array_intersect()всегда будет false.
gmazzap
1
В PHPDoc current_user_can()функции мы можем видеть строку « Хотя проверка по отдельным ролям вместо возможности поддерживается частично, такая практика не рекомендуется, поскольку она может привести к ненадежным результатам ». Поэтому я думаю, что было бы лучше избегать использования ролей при проверке возможностей пользователя :-)
Эренор Пас
Когда я использую array_intersectметод, я получаю предупреждение PHP в нашем журнале ошибок сервера, говорящее array_intersect(): Argument #2 is not an array. Это потому, что проверяемые пользователи имеют только одну роль?
Гарконис
@Garconis обычно это должен быть массив. По какой-то причине вам кажется, что это не массив. array_intersect($allowed_roles, (array)$user->roles )будет работать без проблем.
gmazzap
9

Во-первых, current_user_can()не следует использовать для проверки роли пользователя - его следует использовать для проверки наличия у пользователя определенных возможностей .

Во-вторых, вместо того, чтобы интересоваться ролью пользователя, но вместо этого сосредоточиться на возможностях, вам не нужно заниматься такими вещами, как проблема, о которой говорилось в первоначальном вопросе (который проверяет, является ли пользователь администратором или редактором). Вместо этого, если current_user_can()он используется по назначению, то есть для проверки возможностей пользователя, а не его роли, вам не понадобится условная проверка, содержащая тест «или» (||). Например:

if ( current_user_can( 'edit_pages' ) ) { ...

edit_pages - это возможность как администратора, так и редактора, но не нижестоящих ролей, таких как авторы. Вот как это current_user_can()было предназначено для использования.

butlerblog
источник
Обратите внимание : разработчики WP высокого уровня согласны с этим ответом. Вы должны стараться по возможности избегать проверки ролей, используйте возможности. В настоящее время я работаю над проектом с несколькими ролями, который имеет только «чтение». Единственное решение для меня - проверка ролей. Извините, я не могу найти ссылку, это было открытое обсуждение на WP Github.
Бьорн
Это должен быть принятый ответ, ИМО. current_user_canобычно следует использовать для возможностей, а не для ролей.
Армстронгест
2

Как говорится в ответе @butlerblog, вы не должны использовать current_user_can для проверки роли

Это уведомление специально добавлено в документацию PHP о has_capфункции, которая вызываетсяcurrent_user_can

Хотя проверка на наличие роли вместо возможности поддерживается частично, такая практика не рекомендуется, поскольку она может привести к ненадежным результатам.

ПРАВИЛЬНЫЙ способ сделать это , чтобы заставить пользователя и проверить $user->roles, как это:

if( ! function_exists( 'current_user_has_role' ) ){
    function current_user_has_role( $role ) {

        $user = get_userdata( get_current_user_id() );
        if( ! $user || ! $user->roles ){
            return false;
        }

        if( is_array( $role ) ){
            return array_intersect( $role, (array) $user->roles ) ? true : false;
        }

        return in_array( $role, (array) $user->roles );
    }
}

Вот некоторые вспомогательные функции, которые я использую для этого (так как иногда я не хочу только текущего пользователя):

if( ! function_exists( 'current_user_has_role' ) ){
    function current_user_has_role( $role ){
        return user_has_role_by_user_id( get_current_user_id(), $role );
    }
}

if( ! function_exists( 'get_user_roles_by_user_id' ) ){
    function get_user_roles_by_user_id( $user_id ) {
        $user = get_userdata( $user_id );
        return empty( $user ) ? array() : $user->roles;
    }
}

if( ! function_exists( 'user_has_role_by_user_id' ) ){
    function user_has_role_by_user_id( $user_id, $role ) {

        $user_roles = get_user_roles_by_user_id( $user_id );

        if( is_array( $role ) ){
            return array_intersect( $role, $user_roles ) ? true : false;
        }

        return in_array( $role, $user_roles );
    }
}

Тогда вы можете просто сделать это:

current_user_has_role( 'editor' );

или же

current_user_has_role( array( 'editor', 'administrator' ) );

sMyles
источник
-1
<?php if( current_user_can('editor')) :
  echo "welcome";
elseif( current_user_can('member')) :
  echo "welcome";
else :
 wp_die("<h2>To view this page you must first <a href='". wp_login_url(get_permalink()) ."' title='Login'>log in</a></h2>");
endif;
?>
seowmx
источник
1
Было бы здорово, если бы вы могли объяснить, как это помогает OP.
Бравокейл
Вы можете разрешить видеть на странице только «редактора» или «участника», вы можете разместить этот код прямо в generic-page.php
seowmx
5
Пожалуйста, не бросайте код. Добавьте комментарии и некоторые объяснения, как это решает проблему спрашивающих.
Крафтнер
Итак, ваш ответ - дублирование кода для каждой роли?
Джуликс