Dacă utilizatorul curent este administrator sau editor
Cum pot verifica dacă utilizatorul curent conectat este administrator sau editor?
Știu cum să verific individual:
<?php if(current_user_can('editor')) { ?>
<!-- Conținut aici pentru editori -->
<?php } ?>
<?php if(current_user_can('administrator')) { ?>
<!-- Conținut aici pentru administratori -->
<?php } ?>
Dar cum pot combina aceste verificări? Adică, să verific dacă utilizatorul este administrator sau editor?

Prima soluție, care nu este legată de WordPress pentru că este doar PHP: Folosește operatorul logic "OR":
<?php if( current_user_can('editor') || current_user_can('administrator') ) { ?>
// Conținut aici pentru administratori sau editori
<?php } ?>
Dacă dorești să verifici mai mult de două roluri, poți verifica dacă rolurile utilizatorului curent se află într-un array de roluri, ceva de genul:
$user = wp_get_current_user();
$allowed_roles = array('editor', 'administrator', 'author');
<?php if( array_intersect($allowed_roles, $user->roles ) ) { ?>
// Conținut aici pentru rolurile permise
<?php } ?>
Totuși, current_user_can
poate fi folosit nu doar cu numele rolurilor utilizatorilor, ci și cu capabilități.
Astfel, având în vedere că atât editorii cât și administratorii pot edita pagini, viața ta poate fi mai ușoară verificând aceste capabilități:
<?php if( current_user_can('edit_others_pages') ) { ?>
// Conținut aici pentru rolurile de utilizator care pot edita pagini: editori și administratori
<?php } ?>
Aruncă o privire aici pentru mai multe informații despre capabilități.

@RobBenz nu, în niciunul dintre cazuri. Pentru că current_user_can()
returnează întotdeauna false dacă utilizatorul nu este autentificat, iar wp_get_current_user()
va returna un utilizator fără niciun rol dacă utilizatorul nu este autentificat, astfel încât array_intersect()
va fi întotdeauna false.

În PHPDoc-ul funcției current_user_can()
, putem vedea linia "Deși verificarea rolurilor specifice în locul unei capacități este parțial suportată, această practică este descurajată deoarece poate produce rezultate nesigure". Așadar, cred că ar fi mai bine să evităm utilizarea rolurilor atunci când verificăm capacitatea unui utilizator :-)

Când folosesc metoda array_intersect
, primesc un avertisment PHP în jurnalul de erori al serverului nostru care spune array_intersect(): Argument #2 is not an array
. Este din cauză că utilizatorul/utilizatorii verificați au doar un singur Rol?

@Garconis în mod normal ar trebui să fie un array. Din anumite motive, se pare că în cazul tău nu este un array. array_intersect($allowed_roles, (array)$user->roles )
va funcționa fără probleme.

Aș recomanda să nu verificați rolurile... ci mai degrabă capabilitățile. Este mai ușor să elimini sau să adaugi o capabilitate unui set de roluri... este mai explicit. De exemplu current_user_can('edit_orderform')
... poate că un Reprezentant de Vânzări ar trebui să poată DOAR să editeze formularul de comandă... dar să nu aibă drepturi să adauge conținut. Acordarea explicită a acestei capabilități este o structură de permisiuni mai explicită decât rolul pe care îl are un utilizator. Oamenii pot avea multiple roluri în organizațiile mai mari. Poți avea abonați care au mai mult acces decât doar pentru citire.

În primul rând, current_user_can()
nu ar trebui folosit pentru a verifica rolul unui utilizator - ar trebui folosit pentru a verifica dacă un utilizator are o anumită capacitate.
În al doilea rând, în loc să ne concentrăm pe rolul utilizatorului și să ne focusăm pe capacități, nu trebuie să ne complicăm cu lucruri precum problema menționată în întrebarea originală (care este verificarea dacă utilizatorul este administrator SAU editor). În schimb, dacă current_user_can()
ar fi folosit așa cum a fost intenționat, adică pentru a verifica capacitățile unui utilizator, nu rolul acestuia, nu ar fi nevoie ca verificarea condițională să conțină un test "sau" (||). De exemplu:
if ( current_user_can( 'edit_pages' ) ) { ...
edit_pages este o capacitate pe care o au atât rolurile de administrator cât și cele de editor, dar nu și rolurile inferioare precum autorii. Acesta este modul în care current_user_can()
a fost conceput să fie utilizat.

Vă rugăm să rețineți: Dezvoltatorii WP de nivel înalt sunt de acord cu acest răspuns. Ar trebui să încercați să evitați verificarea rolurilor pe cât posibil și să folosiți capabilitățile. În prezent, lucrez la un proiect cu roluri multiple care au doar capabilitatea 'read'. Singura soluție pentru mine este verificarea rolurilor. Îmi pare rău, nu pot găsi link-ul, a fost o discuție deschisă pe Github-ul WP.

Acesta ar trebui să fie răspunsul acceptat, după părerea mea. current_user_can
ar trebui folosit în general pentru capabilități, nu pentru roluri.

+1 pentru aceasta, evitați verificarea rolurilor prin current_user_can()
. Dacă doriți să verificați rolurile după cheie, atunci efectuați o verificare a rolului în loc de o verificare a capabilităților :)

