Autoriser Contributeur à changer l'auteur de son propre article?

9

Est-il possible de laisser un contributeur changer l'auteur de ses propres articles? Je me rends compte que cela les enfermera efficacement dans le poste, c'est ce que je veux. Je veux qu'ils puissent changer l'auteur une fois qu'ils ont terminé l'édition.

Michael Rogers
la source
Je me demande simplement s'il existe une autre façon de répondre aux besoins de l'entreprise. Donner à un non-éditeur / administrateur la possibilité d'affecter un autre auteur à son message semble un peu large. Existe-t-il une liste prédéfinie d'auteurs qu'ils peuvent désigner comme «auteur»? Existe-t-il une relation définie entre le contributeur et les auteurs autorisés? Ou peuvent-ils choisir l'auteur de leur choix?
anmari
Je note également que cela ne «publiera» pas leur message. Il semble donc que l'intention soit d'imiter une sorte de flux de travail où le contributeur attribue le message à un auteur plutôt que de dire qu'un éditeur sélectionne les messages `` en attente '' pour révision. Si vos auteurs pourraient être des éditeurs, alors optez peut-être pour wp tel quel et utilisez peut-être plutôt des balises pour communiquer ou mettre en évidence quels éditeurs devraient ramasser quels articles.
anmari
Ah, vous dites "verrouillez-les hors du poste, c'est ce que je veux". Est-ce que c'est plus important? Qu'une fois qu'ils «soumettent pour examen», ils ne sont plus en mesure de modifier? Faut-il jouer avec les «auteurs»? Ou un statut non public fonctionnerait-il? Peut-être en utilisant codex.wordpress.org/Post_Status#Custom_Status
anmari

Réponses:

1

J'ajoute une deuxième réponse parce que ma première approche a été rejetée et que celle-ci n'a pas retenu l'attention.

L'idée est de créer une méta-boîte personnalisée qui répertorie tous les utilisateurs et modifie l'auteur en save_postcrochet. De cette façon, vous ne jouez pas avec les capacités des utilisateurs et le changement d'auteur se produit lorsque les messages sont déjà enregistrés. Le bénéfice supplémentaire est également que vous pouvez contrôler la liste des utilisateurs disponibles dans la liste déroulante des auteurs. Étapes à suivre:

Enregistrer la méta-boîte:

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

Construisez un balisage pour votre 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
 }

Accrochez-vous save_postpour enregistrer les données et remplacer l'auteur:

