Modifié par Aurelie Bertrand le 2026/04/28 09:37

Afficher les derniers auteurs
1
2
3 {{ddtoc/}}
4
5 ----
6
7 (% class="wikigeneratedid" id="HPrE9ambule" %)
8 Ce guide présente les méthodes de sécurisation des informations contenues dans les cubes de données. Ceci est généralement appelé Sécurité au niveau ligne (« Row Level Security »). Nous appelons aussi cela la "personnalisation" des cubes et des flux.
9
10 (% class="wikigeneratedid" %)
11 Il présente un aperçu des méthodes classiques de personnalisation avec l’utilisation de variables utilisateur, puis introduit une approche plus puissante et flexible : le** **Live Security, une personnalisation dynamique basée sur des scripts.
12
13 (% class="box" %)
14 (((
15 💡 Consultez la page [[Live Security : exemples d'utilisation>>doc:.Live Security \: exemples.WebHome]] pour des exemples d'utilisation détaillés.
16 )))
17
18 = Sécurisation via la personnalisation =
19
20 La sécurité au niveau ligne peut s'effectuer par la personnalisation des cubes ou la personnalisation des flux à l'aide de variables utilisateur (**${user.<nomvariable>}**).
21
22 == Personnalisation au niveau du modèle de données (cube) ==
23
24 La sécurité au niveau ligne est résolue à la génération du cube de données via l’utilisation de variables utilisateur (**${user.<nomvariable>}**) dans la définition de la source de données et du modèle de données. Par exemple en SQL : SELECT * FROM UneTable WHERE pays='${user.pays}' AND service in '${user.services}'.
25
26 Dans cet exemple, chaque utilisateur a une variable //pays// égale à son pays, et une variable //services// qui est une liste de noms de services séparés par des virgules (Marketing,Ventes,Logistique) auquel l’utilisateur à le droit d’accès.
27
28 Ainsi, pour chaque utilisateur, DigDash génère un cube différent (un par combinaison des valeurs des variables) ne contenant que les données correspondant au « profil de personnalisation » de chaque utilisateur. Si plusieurs utilisateurs ont les mêmes valeurs pour ces variables, on dit qu’ils ont le même profil, alors ils partagent le même cube.
29
30 Ce mécanisme est très simple à mettre en place, et permet en général de segmenter la volumétrie des données, et donc la charge mémoire du serveur lors de la consultation. En effet, les utilisateurs se connectent rarement tous en même temps sur le serveur, celui-ci n’aura pas besoin de stocker tous les cubes en mémoire à chaque instant.
31
32 Un autre avantage est que selon le type de la source de données, la règle de sécurisation peut être très avancée. Notre exemple simple de filtrage sur deux colonnes //pays// et //services// peut prendre en compte d’autres critères, provenir d’autres tables (qu’on ne souhaite pas intégrer au cube), etc.
33
34 Par contre, ce mécanisme multiplie le nombre de cubes à générer et donc le nombre de requêtes vers la source de données.
35
36 Enfin la règle de sécurisation peut engendrer une redondance de données entre différents cubes, représentant la partie commune des données que plusieurs utilisateurs peuvent voir, même s'ils ne partagent pas exactement le même profil. Cette partie commune est dupliquée dans plusieurs cubes.
37
38 * **Avantages **: Sécurisation forte, simplicité de mise en œuvre, grande flexibilité (la complexité de sécurisation est dépendante des capacités de la source de données).
39 * **Inconvénients **: Plus de requêtes pour la génération des cubes, risque de redondance de données dans plusieurs cubes.
40
41 [[image:live_security_fr_html_6eaa6052687470b4.gif||queryString="width=391&height=395" data-xwiki-image-style-alignment="center" height="395" width="391"]]
42
43
44 == Personnalisation au niveau des flux (graphique/tableau) ==
45
46 Une autre approche plus dynamique est d’utiliser ces variables utilisateur dans la valeur de filtres sur chaque graphique exploitant le cube. Pour reprendre l’exemple précédent, le cube prend ses données d’une source SQL : SELECT * FROM UneTable. Il est unique (non personnalisé) pour tous les utilisateurs, donc volumineux. Dans tous les flux utilisant ce cube on peut ajouter un filtre sur la dimension Pays (règle //« égal à »// ${user.pays}) et sur la dimension Service (règle //« est contenu dans » //${user.services}) . A chaque affichage d’un flux le filtre sera appliqué sur le cube de données pour ne conserver que les lignes auxquelles l’utilisateur a accès. Bien sûr la navigation sur ces dimensions doit être interdite pour l’utilisateur afin qu'il soit contraint dans ce périmètre.
47
48 L’avantage est qu’on a qu’un seul cube à générer, donc une seule requête vers la source de données.
49
50 Par contre, le filtrage étant commandé par les flux eux-mêmes lors de la consultation des tableaux de bord, il y a un risque de permettre à des utilisateurs d’accéder à des données qui ne les concernent pas. Soit à cause d’un défaut de conception des pages du tableaux de bord, exemple : l’interdiction de la navigation sur une dimension a été omise, soit par manipulation (par un utilisateur expert) des requêtes d’affichage envoyées au serveur.
51
52 Enfin, un autre inconvénient est une moindre flexibilité de la règle de sécurisation. Dans cette approche, elle dépend directement de ce qui a été stocké dans le cube et ne s’appuie que sur du filtrage de dimension.
53
54 * **Avantage **: Une seule requête pour la génération d’un seul cube.
55 * **Inconvénients **: Fastidieux à mettre en œuvre (pré-configurer un filtrage sur tous les flux), sécurisation faible, règle de sécurisation limitée.
56
57 [[image:live_security_fr_html_db1cee0c8234453e.gif||queryString="width=429&height=426" alt="Peronnalisation flux" data-xwiki-image-style-alignment="center" height="426" width="429"]]
58
59
60 == Comparatif des 2 types de personnalisation ==
61
62 Voici un tableau comparatif de ces deux approches de personnalisation :
63
64 | |**Personnalisation des cubes**|**Personnalisation des flux**
65 |**Sécurisation**|Forte|Faible
66 |**Génération des cubes**|(((
67 X cubes générés (1 par « profil de personnalisation »)
68
69 ~=> X requêtes
70 )))|(((
71 1 cube généré
72
73 ~=> 1 seule requête
74 )))
75 |**Mise en place**|Simple|Fastidieuse
76 |**Flexibilité**|En fonction de la source de données (ex : SQL)|Filtrage sur les données du cube uniquement
77
78 = Sécurisation via Live Security{{id name="live_security"/}} =
79
80 == Concept ==
81
82 L'approche Live Security vise à ne garder que les avantages des deux mécanismes de personnalisation décrits précédemment : une sécurisation forte, un nombre de requêtes nécessaires minimum pour la génération du cube, une mise en place aussi simple que possible tout en conservant un niveau de flexibilité suffisamment élevé.
83
84 Elle permet d’ajouter des règles de sécurisation au niveau du modèle de données lui-même, sans démultiplier le nombre de cubes générés et sans obliger à gérer la sécurité au niveau ligne dans les flux.
85
86 La sécurisation est exprimée aux travers de règles de filtrage simples mises en place grâce à un assistant pour couvrir les besoins les plus courants de restriction de navigation à de membres d'une ou plusieurs dimensions, en fonction des variables d'un utilisateur.
87
88 Pour les besoins avancés on peut avoir recours à un script Javascript qui sera exécuté à chaque interrogation du cube sur la sélection entrante. Dans ce cas c’est véritablement une transformation de la sélection qui peut être faite. Aussi bien du filtrage simple analogue à l’approche « personnalisation de flux » que de la transformation plus complexe en fonction du profil de l’utilisateur. Par exemple, changer un niveau d’exploration, supprimer un axe, une ou plusieurs mesures, etc.
89
90 Quelques exemples de transformations avancées de sélection (des exemples avancés de Live Security sont détaillés sur la page [[ Live Security : exemples d'utilisation>>doc:.Live Security \: exemples.WebHome]]) :
91
92 * Filtrer une dimension //ou //une autre en fonction de la valeur d'une variable utilisateur.
93 * Faire des règles de filtrage "OU" entre dimensions.
94 * Interroger un autre cube pour en extraire un périmètre de sécurisation dynamique, en fonction de la sélection actuelle...
95
96 Coté sécurisation, cette transformation, qu'elle soit simple ou avancée, est appliquée avant le traitement de la sélection coté serveur et ne dépend que du profil de l’utilisateur. Il n’y a aucun moyen pour un utilisateur, même expert, d’altérer ce processus comme pour la personnalisation des flux.
97
98 * **Avantages **: Une seule requête pour la génération d’un seul cube, sécurisation forte, grande flexibilité (transformation potentiellement totale de la sélection du flux)
99 * **Inconvénients **: Mise en place potentiellement compliquée (Javascript) pour les besoins complexes. Mais il existe une interface assistant l'utilisateur à créer des filtres de Live Security simples, sans Javascript.
100
101 [[image:Live Security.png||data-xwiki-image-style-alignment="center" height="413" width="619"]]{{comment}}Capture en basse résolution{{/comment}}
102
103 == Comparatif des méthodes de sécurisation ==
104
105 Voici un tableau comparatif reprenant cette nouvelle approche avec les deux précédentes approches de personnalisation :
106
107 | |**Personnalisation des cubes**|**Personnalisation des flux**|**Personnalisation « Live Security »**
108 |**Sécurisation**|Forte|Faible|Forte
109 |**Génération des cubes**|(((
110 X cubes générés (1 par « profil de personnalisation »)
111
112 ~=> X requêtes
113 )))|(((
114 1 cube généré
115
116 ~=> 1 seule requête
117 )))|(((
118 1 cube généré
119
120 ~=> 1 seule requête
121 )))
122 |**Mise en place**|Simple|Fastidieuse (par flux)|Par assistant / Par script
123 |**Flexibilité**|En fonction de la source de données (ex : SQL)|Filtrage sur les données du cube uniquement|Transformation de la sélection
124
125 == Mise en place ==
126
127 Nous allons à présent voir comment mettre en place le mécanisme Live Security au travers d’un exemple standard de filtrage de dimension.
128
129 L’exemple se base sur une source de données qui contient au moins deux colonnes //pays// et //service// et des colonnes de valeurs (mesures). Chaque utilisateur est assigné à un pays et à un ou plusieurs services et ne verra donc que les chiffres qui s’y rapportent. Certains utilisateur peuvent avoir le droit de voir tous les pays et/ou tous les services.
130
131 === Prérequis ===
132
133 __Utilisateurs__
134
135 Chaque utilisateur a deux variables utilisateur dans le LDAP : //pays// et //services// qui définissent son périmètre de sécurité. Chacune des deux variables peut être vide, cela signifie que l’utilisateur peut voir tous les pays et/ou services. La variable //services// peut être une liste de noms de services séparés par des virgules (pas d’espace après les virgules).
136
137 Par exemple, nous avons les 2 utilisateurs suivants :
138
139 * Utilisateur U1 :
140 ** pays = '//fr'//
141 ** services = 'Marketing,Ventes'
142 * Utilisateur U2 :
143 ** pays = 'de'
144 ** services = (chaîne vide)
145
146 __Modèle de données__
147
148 Le modèle de données se base sur une source SQL sur laquelle on exécute la requête suivante :
149
150 {{code language="SQL"}}
151 SELECT pays, service, val1, val2 FROM UneTable
152 {{/code}}
153
154 On peut noter qu’il n’y a pas de clause WHERE dans cette requête car le but est de générer un cube unique contenant toutes les données pour tous les utilisateurs.
155
156 Le modèle de données contient donc deux dimensions et deux mesures.
157
158 (% class="box warningmessage" %)
159 (((
160 **Important**❗
161 //Les variables utilisateur **${user.pays}**, **${user.services}** ne doivent pas être utilisées dans ce contexte, ni dans la source de données (clause WHERE), ni dans une formule de mesure dérivée ou n’importe où dans le modèle de données. Sinon cela impose au système d’utiliser la personnalisation par cubes, ce que l’on ne veut pas dans cette approche.//
162 )))
163
164 === Création de la fonction Live Security ===
165
166 L’activation du Live Security se fait dans l’écran de **configuration avancée **du modèle de données, onglet **Avancé**. Nous décrivons ici les deux façons de développer une fonction de Live Security, soit via notre assistant dédié aux fonctions simples, soit via la création d'un script Javascript.
167
168 [[image:DM_dvanced_tab_FR.png||alt="Onglet avancé"]]
169
170 (% class="wikigeneratedid" id="HCrE9ationavecl27assistant" %)
171 **Création avec l'assistant**
172
173 1. Pour créer une fonction de Live Security simple sans JavaScript, vous pouvez cliquer sur le bouton **Créer (assistant)...** au niveau de la boite de sélection de la **Fonction de transformation de sélection**.
174 1. Entrez un nom pour la fonction.
175 1. **(Uniquement à partir du patch P10)** Sélectionnez le rôle pour restreindre la fonction à celui-ci ou **Aucun **pour la partager à tous les rôles.(((
176 (% class="box infomessage" %)
177 (((
178 💡 Une fonction restreinte à un rôle peut être partagée à tous les rôles en cliquant sur le bouton [[image:1777300900346-435.png||height="26" width="27"]].
179 Le partage à tous les rôles est définitif. La fonction ne pourra plus être restreinte à un rôle par la suite.
180 )))
181 )))
182 1. Choisissez la dimension **Pays** sur la première règle de filtrage. Cette règle n'a pas de hiérarchie ou niveau, laissez ces deux champs vides.
183 1. Entrez **${user.pays}** dans le champ des membres sélectionnés.
184 1. Ajouter une nouvelle règle en cliquant sur l'icône **+**
185 1. Choisissez la dimension **Service** sur la seconde règle de filtrage. Cette règle n'a pas de hiérarchie ou niveau, laissez ces deux champs vides.
186 1. Entrez **${user.services}** dans le champ des membres sélectionnés.
187 1. Comme nous avons défini que la variable **services **de l'utilisateur peut avoir plusieurs valeurs séparées par des virgules, il faut saisir une virgule (**,**) dans le champ de séparateur de valeurs.
188 1. Cliquez sur **OK **pour créer la nouvelle fonction de Live Security.
189
190 [[image:Live_secuirty_role_fr.png]]
191
192 (% class="wikigeneratedid" id="HCrE9ationd27unscript" %)
193 **Création d'un script**
194
195 1. Pour créer une fonction de Live Security avancée basée sur un script Javascript, cliquez sur le bouton **Editer…** au niveau de la boite de sélection de la **Fonction de transformation de sélection**.
196 1. Choisissez **Fonction partagée **dans le **Type** de fonction.
197 1. Ajoutez une nouvelle fonction en cliquant sur le bouton **+** dans la barre d'outil du gestionnaire de fonctions.
198 1. Entrez un nom pour la fonction puis sélectionnez le rôle pour restreindre la fonction au rôle sélectionné ou **(Aucun)** pour partager la fonction à tous les rôles.
199 1. Cliquez sur **OK**.
200
201 Vous pouvez maintenant saisir un script de transformation des sélections faites sur le cube correspondant à ce modèle de données. Ceci est décrit dans le paragraphe suivant.
202
203 Le script à écrire est le corps d’une fonction Javascript qui prend en paramètre un objet « selection ». Cet objet représente la description du résultat que l’on souhaite obtenir du cube (opération « d’aplatissement »). Cet objet complexe définit les axes souhaités, les dimensions, les filtres, les mesures et d’autres paramètres propres à chaque type de flux (graphique, tableaux…). Ce qui nous intéresse dans cet exemple ce sont les paramètres de filtrage de dimension. Le but est de transformer cette sélection afin d’y inclure deux filtres « forcés », un sur le pays de l’utilisateur et un sur ses services, si l’utilisateur a des variables définies (non vides) pour le pays et/ou les services.
204
205 Commençons par récupérer la valeur de la variable de l’utilisateur //pays// en utilisant la fonction **getUserAttribute(‘<nomvariable>’)** :
206
207 {{code language="JAVASCRIPT" cssClass="notranslate"}}
208 var pays = getUserAttribute('pays');
209 {{/code}}
210
211 Ensuite, si la variable pays est définie et non vide, nous appliquons un filtre sur l’objet selection :
212
213 {{code language="JAVASCRIPT" cssClass="notranslate"}}
214 ...
215
216 if (pays != null && pays != '')
217
218 {
219
220 var tabPays = [pays]; //création d'un tableau contenant le pays
221
222 var dim = selection.dm.getDimensionById('Pays');
223
224 var filt = new FilterSelection(dim, -1, -1, [], tabPays);
225
226 selection.setFilter(filt);
227
228 }
229 {{/code}}
230
231 Explication : La construction du filtre se fait avec l’aide de l’instruction **new FilterSelection(Dimension, indexHierarchie, indexNiveau, [ ], tableauMembres)** :
232
233 * **Dimension** : L’objet dimension peut-être récupéré directement dans le modèle de données accessible via **selection.dm**, grâce à la fonction **getDimensionById(dimId)**.
234 * **indexHierarchie** et **indexNiveau** : Ensuite, dans cet exemple, nous filtrons directement les membres racines de la dimension, il n’y a pas de hiérarchie ni de niveau à préciser (...-1, -1...).
235 * **[ ] **(tableau vide) : Utilisé de manière interne, ne pas modifier.
236 * **TableauMembres** : Enfin, un filtre sur une dimension peut avoir plusieurs membres sélectionnés, il faut donc lui passer un tableau de membres (ici **tabPays**). Pour le pays, comme l’utilisateur n’en a qu’un, le tableau ne contient qu’un élément.
237
238 Puis nous appliquons ce filtre à la sélection par **selection.setFilter(…**).
239
240 Enfin, on fait la même chose pour la variable //services// __qui représente une liste de services__, qu’on traite spécifiquement grâce à la fonction Javascript **split**(). Elle découpe une chaîne de caractères en un tableau de chaînes de caractères selon un caractère séparateur (la virgule dans notre cas) :
241
242 {{code language="JAVASCRIPT" cssClass="notranslate"}}
243 ...
244
245 var services = getUserAttribute('services');
246
247 if (services != null && services != '')
248
249 {
250
251 var tabServices = services.split(',');
252
253 var dim = selection.dm.getDimensionById('Service');
254
255 var filt = new FilterSelection(dim, -1, -1, [], tabServices);
256
257 selection.setFilter(filt);
258
259 }
260 {{/code}}
261
262 === Utilisation ===
263
264 Il ne reste plus qu’à créer un flux sur ce modèle de données et à le placer dans une page de tableau de bord.
265
266 Si on ne cache pas les dimensions pays et service dans le tableau de bord (ou dans le flux) il sera toujours possible de filtrer sur une de ces dimensions. Cependant le filtre sera écrasé par le script de Live Security si l’utilisateur a une valeur non vide pour sa variable //pays// ou //services//. Au final, le filtrage sur ces dimensions dans le tableau de bord n’est utile que pour les utilisateurs ayant le droit de tout voir c’est à dire ceux qui ont une valeur vide dans leur variable //pays// et/ou //services//.
267
268 == Références API ==
269
270 Il existe quelques méthodes recommandées pour manipuler une sélection, présentées ci-dessous.
271
272 * **Récupération d’informations utilisateurs**
273
274 {{code language="JAVASCRIPT" cssClass="notranslate"}}
275 (Chaîne) getUserAttribute (attr)
276 {{/code}}
277
278 Description : Retourne l'attribut LDAP **attr** de l'utilisateur. Consultez la page [[Attributs utilisateur >>doc:.User_attributes.WebHome]]pour accéder à la liste des attributs utilisateur par défaut.
279 Il est également possible de récupérer la valeur de paramètres utilisateurs. Consultez le paragraphe [[Ajouter des paramètres utilisateurs>>doc:Digdash.deployment.configuration.administration.WebHome||anchor="Parametres_utilisateurs"]] pour en savoir plus.
280
281 Exemple :
282
283 {{code cssClass="notranslate" language="JAVASCRIPT"}}
284 var userName = getUserAttribute('displayName');
285 {{/code}}
286
287 * **Récupération d’informations de la session utilisateur**
288
289 {{code cssClass="notranslate" language="JAVASCRIPT"}}
290 (Chaîne) getSessionAttribute (attr)
291 {{/code}}
292
293 Description : Retourne l'attribut Session **attr** de l'utilisateur pour la session courante.
294
295 (% class="box infomessage" %)
296 (((
297 Vous trouverez plus d'informations sur l’utilisation des variables de session sur la page [[**Tutoriel variables de session**>>doc:Digdash.user_guide.tutorials.session_variables_tutorial.WebHome]].
298 )))
299
300 Exemple :
301
302 {{code cssClass="notranslate" language="JAVASCRIPT"}}
303 var scenario = getSessionAttribute('Scenario');
304 {{/code}}
305
306 * **Récupération d’informations de la sélection ou du modèle de données courant**
307
308 __Variable du modèle__
309
310 {{code language="JAVASCRIPT" cssClass="notranslate"}}
311 (Nombre) getDDVar(variable)
312 {{/code}}
313
314 **​​​​​​**Description : Retourne la valeur de la **variable du modèle** (DDVar) correspondante. Ces variables sont définies dans le modèle de données et correspondent à un widget dans la page de tableau de bord.
315
316 (% class="box warningmessage" %)
317 (((
318 //Attention : ne pas confondre la DDVar avec la variable d’utilisateur (attribut LDAP).//
319 )))
320
321 Exemple :
322
323 {{code cssClass="notranslate" language="JAVASCRIPT"}}
324 var tauxEuroDollar = getDDVar('txEuroDollar');
325
326 {{/code}}
327
328 __Dimension __
329
330 {{code cssClass="javascript"}}
331 (Dimension) selection.dm.getDimensionById(dimId)
332 {{/code}}
333
334 Description : Retourne un objet Javascript correspondant à la dimension d’identifiant **dimId**. Retourne **null** si cette dimension n’est pas dans modèle courant. Cet objet est nécessaire à d’autres fonctions, par exemple pour la construction d’un filtre.
335
336 Exemple :
337
338 {{code language="JAVASCRIPT" cssClass="notranslate"}}
339 var dimPays = selection.dm.getDimensionById('Pays');
340 {{/code}}
341
342 * **Transformations de la sélection**
343
344 __Fonction FilterSelection{{id name="FilterSelection"/}}__
345
346 (((
347 {{code language="javascript"}}
348 (Filtre) new FilterSelection(dim, hierarchy, level, [ ], ValuesTab)
349 // dim : dimension à filtrer
350 // hierarchy : index de la hiérarchie (ou -1 si pas de hiérarchie)
351 // level : niveau de la hiérarchie (ou -1 pour la racine)
352 // [] : tableau interne — toujours vide, ne pas toucher!
353 // ValuesTab : Liste des valeurs/membres sur lesquels filtrer
354 {{/code}}
355
356 Description : Retourne un objet Javascript correspondant au filtre souhaité sur la dimension en paramètre, dans une hiérarchie et un niveau donné (**-1** si pas de hiérarchie/niveau) et avec les membres spécifiés. Cet objet est nécessaire à d’autres fonctions, par exemple pour l’application du filtre sur la sélection.
357
358 Cette fonction utilise la position de la hiérarchie dans les hiérarchies de la dimension ainsi que son niveau (voir encadré ci-dessous)
359 Pour éviter tout problème lié à des modifications (changement de hiérarchie, etc), utilisez la méthode suivante :
360
361 {{code language="javascript"}}
362 // Récupération de l'identifiant de la dimension à filtrer
363 var dim = selection.dm.getDimensionById('DimID');
364 // Récupération de l'index de la hiérarchie et du niveau dans le cas d'une hiérarchie
365 var pos = dim.getHierarchyLevelPos('HierarchyID', 'LevelID');
366 // Fonction
367 new FilterSelection(dim, pos[0], pos[1], [], ValuesTab);
368 // dim : dimension à filtrer
369 // pos[0] : index de la hiérarchie (à remplacer par -1 si pas de hiérarchie)
370 // pos[1] : index du niveau (à remplacer par -1 pour la racine)
371 // [] : tableau interne — toujours vide, ne pas toucher!
372 // ValuesTab : Liste des valeurs/membres sur lesquels filtrer
373 {{/code}}
374 )))
375
376 (% class="box warningmessage" %)
377 (((
378 ⚠ Il faut bien utiliser les identifiants et pas les traductions.
379 )))
380
381 (% class="box infomessage" %)
382 (((
383 ℹ **Hiérarchies et niveaux (index)**
384
385 Cette fonction s’appuie sur les index de hiérarchie et de niveau, qui correspondent à leur position.
386
387 Les hiérarchies sont indexées selon leur position dans les hiérarchies de la dimension dans la dimension :
388 0
389 1
390 2
391
392
393 Les niveaux d’une hiérarchie sont indexés comme suit :
394 -1 : niveau racine
395 0
396 1
397
398
399 **Exemple**
400
401 Pour une dimension temporelle contenant les hiérarchies suivantes :
402 Date
403 Mois Année
404 Semaine Année
405
406 Les index correspondants sont :
407 Date → 0
408 Mois Année → 1
409 Semaine Année → 2
410
411 Pour la hiérarchie Date, les niveaux sont :
412 Racine → -1
413 Jour → 0
414 Mois → 1
415 Année → 2
416 \\Ces index peuvent évoluer (modification des hiérarchies ou niveaux).
417 Afin d’éviter tout problème, il est fortement recommandé d’utiliser la méthode getHierarchyLevelPos() comme ci-dessus plutôt que de coder les index en dur.
418 )))
419
420 Exemple :
421
422 {{code language="JAVASCRIPT"}}
423 var filter = new FilterSelection(dim, -1, -1, [], new Array('fr','it','de'));
424 {{/code}}
425
426 __
427 Fonction setFilter__
428
429 {{code cssClass="notranslate" language="JAVASCRIPT"}}
430 selection.setFilter(filter)
431 {{/code}}
432
433 Description : Applique un filtre sur la sélection courante. Écrase le filtre existant sur cette dimension s’il y en avait un.
434
435
436 __Fonction setDDVar__
437
438 {{code cssClass="notranslate" language="JAVASCRIPT"}}
439 void setDDVar(variable, valeur)
440 {{/code}}
441
442 Description : Modifie la valeur d’une variable de modèle (DDVar) pour la sélection courante. La valeur de la variable n’est pas modifiée de manière persistante, seulement pour cette sélection.
443
444 (% class="box warningmessage" %)
445 (((
446 //Attention : ne pas confondre la DDVar avec la variable d’utilisateur (attribut LDAP).//
447 )))
448
449 Exemple :
450
451 {{code language="JAVASCRIPT" cssClass="notranslate"}}
452 setDDVar('txEuroDollar', 1.06);
453 {{/code}}
454
455 __
456 Fonction FilterSelectionMatch__
457
458 {{code language="js"}}
459 new FilterSelectionMatch (dim, hierarchy, level, values, operators, matchMode)
460 // dimension : la dimension à filtrer
461 // hierarchy : index de la hiérarchie (ou -1 si pas de hiérarchie)
462 // level : niveau de la hiérarchie (ou -1 pour la racine)
463 // values : tableau des valeurs à filtrer
464 // operators : tableau des opérateurs appliqués à chaque valeur
465 // matchMode : 0 = toutes les règles doivent être vraies (ET), 1 = au moins une doit être vraie (OU)
466 {{/code}}
467
468 (% class="box warningmessage" %)
469 (((
470 ⚠ Cette fonction utilise la position de la hiérarchie dans les hiérarchies de la dimension ainsi que son niveau. Consultez le paragraphe [[Fonction FilterSelection>>doc:||anchor="FilterSelection"]] pour des informations détaillées sur leur récupération.
471 )))
472
473 Description : Permet de filtrer une dimension avec une ou plusieurs conditions, en précisant pour chaque valeur quel opérateur utiliser (égal, commence par, contient, etc.).
474 //values// et //operators// sont des tableaux parallèles : chaque valeur a son opérateur.
475 Il est également possible de choisir si les conditions doivent être combinées en ET ou en OU.
476
477 Les opérateurs disponibles sont les suivants :
478
479 |=(% style="width: 330px;" %)Code JavaScript|=(% style="width: 260px;" %)Valeur|=(% style="width: 902px;" %)Signification
480 |(% style="width:330px" %)OP_ISNOTNULL|(% style="width:260px" %)0|(% style="width:902px" %)Est non nul
481 |(% style="width:330px" %)OP_ISNULL|(% style="width:260px" %)1|(% style="width:902px" %)Est nul
482 |(% style="width:330px" %)OP_EQUAL|(% style="width:260px" %)2|(% style="width:902px" %)Égal
483 |(% style="width:330px" %)OP_CONTAIN|(% style="width:260px" %)3|(% style="width:902px" %)Contient
484 |(% style="width:330px" %)OP_NOTCONTAIN|(% style="width:260px" %)4|(% style="width:902px" %)Ne contient pas
485 |(% style="width:330px" %)OP_NOTEQUAL|(% style="width:260px" %)5|(% style="width:902px" %)Différent
486 |(% style="width:330px" %)OP_MATCHREGEXP|(% style="width:260px" %)6|(% style="width:902px" %)Correspond à l'expression régulière
487 |(% style="width:330px" %)OP_CONTAINWORD|(% style="width:260px" %)7|(% style="width:902px" %)Contient le mot
488 |(% style="width:330px" %)OP_NOTCONTAINWORD|(% style="width:260px" %)8|(% style="width:902px" %)Ne contient pas le mot
489 |(% style="width:330px" %)OP_SUP|(% style="width:260px" %)9|(% style="width:902px" %)Supérieur
490 |(% style="width:330px" %)OP_INF|(% style="width:260px" %)10|(% style="width:902px" %)Inférieur
491 |(% style="width:330px" %)OP_SUPEQUAL|(% style="width:260px" %)11|(% style="width:902px" %)Supérieur ou égal
492 |(% style="width:330px" %)OP_INFEQUAL|(% style="width:260px" %)12|(% style="width:902px" %)Inférieur ou égal
493 |(% style="width:330px" %)OP_STARTSWITH|(% style="width:260px" %)13|(% style="width:902px" %)Commence par
494 |(% style="width:330px" %)OP_ENDSWITH|(% style="width:260px" %)14|(% style="width:902px" %)Finit par
495 |(% style="width:330px" %)OP_ISIN|(% style="width:260px" %)15|(% style="width:902px" %)Est dans
496 |(% style="width:330px" %)OP_ISNOTIN|(% style="width:260px" %)16|(% style="width:902px" %)N’est pas dans
497
498 __Exemple avec 1 seul filtre :__
499
500 {{code}}
501 new FilterSelectionMatch(dim, hierarchy, level, ['admin'], [13], 0);
502 {{/code}}
503
504 Dans ce cas :
505
506 * Valeur : ['admin']
507 * Opérateur : [13] → OP_STARTSWITH → le login doit commencer par admin
508 * matchMode : 0 → une seule règle donc ET ou OU ne change rien.
509
510 __Exemple avec 2 filtres :__
511
512 {{code}}
513 new FilterSelectionMatch(dim, hierarchy, level, ['admin', 'Jean'], [13, 2], 1);
514 {{/code}}
515
516 Dans ce cas :
517
518 * On combine 2 règles :
519 ** login commence par admin (13 = STARTSWITH)
520 ** login égal à Jean (2 = EQUAL)
521 * matchMode : 1 → au moins une des règles doit être vraie (logique OU).
522
523 = Pour en savoir plus... =
524
525 {{ddchildren}}{{/ddchildren}}