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.
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
):
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.
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_post
hook :
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.
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.
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à.