/**
 * 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');

REMARQUE N'oubliez pas d'ajouter un champ nonce et de le vérifier lors de la sauvegarde. Vous pouvez également envisager d'utiliser d'autres crochets au lieu de save_post, c'est-à-dire pre_post_updateou wp_insert_post_data, pour traiter les données lors de la sauvegarde initiale.

J'espère que cela pourra aider!

Levi Dulstein
la source
1

Pièges:

Même s'il est possible d'autoriser un auteur (ou contributeur) à affecter un autre auteur à son propre article à l'aide du user_has_capfiltre crochet et de certains codes associés, cette approche elle-même est fondamentalement défectueuse . Donc, même si vous prenez toutes les mesures de sécurité nécessaires, c'est toujours une vulnérabilité car elle casse l'architecture des capacités ensemble.

Permettez-moi de vous donner un exemple de scénario: disons qu'un utilisateur avec un rôle d'auteur a une intention moins qu'honorable et spams un autre auteur avec beaucoup de messages (peut-être en utilisant un script). La prochaine fois que l'auteur de la destination se connectera, il verra tous ces messages à son nom! Cela continuera car l'autre auteur n'a aucun moyen de l'arrêter! Nous devons donc trouver une approche alternative qui n'a pas ce défaut.

Une meilleure approche:

Si le changement d'auteur est une fonctionnalité nécessaire, alors une meilleure approche consiste à impliquer l'autre auteur (ou un utilisateur plus puissant comme d'autres éditeurs ou administrateurs) dans le processus de changement d'auteur, de sorte que l'auteur initiateur ne puisse pas spammer le auteur de destination.

Pour ce faire, nous laisserons l'auteur initiateur choisir l'auteur de destination dans l'éditeur, mais nous ne changerons pas directement l'auteur du message. Au lieu de cela, au moment du changement d'auteur, nous enregistrerons une méta de publication personnalisée qui enregistrera l'ID de l'auteur de destination. Ensuite, dans le panneau d'administration, nous aurons un sous-menu de publication, où tous les messages avec la demande de changement d'auteur apparaîtront. Seuls l'auteur de destination et les utilisateurs disposant de edit_others_postcapacités (comme les éditeurs, les administrateurs, etc.) auront accès à cette interface utilisateur de demande de changement d'auteur. À partir de l'interface utilisateur, l'utilisateur disposant d'un accès approprié approuvera la modification et ce n'est qu'alors que la modification finale de l'auteur se produira.

Qu'advient-il des publications dans la file d'attente d'approbation?

L'implémentation de CODE peut varier en fonction de l'exigence, cependant, sans aucune autre implémentation de CODE, les auteurs initiateurs pourront modifier la publication ou même annuler la demande de changement d'auteur dans la fenêtre du processus d'approbation. Ils seront exclus de la publication dès que la demande de changement d'auteur sera approuvée.

Fayaz
la source
0

La liste déroulante de l'auteur ne s'affiche que lorsque l'utilisateur en a la edit_others_postscapacité. Cependant, vous ne voulez pas donner cette capacité aux auteurs par défaut, pour des raisons évidentes. La solution consiste à n'accorder cette capacité que dans des circonstances spécifiques, notamment lorsqu'il modifie l'un de ses propres messages. Étant donné que la capacité est écrite dans la base de données, vous devez également vous assurer qu'elle est supprimée sur toute autre page.

C'est une question de timing précis. Vous souhaitez modifier la capacité une fois que WP a décidé que le contributeur a le droit de modifier le message, mais avant que le formulaire de la page de modification ( post.php) ne soit généré. Un crochet approprié est admin_init.

Comme ça:

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

Je n'ai pas testé le code, il peut donc être bogué, mais vous avez compris.

cjbj
la source
-1

J'ai essayé d'obtenir ce dont vous avez besoin en filtrant les méta-capacités des contributeurs et cela semble bien fonctionner. Tout ce que je fais ici est d'ajouter la edit_others_postscapacité des contributeurs lorsque WordPress le demande.

Cependant, je dirais que c'est une solution un peu hacky pour moi et je ne suis pas sûr que ce soit entièrement sûr. D'après ce que j'ai vérifié après avoir mis mon filtre sur functions.phpWordPress, les contributeurs ne peuvent pas modifier les messages d'autres utilisateurs dans d'autres contextes que celui que vous avez demandé. Cela semble bien, mais nous ne pouvons pas vraiment vérifier explicitement si l'utilisateur actuel est l'auteur du message actuellement édité (vous ne seriez pas en mesure d'enregistrer le message en tant qu'utilisateur différent si ce contrôle conditionnel était ajouté à la fonction) - que m'inquiète.

/**
 * 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 );
Levi Dulstein
la source
2
Veuillez noter que l'octroi de la edit_others_postscapacité aux auteurs leur permettra essentiellement de modifier les publications des autres. Nous pouvons tout aussi bien faire l'auteur à un éditeur, c'est probablement mieux que de leur donner une capacité plus élevée. La deuxième solution est une possibilité, mais a besoin de plus de travail, à mon humble avis.
Scott
J'ai l'impression que le downvote ici n'est pas juste, je souligne en fait les deux choses dans ma réponse en déclarant que la première solution n'est pas sûre et en soulignant que la seconde a besoin de plus de travail, mais je crois que c'est utile car elle montre une solution de travail que l'OP peut s'améliorer (je ne pense pas que répondre à une question sur WPSE devrait signifier fournir des extraits de code prêts pour la production). En outre, il serait utile que vous soyez plus précis et que vous indiquiez ce qui pourrait être amélioré ou même que je modifie mon message si vous voulez dire quelques petits ajustements. À votre santé!
Levi Dulstein
En outre, vous n'avez pas tout à fait raison de edit_others_poststoujours autoriser la modification des publications d'autres utilisateurs. Veuillez tester le code de ma réponse - même avec le filtre en place, la vérification des capacités if ( ! current_user_can( 'edit_post', $post_id ) )dans github.com/WordPress/WordPress/blob/… renvoie toujours false. Encore une fois, je suis d'accord que ce n'est pas la solution sûre comme mentionné dans ma réponse, mais j'ai pensé qu'il valait la peine d'être mentionné car cela fonctionne réellement. (désolé pour deux commentaires d'affilée, je n'ai pas respecté la limite de caractères)
Levi Dulstein
-2

Tout d'abord, installez le plugin User Role Editor ( https://wordpress.org/plugins/user-role-editor/ ).

Deuxièmement, en utilisant le plugin, créez un nouveau rôle appelé Post Manager, par exemple:

entrez la description de l'image ici

Après avoir créé le nouveau rôle, vous pourrez modifier ses capacités. Maintenant, c'est le moment où vous résolvez votre problème, mais vous devez choisir entre deux options:

(ne vous inquiétez pas encore du rôle de contributeur)

Première:

  • Donnez à votre nouveau rôle deux capacités supplémentaires, edit_others_postset publish_posts.
  • De cette façon, votre contributeur ne pourra modifier que les publications qui ne sont pas publiées (uniquement les publications en attente et brouillon). Donc, si le contributeur change simplement l'auteur du message, il pourra toujours modifier le message. Ils ne seront empêchés de modifier le message qu'après l'avoir publié. Cela signifie également que si le contributeur publie le message et oublie de changer l'auteur, il perdra la possibilité de changer l'auteur du message.

Seconde:

  • Donnez votre nouveau rôle juste une capacité supplémentaire, edit_others_posts.
  • Cela fonctionne comme le premier, MAIS ici, votre contributeur ne peut pas publier, ce qui signifie qu'il ne peut pas publier et oublier de changer l'auteur. Ici, quelqu'un devrait publier le message.

Après avoir décidé, cliquez sur "Mettre à jour". Votre nouveau rôle devrait maintenant avoir la readcapacité plus celle que vous avez choisie.

Maintenant, allez sur votre page de profil utilisateur de contributeur , et à la fin de la page, donnez-leur des rôles supplémentaires (fonctionnalité Editeur de rôle utilisateur):

entrez la description de l'image ici

Désormais, chaque utilisateur qui est un contributeur et un gestionnaire de publication pourra changer l'auteur de la publication des publications non publiées. Et selon votre choix précédent, l'utilisateur peut également publier des articles, et s'ils le font, ils ne peuvent plus éditer l'article.

IMPORTANT!!!

Je vous ai montré une solution créant un nouveau rôle pour préserver les capacités par défaut du contributeur. Si vous le souhaitez (pas sage), vous pouvez ignorer la création de Post Manager et en utilisant l'éditeur de rôle utilisateur, vous devez simplement modifier directement les capacités de Contributeur .

Et juste pour mémoire, par défaut, WordPress ne permet que la edit_others_postspossibilité de changer l'auteur du message. Voir https://github.com/WordPress/WordPress/blob/master/wp-admin/includes/class-wp-posts-list-table.php ligne 1483.

filipecsweb
la source
1
cela fait de l'utilisateur un éditeur, pas besoin d'installer de plugins pour cela, il suffit d'utiliser l'administrateur de l'utilisateur. Quoi qu'il en soit, ce n'est pas ce que le PO demande.
Mark Kaplun
Cette solution permet explicitement au contributeur de changer l'auteur du message. Alors, oui, c'est ce qu'il a demandé. Deuxièmement, par défaut, l'éditeur dispose de plus de 20 fonctionnalités. Ma solution ne fait pas du contributeur un éditeur. Que celui qui a demandé décide si ma réponse résout leur problème. S'il vous plaît, réfléchissez bien à votre downvote.
filipecsweb
le PO demande à un contributeur de faire les choses. Votre solution est de le faire rédacteur en chef qui peut changer d'auteurs partout et briser la sécurité
Mark Kaplun