Consentire all'utente di modificare solo determinate pagine
La prima cosa da fare per implementare questo compito è essere in grado di riconoscere quale pagina un utente può modificare.
Ci sono diversi modi per farlo. Potrebbe essere un meta utente, qualche valore di configurazione... Per semplificare questa risposta, assumerò che esista una funzione come questa:
function wpse_user_can_edit( $user_id, $page_id ) {
$page = get_post( $page_id );
// troviamo la pagina più in alto nella gerarchia
while( $page && (int) $page->parent ) {
$page = get_post( $page->parent );
}
if ( ! $page ) {
return false;
}
// ora $page è la pagina principale nella gerarchia
// come determinare se un utente può modificarla, dipende da te...
}
Ora che abbiamo un modo per determinare se un utente può modificare una pagina, dobbiamo solo dire a WordPress di usare questa funzione per verificare la capacità dell'utente di modificare una pagina.
Questo può essere fatto tramite il filtro 'map_meta_cap'
.
Qualcosa come:
add_filter( 'map_meta_cap', function ( $caps, $cap, $user_id, $args ) {
$to_filter = [ 'edit_post', 'delete_post', 'edit_page', 'delete_page' ];
// Se la capacità filtrata non ci interessa, restituiamo il valore corrente
if ( ! in_array( $cap, $to_filter, true ) ) {
return $caps;
}
// Il primo elemento nell'array $args dovrebbe essere l'ID della pagina
if ( ! $args || empty( $args[0] ) || ! wpse_user_can_edit( $user_id, $args[0] ) ) {
// L'utente non è autorizzato, comunichiamolo a WP
return [ 'do_not_allow' ];
}
// Altrimenti restituiamo il valore corrente
return $caps;
}, 10, 4 );
A questo punto, ci serve solo un modo per collegare un utente a una o più pagine.
Potrebbero esserci diverse soluzioni a seconda del caso d'uso.
Una soluzione flessibile potrebbe essere aggiungere un dropdown di pagine "radice" (vedi wp_dropdown_pages
) alla schermata di modifica utente nel backend, e salvare la pagina selezionata come meta utente.
Possiamo sfruttare 'edit_user_profile'
per aggiungere il campo dropdown delle pagine e 'edit_user_profile_update'
per salvare il valore selezionato come meta utente.
Sono sicuro che in questo sito ci sono abbastanza guide su come farlo nel dettaglio.
Quando le pagine sono salvate come meta utente, la funzione wpse_user_can_edit()
di cui sopra può essere completata verificando se l'ID della pagina fa parte del valore meta dell'utente.
Rimuovendo la capacità di modificare la pagina, WordPress farà il resto: rimuoverà ogni link di modifica dal backend e frontend, impedirà l'accesso diretto... e così via.

Questa soluzione è molto migliore della mia. Perché limitare i link di modifica quando puoi semplicemente modificare le capacità dell'utente e lasciare che WordPress gestisca il resto?

Implementare questa funzionalità richiede una piccola quantità di codice, anche se si utilizza una classe PHP per evitare variabili globali. Inoltre, non volevo nascondere le pagine proibite per l'utente nella Dashboard. E se avessero aggiunto contenuti già presenti sul sito?
$user_edit_limit = new NS_User_Edit_Limit(
15, // ID dell'utente che vogliamo limitare
[2, 17] // Array di ID delle pagine genitore che l'utente può modificare
(accetta anche gli ID delle pagine figlio)
);
class NS_User_Edit_Limit {
/**
* Memorizza l'ID dell'utente che vogliamo controllare e i
* post che permetteremo all'utente di modificare.
*/
private $user_id = 0;
private $allowed = array();
public function __construct( $user_id, $allowed ) {
// Salva l'ID dell'utente che vogliamo limitare.
$this->user_id = $user_id;
// Espande la lista delle pagine consentite per includere le pagine figlio
$all_pages = new WP_Query( array(
'post_type' => 'page',
'posts_per_page' => -1,
) );
foreach ( $allowed as $page ) {
$this->allowed[] = $page;
$sub_pages = get_page_children( $page, $all_pages );
foreach ( $sub_pages as $sub_page ) {
$this->allowed[] = $sub_page->ID;
}
}
// Per l'utente limitato...
// Rimuove il link di modifica dal front-end se necessario
add_filter( 'get_edit_post_link', array( $this, 'remove_edit_link' ), 10, 3 );
add_action( 'admin_bar_menu', array( $this, 'remove_wp_admin_edit_link' ), 10, 1 );
// Rimuove il link di modifica da wp-admin se necessario
add_action( 'page_row_actions', array( $this, 'remove_page_list_edit_link' ), 10, 2 );
}
/**
* Funzioni helper che verificano se l'utente corrente è quello
* che vogliamo limitare e controllano se un post specifico è nella
* lista dei post che permettiamo all'utente di modificare.
*/
private function is_user_limited() {
$current_user = wp_get_current_user();
return ( $current_user->ID == $this->user_id );
}
private function is_page_allowed( $post_id ) {
return in_array( $post_id, $this->allowed );
}
/**
* Rimuove il link di modifica dal front-end se necessario.
*/
public function remove_edit_link( $link, $post_id, $test ) {
/**
* Se...
* - L'utente limitato è loggato
* - La pagina per cui viene creato il link di modifica non è nella lista consentita
* ...ritorna una stringa vuota $link. Questo fa anche sì che edit_post_link() non mostri nulla.
*
* Altrimenti, ritorna il link normalmente.
*/
if ( $this->is_user_limited() && !$this->is_page_allowed( $post_id ) ) {
return '';
}
return $link;
}
/**
* Rimuove il link di modifica dalla barra di amministrazione di WP
*/
public function remove_wp_admin_edit_link( $wp_admin_bar ) {
/**
* Se:
* - Siamo su una singola pagina
* - L'utente limitato è loggato
* - La pagina non è nella lista consentita
* ...Rimuove il link di modifica dalla barra di amministrazione di WP
*/
if (
is_page() &&
$this->is_user_limited() &&
!$this->is_page_allowed( get_post()->ID )
) {
$wp_admin_bar->remove_node( 'edit' );
}
}
/**
* Rimuove il link di modifica da edit.php di WP Admin
*/
public function remove_page_list_edit_link( $actions, $post ) {
/**
* Se:
* - L'utente limitato è loggato
* - La pagina non è nella lista consentita
* ...Rimuove i link rapidi "Modifica", "Modifica rapida" e "Cestino".
*/
if (
$this->is_user_limited() &&
!$this->is_page_allowed( $post->ID )
) {
unset( $actions['edit'] );
unset( $actions['inline hide-if-no-js']);
unset( $actions['trash'] );
}
return $actions;
}
}
Il codice sopra impedisce che le seguenti funzionalità funzionino o appaiano quando necessario:
get_edit_post_link
- Il link
Modifica Pagina
sulla barra di amministrazione di WP che appare per le pagine - I link rapidi
Modifica
,Modifica rapida
eCestino
che appaiono sotto le pagine in/wp-admin/edit.php?post_type=page
Questo ha funzionato sulla mia installazione locale di WordPress 4.7. Supponendo che le pagine del sito non cambino spesso, potrebbe essere meglio hardcodare gli ID della pagina e delle sue pagine figlio, rimuovendo la WP_Query
all'interno del metodo __construct
. Questo risparmierà molte chiamate al database.

