web-dev-qa-db-fra.com

Puis-je créer des utilisateurs qui ont accès à * certains * messages d'autres utilisateurs au lieu de tous les autres messages d'utilisateurs?

J'utilise depuis quelques temps la fonctionnalité de droits d'utilisateur de base sur un site multi-utilisateurs WP et tout s'est très bien déroulé. La plupart des comptes d'utilisateurs ont juste accès à leurs propres messages, mais quelques éditeurs en ont accès. à tous les messages. Ceci a été assisté par le plugin wp-front qui vous permet de définir facilement les rôles des utilisateurs.

Cependant, j'ai maintenant un scénario dans lequel j'ai besoin de plusieurs auteurs dans la même société externe et d'un éditeur également dans la société qui supervisera le travail des autres individus.

Ce nouveau rôle d’éditeur à distance est nouveau et problématique, car ils auraient besoin de pouvoir voir leurs propres publications, ainsi que toutes les publications créées par d’autres éditeurs de la même société. Ils ne doivent cependant pas pouvoir voir les messages de tout le monde.

Est-ce possible avec wp-front ou tout autre plugin ou simplement avec une solution faite à la main en dehors des plugins?

Idéalement, une solution fonctionnerait en ajoutant des collections d'utilisateurs à des groupes, mais cela ne serait pas nécessaire.

2
AdamJones

Voici mon approche. N'oubliez pas qu'il couvre les besoins de base que vous avez décrits, mais qu'il pourrait facilement être étendu à une solution plus robuste. Quelques étapes à suivre (tout le code va à votre functions.php):

1. Enregistrer le nom de la société en tant que méta de l'utilisateur

La première chose à faire est d’attribuer un nom de société à un utilisateur - j’aimerais utiliser méta utilisateur pour atteindre cet objectif. Vous pouvez ajouter un metabox pour modifier l'écran de l'utilisateur afin de faciliter sa gestion. Je n'inclus pas le code correspondant à cela, mais je suis sûr que vous avez compris l'idée.

Pour tester, vous pouvez simplement ajouter une méta à l'utilisateur avec update_user_meta( $user_id, 'company', 'Tyrell Corporation' ); ( codex )

Donc, dans cet exemple, je suppose que nous avons un groupe d’auteurs avec Tyrell Corporation défini comme clé de méta utilisateur company et éditeur avec exactement la même méta.

2. Ajouter la méta de la société aux publications en fonction de la méta de l'utilisateur

Pour rendre les choses plus faciles et moins chères, je garderais la référence au nom de la société également dans chaque message sauvegardé par n'importe quel auteur auquel la société a été assignée (de cette façon, nous pouvons supprimer au moins une requête à la méta-table des auteurs à chaque vérification de l'éditeur droits pour éditer le post plus tard). Pour ce faire, j'utilise save_posthook :

function save_company_meta( $post_id, $post, $update ) {
    // get author's company meta
    $company = get_user_meta( $post->post_author, 'company', true );

    if ( ! empty( $author_id ) ) {
        // add meta data to the post
        update_post_meta( $post_id, 'company', true );
    }
}

add_action( 'save_post', 'save_company_meta', 10, 3 );

Désormais, chaque fois qu'un utilisateur enregistre son brouillon, le nom de société attribué à cet utilisateur est copié dans le méta de publication.

3. Fonction edit_post de l'éditeur de carte

Enfin, nous pouvons simplement map la capacité 'edit_post' de l'éditeur. Si les méta-données company du message sont différentes des méta-utilisateurs company de l'éditeur, nous supprimons la possibilité de modifier ce message particulier de l'éditeur en question. Il existe certaines conditions supplémentaires dans le code ci-dessous. Par exemple, nous n'appliquons aucune restriction si la publication ne contient pas de méta company ou si elle n'est pas du type publication post. Vous pouvez adapter cela à vos besoins:

function restrict_access_to_company_posts( $caps, $cap, $user_id, $args ) {

    /*
    We're messing with capabilities only if 'edit_post' 
    is currently checked and the current user has editor role
    but is not the administrator
    */

    if ( ! in_array( $cap, [ 'edit_post' ], true ) ) {
        return $caps;
    }

    if ( ! user_can( $user_id, 'editor' ) || user_can( $user_id, 'administrator' ) ) {
        return $caps;
    }

    /*
    $args[0] holds post ID. $args var is a bit enigmatic, it contains
    different stuff depending on the context and there's almost 
    no documentation on that, you've got to trust me on this one :)
    Anyways, if no post ID is set, we bail out and return default capabilities
    */
    if ( empty( $args[0] ) ) {
        return $caps;
    }

    /*
    You can also make sure that you're restricting access 
    to posts only and not pages or other post types
    */
    if ( 'post' !== get_post_type( $args[0] ) ) {
        return $caps;
    }

    $post_company   = get_post_meta( $args[0], 'company', true );
    $editor_company = get_user_meta( $user_id, 'company', true );

    /*
    if no meta data is set or editor is assigned 
    to the same company as the post, we allow normal editing
    */
    if ( empty( $post_company ) || $post_company === $editor_company ) {
        return $caps;
    }

    // finally, in all other cases, we restrict access to this post
    $caps = [ 'do_not_allow' ];

    return $caps;
}

Cela ne cacherait pas complètement les messages de l'interface utilisateur d'administration, vous pouvez toujours les voir sur la liste, mais l'éditeur ne peut pas accéder à l'écran d'édition de l'article et le modifier, ni voir le brouillon (WordPress supprimera automatiquement tous les liens "d'édition" pour vous, également dans la barre d'administration sur le front-end). Une fois l'article publié, l'éditeur ne serait toujours pas en mesure de modifier le contenu de l'article.

4. (Optionaly) Supprimer complètement les messages de la liste des administrateurs

Si ce qui précède ne suffit toujours pas, vous pouvez également vous connecter à pre_get_posts ( codex ) pour masquer complètement les messages de la liste d'administration:

function query_company_posts_only( $query ) {

    if ( ! is_admin() || empty( get_current_user_id() ) ) {
        return $query;
    }

    $editor_company = get_user_meta( get_current_user_id(), 'company', true );

    if ( empty( $editor_company ) ) {
        return $query;
    }

    $query->set( 'meta_key', 'company' );
    $query->set( 'meta_value', $editor_company );
}

add_action( 'pre_get_posts', 'query_company_posts_only', 10, 1 );

J'espère que cela fera l'affaire, il suffit de jouer avec et d'ajouter quelques améliorations ici et là.

4
Levi Dulstein