web-dev-qa-db-fra.com

Autoriser le contributeur à changer l'auteur de son propre message?

Est-il possible de laisser un contributeur changer l'auteur de ses propres posts? Je me rends compte que cela les mettra en dehors du poste, c'est ce que je veux. Je veux qu’ils puissent changer d’auteur une fois l’édition terminée.

8
Michael Rogers

Pièges:

Même s'il est possible d'autoriser un auteur (ou un contributeur) à affecter un autre auteur à son propre message en utilisant le crochet de filtre user_has_cap et un code CODE associé, cependant, cette approche est fondamentalement imparfaite . Ainsi, même si vous prenez toutes les mesures de sécurité nécessaires, cela reste une vulnérabilité, car elle casse l’architecture des capacités dans son 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 envoie un spam à 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/elle verra toutes ces publications en 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’ait pas cette faille.

Une meilleure approche:

Si le changement d’auteur est une fonctionnalité nécessaire, il est préférable d’impliquer l’autre auteur (ou un utilisateur plus puissant, comme d’autres éditeurs ou administrateurs) dans le processus de changement d’auteur, afin que l’auteur initiateur ne puisse pas envoyer de spam auteur de destination.

Pour ce faire, nous laisserons l’auteur initiateur choisir l’auteur de destination dans l’éditeur, mais nous ne changerons pas le post-auteur directement. Au lieu de cela, au moment du changement d'auteur, nous enregistrerons une méta de publication personnalisée qui sauvegardera l'identifiant de l'auteur de destination. Ensuite, dans le panneau d'administration, nous aurons un sous-menu de publication dans lequel toutes les publications contenant la demande de modification de l'auteur apparaîtront. Seul l'auteur de destination et les utilisateurs dotés de la capacité edit_others_post (tels que les éditeurs, les administrateurs, etc.) auront accès à cette interface de demande de modification d'auteur. À partir de l'interface utilisateur, l'utilisateur disposant d'un accès approprié approuvera le changement, puis le changement de l'auteur final se produira.

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

La mise en œuvre de CODE peut varier en fonction des besoins. Toutefois, sans aucune autre implémentation de CODE, les auteurs initiateurs seront en mesure de modifier la publication, voire d'annuler la demande de changement d'auteur dans la fenêtre du processus d'approbation. Ils seront verrouillés dès que la demande de changement d’auteur aura été approuvée.

Exemple de code

Remarque: Cette réponse est un travail en cours. J'ajouterai l'exemple de code plus tard.

2
Fayaz

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 crochet save_post. De cette façon, vous ne jouez pas avec les capacités des utilisateurs et le changement d’auteur se produit lorsque les publications sont déjà enregistrées. 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
 }

Accédez à save_post pour 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');

NOTEN'oubliez pas d'ajouter un champ nonce et de le vérifier après l'enregistrement. Vous pouvez également envisager d’utiliser d’autres hooks au lieu de save_post, c’est-à-dire pre_post_update ou wp_insert_post_data, pour traiter les données lors de la sauvegarde initiale.

J'espère que cela pourra aider!

1
Levi Dulstein

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

C'est une question de timing précis. Vous souhaitez modifier la capacité après que WP ait décidé que le contributeur a le droit de modifier le message, mais before le formulaire de la page de modification (post.php) est 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, alors c'est peut-être un buggy, mais vous voyez l'idée.

0
cjbj