We apologize for untranslated text, you can use the Google Translation button to get an automatic translation of the web page in the language of your choice.

Profils de consultation (Audiencement)

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.

Quelques remarques importantes avant de définir les axes :
  • 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

  • Hiérarchie : Dirigeant
  • Métiers : Tous métiers
  • Géographie : Monde

John Smith

  • Hiérarchie : Cadre
  • Métiers : Ressources Humaines
  • Géographie : Angleterre

Yamada Taro

  • Hiérarchie : Employé
     
  • Métiers : Recherche et développement
  • Géographie : Kyoto

Wúmíng Shì

  • Hiérarchie : Ouvrier
  • Métiers : Production
  • Géographie : Taipei

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.

Edition d'un type de contenu : activation du profil de consultation

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é
- Hiérarchie : Ouvrier
- Métiers : R&D
- Métiers : Production
- Géographie : Asie

- Yamada Taro (Employé, R&D, Kyoto)
- Wúmíng Shì (Ouvrier, Production,Taipei)

Plan de restructuration

- Hiérarchie : Dirigeant
- Métiers : RH
- Géographie : Paris

- Jean Dupont (Dirigeant, Tous les métiers, Monde)

Evolutions du prix ...

- Hiérarchie : Dirigeant
- Métiers : Tous les métiers
- Géographie : Monde

- Jean Dupont (Dirigeant, Tous les métiers, Monde)
- John Smith (rédacteur du contenu)

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é.

In brief...

Le mécanisme originel de gestion du profiling de JCMS s'appuie sur les droits d'accès qui diffusent l'information aux utilisateurs selon les groupes auxquels ils appartiennent. Ce système atteind ses limites dans le cas d'organisations très complexes. Pour faire face à ce besoin, JCMS propose les profils de consultation. Cet article décrit leurs principes et leurs mises en oeuvre.

Subject
Published

5/23/06

Writer
  • Olivier Jaquemet