Care este funcția corectă atunci, pentru verificarea explicită și sigură a rolurilor utilizatorilor? Se pare că este puțin dificil de găsit (dacă există). @Bjorn

@Viktor Borítás Există mai multe soluții valide pe această pagină. Dar folosește-le doar dacă current_user_can()
nu este o opțiune. De asemenea, comentariul meu se bazează mai mult pe securitate. De exemplu, dacă vrei să restricționezi conținutul pentru anumiți utilizatori, în majoritatea cazurilor o verificare a capabilităților este suficientă pentru această sarcină.

Este preferabil să folosești capabilitățile "pentru a proteja" operațiunile deoarece acestea sunt mai flexibile, mai ușor de filtrat și de atribuit granular utilizatorilor. Dar dacă întrebarea la care căutăm un răspuns este "Este utilizatorul curent un editor?" atunci folosirea current_user_can
este perfect în regulă, de fapt, acesta este exact modul în care ar trebui să fie folosit.

@gmazzap - de fapt, folosirea current_user_can()
pentru verificarea unui rol nu este "perfect în regulă." Dacă ar fi așa, de ce ar trebui ca documentația funcției să spună "această practică este descurajată deoarece poate produce rezultate nesigure." Doar pentru că ceva "funcționează" nu înseamnă că este o practică bună sau acceptabilă. Internetul este deja plin de practici proaste de programare prezentate ca fiind acceptabile. Te rog să nu contribui la asta.

@butlerblog știi că documentația Codex este scrisă de contribuitori? Programez pentru WordPress de 16 ani și cu numărul de greșeli pe care le-am găsit în Codex în acești ani aș putea scrie o carte. Având în vedere asta, nu este o greșeală dar este scris neclar. Așa cum am scris deja, practica este descurajată pentru a răspunde la întrebarea: "are utilizatorul curent permisiunea să facă X?" pentru că dacă asta trebuie să aflați, verificarea rolului va produce rezultate nesigure. Dar dacă vrei să răspunzi la întrebarea "Are acest utilizator rolul X?", care este o întrebare diferită, atunci current_user_can()
este calea corectă de urmat.

Nu mă refer la codex. Nu doar că acest codex este tehnic depreciat, dar ceea ce discutăm vine direct din documentația inline din Core și se află în documentația pentru dezvoltatori, care are considerabil mai multă supraveghere decât codex. În plus, încurajarea folosirii acestei funcții în acest mod duce la alte obiceiuri proaste în utilizarea incorectă a rolurilor vs. capacităților, exemple care abundă pe internet. Ești liber să-ți păstrezi opinia, dar va trebui să cădem de acord că nu suntem de acord.

Îmi pare rău, dacă această metodă este tehnic învechită, care este modalitatea pe care o folosiți în WordPress pentru a verifica dacă un utilizator are un rol? @butlerblog Rețineți că nu întreb care este modalitatea de a verifica dacă un utilizator este autorizat să efectueze o operațiune, ci - din nou - să verific dacă un utilizator are sau nu un rol.

Când am spus "tehnic învechit", mă refeream specific la referința ta din codex. Folosirea current_user_can()
nu este învechită - niciodată nu a fost destinată să verifice un rol - așa a fost încă de la WP 2.0, și este menționat în linie și în documentația pentru dezvoltatori. Pentru a verifica dacă un utilizator are un rol (pentru care aproape nu există niciun motiv bun să o faci), este un array în obiect: $user->roles
. De exemplu: in_array( 'some_role', $user->roles );
Dar verificarea rolurilor duce la obiceiuri proaste. Rolurile sunt destinate să atribuie în bloc un grup de capacități unui utilizator, capacitatea este cea care ar trebui verificată.

Așa cum a menționat @butlerblog în răspunsul său, nu ar trebui să folosiți current_user_can pentru a verifica un rol
Această notificare este adăugată specific în documentația PHP a funcției has_cap
care este apelată de current_user_can
Deși verificarea unui rol în locul unei capacități este parțial suportată, această practică este descurajată deoarece poate produce rezultate instabile.
Modalitatea CORECTĂ de a face acest lucru este să obțineți utilizatorul și să verificați $user->roles
, astfel:
if( ! function_exists( 'current_user_has_role' ) ){
function current_user_has_role( $role ) {
$user = get_userdata( get_current_user_id() );
// Verifică dacă utilizatorul sau rolurile sale există
if( ! $user || ! $user->roles ){
return false;
}
// Verifică dacă rolul este un array
if( is_array( $role ) ){
return array_intersect( $role, (array) $user->roles ) ? true : false;
}
return in_array( $role, (array) $user->roles );
}
}
Iată câteva funcții ajutătoare pe care le folosesc pentru acest lucru (deoarece uneori nu vreau doar utilizatorul curent):
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' ) ){
// Obține rolurile utilizatorului după 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' ) ){
// Verifică dacă utilizatorul are un anumit rol după 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 );
}
}
Apoi puteți folosi simplu așa:
current_user_has_role( 'editor' );
sau
current_user_has_role( array( 'editor', 'administrator' ) );