Se desideri evitare l'uso di plugin, puoi utilizzare una variante del codice seguente nel file functions.php o in un plugin personalizzato.
Ci sono 2 parti separate in questo codice, avresti bisogno di utilizzarne solo 1, ma quale dipende dalla complessità dei requisiti.
La Parte 1 specifica un singolo utente e lo limita a un post specifico.
La Parte 2 ti permette di creare una mappa di utenti e ID dei post e consente più post.
Il codice seguente è per una pagina soltanto, ma se desideri cambiarlo per un post o un custom post type, dovrai modificare la stringa in $screen->id == 'page'
con qualcos'altro.
Puoi trovare un riferimento agli ID degli screen in wp-admin qui
function my_pre_get_posts( $query ){
$screen = get_current_screen();
$current_user = wp_get_current_user();
/**
* Specifica un singolo utente e limita a una singola pagina
*/
$restricted_user_id = 10; //ID dell'utente limitato
$allowed_post_id = 1234; //ID del post consentito
$current_post_id = isset( $_GET['post'] ) ? (int)$_GET['post'] : false ;
//Interessa solo un utente specifico
if( $current_user->ID !== $restricted_user_id ){
return;
}
//Interessa solo la pagina di MODIFICA.
if( ! $current_post_id ){
return;
}
if( $screen->id == 'page' && $current_post_id !== $allowed_post_id ){
wp_redirect( admin_url( ) );
exit;
}
/**
* Specifica una mappa di user_id => $allowed_posts
*/
$restrictions_map = [
10 => [ 123 ], //Consenti all'utente con ID di modificare la Pagina con ID 123
11 => [ 152, 186 ] //Consenti all'utente con ID di modificare le Pagine con ID 123 e 186
];
if( array_key_exists( $current_user->ID, $restrictions_map ) ){
$allowed_posts = $restrictions_map[$current_user->ID];
if( $screen->id == 'page' && ! in_array( $current_user->ID, $allowed_posts ) ){
wp_redirect( admin_url( ) );
exit;
}
}
}
add_action( 'pre_get_posts', 'my_pre_get_posts' );

Ho utilizzato User Role Editor
un paio di volte ed è davvero ottimo.
Forse potrebbe esserti utile anche a te.
Ecco il link User Role Editor

Sembra un plugin solido, ma non riesco a trovare un modo per limitare un utente a modificare pagine specifiche.

Rendi gli utenti che vuoi limitare utenti di livello autore Aggiungi la capacità "edit_pages" al livello utente autore (utilizzando User Role Editor) Imposta l'autore di una pagina all'utente a cui vuoi concedere il privilegio di modificarla. Un utente di livello autore a cui viene data la capacità edit_pages può vedere l'elenco delle pagine nella dashboard, ma non ha l'opzione per modificare tranne le pagine di cui è autore.

Grazie, funziona fino a un certo punto. A un certo punto potrei avere la necessità di avere più utenti limitati a modificare una pagina specifica, quindi ci sarebbe bisogno di un modo per impostare più autori per una pagina.

Per limitare gli utenti a pagine specifiche dovrai acquistare la versione Pro. Sto cercando la stessa cosa e l'ho scoperto. http://wordpress.stackexchange.com/questions/191658/allowing-user-to-edit-only-certain-pages/191661#191661?s=f87626a8cf184588bca7c4e397c972a4
