È possibile consentire a un collaboratore di modificare l'autore dei propri post? Mi rendo conto che questo li bloccherà efficacemente, è quello che voglio. Voglio che siano in grado di cambiare l'autore una volta terminata la modifica.
È possibile consentire a un collaboratore di modificare l'autore dei propri post? Mi rendo conto che questo li bloccherà efficacemente, è quello che voglio. Voglio che siano in grado di cambiare l'autore una volta terminata la modifica.
Risposte:
Sto aggiungendo una seconda risposta perché il mio primo approccio è stato votato verso il basso e questo non ha ricevuto la giusta attenzione.
L'idea è quella di creare una meta-box personalizzata che elenchi tutti gli utenti e cambi l'autore save_post
all'amo. In questo modo non si scherza con le funzionalità degli utenti e la modifica dell'autore avviene quando i post sono già stati salvati. Inoltre, il profitto aggiuntivo è che puoi controllare l'elenco degli utenti disponibili nel menu a discesa dell'autore. Passaggi da seguire:
Registra meta box:
function wpse313020_add_custom_box() {
// Bail out for users other than contributors
if ( ! user_can( get_current_user_id(), 'contributor' ) ) {
return;
}
// Register custom meta box
add_meta_box(
'wpse313020_author_override',
'Change Author', // metabox title
'wpse313020_author_ovveride_box_html', // callbac function
'post' // a post type you want to show the metabox on
);
}
add_action('add_meta_boxes', 'wpse313020_add_custom_box');
Crea markup per la tua meta-box:
/**
* HTML for custom meta box
*/
function wpse313020_author_ovveride_box_html() {
// you can modify the list of users by passing additional args to get_users()
$users = get_users();
?>
<label for="wpse313020_author_override_id">Select post author</label><br />
<select name="wpse313020_author_override_id" id="wpse313020_author_override_id" class="postbox">
<option value="">Select user...</option>
<?php
// get post ID on admin edit screen and retrieve saved post meta
$post_id = is_admin() && isset( $_GET['post'] ) ? absint( wp_unslash( $_GET['post'] ) ) : '';
$saved_value = ! empty( $post_id ) ? get_post_meta( $post_id, 'wpse313020_author_override', true ) : '';
foreach ( $users as $user ) {
echo sprintf( '<option value="%1$d" %2$s>%3$s</option>', absint( $user->ID ), selected( $saved_value, absint($user->ID, false ) ), esc_html( $user->display_name ) );
}
?>
</select>
<?php
}
Aggancia save_post
per salvare i dati e sovrascrivere l'autore:
/**
* Save custom post meta and override the post author
*/
function wpse313020_save_postdata( $post_id ) {
if ( array_key_exists('wpse313020_author_override_id', $_POST ) ) {
// save post meta with author ID
update_post_meta( $post_id, 'wpse313020_author_override', absint( $_POST['wpse313020_author_override_id'] ) );
// now modify the post author, we need to unhook the current function to prevent infinite loop
// you could add additional check here to see if the current author is not the same as chosen author
remove_action( 'save_post', 'wpse313020_save_postdata' );
$updated_data = [
'ID' => $post_id,
'post_author' => absint( $_POST['wpse313020_author_override_id'] ),
];
wp_update_post( $updated_data );
add_action( 'save_post', 'wpse313020_save_postdata' );
}
}
add_action('save_post', 'wpse313020_save_postdata');
NOTA
Ricordarsi di aggiungere un campo nonce e selezionarlo dopo il salvataggio. Inoltre, potresti prendere in considerazione l'utilizzo di altri hook anziché save_post
, ad esempio pre_post_update
o wp_insert_post_data
, per elaborare i dati sul salvataggio iniziale dei post.
Spero che aiuti!
Anche se è possibile consentire a un autore (o collaboratore) di assegnare un altro autore al proprio post usando il user_has_cap
hook di filtro e alcuni CODICI correlati, tuttavia, questo approccio stesso è fondamentalmente imperfetto . Quindi, anche se si adottano tutte le misure di sicurezza necessarie, è comunque una vulnerabilità perché interrompe l'architettura delle capacità tutti insieme.
Permettetemi di darvi uno scenario esemplificativo: supponiamo che un utente con ruolo di autore abbia un intento inferiore all'onore e spamera un altro autore con molti post (magari usando uno script). La prossima volta che l'autore della destinazione accederà, vedrà tutti quei post a suo nome! Questo continuerà poiché l'altro autore non ha modo di fermarlo! Quindi dobbiamo trovare un approccio alternativo che non abbia questo difetto.
Se la modifica dell'autore è una funzionalità necessaria, un approccio migliore consiste nel coinvolgere l'altro autore (o un utente più potente come altri editor o amministratori) nel processo di modifica dell'autore, in modo tale che l'autore che ha avviato la procedura potrebbe non essere in grado di inviare spam autore di destinazione.
A tal fine, lasceremo all'autore che ha avviato la scelta l'autore di destinazione dall'editor, ma non cambieremo l'autore del post in modo diretto. Invece, al momento della modifica dell'autore, salveremo una meta post personalizzata che salverà l'ID autore di destinazione. Quindi, nel pannello di amministrazione, avremo un sottomenu di post, in cui verranno visualizzati tutti i post con la richiesta di modifica dell'autore. Solo l'autore di destinazione e gli utenti con edit_others_post
funzionalità (come editor, amministratori, ecc.) Avranno accesso all'interfaccia utente della richiesta di modifica dell'autore. Dall'interfaccia utente, l'utente con accesso adeguato approverà la modifica e solo allora avverrà la modifica dell'autore finale.
L'implementazione del CODICE può variare a seconda del requisito, tuttavia, senza altre implementazioni del CODICE, gli autori iniziatori saranno in grado di modificare il post o persino di invertire la richiesta di modifica dell'autore all'interno della finestra del processo di approvazione. Saranno bloccati fuori dal post non appena verrà approvata la richiesta di modifica dell'autore.
La casella a discesa dell'autore verrà visualizzata solo quando l'utente ha iledit_others_posts
possibilità. Tuttavia, non si desidera dare questa funzionalità agli autori per impostazione predefinita, per ovvie ragioni. La soluzione è quella di dare questa capacità solo in circostanze specifiche, vale a dire quando sta modificando uno dei suoi post. Poiché la funzionalità è scritta nel database, è necessario assicurarsi anche che sia rimosso su qualsiasi altra pagina.
Questa è una questione di tempismo preciso. Si desidera modificare la funzionalità dopo che WP ha deciso che il contributore ha il diritto di modificare il post, ma prima chepost.php
venga generato il modulo della pagina di modifica ( ). Un gancio adatto è admin_init
.
Come questo:
add_action ('admin_init', 'wpse313020_change_author');
function wpse313020_change_author () {
global $pagenow;
$current_user = wp_get_current_user();
// only do this if current user is contributor
if ('contributor' == $current_user->roles[0]) {
// add capability when we're editing a post, remove it when we're not
if ('post.php' == $pagenow)
$current_user->add_cap('edit_others_posts')
else
$current_user->remove_cap('edit_others_posts');
}
}
Non ho testato il codice, quindi potrebbe essere difettoso, ma hai capito.
Ho cercato di ottenere ciò di cui hai bisogno filtrando le meta funzionalità del contributore e sembra funzionare bene. Tutto quello che faccio qui è aggiungere la edit_others_posts
capacità per i collaboratori quando WordPress lo richiede.
Tuttavia, direi che è una soluzione un po 'confusa per me e non sono sicuro che sia del tutto sicuro. Da quello che ho controllato dopo aver messo il mio filtro su functions.php
WordPress non consente ai collaboratori di modificare i post di altri utenti in altri contesti rispetto a quello che hai richiesto. Sembra a posto, ma non possiamo davvero verificare esplicitamente se l'utente corrente è l'autore del post attualmente modificato (non saresti in grado di salvare il post come utente diverso se quel controllo condizionale fosse aggiunto alla funzione) - che mi preoccupa.
/**
* author_cap_filter()
*
* Filter on the current_user_can() function.
* This function is used to explicitly allow contributors to change post authors
*
* @param array $allcaps All the capabilities of the user
* @param array $cap [0] Required capability
* @param array $args [0] Requested capability
* [1] User ID
*/
function author_cap_filter( $allcaps, $cap, $args ) {
// Bail out if we're not dealing with right capability:
if ( ! in_array( $args[0], [ 'edit_others_posts' ] ) ) {
return $allcaps;
}
// Bail out for users who are not contributors
if ( ! user_can( $args[1], 'contributor' ) ) {
return $allcaps;
}
// Bail out for users who can already edit others posts:
if ( isset( $allcaps['edit_others_posts'] ) && $allcaps['edit_others_posts'] ) {
return $allcaps;
}
// overwrite 'edit_others_posts' capability
$allcaps[ $args[0] ] = true;
return $allcaps;
}
add_filter( 'user_has_cap', 'author_cap_filter', 100, 3 );
edit_others_posts
possibilità essenzialmente consentirà loro di modificare i post degli altri. Possiamo anche rendere l'autore un editore, probabilmente è meglio che dare loro una capacità superiore. La seconda soluzione è una possibilità, ma ha bisogno di più lavoro, IMHO.
edit_others_posts
consentire sempre la modifica dei post di altri utenti. Si prega di testare il codice dalla mia risposta - anche con il filtro in atto, il controllo della capacità if ( ! current_user_can( 'edit_post', $post_id ) )
in github.com/WordPress/WordPress/blob/… restituisce comunque false. Ancora una volta, concordo sul fatto che non è la soluzione sicura come indicato nella mia risposta, ma ho pensato che valesse la pena menzionarlo poiché funziona davvero. (scusate per due commenti di seguito, non ho adattato il limite del carattere)
Prima di tutto, installa il plugin User Role Editor ( https://wordpress.org/plugins/user-role-editor/ ).
In secondo luogo, utilizzando il plug-in creare un nuovo ruolo chiamato Post Manager, ad esempio:
Dopo aver creato il nuovo ruolo, sarai in grado di modificarne le capacità. Ora, è il momento in cui risolvi il problema, ma devi decidere tra due opzioni:
(non preoccuparti ancora del ruolo del collaboratore)
Primo:
edit_others_posts
e publish_posts
.Secondo:
edit_others_posts
.Dopo aver deciso, fai clic su "Aggiorna". Il tuo nuovo ruolo dovrebbe ora avere la read
capacità più quella che hai scelto.
Ora vai alla pagina del profilo utente del contributore e alla fine della pagina assegna loro ruoli aggiuntivi (funzionalità Editor ruoli utente):
Ora, ogni utente che è un Collaboratore e un Post Manager sarà in grado di modificare l'autore del post di post non pubblicati. E a seconda della tua scelta precedente, l'utente può anche pubblicare post e, in tal caso, non possono più modificare il post.
IMPORTANTE!!!
Ti ho mostrato una soluzione che crea un nuovo ruolo per preservare le funzionalità predefinite del Collaboratore. Se lo desideri (non saggio), puoi saltare la creazione di Post Manager e usando l'editor dei ruoli utente dovresti semplicemente modificare direttamente le funzionalità di Contributor .
E solo per la cronaca, per impostazione predefinita WordPress consente solo la edit_others_posts
possibilità di modificare l'autore del post. Vedi https://github.com/WordPress/WordPress/blob/master/wp-admin/includes/class-wp-posts-list-table.php linea 1483.