Cum să permiți editorului să editeze doar pagina/setările de confidențialitate?
În instalarea mea WordPress (4.9.8.)
rolul de editor nu are permisiunea de a edita pagina de confidențialitate.
Ar funcționa cu următoarele în functions.php
:
$role_object = get_role( 'editor' );
$role_object->add_cap( 'manage_privacy_options', true );
$role_object->add_cap( 'manage_options' ); // aceasta trebuie să fie activă pentru ca capacitatea anterioară să funcționeze
Dar acum editorul are mult mai multe drepturi decât doar editarea paginii de confidențialitate.
Există o altă modalitate de a acorda acces rolului de editor
cu câteva linii de cod PHP?
Ca soluție temporară folosesc acum acest Plugin: https://wordpress.org/plugins/manage-privacy-options/
O altă soluție temporară este să nu selectezi nicio pagină de confidențialitate în setările de confidențialitate.

Editarea paginii de politică de confidențialitate este restricționată la manage_privacy_options
, așa cum este menționat într-un comentariu din fișierul de bază al WordPress wp-includes/capabilities.php
:
/*
* Setarea paginii de politică de confidențialitate necesită `manage_privacy_options`,
* deci editarea ei ar trebui să necesite și aceasta.
*/
if ( (int) get_option( 'wp_page_for_privacy_policy' ) === $post->ID ) {
$caps = array_merge( $caps, map_meta_cap( 'manage_privacy_options', $user_id ) );
}
Pentru a permite utilizatorilor cu rolurile care pot edita pagini (în instanțe single și multisite) să editeze și să șteargă pagina de politică de confidențialitate, trebuie să suprascriem array-ul editor
și administrator
$caps
:
add_filter('map_meta_cap', 'custom_manage_privacy_options', 1, 4);
function custom_manage_privacy_options($caps, $cap, $user_id, $args)
{
if (!is_user_logged_in()) return $caps;
if ('manage_privacy_options' === $cap) {
$manage_name = is_multisite() ? 'manage_network' : 'manage_options';
$caps = array_diff($caps, [ $manage_name ]);
}
return $caps;
}
Actualizare: Permite utilizatorilor cu rolul editor
sau administrator
să editeze și să șteargă pagina de politică de confidențialitate (ceea ce nu este posibil implicit în instanțele multisite):
add_filter('map_meta_cap', 'custom_manage_privacy_options', 1, 4);
function custom_manage_privacy_options($caps, $cap, $user_id, $args)
{
if (!is_user_logged_in()) return $caps;
$user_meta = get_userdata($user_id);
if (array_intersect(['editor', 'administrator'], $user_meta->roles)) {
if ('manage_privacy_options' === $cap) {
$manage_name = is_multisite() ? 'manage_network' : 'manage_options';
$caps = array_diff($caps, [ $manage_name ]);
}
}
return $caps;
}

oh, pare foarte inteligent.. 1. $caps = array_diff($caps, [ $manage_name ]);
restricționează toate celelalte capabilități ale manage_options
? și permite doar editarea opțiunilor de confidențialitate? 2. administrator
nu ar avea nevoie de asta cu adevărat, deoarece această capabilitate este deja inclusă, nu-i așa?

@AndréKelling 1. Hook-ul map_meta_cap
funcționează pe bază de post. Niciun alt post nu are restricția manage_privacy_options
, așa că ar trebui să fie în regulă să o elimini. Mai multe informații aici.
2. În mediile WordPress multisite, doar super-administratorii au voie să editeze pagina politicii de confidențialitate. După cum ai menționat, acest lucru nu este relevant pentru instalațiile cu o singură pagină.

@AndréKelling Mai ai întrebări în legătură cu răspunsul meu? Dacă nu, te rog acceptă răspunsul pentru a marca această întrebare ca rezolvată :)

nu, îmi pare rău, nu am avut timp să verific asta. o voi face imediat!

Funcționează destul de bine, dar nu ar fi mai bine să verificăm și rolul utilizatorului în plus... acest lucru ar afecta această capacitate pentru toți utilizatorii, nu-i așa?

