dolibarr 25.0.0-alpha
perms.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2002-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2002-2003 Jean-Louis Bergamo <jlb@j1b.org>
4 * Copyright (C) 2004-2020 Laurent Destailleur <eldy@users.sourceforge.net>
5 * Copyright (C) 2004 Eric Seigne <eric.seigne@ryxeo.com>
6 * Copyright (C) 2005-2017 Regis Houssin <regis.houssin@inodbox.com>
7 * Copyright (C) 2020 Tobias Sekan <tobias.sekan@startmail.com>
8 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
9 * Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
10 * Copyright (C) 2026 Alexandre Spangaro <alexandre@inovea-conseil.com>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 3 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program. If not, see <https://www.gnu.org/licenses/>.
24 */
25
31if (!defined('CSRFCHECK_WITH_TOKEN')) {
32 define('CSRFCHECK_WITH_TOKEN', '1'); // Force use of CSRF protection with tokens even for GET
33}
34
35// Load Dolibarr environment
36require '../../main.inc.php';
45require_once DOL_DOCUMENT_ROOT.'/user/class/usergroup.class.php';
46require_once DOL_DOCUMENT_ROOT.'/core/lib/usergroups.lib.php';
47require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
48require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
49require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
50
51// Load translation files required by page
52$langs->loadLangs(array('users', 'admin'));
53
54$id = GETPOSTINT('id');
55$action = GETPOST('action', 'aZ09');
56$confirm = GETPOST('confirm', 'alpha');
57$module = GETPOST('module', 'alpha');
58$rights = GETPOSTINT('rights');
59$updatedmodulename = GETPOST('updatedmodulename', 'alpha');
60$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'groupperms'; // To manage different context of search
61
62if (!isset($id) || empty($id)) {
64}
65
66// Define if user can read permissions
67$permissiontoread = ($user->admin || $user->hasRight("user", "user", "read"));
68// Define if user can modify group permissions
69$permissiontoedit = ($user->admin || $user->hasRight("user", "user", "write"));
70// Advanced permissions
71$advancedpermsactive = false;
72if (getDolGlobalString('MAIN_USE_ADVANCED_PERMS')) {
73 $advancedpermsactive = true;
74 $permissiontoread = ($user->admin || ($user->hasRight("user", "group_advance", "read") && $user->hasRight("user", "group_advance", "readperms")));
75 $permissiontoedit = ($user->admin || $user->hasRight("user", "group_advance", "write"));
76}
77
78// Security check
79$socid = 0;
80if (!empty($user->socid) && $user->socid > 0) {
81 $socid = $user->socid;
82}
83//restrictedArea($user, 'user', $id, 'usergroup', '');
84if (!$permissiontoread) {
86}
87
88$object = new UserGroup($db);
89$object->fetch($id);
90$object->loadRights();
91
92$entity = $conf->entity;
93
94// Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context
95$hookmanager->initHooks(array('groupperms', 'globalcard'));
96
97
98/*
99 * Actions
100 */
101
102$parameters = array('socid' => $socid);
103$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
104if ($reshook < 0) {
105 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
106}
107
108if (empty($reshook)) {
109 if ($action == 'addrights' && $permissiontoedit) {
110 $editgroup = new UserGroup($db);
111 $result = $editgroup->fetch($object->id);
112 if ($result > 0) {
113 $result = $editgroup->addrights($rights, $module, '', $entity);
114 if ($result < 0) {
115 setEventMessages($editgroup->error, $editgroup->errors, 'errors');
116 }
117 } else {
119 }
120
121 $user->clearrights();
122 $user->loadRights();
123
124 // We redirect to avoid to get an URL with token inside
125 $qs = $_SERVER["QUERY_STRING"];
126 $qs = preg_replace('/&action=addrights/', '', $qs);
127 $qs = preg_replace('/&token=[0-9a-f]+/i', '', $qs);
128 $qs = preg_replace('/&confirm=yes/', '', $qs);
129 header("Location: ".$_SERVER["PHP_SELF"].($qs ? "?".$qs : ""));
130 exit;
131 }
132
133 if ($action == 'delrights' && $permissiontoedit) {
134 $editgroup = new UserGroup($db);
135 $result = $editgroup->fetch($id);
136 if ($result > 0) {
137 $result = $editgroup->delrights($rights, $module, '', $entity);
138 if ($result < 0) {
139 setEventMessages($editgroup->error, $editgroup->errors, 'errors');
140 }
141 } else {
143 }
144
145 $user->clearrights();
146 $user->loadRights();
147
148 // We redirect to avoid to get an URL with token inside
149 $qs = $_SERVER["QUERY_STRING"];
150 $qs = preg_replace('/&action=delrights/', '', $qs);
151 $qs = preg_replace('/&token=[0-9a-f]+/i', '', $qs);
152 $qs = preg_replace('/&confirm=yes/', '', $qs);
153 header("Location: ".$_SERVER["PHP_SELF"].($qs ? "?".$qs : ""));
154 exit;
155 }
156}
157
158
159/*
160 * View
161 */
162
163$form = new Form($db);
164$formother = new FormOther($db);
165
166$title = $object->name." - ".$langs->trans('Permissions');
167$help_url = '';
168llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-user page-group_perms');
169
170if ($object->id <= 0) {
171 accessforbidden('Group not found');
172}
173
175$title = $langs->trans("Group");
176print dol_get_fiche_head($head, 'rights', $title, -1, 'group');
177
178// Load modules subject to permissions
179$modules = array();
180$modulesdir = dolGetModulesDirs();
181
182// Modules to ignore depending on supplier module mode
183$excludedModules = getDolGlobalInt('MAIN_USE_NEW_SUPPLIERMOD') ? array('modFournisseur') : array('modSupplierOrder', 'modSupplierInvoice');
184
185// Preload MAIN_MODULE_* enablement for the target entity in one query, so we can skip calling
186// insert_permissions() (which starts by re-checking this same enablement with its own query) on
187// every disabled module found on disk. If we are looking at our own entity, $conf->global already
188// has this cached from bootstrap and no query is needed at all.
189if ($entity == $conf->entity) {
190 $enabledmoduleconst = (array) $conf->global;
191} else {
192 $enabledmoduleconst = array();
193 $sql = "SELECT ".$db->decrypt('name')." as name, ".$db->decrypt('value')." as value";
194 $sql .= " FROM ".MAIN_DB_PREFIX."const";
195 $sql .= " WHERE entity IN (0, ".((int) $entity).")";
196 $sql .= " ORDER BY entity"; // entity 0 first, then entity-specific overrides it
197 $resql = $db->query($sql);
198 if ($resql) {
199 while ($obj = $db->fetch_object($resql)) {
200 $enabledmoduleconst[$obj->name] = $obj->value;
201 }
202 $db->free($resql);
203 }
204}
205
206// Preload the ids of rights already present in llx_rights_def for this entity in one query, so insert_permissions()
207// below can check existence in-memory instead of issuing one "SELECT count(*)" query per permission of every module.
208$existingrightsdefids = array();
209$sql = "SELECT id FROM ".MAIN_DB_PREFIX."rights_def WHERE entity = ".((int) $entity);
210$resql = $db->query($sql);
211if ($resql) {
212 while ($obj = $db->fetch_object($resql)) {
213 $existingrightsdefids[$obj->id] = 1;
214 }
215 $db->free($resql);
216}
217
218$db->begin();
219
220foreach ($modulesdir as $dir) {
221 $handle = @opendir(dol_osencode($dir));
222 if (is_resource($handle)) {
223 while (($file = readdir($handle)) !== false) {
224 if (is_readable($dir.$file) && substr($file, 0, 3) == 'mod' && substr($file, dol_strlen($file) - 10) == '.class.php') {
225 $modName = substr($file, 0, dol_strlen($file) - 10);
226
227 if ($modName) {
228 // Exclude old/new supplier descriptors depending on MAIN_USE_NEW_SUPPLIERMOD
229 if (in_array($modName, $excludedModules, true)) {
230 continue;
231 }
232
233 include_once $dir.$file;
234 $objMod = new $modName($db);
235 '@phan-var-force DolibarrModules $objMod';
238 // Load all lang files of module
239 if (isset($objMod->langfiles) && is_array($objMod->langfiles)) {
240 foreach ($objMod->langfiles as $domain) {
241 $langs->load($domain);
242 }
243 }
244 // Load all permissions
245 if ($objMod->rights_class) {
246 // Skip the DB round trip insert_permissions() would do just to find out the
247 // module is disabled for this entity - we already know from the preload above.
248 if (empty($objMod->const_name) || !empty($enabledmoduleconst[$objMod->const_name])) {
249 $objMod->insert_permissions(0, $entity, 0, $existingrightsdefids);
250 }
251 $modules[$objMod->rights_class] = $objMod;
252 }
253 }
254 }
255 }
256 }
257}
258
259$db->commit();
260
261// Read permissions of group
262$permsgroupbyentity = array();
263
264$sql = "SELECT DISTINCT r.id, r.libelle, r.module, r.perms, r.subperms, r.module_position, r.family, r.family_position, gr.entity";
265$sql .= " FROM ".MAIN_DB_PREFIX."rights_def as r,";
266$sql .= " ".MAIN_DB_PREFIX."usergroup_rights as gr";
267$sql .= " WHERE gr.fk_id = r.id";
268$sql .= " AND gr.entity = ".((int) $entity);
269$sql .= " AND r.entity = ".((int) $entity);
270$sql .= " AND gr.fk_usergroup = ".((int) $object->id);
271
272dol_syslog("get user perms", LOG_DEBUG);
273$result = $db->query($sql);
274if ($result) {
275 $num = $db->num_rows($result);
276 $i = 0;
277 while ($i < $num) {
278 $obj = $db->fetch_object($result);
279 if (!isset($permsgroupbyentity[(int) $obj->entity])) {
280 $permsgroupbyentity[(int) $obj->entity] = array();
281 }
282 array_push($permsgroupbyentity[(int) $obj->entity], (int) $obj->id);
283 $i++;
284 }
285 $db->free($result);
286} else {
288}
289
290/*
291 * Part to add/remove permissions
292 */
293
294$linkback = '<a href="'.DOL_URL_ROOT.'/user/group/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
295
296dol_banner_tab($object, 'id', $linkback, $user->hasRight("user", "user", "read") || $user->admin);
297
298
299print '<div class="fichecenter">';
300print '<div class="fichehalfleft">';
301
302print '<div class="underbanner clearboth"></div>';
303print '<table class="border centpercent tableforfield">';
304
305// Name (already in dol_banner, we keep it to have the GlobalGroup picto, but we should move it in dol_banner)
306if (isModEnabled('multicompany')) {
307 print '<tr><td class="titlefield">'.$langs->trans("Name").'</td>';
308 print '<td class="valeur">'.dol_escape_htmltag($object->name);
309 if (empty($object->entity)) {
310 print img_picto($langs->trans("GlobalGroup"), 'superadmin');
311 }
312 print "</td></tr>\n";
313}
314
315// Multicompany
316if (isModEnabled('multicompany') && isset($mc) && is_object($mc) && !getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE') && $conf->entity == 1 && $user->admin && !$user->entity) {
317 $mc->getInfo($object->entity);
318 print "<tr>".'<td class="titlefield">'.$langs->trans("Entity").'</td>';
319 print '<td class="valeur">'.dol_escape_htmltag($mc->label);
320 print "</td></tr>\n";
321}
322
323unset($object->fields['nom']); // Name already displayed in banner
324unset($object->fields['color']);
325
326// Common attributes
327$keyforbreak = '';
328include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php';
329
330print '<tr><td>'.$langs->trans("ColorGroup").'</td>';
331print '<td>';
332print $formother->showColor($object->color, '');
333print '</td></tr>';
334
335// Other attributes
336include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
337
338print '</table>';
339
340print '</div>';
341print '</div>';
342
343print '<div class="clearboth"></div>';
344
345print '<br>';
346
347
348if ($user->admin) {
349 $s = $langs->trans("WarningOnlyPermissionOfActivatedModules")." ".$langs->trans("YouCanEnableModulesFrom");
350 if (getDolGlobalString('MAIN_USE_ADVANCED_PERMS')) {
351 $s .= '<br>';
352 $s .= img_picto($langs->trans('InfoAdmin'), 'info-circle').' ';
353 $s .= $langs->trans("YouAreUsingTheAdvancedPermissionsMode");
354 } else {
355 $s .= '<br>';
356 $s .= img_picto($langs->trans('InfoAdmin'), 'info-circle').' ';
357 $s .= $langs->trans("YouAreUsingTheSimplePermissionsMode");
358 }
359 print info_admin($s);
360
361 print '<br>';
362}
363
364$parameters = array();
365$reshook = $hookmanager->executeHooks('insertExtraHeader', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
366if ($reshook < 0) {
367 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
368}
369
370print "\n";
371print '<div class="div-table-responsive-no-min">';
372print '<table class="noborder centpercent">';
373print '<tr class="liste_titre">';
374print '<td>'.$langs->trans("Module").'</td>';
375if ($permissiontoedit) {
376 print '<td class="center nowrap">';
377 print '<a class="reposition commonlink addexpandedmodulesinparamlist" title="'.dol_escape_htmltag($langs->trans("All")).'" alt="'.dol_escape_htmltag($langs->trans("All")).'" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=addrights&token='.newToken().'&entity='.$entity.'&module=allmodules&confirm=yes">'.$langs->trans("All")."</a>";
378 print '/';
379 print '<a class="reposition commonlink addexpandedmodulesinparamlist" title="'.dol_escape_htmltag($langs->trans("None")).'" alt="'.dol_escape_htmltag($langs->trans("None")).'" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delrights&&token='.newToken().'&entity='.$entity.'&module=allmodules&confirm=yes">'.$langs->trans("None")."</a>";
380 print '</td>';
381} else {
382 print '<td></td>';
383}
384print '<td></td>';
385print '<td class="right nowrap" colspan="2">';
386print '<a class="showallperms" title="'.dol_escape_htmltag($langs->trans("ShowAllPerms")).'" alt="'.dol_escape_htmltag($langs->trans("ShowAllPerms")).'" href="#">'.img_picto('', 'folder-open', 'class="paddingright"').'<span class="hideonsmartphone">'.$langs->trans("ExpandAll").'</span></a>';
387print ' | ';
388print '<a class="hideallperms" title="'.dol_escape_htmltag($langs->trans("HideAllPerms")).'" alt="'.dol_escape_htmltag($langs->trans("HideAllPerms")).'" href="#">'.img_picto('', 'folder', 'class="paddingright"').'<span class="hideonsmartphone">'.$langs->trans("UndoExpandAll").'</span></a>';
389print '</td>';
390print '</tr>'."\n";
391
392// Get list of all permissions
393$sql = "SELECT r.id, r.libelle as label, r.module, r.module_origin, r.perms, r.subperms, r.module_position, r.bydefault, r.family, r.family_position";
394$sql .= " FROM ".MAIN_DB_PREFIX."rights_def as r";
395$sql .= " WHERE r.libelle NOT LIKE 'tou%'"; // We ignore permission "tous les tiers". Why ?
396$sql .= " AND r.entity = ".((int) $entity);
397if (!getDolGlobalString('MAIN_USE_ADVANCED_PERMS')) {
398 $sql .= " AND r.perms NOT LIKE '%_advance'"; // Hide advanced perms if option is not enabled
399}
400$sql .= " ORDER BY r.family_position, r.module_position, r.right_position, r.module, r.id";
401
402$familyinfo = array(
403 'hr' => array('position' => '001', 'label' => $langs->trans("ModuleFamilyHr")),
404 'crm' => array('position' => '006', 'label' => $langs->trans("ModuleFamilyCrm")),
405 'srm' => array('position' => '007', 'label' => $langs->trans("ModuleFamilySrm")),
406 'financial' => array('position' => '009', 'label' => $langs->trans("ModuleFamilyFinancial")),
407 'products' => array('position' => '012', 'label' => $langs->trans("ModuleFamilyProducts")),
408 'projects' => array('position' => '015', 'label' => $langs->trans("ModuleFamilyProjects")),
409 'ecm' => array('position' => '018', 'label' => $langs->trans("ModuleFamilyECM")),
410 'technic' => array('position' => '021', 'label' => $langs->trans("ModuleFamilyTechnic")),
411 'portal' => array('position' => '040', 'label' => $langs->trans("ModuleFamilyPortal")),
412 'interface' => array('position' => '050', 'label' => $langs->trans("ModuleFamilyInterface")),
413 'base' => array('position' => '060', 'label' => $langs->trans("ModuleFamilyBase")),
414 'other' => array('position' => '100', 'label' => $langs->trans("ModuleFamilyOther")),
415);
416
417$arrayofpermission = array();
418$cookietohidegroup = (empty($_COOKIE["DOLUSER_PERMS_HIDE_GRP"]) ? '' : preg_replace('/^,/', '', $_COOKIE["DOLUSER_PERMS_HIDE_GRP"]));
419$cookietohidegrouparray = explode(',', $cookietohidegroup);
420
421$result = $db->query($sql);
422if ($result) {
423 $num = $db->num_rows($result);
424 $i = 0;
425
426
427 while ($i < $num) {
428 $obj = $db->fetch_object($result);
429
430 if (empty($obj->family)) {
431 $obj->family = 'other';
432 }
433
434 if (empty($obj->family_position)) {
435 $obj->family_position = $familyinfo[$obj->family]['position'];
436 if ($obj->module_position < 100000) {
437 $obj->module_position = intval($obj->module_position) + 100000;
438 } else {
439 $obj->module_position = intval($obj->module_position);
440 }
441 }
442
443 $obj->position = $obj->family_position.'_'.$obj->module_position.'_'.$obj->id;
444
445 $arrayofpermission[$i] = $obj;
446 $i++;
447 }
448} else {
450}
451
452$arrayofpermission = dol_sort_array($arrayofpermission, 'position');
453
454$j = 0;
455$oldmod = '';
456
457foreach ($arrayofpermission as $i => $obj) {
458 // If line is for a module that does not exist anymore (absent of includes/module), we ignore it
459 if (empty($modules[$obj->module])) {
460 $i++;
461 continue;
462 }
463
464 // Special cases
465 if (isModEnabled("reception")) {
466 // The 2 permission in fournisseur modules has been replaced by permissions into reception module
467 if ($obj->module == 'fournisseur' && $obj->perms == 'commande' && $obj->subperms == 'receptionner') {
468 $i++;
469 continue;
470 }
471 if ($obj->module == 'fournisseur' && $obj->perms == 'commande_advance' && $obj->subperms == 'check') {
472 $i++;
473 continue;
474 }
475 }
476
477 $objMod = $modules[$obj->module];
478
479 if (GETPOSTISSET('forbreakperms_'.$obj->module)) {
480 $ishidden = GETPOSTINT('forbreakperms_'.$obj->module);
481 } elseif (in_array($j, $cookietohidegrouparray)) { // If j is among list of hidden group
482 $ishidden = 1;
483 } else {
484 $ishidden = 0;
485 }
486 $isexpanded = ! $ishidden;
487
488 $permsgroupbyentitypluszero = array();
489 if (!empty($permsgroupbyentity[0])) {
490 $permsgroupbyentitypluszero = array_merge($permsgroupbyentitypluszero, $permsgroupbyentity[0]);
491 }
492 if (!empty($permsgroupbyentity[$entity])) {
493 $permsgroupbyentitypluszero = array_merge($permsgroupbyentitypluszero, $permsgroupbyentity[$entity]);
494 }
495
496 // Break found, it's a new module to catch
497 if (isset($obj->module) && ($oldmod != $obj->module)) {
498 $oldmod = $obj->module;
499
500 $j++;
501 if (GETPOSTISSET('forbreakperms_'.$obj->module)) {
502 $ishidden = GETPOSTINT('forbreakperms_'.$obj->module);
503 } elseif (in_array($j, $cookietohidegrouparray)) { // If j is among list of hidden group
504 $ishidden = 1;
505 } else {
506 $ishidden = 0;
507 }
508 $isexpanded = ! $ishidden;
509
510 // Break detected, we get objMod
511 $objMod = $modules[$obj->module];
512 $picto = ($objMod->picto ? $objMod->picto : 'generic');
513
514 // Show break line
515 print '<tr class="oddeven trforbreakperms trforbreaknobg" data-hide-perms="'.$obj->module.'" data-j="'.$j.'">';
516 // Picto and label of module
517 print '<td class="maxwidthonsmartphone tdoverflowmax200 tdforbreakperms" data-hide-perms="'.dol_escape_htmltag($obj->module).'" title="'.dol_escape_htmltag($objMod->getName()).'">';
518 print '<input type="hidden" name="forbreakperms_'.$obj->module.'" id="idforbreakperms_'.$obj->module.'" css="cssforfieldishiden" data-j="'.$j.'" value="'.($isexpanded ? '0' : "1").'">';
519 print img_object('', $picto, 'class="pictoobjectwidth paddingright"').' '.$objMod->getName();
520 print '<a name="'.$objMod->getName().'"></a>';
521 print '</td>';
522
523 // Permission and tick (2 columns)
524 if ($permissiontoedit) {
525 print '<td class="tdforbreakperms tdforbreakpermsifnotempty center width50 nowraponall" data-hide-perms="'.dol_escape_htmltag($obj->module).'">';
526 print '<span class="permtohide_'.dol_escape_htmltag($obj->module).'" '.(!$isexpanded ? ' style="display:none"' : '').'>';
527 print '<a class="reposition alink addexpandedmodulesinparamlist" title="'.dol_escape_htmltag($langs->trans("All")).'" alt="'.dol_escape_htmltag($langs->trans("All")).'" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=addrights&token='.newToken().'&entity='.$entity.'&module='.$obj->module.'&confirm=yes&updatedmodulename='.$obj->module.'">'.$langs->trans("All")."</a>";
528 print ' / ';
529 print '<a class="reposition alink addexpandedmodulesinparamlist" title="'.dol_escape_htmltag($langs->trans("None")).'" alt="'.dol_escape_htmltag($langs->trans("None")).'" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delrights&token='.newToken().'&entity='.$entity.'&module='.$obj->module.'&confirm=yes&updatedmodulename='.$obj->module.'">'.$langs->trans("None")."</a>";
530 print '</span>';
531 print '</td>';
532 print '<td class="tdforbreakperms" data-hide-perms="'.dol_escape_htmltag($obj->module).'">';
533 print '</td>';
534 } else {
535 print '<td class="tdforbreakperms" data-hide-perms="'.dol_escape_htmltag($obj->module).'"></td>';
536 print '<td class="tdforbreakperms" data-hide-perms="'.dol_escape_htmltag($obj->module).'"></td>';
537 }
538 // Description of permission (2 columns)
539 print '<td class="tdforbreakperms" data-hide-perms="'.dol_escape_htmltag($obj->module).'"></td>';
540 print '<td class="maxwidthonsmartphone right tdforbreakperms" data-hide-perms="'.dol_escape_htmltag($obj->module).'">';
541 print '<div class="switchfolderperms inline-block marginrightonly folderperms_'.dol_escape_htmltag($obj->module).'"'.($isexpanded ? ' style="display:none;"' : '').'>';
542 print img_picto('', 'folder', 'class="marginright"');
543 print '</div>';
544 print '<div class="switchfolderperms inline-block marginrightonly folderopenperms_'.dol_escape_htmltag($obj->module).'"'.(!$isexpanded ? ' style="display:none;"' : '').'>';
545 print img_picto('', 'folder-open', 'class="marginright"');
546 print '</div>';
547 print '</td>'; //Add picto + / - when open en closed
548 print '</tr>'."\n";
549 }
550
551 $permlabel = (getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && ($langs->trans("PermissionAdvanced".$obj->id) != "PermissionAdvanced".$obj->id) ? $langs->trans("PermissionAdvanced".$obj->id) : (($langs->trans("Permission".$obj->id) != "Permission".$obj->id) ? $langs->trans("Permission".$obj->id) : $langs->trans($obj->label)));
552
553 // This right is declared by another module (module_origin) but filed into this module's
554 // section for display (KEY_MODULE): show a small badge so it is not mistaken for a native
555 // right of this module.
556 if (!empty($obj->module_origin) && $obj->module_origin != $obj->module && !empty($modules[$obj->module_origin])) {
557 $permoriginmod = $modules[$obj->module_origin];
558 $permoriginpicto = ($permoriginmod->picto ? $permoriginmod->picto : 'generic');
559 $permlabel = img_picto($langs->trans("RightProvidedByModule", $permoriginmod->getName()), $permoriginpicto, 'class="paddingrightonly"').$permlabel;
560 }
561
562 print '<!-- '.$obj->module.'->'.$obj->perms.($obj->subperms ? '->'.$obj->subperms : '').' -->'."\n";
563 print '<tr class="oddeven trtohide_'.$obj->module.'"'.(!$isexpanded ? ' style="display:none"' : '').'>';
564
565
566 // Picto and label of module
567 print '<td class="maxwidthonsmartphone">';
568 print '</td>';
569
570 // Permission and tick (2 columns)
571 print '<!-- permsgroupbyentitypluszero -->';
572 // @phan-suppress-next-line PhanTypeMismatchArgumentNullableInternal
573 if (in_array($obj->id, $permsgroupbyentitypluszero)) {
574 // Own permission by group
575 if ($permissiontoedit) {
576 print '<td class="center nowrap">';
577 print '<a class="reposition" id="'.$obj->id.'" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delrights&token='.newToken().'&entity='.$entity.'&rights='.$obj->id.'&confirm=yes&updatedmodulename='.$obj->module.'">';
578 //print img_edit_remove($langs->trans("Remove"));
579 print img_picto($langs->trans("Remove"), 'switch_on');
580 print '</a>';
581 print '</td>';
582 } else {
583 print '<td></td>';
584 }
585 print '<td class="center nowrap">';
586 print img_picto($langs->trans("Active"), 'tick');
587 print '</td>';
588 } else {
589 // Do not own permission
590 if ($permissiontoedit) {
591 print '<td class="center nowrap">';
592 print '<a class="reposition addexpandedmodulesinparamlist" id="'.$obj->id.'" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=addrights&token='.newToken().'&entity='.$entity.'&rights='.$obj->id.'&confirm=yes&updatedmodulename='.$obj->module.'">';
593 //print img_edit_add($langs->trans("Add"));
594 print img_picto($langs->trans("Add"), 'switch_off');
595 print '</a>';
596 print '</td>';
597 } else {
598 print '<td></td>';
599 }
600 print '<td>';
601 print '</td>';
602 }
603
604 // Description of permission (1 or 2 columns)
605 print '<td>';
606 print $permlabel;
607 $idtouse = $obj->id;
608 if (in_array($idtouse, array(121, 122, 125, 126))) { // Force message for the 3 permission on third parties
609 $idtouse = 122;
610 }
611 if ($langs->trans("Permission".$idtouse.'b') != "Permission".$idtouse.'b') {
612 print '<br><span class="opacitymedium">'.$langs->trans("Permission".$idtouse.'b').'</span>';
613 }
614 if ($langs->trans("Permission".$obj->id.'c') != "Permission".$obj->id.'c') {
615 print '<br><span class="opacitymedium">'.$langs->trans("Permission".$obj->id.'c').'</span>';
616 }
617 if (getDolGlobalString('MAIN_USE_ADVANCED_PERMS')) {
618 if (preg_match('/_advance$/', $obj->perms)) {
619 print ' <span class="opacitymedium">('.$langs->trans("AdvancedModeOnly").')</span>';
620 }
621 }
622 print '</td>';
623
624 // Permission id
625 if ($user->admin) {
626 print '<td class="right">';
627 $htmltext = $langs->trans("ID").': '.$obj->id;
628 // hasRight() is actually checked against module_origin when set, not the display
629 // module column, see User::loadRights().
630 $htmltextmodule = (!empty($obj->module_origin) ? $obj->module_origin : $obj->module);
631 $htmltext .= '<br>'.$langs->trans("Permission").': user->hasRight(\''.dol_escape_htmltag($htmltextmodule).'\', \''.dol_escape_htmltag($obj->perms).'\''.($obj->subperms ? ', \''.dol_escape_htmltag($obj->subperms).'\'' : '').')';
632 print $form->textwithpicto('', $htmltext, 1, 'help', 'inline-block marginrightonly');
633 //print '<span class="opacitymedium">'.$obj->id.'</span>';
634 print '</td>';
635 } else {
636 print '<td></td>';
637 }
638
639 print '</tr>'."\n";
640
641 $i++;
642}
643
644print '</table>';
645print '</div>';
646
647print '<script>';
648print '$(".tdforbreakperms:not(.alink)").on("click", function(){
649 console.log("Click on tdforbreakperms");
650 moduletohide = $(this).data("hide-perms");
651 j = $(this).data("j");
652 if ($("#idforbreakperms_"+moduletohide).val() == 1) {
653 console.log("idforbreakperms_"+moduletohide+" has value hidden=1, so we show all lines");
654 $(".trtohide_"+moduletohide).show();
655 $(".permtoshow_"+moduletohide).hide();
656 $(".permtohide_"+moduletohide).show();
657 $(".folderperms_"+moduletohide).hide();
658 $(".folderopenperms_"+moduletohide).show();
659 $("#idforbreakperms_"+moduletohide).val("0");
660 } else if (! $(this).hasClass("tdforbreakpermsifnotempty")) {
661 console.log("idforbreakperms_"+moduletohide+" has value hidden=0, so we hide all lines");
662 $(".trtohide_"+moduletohide).hide();
663 $(".folderopenperms_"+moduletohide).hide();
664 $(".folderperms_"+moduletohide).show();
665 $(".permtoshow_"+moduletohide).show();
666 $(".permtohide_"+moduletohide).hide();
667 $("#idforbreakperms_"+moduletohide).val("1");
668 }
669
670 // Now rebuild the value for cookie
671 var hideuserperm="";
672 $(".trforbreakperms").each(function(index) {
673 //console.log( index + ": " + $( this ).data("j") + " " + $( this ).data("hide-perms") + " " + $("input[data-j="+(index+1)+"]").val());
674 if ($("input[data-j="+(index+1)+"]").val() == 1) {
675 hideuserperm=hideuserperm+","+(index+1);
676 }
677 });
678 // set cookie by js
679 date = new Date(); date.setTime(date.getTime()+(30*86400000));
680 if (hideuserperm) {
681 console.log("set cookie DOLUSER_PERMS_HIDE_GRP="+hideuserperm);
682 document.cookie = "DOLUSER_PERMS_HIDE_GRP=" + hideuserperm + "; expires=" + date.toGMTString() + "; path=/ ";
683 } else {
684 console.log("delete cookie DOLUSER_PERMS_HIDE_GRP");
685 document.cookie = "DOLUSER_PERMS_HIDE_GRP=; expires=Thu, 01-Jan-70 00:00:01 GMT; path=/ ";
686 }
687});';
688print "\n";
689
690// Button expand / collapse all
691print '$(".showallperms").on("click", function(){
692 console.log("Click on showallperms");
693
694 console.log("delete cookie DOLUSER_PERMS_HIDE_GRP from showallperms click");
695 document.cookie = "DOLUSER_PERMS_HIDE_GRP=; expires=Thu, 01-Jan-70 00:00:01 GMT; path=/ ";
696 $(".tdforbreakperms").each( function(){
697 moduletohide = $(this).data("hide-perms");
698 //console.log(moduletohide);
699 if ($("#idforbreakperms_"+moduletohide).val() != 0) {
700 $(this).trigger("click"); // emulate the click, so the cooki will be resaved
701 }
702 })
703});
704
705$(".hideallperms").on("click", function(){
706 console.log("Click on hideallperms");
707
708 $(".tdforbreakperms").each( function(){
709 moduletohide = $(this).data("hide-perms");
710 //console.log(moduletohide);
711 if ($("#idforbreakperms_"+moduletohide).val() != 1) {
712 $(this).trigger("click"); // emulate the click, so the cooki will be resaved
713 }
714 })
715});';
716print "\n";
717print '</script>';
718
719print '<style>';
720print '.switchfolderperms{
721 cursor: pointer;
722}';
723print '</style>';
724
725$parameters = array();
726$reshook = $hookmanager->executeHooks('insertExtraFooter', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
727if ($reshook < 0) {
728 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
729}
730
731print dol_get_fiche_end();
732
733
734// End of page
735llxFooter();
736$db->close();
$id
Support class for third parties, contacts, members, users or resources.
Definition account.php:47
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
Definition wrapper.php:91
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Definition wrapper.php:73
Class to manage generation of HTML components Only common components must be here.
Class to help generate other html components Only common components are here.
Class to manage user groups.
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $db
API class for accounts.
dolGetModulesDirs($subdir='')
Return list of directories that contain modules.
dol_osencode($str)
Return a string encoded into OS filesystem encoding.
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_sort_array(&$array, $index, $order='asc', $natsort=0, $case_sensitive=0, $keepindex=0)
Advanced sort array by the value of a given key, which produces ascending (default) or descending out...
newToken()
Return the value of token currently saved into session with name 'newtoken'.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0, $nodefault=0)
Return value of a param into GET or POST supervariable.
GETPOSTINT($paramname, $method=0, $nodefault=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0, $morecssdiv='')
Show tabs of a record.
Definition html.lib.php:519
dol_get_fiche_end($notab=0)
Return tab footer of a card.
Definition html.lib.php:717
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $allowothertags=array())
Show a picto called object_picto (generic function)
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
info_admin($text, $infoonimgalt=0, $nodiv=0, $admin='1', $morecss='hideonsmartphone', $textfordropdown='', $picto='', $textonpictotooltip='', $cssfordropdown='info_admin')
Show information in HTML for admin users or standard users.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
Definition html.lib.php:172
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.
group_prepare_head($object)
Prepare array with list of tabs.