Jeśli bieżącym użytkownikiem jest administrator lub redaktor

100

Jak mogę sprawdzić, czy bieżący zalogowany użytkownik jest administratorem czy edytorem?

Wiem, jak to zrobić indywidualnie:

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

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

Ale jak mam pracować razem? Czyli użytkownik jest administratorem lub redaktorem?

andy
źródło
10
if( current_user_can('editor') || current_user_can('administrator') )
Shazzad

Odpowiedzi:

189

Pierwsza odpowiedź, niezwiązana z WordPress, ponieważ jest to tylko PHP: użyj logicznego operatora „LUB”:

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

Jeśli chcesz sprawdzić więcej niż dwie role, możesz sprawdzić, czy role bieżącego użytkownika znajdują się w tablicy ról, na przykład:

$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 } ?>

Jednakże, current_user_canmoże być stosowany nie tylko z nazwy ról użytkowników, ale także z możliwościami.

Tak więc, gdy zarówno redaktorzy, jak i administratorzy będą mogli edytować strony, łatwiej będzie ci sprawdzić te możliwości:

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

Zajrzyj tutaj, aby uzyskać więcej informacji na temat możliwości.

gmazzap
źródło
musisz sprawdzić, czy is_logged_in();?
RobBenz
3
@RobBenz nie, w żadnym z przypadków. Ponieważ current_user_can()zawsze zwraca false, jeśli użytkownik nie jest zalogowany, i wp_get_current_user()zwraca użytkownika bez żadnej roli, jeśli użytkownik nie jest zalogowany, więc array_intersect()zawsze będzie false.
gmazzap
1
W PHPDoc current_user_can()funkcji widzimy wiersz „ Chociaż częściowe sprawdzanie poszczególnych ról zamiast funkcji jest obsługiwane, ta praktyka jest odradzana, ponieważ może dawać niewiarygodne wyniki ”. Myślę więc, że lepiej byłoby unikać ról podczas sprawdzania możliwości użytkownika :-)
Erenor Paz
Gdy korzystam z tej array_intersectmetody, w dzienniku błędów serwera pojawia się ostrzeżenie PHP array_intersect(): Argument #2 is not an array. Czy to dlatego, że sprawdzany użytkownik (użytkownicy) ma tylko jedną rolę?
Garconis
@Garconis zwykle powinna być tablicą. Z jakiegoś powodu wydaje się, że nie jest tablicą. array_intersect($allowed_roles, (array)$user->roles )będzie działać bez problemów.
gmazzap
9

Po pierwsze, current_user_can()nie powinien być używany do sprawdzania roli użytkownika - powinien być używany do sprawdzania, czy użytkownik ma określone możliwości .

Po drugie, zamiast przejmować się rolą użytkownika, ale koncentrując się na możliwościach, nie musisz zawracać sobie głowy robieniem rzeczy takich jak problem zadany w pierwotnym pytaniu (czyli sprawdzenie, czy użytkownik jest administratorem LUB redaktorem). Zamiast tego, jeśli current_user_can()był używany zgodnie z przeznaczeniem, czyli do sprawdzania możliwości użytkownika, a nie jego roli, nie trzeba sprawdzania warunkowego, aby zawierał test „lub” (||). Na przykład:

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

edit_pages to funkcja zarówno roli administratora, jak i edytora, ale nie żadnych niższych ról, takich jak autorzy. Tak current_user_can()zamierzano go używać.

blog lokaja
źródło
Uwaga : deweloperzy WP wysokiego poziomu zgadzają się z tą odpowiedzią. Powinieneś starać się unikać sprawdzania ról w jak największym stopniu, wykorzystuj możliwości. Obecnie pracuję nad projektem z wieloma rolami, które mają tylko limit odczytu. Jedynym rozwiązaniem jest dla mnie sprawdzenie roli. Niestety nie mogę znaleźć linku, była to otwarta dyskusja na temat WP Github.
Bjorn
To powinna być zaakceptowana odpowiedź, IMO. current_user_canpowinny być generalnie używane dla funkcji, a nie ról.
Armstrongest
2

Jak stwierdzono w odpowiedzi @butlerblog, nie powinieneś używać current_user_can do sprawdzania roli

To powiadomienie jest specjalnie dodane w dokumentacji PHP has_capfunkcji, która jest wywoływanacurrent_user_can

Podczas gdy częściowo sprawdzono, czy rola zastępuje jakąś funkcję, praktyka ta jest odradzana, ponieważ może dawać niewiarygodne wyniki.

POPRAWNIE sposobem na to jest, aby użytkownik i sprawdzić $user->roles, jak poniżej:

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 );
    }
}

Oto kilka funkcji pomocniczych, których używam do tego (ponieważ czasami nie chcę tylko bieżącego użytkownika):

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 );
    }
}

Następnie możesz po prostu to zrobić:

current_user_has_role( 'editor' );

lub

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

sMyles
źródło
-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
źródło
1
Byłoby wspaniale, gdybyś mógł wyjaśnić, w jaki sposób pomaga OP.
bravokeyl
Możesz zezwolić na wyświetlanie tylko „edytora” lub „członka” strony, możesz opublikować ten kod bezpośrednio w generic-page.php
seowmx
4
Proszę nie upuszczać kodu. Dodaj komentarze i wyjaśnienia, jak to rozwiązuje problem pytających.
kraftner