@GDY Bun punct. Am presupus că doar editorii și administratorii pot edita pagini. Am adăugat verificarea rolului utilizatorului în răspunsul meu.

De fapt, întrebarea se referă la rolul de editor (care nu poate edita pagina de confidențialitate în instalările obișnuite), așa că ar trebui să acopere atât editorii, cât și administratorii.

Mulțumesc mult pentru soluție. Pentru cei care doresc să permită Managerilor de Magazin WooCommerce să editeze politica de confidențialitate, adăugați "shop_manager" la array_intersect în al doilea exemplu.

Știu că add_action
este un alias pentru add_filter
, dar deoarece filtrul map_meta_cap
este definit folosind apply_filters
, cred că ar trebui să înlocuiți add_action()
cu add_filter()
pentru concizie.

Acest cod provoacă o eroare fatală (Fatal error: Uncaught TypeError: array_intersect(): Argument #2 must be of type array, null given ...snip... /wp-admin/user-new.php(195): edit_user()
) la crearea unui nou cont de utilizator. Se pare că utilizatorul poate fi null. Am adăugat o linie suplimentară de verificări după apelul get_userdata()
care îl înfășoară astfel: if ($user_meta && isset($user_meta->roles) && is_array($user_meta->roles)) { }

Mulțumesc @Sven pentru soluția elegantă, funcționează bine dar am întâmpinat o problemă când utilizatorul nu este autentificat, acțiunea map_meta_cap este declanșată oricum, ceea ce a rezultat într-o eroare "502 bad getaway". Am adăugat o verificare is_user_logged_in()
înainte astfel:
if (is_user_logged_in()){
add_action('map_meta_cap', 'custom_manage_privacy_options', 1, 4);
}
Posibil să fie o configurație specifică a serverului meu (nginx) care provoacă această eroare, dar dacă cineva întâlnește aceeași problemă, iată o soluție.

Răspunsul furnizat a funcționat. Totuși, această linie:
if (array_intersect(['editor', 'administrator'], $user_meta->roles)) {
Genera această eroare:
array_intersect(): Expected parameter 2 to be an array, null given in
Așadar, am ajustat puțin codul pentru a mă asigura că ambele valori sunt array-uri valide (codul complet):
add_action('map_meta_cap', 'custom_manage_privacy_options', 1, 4);
function custom_manage_privacy_options($caps, $cap, $user_id, $args) {
if ( !is_user_logged_in() ) return $caps;
$target_roles = array('editor', 'administrator');
$user_meta = get_userdata($user_id);
$user_roles = ( array ) $user_meta->roles;
if ( array_intersect($target_roles, $user_roles) ) {
if ('manage_privacy_options' === $cap) {
$manage_name = is_multisite() ? 'manage_network' : 'manage_options';
$caps = array_diff($caps, [ $manage_name ]);
}
}
return $caps;
}

Nu văd ce ai schimbat. Dacă $user_meta->roles este null, tot treci null la array_intersect aici.

Deoarece ne asigurăm mai întâi că utilizatorul este autentificat, $user_meta->roles nu ar putea fi niciodată null? Am crezut că problema era din cauza utilizării directe a $user_meta->roles în array_intersect, așa că am salvat mai întâi valoarea într-o variabilă. Nu mai primesc niciun mesaj de eroare, deci se pare că asta a rezolvat problema.

⚠ Atenție! Până când acest bug este rezolvat, acest răspuns, deși conceptual valid, nu va funcționa! ⚠
În opinia mea, acum acest lucru este mai bine realizat prin wp-cli
.
De exemplu, pentru a extinde rolul de editor:
wp cap add editor manage_privacy_options
Sau, doar pentru un singur utilizator:
wp user add-cap USER_ID manage_privacy_options

Uau, se pare că nu funcționează :-( Dacă cineva poate comenta, confirma... Miroase a bug.

Am găsit vinovatul, un bug destul de vechi :-/