Accesarea proprietăților de nivel inferior nu este niciodată o idee bună în WP, cu siguranță nu este calea corectă. Dacă întrebarea la care se caută un răspuns este "Este utilizatorul curent un editor?" atunci folosirea current_user_can
este perfect în regulă, de fapt, aceasta este exact calea de urmat. Faptul că este preferabil să folosim capabilități pentru a "proteja" operațiunile este un subiect diferit. A cunoaște rolul unui utilizator poate fi un lucru legitim și în acest caz, current_user_can
este perfect valid pentru utilizare.

@gmazzap atunci de ce ar specifica în mod expres "Deși verificarea rolurilor specifice în locul unei capabilități este parțial suportată, această practică este descurajată deoarece poate produce rezultate nesigure." în pagina de documentație a current_user_can
. Se pare că documentația și comentariul tău se contrazic, deși înțeleg ce spui. Având în vedere acestea, $roles
este o proprietate publică în obiectul WP_User
și este așa încă din versiunea 2.0.0. https://developer.wordpress.org/reference/functions/current_user_can/

documentația se referă la faptul că, de exemplu, un editor este de obicei capabil să editeze articole. Așa că ai putea fi tentat să verifici dacă utilizatorul este editor pentru a-i permite să editeze un articol. Acest lucru este greșit deoarece poate capabilitatea a fost filtrată astfel încât utilizatorul, deși este editor, nu ar trebui să editeze articolul. Și poate fi și invers, un abonat ar putea avea permisiunea de a edita articole sau doar acel articol specific. Verificarea capabilității asigură respectarea acestor rezultate așteptate.

Totuși, întrebarea "Este acest utilizator un editor?" ar putea fi în continuare o întrebare legitimă. Nu ar trebui să o pui pentru a determina dacă un utilizator are sau nu permisiunea să facă ceva, dar ai putea pune această întrebare din alte motive. Și în acest caz, folosirea current_user_can
cu numele rolului este în regulă.

În ceea ce privește rolurile, da, aceasta este o proprietate publică pe care te poți baza că va exista, dar current_user_can
are filtre, de exemplu, https://developer.wordpress.org/reference/hooks/user_has_cap/ sau https://developer.wordpress.org/reference/hooks/map_meta_cap/. Dacă un plugin sau orice altceva folosește aceste filtre pentru a modifica ceea ce returnează current_user_can
, prin verificarea directă a proprietății rolurilor vei rata filtrele și astfel vei reduce compatibilitatea codului tău cu codul altora.

Pentru administrator
$current_user = wp_get_current_user();
if (!in_array('administrator', $current_user->roles)) {
//execută ceva
}
Pentru editor
$current_user = wp_get_current_user();
if (!in_array('editor', $current_user->roles)) {
//execută ceva
}
Te rugăm să reții că acest cod funcționează doar dacă dorești să verifici rolurile utilizatorului curent. Dacă trebuie să verifici pentru orice alt utilizator specific, trebuie să folosești get_user_by (https://developer.wordpress.org/reference/functions/get_user_by/) sau metode similare pentru a obține utilizatorul pe care dorești să-l verifici

<?php
// Verifică dacă utilizatorul curent are rol de editor
if( current_user_can('editor')) :
echo "bun venit";
// Verifică dacă utilizatorul curent are rol de membru
elseif( current_user_can('member')) :
echo "bun venit";
else :
// Afișează mesaj și link de autentificare dacă utilizatorul nu este logat
wp_die("<h2>Pentru a vizualiza această pagină trebuie mai întâi să te <a href='". wp_login_url(get_permalink()) ."' title='Autentificare'>autentifici</a></h2>");
endif;
?>

Poți permite vizualizarea paginii doar pentru "editor" sau "membru" dacă adaugi acest cod direct în generic-page.php

Te rog nu posta doar cod. Adaugă comentarii și explicații despre cum rezolvă această soluție problema celui care întreabă.

Răspunsurile corecte la întrebarea-soluție de mai sus sunt prin programare de bază folosind else:
if( current_user_can('administrator')) {
<!-- doar administratorul va vedea acest mesaj -->
} else {
if( wp_get_current_user('editor')) {
<!-- doar editorul, dar nu și administratorul va vedea acest mesaj -->
?>
<style type="text/css">#perhapsDIVremovalidentifier{
display:none;
</style>
}
<?php
} else {
<!-- utilizatorul nu este nici editor și nici administrator -->
}}
Pe scurt: Administratorul este găsit, dar dacă verificăm pentru editor, administratorul este de asemenea găsit. Așa că permitem doar administratorului să treacă și identificăm doar editorul.
Nu uitați că ar trebui să folosiți întotdeauna acest cod pentru a apela codul de mai sus pentru a minimiza utilizarea procesorului:
if(is_user_logged_in()){}
