Pour filtrer la visibilité des publications, JCMS dispose d'un système de droits de consultation qui permet de définir à la contribution l'ensemble des groupes et des utilisateurs autorisés à consulter la publication.
Si ce système convient pour les cas d'usage courant ; il peut atteindre ses limites au sein d'organisation très complexes car on se voit confronté à la création d'un nombre très important de groupes.
Pour faire face à ces besoins, JCMS propose les profils de consultation, parfois appelé audiencement (disponible depuis JCMS 5.5).
1. Principes
Le principe de l'audiencement consiste à déduire les droits de consultation en croisant les catégories d’un contenu et les catégories du membre qui cherche à accéder à ce contenu. Pour cela, tous les membres doivent être catégorisés sur les mêmes axes d'audiencement que les contenus. Les rédacteurs n'ont plus à déclarer explicitement les droits de consultations mais simplement à quelles catégories sont rattachés les contenus.
Une ou plusieurs branches de catégories sont définies comme axes du profil. Chaque axe représente une dimension des contenus et des utilisateurs (métier, hiérarchie, zone géographique, …). Un contenu n’est alors visible par un membre que si une des conditions suivantes est remplie :
- L'audience coincide pour tous les axes : c'est à dire que pour chaque axe, la catégorie d'un membre est un ancêtre ou un descendant direct de la catégorie selectionnée dans le contenu (ou la même catégorie que le contenu).
- Le membre est le rédacteur du contenu.
Prenons l'exemple d'un site où les profils de consultation sont gérés avec un seul axe Géographie. En rattachant un contenu à la catégorie Angleterre, ce contenu sera visible uniquement des membres qui ont au moins une catégorie cochée "au dessus" ou "en dessous" d'Angleterre (ou Angleterre elle même). Ainsi, un membre rattaché à la catégorie Monde, Angleterre ou Londres pourra consulter ce contenu ; mais un membre rattaché uniquement à la catégorie France ne pourra pas le voir.
Visibilité d'un contenu suivant la catégorie selectionnée.
Un membre qui n'a pas au moins une catégorie de cochée dans chacun des axes ne verra aucune publication utilisant les profils de consultations. Cette particularité peut être exploitée pour restreindre l'accès aux publications profilées pour un ensemble de membre bien déterminé.
2. Mise en oeuvre
2.1 Définition des axes
La première étape dans la mise en place des profils de consultation dans JCMS, est de définir les branches de catégories qui seront utilisées pour profiler les publications et les membres.
Voici les catégories que nous utiliserons pour les exemples de cet article. Un fichier joint à la fin de cet article permet d'importer rapidement ces branches de catégories dans un site JCMS.
- Il est souhaitable d'ajouter une catégorie de premier niveau "Tous" sous chacun des axes, pour rapidement cibler l'ensemble des profils de cet axe.
- Les hiérarchies d'entreprise ne doivent pas être réprésentées sous forme arborescente. En effet, en plaçant une catégorie Cadre sous la catégorie Dirigeant, toutes publications avec la catégorie Dirigeant seraient visibles par les membres ayant la catégorie Cadre dans leur profil de consultation.
Une fois ces catégories définies dans JCMS, allez dans Espace d'Administration > Configuration. Dans l'onglet Utilisateurs, activez les profils de consultation et selectionnez les axes Hierarchie, Métiers et Géographie. Attention ! si aucun axe n'est défini, les droits par profils de consultations sont alors automatiquement désactivés.
Activation des profils de consultation.
2.2 Profils de consultation des membres
La seconde étape consiste à remplir le profil de consultation de chaque membre en cochant les catégories qui le caratérisent pour chaque axe.
Edition du profil de consultation d'un membre.
Pour notre exemple, nous créons 5 membres avec les profils suivants :
Nom | Profil de consultation |
---|---|
Jean Dupont |
|
John Smith |
|
Yamada Taro |
|
Wúmíng Shì |
|
Paul Martin |
Aucun profiles |
2.3 Profils de consultation des publications
2.3.1 Activer les profils de consultation d'un type de contenu
Par défaut, pour que les profils de consultation soient utilisés pour une publication, il faut activer cette option dans l'édition de ce type de contenu, dans l'onglet Propriétés.
Pour notre exemple, nos activons les profils de consultations pour les publications de type Brève.
2.3.2 Saisir le profil de consultation d'une publication
Lors de la création d'un contenu profilé, il est impératif de saisir au moins une catégorie dans chacun des axes de profil de consultation pour qu'elle soit visible par les membres profilés. Aussi, il est recommandé de créer dans le type autant de champs catégories obligatoires qu'il y a d'axes.
Pour notre exemple, trois champs catégories correspondant aux axes Hiérarchie, Métiers et Géographie ont été ajoutés au type Brève et regroupés dans l'onglet Profils de consutlation.
Selection des catégories d'audiencement d'un contenu.
2.3.3 Gérer les publications profilées
Lorsque les profils de consultation sont activés, une nouvelle colonne apparait dans le gestionnaire de contenus. L'icone cible indique les publications profilées. En laissant la souris sur l'icône, on obtient les catégories sélectionnées pour son profil de consultation.
Les profils de consultation dans le gestionnaire de contenus
Pour notre exemple, trois brèves (profilées) et un article (non profilé) ont été créés.
2.4 Résultats
Le tableau ci-dessous récapitule pour chaque publication quels membres peuvent la consulter.
Contenu | Profil de consultation | Visible par |
---|---|---|
Note Technique... |
- Hiérarchie : Employé |
- Yamada Taro (Employé, R&D, Kyoto) |
Plan de restructuration |
- Hiérarchie : Dirigeant |
- Jean Dupont (Dirigeant, Tous les métiers, Monde) |
Evolutions du prix ... |
- Hiérarchie : Dirigeant |
- Jean Dupont (Dirigeant, Tous les métiers, Monde) |
Message d'accueil |
Aucun |
Tous le monde |
Avec la multiplication du nombre de contenu et la multiplication des critéres de visualisation, réaliser des croisements similaires en utilisant les groupes aurait été fastidieux.
3. Personnalisation
3.1 Introduction
Si vous souhaitez utiliser un autre critère pour déterminer quelles publications doivent utiliser les profils de consultation, vous devez personnaliser la méthode isAudienced(Publication)
de la classe custom.RightPolicy
.
L'implémentation par défaut est la suivante :
public static boolean isAudienced(Publication pub) { return pub instanceof AudiencedPublication; }
Attention! quelque soit la personnalisation mise en oeuvre, cette méthode étant appelée très fréquement dans JCMS, il faut veiller à optimiser l'implémentation au maximum pour éviter tout problème de performance.
3.2 Exemple
Nous allons modifier cette méthode pour activer le profil de consultation d'une publication uniquement si l'ensemble des axes de profil de consultation de la publication ont été remplis.
Le code source de cet exemple est fourni à la fin de cet article.
Pour des raisons de performances, il est nécessaire de réaliser ce calcul préalablement à l'appel de la méthode isAudienced()
et de mettre en cache le résultat. Nous utiliserons les ExtraInfos
fourni par la classe Data
de jcms, ces extra informations permettent de stocker de manière non persistante (transient) des informations associées à la données.
Pour cela, nous créons un AudiencedPublicationListener
qui se charge de vérifier les publications lors de leur création et lors de leur mise à jour.
package custom; [...] public class AudiencedPublicationListener implements StoreListener { private static final Logger logger = Logger.getLogger(AudiencedPublicationListener.class); /** * Key of the attribute we store in the Publication's extraInfo to cache a Boolean * to know if the publication has been declared audienced or not. */ public static final String PUBLICATION_AUDIENCED_EXTRAINFO_KEY = "ExtraInfo.isAudienced"; Channel channel = Channel.getChannel(); AudienceRights ar = AudienceRights.getInstance(); public void handleCreate(Storable storable, boolean firstTime) { if (ar.isEnabled() && storable instanceof Publication) { checkPublication((Publication) storable); } } public void handleCommitUpdate(Storable storable, Storable oldStorable, boolean firstTime) { if (ar.isEnabled() && storable instanceof Publication) { checkPublication((Publication) storable); } } [...] /** * Check if the given publication is audienced by checking its categories, * cache the result in the publiction's extra info. */ public void checkPublication(Publication pub) { boolean pubIsAudienced = true; // Iterate on all AudienceRight axes List axesList = ar.getCategoriesAxesList(); for (Iterator it = axesList.iterator(); it.hasNext();) { Category axeCat = (Category) it.next(); // Iterate on all publication's categories and check there is // at least one category descendant of the axe boolean pubHasAxeCat = false; Category[] categories = pub.getCategories(); for (int i = 0; categories != null && i < categories.length; i++) { Category pubCat = categories[i]; if (axeCat.containsDescendant(pubCat)) { pubHasAxeCat = true; break; } } // Publication has no selected category in this axe, end verification here. if (!pubHasAxeCat) { pubIsAudienced = false; break; } } if (logger.isDebugEnabled() && pubIsAudienced) { logger.debug(pub + " is audienced"); } pub.setExtraInfo(PUBLICATION_AUDIENCED_EXTRAINFO_KEY, Boolean.valueOf(pubIsAudienced)); } [...] }
Nous utilisons le singleton fourni par la classe AudienceRights
pour récuperer la liste des axes.
Ce singleton AudienceRights
ayant besoin d'etre initialisé apres le chargement des catégories, nous initialisons le AudiencedPublicationListener après le chargement du Store.
Cette initialisation se fait dans la classe custom.JcmsInit
:
package custom; [...] public class JcmsInit { [...] public static void initAfterStoreLoad() throws Exception { [...] initCustomAudienceRight(); } /** * Initialize custom audience right checks. */ public static void initCustomAudienceRight() { Channel channel = Channel.getChannel(); AudiencedPublicationListener apl = new AudiencedPublicationListener(); channel.addStoreListener(apl, Publication.class, true); } [...] }
Le listener n'étant pas appelé durant la phase de chargement du Store, il nous faut donc parcourir la liste des Publications apres le chargement pour effectuer le calcul sur l'ensemble des Publications.
Pour cela, nous ajoutons la méthode checkAllPublication()
dans le listener et nous l'invoquons dans le constructeur :
public class AudiencedPublicationListener implements StoreListener { [...] public AudiencedPublicationListener() { checkAllPublication(); } /** * Method to be called after store load (and therefore after audience right * has been properly loaded) to iterate on all publication and check their status. */ public void checkAllPublication() { if (!ar.isEnabled()) { return; } Set publicationSet = channel.getDataSet(Publication.class); for (Iterator it = publicationSet.iterator(); it.hasNext();) { Publication pub = (Publication) it.next(); checkPublication(pub); } } [...] }
Il ne nous reste plus qu'a modifier la classe custom.RightPolicy
pour récupérer le calcul dans les ExtraInfo
:
public static boolean isAudienced(Publication pub) { Object extraInfo = pub.getExtraInfo(AudiencedPublicationListener.PUBLICATION_AUDIENCED_EXTRAINFO_KEY); return Util.toBoolean(extraInfo, false); }
Limites
L'utilisation de l'audiencement est possible uniquement pour les publications JStore.Les publications stockées dans JcmsDB (en base de donnée) ne bénéficient pas de cette fonctionnalité.