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) 2012 Juanjo Menent <jmenent@2byte.es>
8 * Copyright (C) 2020 Tobias Sekan <tobias.sekan@startmail.com>
9 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
10 * Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
11 * Copyright (C) 2025-2026 Charlene Benke <charlene@patas-monkey.com>
12 * Copyright (C) 2026 Alexandre Spangaro <alexandre@inovea-conseil.com>
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 3 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program. If not, see <https://www.gnu.org/licenses/>.
26 */
27
33if (!defined('CSRFCHECK_WITH_TOKEN')) {
34 define('CSRFCHECK_WITH_TOKEN', '1'); // Force use of CSRF protection with tokens even for GET
35}
36
37// Load Dolibarr environment
38require '../main.inc.php';
47require_once DOL_DOCUMENT_ROOT.'/core/lib/usergroups.lib.php';
48require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
49require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.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') : 'userperms'; // To manage different context of search
61
62if (!isset($id) || empty($id)) {
64}
65
66// Define if user can read permissions
67$canreaduser = ($user->admin || $user->hasRight("user", "user", "read"));
68// Define if user can modify other users and permissions
69$caneditperms = ($user->admin || $user->hasRight("user", "user", "write"));
70// Advanced permissions
71if (getDolGlobalString('MAIN_USE_ADVANCED_PERMS')) {
72 $canreaduser = ($user->admin || ($user->hasRight("user", "user", "read") && $user->hasRight("user", "user_advance", "readperms")));
73 $caneditselfperms = ($user->id == $id && $user->hasRight("user", "self_advance", "writeperms"));
74 $caneditperms = (($caneditperms || $caneditselfperms) ? 1 : 0);
75}
76
77// Security check
78$socid = 0;
79if (!empty($user->socid) && $user->socid > 0) {
80 $socid = $user->socid;
81}
82$feature2 = (($socid && $user->hasRight("user", "self", "write")) ? '' : 'user');
83// A user can always read its own card if not advanced perms enabled, or if he has advanced perms, except for admin
84if ($user->id == $id && (getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && !$user->hasRight("user", "self_advance", "readperms") && empty($user->admin))) {
86}
87
88// Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context
89$hookmanager->initHooks(array('usercard', 'userperms', 'globalcard'));
90
91$result = restrictedArea($user, 'user', $id, 'user&user', $feature2);
92if ($user->id != $id && !$canreaduser) {
94}
95
96$object = new User($db);
97$object->fetch($id, '', '', 1);
98$object->loadRights();
99
100$entity = $conf->entity;
101
102
103/*
104 * Actions
105 */
106
107$parameters = array('socid' => $socid);
108$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
109if ($reshook < 0) {
110 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
111}
112
113if (empty($reshook)) {
114 if ($action == 'addrights' && $caneditperms && $confirm == 'yes') {
115 $edituser = new User($db);
116 $edituser->fetch($object->id);
117 $result = $edituser->addrights($rights, $module, '', $entity);
118 if ($result < 0) {
119 setEventMessages($edituser->error, $edituser->errors, 'errors');
120 }
121
122 // If we are changing our own permissions, we reload permissions and menu
123 if ($object->id == $user->id) {
124 $user->clearrights();
125 $user->loadRights();
126 // @phan-suppress-next-line PhanRedefinedClassReference
127 $menumanager->loadMenu();
128 }
129
130 $object->clearrights();
131 $object->loadRights();
132
133 // We redirect to avoid to get an URL with token inside
134 $qs = $_SERVER["QUERY_STRING"];
135 $qs = preg_replace('/&action=addrights/', '', $qs);
136 $qs = preg_replace('/&token=[0-9a-f]+/i', '', $qs);
137 $qs = preg_replace('/&confirm=yes/', '', $qs);
138 header("Location: ".$_SERVER["PHP_SELF"].($qs ? "?".$qs : ""));
139 exit;
140 }
141
142 if ($action == 'delrights' && $caneditperms && $confirm == 'yes') {
143 $edituser = new User($db);
144 $edituser->fetch($object->id);
145 $result = $edituser->delrights($rights, $module, '', $entity);
146 if ($result < 0) {
147 setEventMessages($edituser->error, $edituser->errors, 'errors');
148 }
149
150 // If we are changing our own permissions, we reload permissions and menu
151 if ($object->id == $user->id) {
152 $user->clearrights();
153 $user->loadRights();
154 // @phan-suppress-next-line PhanRedefinedClassReference
155 $menumanager->loadMenu();
156 }
157
158 $object->clearrights();
159 $object->loadRights();
160
161 // We redirect to avoid to get an URL with token inside
162 $qs = $_SERVER["QUERY_STRING"];
163 $qs = preg_replace('/&action=delrights/', '', $qs);
164 $qs = preg_replace('/&token=[0-9a-f]+/i', '', $qs);
165 $qs = preg_replace('/&confirm=yes/', '', $qs);
166 header("Location: ".$_SERVER["PHP_SELF"].($qs ? "?".$qs : ""));
167 exit;
168 }
169}
170
171$db->begin();
172
173// Search all modules with permission and reload permissions def.
174$modules = array();
175$modulesdir = dolGetModulesDirs();
176
177// Modules to ignore depending on supplier module mode
178$excludedModules = getDolGlobalInt('MAIN_USE_NEW_SUPPLIERMOD') ? array('modFournisseur') : array('modSupplierOrder', 'modSupplierInvoice');
179
180// Preload MAIN_MODULE_* enablement for the target entity in one query, so we can skip calling
181// insert_permissions() (which starts by re-checking this same enablement with its own query) on
182// every disabled module found on disk. If we are looking at our own entity, $conf->global already
183// has this cached from bootstrap and no query is needed at all.
184if ($entity == $conf->entity) {
185 $enabledmoduleconst = (array) $conf->global;
186} else {
187 $enabledmoduleconst = array();
188 $sql = "SELECT ".$db->decrypt('name')." as name, ".$db->decrypt('value')." as value";
189 $sql .= " FROM ".MAIN_DB_PREFIX."const";
190 $sql .= " WHERE entity IN (0, ".((int) $entity).")";
191 $sql .= " ORDER BY entity"; // entity 0 first, then entity-specific overrides it
192 $resql = $db->query($sql);
193 if ($resql) {
194 while ($obj = $db->fetch_object($resql)) {
195 $enabledmoduleconst[$obj->name] = $obj->value;
196 }
197 $db->free($resql);
198 }
199}
200
201// Preload the ids of rights already present in llx_rights_def for this entity in one query, so insert_permissions()
202// below can check existence in-memory instead of issuing one "SELECT count(*)" query per permission of every module.
203$existingrightsdefids = array();
204$sql = "SELECT id FROM ".MAIN_DB_PREFIX."rights_def WHERE entity = ".((int) $entity);
205$resql = $db->query($sql);
206if ($resql) {
207 while ($obj = $db->fetch_object($resql)) {
208 $existingrightsdefids[$obj->id] = 1;
209 }
210 $db->free($resql);
211}
212
213foreach ($modulesdir as $dir) {
214 $handle = @opendir(dol_osencode($dir));
215 if (is_resource($handle)) {
216 while (($file = readdir($handle)) !== false) {
217 if (is_readable($dir.$file) && substr($file, 0, 3) == 'mod' && substr($file, dol_strlen($file) - 10) == '.class.php') {
218 $modName = substr($file, 0, dol_strlen($file) - 10);
219
220 if ($modName) {
221 // Exclude old/new supplier descriptors depending on MAIN_USE_NEW_SUPPLIERMOD
222 if (in_array($modName, $excludedModules, true)) {
223 continue;
224 }
225
226 include_once $dir.$file;
227 $objMod = new $modName($db);
228 '@phan-var-force DolibarrModules $objMod';
231 // Load all lang files of module
232 if (isset($objMod->langfiles) && is_array($objMod->langfiles)) {
233 foreach ($objMod->langfiles as $domain) {
234 $langs->load($domain);
235 }
236 }
237 // Load all permissions
238 if ($objMod->rights_class) {
239 // Skip the DB round trip insert_permissions() would do just to find out the
240 // module is disabled for this entity - we already know from the preload above.
241 if (empty($objMod->const_name) || !empty($enabledmoduleconst[$objMod->const_name])) {
242 $objMod->insert_permissions(0, $entity, 0, $existingrightsdefids);
243 }
244 $modules[$objMod->rights_class] = $objMod;
245 //print "modules[".$objMod->rights_class."]=$objMod;";
246 }
247 }
248 }
249 }
250 }
251}
252
253$db->commit();
254
255'@phan-var-force DolibarrModules[] $modules';
256
257
258// Fix bad value for module_position in table
259// ------------------------------------------
260$sql = "SELECT r.id, r.libelle as label, r.module, r.perms, r.subperms, r.module_position, r.family, r.family_position, r.bydefault";
261$sql .= " FROM ".MAIN_DB_PREFIX."rights_def as r";
262$sql .= " WHERE r.libelle NOT LIKE 'tou%'"; // We ignore permission "tous les tiers". Why ?
263$sql .= " AND r.entity = ".((int) $entity);
264$sql .= " ORDER BY r.family, r.family_position, r.module_position, r.right_position, r.module, r.id";
265
266$result = $db->query($sql);
267if ($result) {
268 $num = $db->num_rows($result);
269 $i = 0;
270
271 while ($i < $num) {
272 $obj = $db->fetch_object($result);
273
274 // If line is for a module that does not exist anymore (absent of includes/module), we ignore it
275 if (!isset($obj->module) || empty($modules[$obj->module])) {
276 $i++;
277 continue;
278 }
279
280 // Special cases
281 if (isModEnabled("reception")) {
282 // The 2 permissions in vendor modules are replaced by the 2 permissions into reception module
283 if ($obj->module == 'fournisseur' && $obj->perms == 'commande' && $obj->subperms == 'receptionner') {
284 $i++;
285 continue;
286 }
287 if ($obj->module == 'fournisseur' && $obj->perms == 'commande_advance' && $obj->subperms == 'check') {
288 $i++;
289 continue;
290 }
291 }
292
293 $objMod = $modules[$obj->module];
294 // $objMod is necessarily an object here
295
296 // Save field module_position in database if value is undefined or wrong (old data/version)
297 if (empty($obj->module_position) || ($objMod->isCoreOrExternalModule() == 'external' && $obj->module_position < 100000)) {
298 if (is_object($modules[$obj->module]) && ($modules[$obj->module]->module_position > 0)) {
299 // TODO Define familyposition
300 //$familyposition = $modules[$obj->module]->family_position;
301 $familyposition = 0;
302
303 $newmoduleposition = $modules[$obj->module]->module_position;
304
305 // Correct $newmoduleposition position for external modules
306 $objMod = $modules[$obj->module];
307 if (is_object($objMod) && $objMod->isCoreOrExternalModule() == 'external' && $newmoduleposition < 100000) {
308 $newmoduleposition += 100000;
309 }
310
311 $sqlupdate = 'UPDATE '.MAIN_DB_PREFIX."rights_def SET module_position = ".((int) $newmoduleposition).",";
312 $sqlupdate .= " family_position = ".((int) $familyposition);
313 $sqlupdate .= " WHERE module_position = ".((int) $obj->module_position)." AND module = '".$db->escape($obj->module)."'";
314
315 $db->query($sqlupdate);
316 }
317 }
318
319 // Save field family in database if value is undefined (old data/version)
320 if (empty($obj->family) && !empty($objMod->family)) {
321 $newfamily = $objMod->family;
322 $sqlupdate = 'UPDATE '.MAIN_DB_PREFIX."rights_def SET family = '".$db->escape($newfamily)."'";
323 $sqlupdate .= " WHERE id = ".((int) $obj->id);
324
325 $db->query($sqlupdate);
326 }
327 }
328} else {
330}
331
332
333/*
334 * View
335 */
336
337$form = new Form($db);
338
339$person_name = !empty($object->firstname) ? $object->lastname.", ".$object->firstname : $object->lastname;
340$title = $person_name." - ".$langs->trans('Permissions');
341$help_url = '';
342llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-user page-card_perms');
343
345
346$title = $langs->trans("User");
347print dol_get_fiche_head($head, 'rights', $title, -1, 'user');
348
349// Read permissions of edited user
350$permsuser = array();
351
352$sql = "SELECT ur.fk_id";
353$sql .= " FROM ".MAIN_DB_PREFIX."user_rights as ur";
354$sql .= " WHERE ur.entity = ".((int) $entity);
355$sql .= " AND ur.fk_user = ".((int) $object->id);
356
357dol_syslog("get user perms", LOG_DEBUG);
358$result = $db->query($sql);
359if ($result) {
360 $num = $db->num_rows($result);
361 $i = 0;
362 while ($i < $num) {
363 $obj = $db->fetch_object($result);
364 array_push($permsuser, $obj->fk_id);
365 $i++;
366 }
367 $db->free($result);
368} else {
370}
371
372// Read the permissions of a user inherited by its groups
373$permsgroupbyentity = array();
374
375$sql = "SELECT DISTINCT gr.fk_id, gu.entity"; // fk_id are permission id and entity is entity of the group
376$sql .= " FROM ".MAIN_DB_PREFIX."usergroup_rights as gr,";
377$sql .= " ".MAIN_DB_PREFIX."usergroup_user as gu"; // all groups of a user
378$sql .= " WHERE gr.entity = ".((int) $entity); // it's very important, don't change please !
379// The entity on the table gu=usergroup_user should be useless and should never be used because it is already into gr and r.
380// but when using MULTICOMPANY_TRANSVERSE_MODE, we may have inserted record that make rubbish result here due to the duplicate record of
381// other entities, so we are forced to add a filter on gu here
382if (getDolGlobalString("MULTICOMPANY_TRANSVERSE_MODE_FIX_WHEN_GU_CONTAINS_0")) {
383 $sql .= " AND gu.entity IN (0,". ((int) $entity).")";
384} else {
385 $sql .= " AND gu.entity = ".((int) $entity);
386}
387$sql .= " AND gr.fk_usergroup = gu.fk_usergroup";
388$sql .= " AND gu.fk_user = ".((int) $object->id);
389
390dol_syslog("get user perms", LOG_DEBUG);
391$result = $db->query($sql);
392if ($result) {
393 $num = $db->num_rows($result);
394 $i = 0;
395 while ($i < $num) {
396 $obj = $db->fetch_object($result);
397 if (!isset($permsgroupbyentity[$obj->entity])) {
398 $permsgroupbyentity[$obj->entity] = array();
399 }
400 array_push($permsgroupbyentity[$obj->entity], $obj->fk_id);
401 $i++;
402 }
403 $db->free($result);
404} else {
406}
407
408
409
410/*
411 * Part to add/remove permissions
412 */
413
414$linkback = '';
415
416if ($user->hasRight("user", "user", "read") || $user->admin) {
417 $linkback = '<a href="'.DOL_URL_ROOT.'/user/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
418}
419
420$morehtmlref = '<a href="'.DOL_URL_ROOT.'/user/vcard.php?id='.$object->id.'&output=file&file='.urlencode(dol_sanitizeFileName($object->getFullName($langs).'.vcf')).'" class="refid valignmiddle" rel="noopener">';
421$morehtmlref .= img_picto($langs->trans("Download").' '.$langs->trans("VCard"), 'vcard', 'class="valignmiddle marginleftonly paddingrightonly"');
422$morehtmlref .= '</a>';
423
424$urltovirtualcard = '/user/virtualcard.php?id='.((int) $object->id);
425$morehtmlref .= dolButtonToOpenUrlInDialogPopup('publicvirtualcard', $langs->transnoentitiesnoconv("PublicVirtualCardUrl").' - '.$object->getFullName($langs), img_picto($langs->trans("PublicVirtualCardUrl"), 'card', 'class="refid valignmiddle marginleftonly paddingrightonly"'), $urltovirtualcard, '', 'refid valignmiddle nohover');
426
427dol_banner_tab($object, 'id', $linkback, $user->hasRight("user", "user", "read") || $user->admin, 'rowid', 'ref', $morehtmlref);
428
429
430print '<div class="fichecenter">';
431
432print '<div class="underbanner clearboth"></div>';
433print '<table class="border centpercent tableforfield">';
434
435// Login
436print '<tr><td id="anchorforperms" class="titlefield">'.$langs->trans("Login").'</td>';
437if (!empty($object->ldap_sid) && $object->status == 0) {
438 print '<td class="error">';
439 print $langs->trans("LoginAccountDisableInDolibarr");
440 print '</td>';
441} else {
442 print '<td>';
443 $addadmin = '';
444 if (isModEnabled('multicompany') && !empty($object->admin) && empty($object->entity)) {
445 $addadmin .= img_picto($langs->trans("SuperAdministratorDesc"), "superadmin", 'class="paddingleft valignmiddle"');
446 } elseif (!empty($object->admin)) {
447 $addadmin .= img_picto($langs->trans("AdministratorDesc"), "admin", 'class="paddingleft valignmiddle"');
448 }
449 print showValueWithClipboardCPButton($object->login).$addadmin;
450 print '</td>';
451}
452print '</tr>'."\n";
453
454// Type
455print '<tr><td>';
456$text = $langs->trans("Type");
457print $form->textwithpicto($text, $langs->trans("InternalExternalDesc"));
458print '</td><td>';
459$type = $langs->trans("Internal");
460if ($object->socid > 0) {
461 $type = $langs->trans("External");
462}
463print '<span class="badgeneutral">';
464print $type;
465if ($object->ldap_sid) {
466 print ' ('.$langs->trans("DomainUser").')';
467}
468print '</span>';
469print '</td></tr>'."\n";
470
471print '</table>';
472print '</div>';
473
474
475print '<br>';
476
477
478if ($user->admin) {
479 $s = $langs->trans("WarningOnlyPermissionOfActivatedModules")." ".$langs->trans("YouCanEnableModulesFrom");
480 if (getDolGlobalString('MAIN_USE_ADVANCED_PERMS')) {
481 $s .= '<br>';
482 $s .= img_picto($langs->trans('InfoAdmin'), 'info-circle').' ';
483 $s .= $langs->trans("YouAreUsingTheAdvancedPermissionsMode");
484 } else {
485 $s .= '<br>';
486 $s .= img_picto($langs->trans('InfoAdmin'), 'info-circle').' ';
487 $s .= $langs->trans("YouAreUsingTheSimplePermissionsMode");
488 }
489 print info_admin($s);
490}
491// If edited user is an extern user, we show warning for external users
492if (!empty($object->socid)) {
493 print info_admin(showModulesExludedForExternal($modules))."\n";
494}
495print '<br>';
496
497$parameters = array('permsgroupbyentity' => $permsgroupbyentity);
498$reshook = $hookmanager->executeHooks('insertExtraHeader', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
499if ($reshook < 0) {
500 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
501}
502
503print "\n";
504print '<div class="div-table-responsive-no-min">';
505print '<table class="noborder centpercent">';
506
507print '<tr class="liste_titre">';
508print '<td>'.$langs->trans("Module").'</td>';
509if ($caneditperms) {
510 print '<td class="center nowrap">';
511 print '<a class="reposition commonlink addexpandedmodulesinparamlist" title="'.dol_escape_htmltag($langs->trans("All")).'" alt="'.dol_escape_htmltag($langs->trans("All")).'" href="'.dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id, 'action' => 'addrights', 'entity' => $entity, 'module' => 'allmodules', 'confirm' => 'yes'], true).'">'.$langs->trans("All")."</a>";
512 print ' / ';
513 print '<a class="reposition commonlink addexpandedmodulesinparamlist" title="'.dol_escape_htmltag($langs->trans("None")).'" alt="'.dol_escape_htmltag($langs->trans("None")).'" href="'.dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id, 'action' => 'delrights', 'entity' => $entity, 'module' => 'allmodules', 'confirm' => 'yes'], true).'">'.$langs->trans("None")."</a>";
514 print '</td>';
515} else {
516 print '<td></td>';
517}
518print '<td></td>';
519print '<td class="right nowrap" colspan="2">';
520print '<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>';
521print ' | ';
522print '<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>';
523print '</td>';
524print '</tr>'."\n";
525
526// Get list of all permissions
527$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";
528$sql .= " FROM ".MAIN_DB_PREFIX."rights_def as r";
529$sql .= " WHERE r.libelle NOT LIKE 'tou%'"; // We ignore permission "tous les tiers". Why ?
530$sql .= " AND r.entity = ".((int) $entity);
531if (!getDolGlobalString('MAIN_USE_ADVANCED_PERMS')) {
532 $sql .= " AND r.perms NOT LIKE '%_advance'"; // Hide advanced perms if option is not enabled
533}
534$sql .= " ORDER BY r.family_position, r.module_position, r.right_position, r.module, r.id";
535
536$familyinfo = array(
537 'hr' => array('position' => '001', 'label' => $langs->trans("ModuleFamilyHr")),
538 'crm' => array('position' => '006', 'label' => $langs->trans("ModuleFamilyCrm")),
539 'srm' => array('position' => '007', 'label' => $langs->trans("ModuleFamilySrm")),
540 'financial' => array('position' => '009', 'label' => $langs->trans("ModuleFamilyFinancial")),
541 'products' => array('position' => '012', 'label' => $langs->trans("ModuleFamilyProducts")),
542 'projects' => array('position' => '015', 'label' => $langs->trans("ModuleFamilyProjects")),
543 'ecm' => array('position' => '018', 'label' => $langs->trans("ModuleFamilyECM")),
544 'technic' => array('position' => '021', 'label' => $langs->trans("ModuleFamilyTechnic")),
545 'portal' => array('position' => '040', 'label' => $langs->trans("ModuleFamilyPortal")),
546 'interface' => array('position' => '050', 'label' => $langs->trans("ModuleFamilyInterface")),
547 'base' => array('position' => '060', 'label' => $langs->trans("ModuleFamilyBase")),
548 'other' => array('position' => '100', 'label' => $langs->trans("ModuleFamilyOther")),
549 'external' => array('position' => '500', 'label' => 'External'),
550);
551
552$arrayofpermission = array();
553$cookietohidegroup = (empty($_COOKIE["DOLUSER_PERMS_HIDE_GRP"]) ? '' : preg_replace('/^,/', '', $_COOKIE["DOLUSER_PERMS_HIDE_GRP"]));
554$cookietohidegrouparray = explode(',', $cookietohidegroup);
555
556$result = $db->query($sql);
557if ($result) {
558 $num = $db->num_rows($result);
559 $i = 0;
560
561
562 while ($i < $num) {
563 $obj = $db->fetch_object($result);
564
565 if (empty($obj->family)) {
566 $obj->family = 'other';
567 }
568 if (!empty($obj->family) && !isset($familyinfo[$obj->family])) {
569 $obj->family = 'external';
570 }
571
572 // If the family does not exist in $familyinfo, use 'other'
573 if (!empty($obj->family) && !isset($familyinfo[$obj->family])) {
574 $obj->family = 'other';
575 }
576 if (empty($obj->family_position)) {
577 $obj->family_position = $familyinfo[$obj->family]['position'];
578 if ($obj->module_position < 100000) {
579 $obj->module_position = intval($obj->module_position) + 100000;
580 } else {
581 $obj->module_position = intval($obj->module_position);
582 }
583 }
584
585 $obj->position = $obj->family_position.'_'.$obj->module_position.'_'.$obj->id;
586
587 $arrayofpermission[$i] = $obj;
588 $i++;
589 }
590} else {
592}
593
594
595$arrayofpermission = dol_sort_array($arrayofpermission, 'position');
596
597$j = 0;
598$oldmod = '';
599
600foreach ($arrayofpermission as $i => $obj) {
601 // If line is for a module that does not exist anymore (absent of includes/module), we ignore it
602 if (empty($modules[$obj->module])) {
603 $i++;
604 continue;
605 }
606
607 // Special cases
608 if (isModEnabled("reception")) {
609 // The 2 permission in fournisseur modules has been replaced by permissions into reception module
610 if ($obj->module == 'fournisseur' && $obj->perms == 'commande' && $obj->subperms == 'receptionner') {
611 $i++;
612 continue;
613 }
614 if ($obj->module == 'fournisseur' && $obj->perms == 'commande_advance' && $obj->subperms == 'check') {
615 $i++;
616 continue;
617 }
618 }
619
620 $objMod = $modules[$obj->module];
621
622 if (GETPOSTISSET('forbreakperms_'.$obj->module)) {
623 $ishidden = GETPOSTINT('forbreakperms_'.$obj->module);
624 } elseif (in_array($j, $cookietohidegrouparray)) { // If j is among list of hidden group
625 $ishidden = 1;
626 } else {
627 $ishidden = 0;
628 }
629 $isexpanded = ! $ishidden;
630
631 $permsgroupbyentitypluszero = array();
632 if (!empty($permsgroupbyentity[0])) {
633 $permsgroupbyentitypluszero = array_merge($permsgroupbyentitypluszero, $permsgroupbyentity[0]);
634 }
635 if (!empty($permsgroupbyentity[$entity])) {
636 $permsgroupbyentitypluszero = array_merge($permsgroupbyentitypluszero, $permsgroupbyentity[$entity]);
637 }
638
639 // Break found, it's a new module to catch
640 if (isset($obj->module) && ($oldmod != $obj->module)) {
641 $oldmod = $obj->module;
642
643 $j++;
644 if (GETPOSTISSET('forbreakperms_'.$obj->module)) {
645 $ishidden = GETPOSTINT('forbreakperms_'.$obj->module);
646 } elseif (in_array($j, $cookietohidegrouparray)) { // If j is among list of hidden group
647 $ishidden = 1;
648 } else {
649 $ishidden = 0;
650 }
651 $isexpanded = ! $ishidden;
652
653 // Break detected, we get objMod
654 $objMod = $modules[$obj->module];
655 $picto = ($objMod->picto ? $objMod->picto : 'generic');
656
657 // Show break line
658 print '<tr class="oddeven trforbreakperms trforbreaknobg" data-hide-perms="'.$obj->module.'" data-j="'.$j.'">';
659 // Picto and label of module
660 print '<td class="maxwidthonsmartphone tdoverflowmax200 tdforbreakperms" data-hide-perms="'.dol_escape_htmltag($obj->module).'" title="'.dol_escape_htmltag($objMod->getName()).'">';
661 print '<input type="hidden" name="forbreakperms_'.$obj->module.'" id="idforbreakperms_'.$obj->module.'" css="cssforfieldishiden" data-j="'.$j.'" value="'.($isexpanded ? '0' : "1").'">';
662 print img_object('', $picto, 'class="pictoobjectwidth paddingright"').' '.$objMod->getName();
663 print '<a name="'.$objMod->getName().'"></a>';
664 print '</td>';
665
666 // Permission and tick (2 columns)
667 if (($caneditperms && empty($objMod->rights_admin_allowed)) || empty($object->admin)) {
668 if ($caneditperms) {
669 print '<td class="tdforbreakperms tdforbreakpermsifnotempty center width50 nowraponall" data-hide-perms="'.dol_escape_htmltag($obj->module).'">';
670 print '<span class="permtohide_'.dol_escape_htmltag($obj->module).'" '.(!$isexpanded ? ' style="display:none"' : '').'>';
671 print '<a class="reposition alink addexpandedmodulesinparamlist" title="'.dol_escape_htmltag($langs->trans("All")).'" alt="'.dol_escape_htmltag($langs->trans("All")).'" href="'.dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id, 'action' => 'addrights', 'entity' => $entity, 'module' => $obj->module, 'confirm' => 'yes', 'updatedmodulename' => $obj->module], true).'">'.$langs->trans("All")."</a>";
672 print ' / ';
673 print '<a class="reposition alink addexpandedmodulesinparamlist" title="'.dol_escape_htmltag($langs->trans("None")).'" alt="'.dol_escape_htmltag($langs->trans("None")).'" href="'.dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id, 'action' => 'delrights', 'entity' => $entity, 'module' => $obj->module, 'confirm' => 'yes', 'updatedmodulename' => $obj->module], true).'">'.$langs->trans("None")."</a>";
674 print '</span>';
675 print '</td>';
676 print '<td class="tdforbreakperms" data-hide-perms="'.dol_escape_htmltag($obj->module).'">';
677 print '</td>';
678 } else {
679 print '<td class="tdforbreakperms" data-hide-perms="'.dol_escape_htmltag($obj->module).'"></td>';
680 print '<td class="tdforbreakperms" data-hide-perms="'.dol_escape_htmltag($obj->module).'"></td>';
681 }
682 } else {
683 if ($caneditperms) {
684 print '<td class="tdforbreakperms center wraponsmartphone" data-hide-perms="'.dol_escape_htmltag($obj->module).'">';
685 /*print '<a class="reposition alink" 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>";
686 print ' / ';
687 print '<a class="reposition alink" 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>";
688 */
689 print '</td>';
690 print '<td class="tdforbreakperms" data-hide-perms="'.dol_escape_htmltag($obj->module).'">';
691 print '</td>';
692 } else {
693 print '<td class="right tdforbreakperms" data-hide-perms="'.dol_escape_htmltag($obj->module).'"></td>';
694 print '<td class="tdforbreakperms" data-hide-perms="'.dol_escape_htmltag($obj->module).'"></td>';
695 }
696 }
697
698 // Description of permission (2 columns)
699 print '<td class="tdforbreakperms" data-hide-perms="'.dol_escape_htmltag($obj->module).'"></td>';
700 print '<td class="maxwidthonsmartphone right tdforbreakperms" data-hide-perms="'.dol_escape_htmltag($obj->module).'">';
701
702 print '<div class="switchfolderperms inline-block marginrightonly folderperms_'.dol_escape_htmltag($obj->module).'"'.($isexpanded ? ' style="display:none;"' : '').'>';
703 print img_picto('', 'folder', 'class="marginright"');
704 print '</div>';
705 print '<div class="switchfolderperms inline-block marginrightonly folderopenperms_'.dol_escape_htmltag($obj->module).'"'.(!$isexpanded ? ' style="display:none;"' : '').'>';
706 print img_picto('', 'folder-open', 'class="marginright"');
707 print '</div>';
708
709 print '</td>'; //Add picto + / - when open en closed
710 print '</tr>'."\n";
711 }
712
713 $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)));
714
715 // This right is declared by another module (module_origin) but filed into this module's
716 // section for display (KEY_MODULE): show a small badge so it is not mistaken for a native
717 // right of this module.
718 if (!empty($obj->module_origin) && $obj->module_origin != $obj->module && !empty($modules[$obj->module_origin])) {
719 $permoriginmod = $modules[$obj->module_origin];
720 $permoriginpicto = ($permoriginmod->picto ? $permoriginmod->picto : 'generic');
721 $permlabel = img_picto($langs->trans("RightProvidedByModule", $permoriginmod->getName()), $permoriginpicto, 'class="paddingrightonly"').$permlabel;
722 }
723
724 print '<!-- '.$obj->module.'->'.$obj->perms.($obj->subperms ? '->'.$obj->subperms : '').' -->'."\n";
725 print '<tr class="oddeven trtohide_'.$obj->module.'"'.(!$isexpanded ? ' style="display:none"' : '').'>';
726
727 // Picto and label of module
728 print '<td class="maxwidthonsmartphone">';
729 print '</td>';
730
731 // Permission and tick (2 columns)
732 if (!empty($object->admin) && !empty($objMod->rights_admin_allowed)) { // Permission granted because admin
733 print '<!-- perm is a perm allowed to any admin -->';
734 if ($caneditperms) {
735 print '<td class="center nowrap">';
736 print img_picto($langs->trans("AdministratorDesc"), 'admin', 'class="paddingleft valignmiddle"');
737 print '</td>';
738 } else {
739 print '<td class="center nowrap">';
740 print img_picto($langs->trans("Active"), 'switch_on', '', 0, 0, 0, '', 'opacitymedium');
741 print '</td>';
742 }
743 print '<td>';
744 print '</td>';
745 } elseif (in_array($obj->id, $permsuser)) { // Permission granted by user
746 print '<!-- user has perm -->';
747 if ($caneditperms) {
748 print '<td class="center nowrap">';
749 print '<a class="reposition addexpandedmodulesinparamlist" id="'.$obj->id.'" href="'.dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id, 'action' => 'delrights', 'entity' => $entity, 'rights' => $obj->id, 'confirm' => 'yes', 'updatedmodulename' => $obj->module], true).'">';
750 //print img_edit_remove($langs->trans("Remove"));
751 print img_picto($langs->trans("Remove"), 'switch_on');
752 print '</a>';
753 print '</td>';
754 } else {
755 print '<td class="center nowrap">';
756 print img_picto($langs->trans("Active"), 'switch_on', '', 0, 0, 0, '', 'opacitymedium');
757 print '</td>';
758 }
759 print '<td>';
760 print '</td>';
761 } elseif (isset($permsgroupbyentitypluszero) && is_array($permsgroupbyentitypluszero)) {
762 print '<!-- permsgroupbyentitypluszero -->';
763 if (in_array($obj->id, $permsgroupbyentitypluszero)) { // Permission granted by group
764 print '<td class="center nowrap">';
765 print img_picto($langs->trans("Active"), 'switch_on', '', 0, 0, 0, '', 'opacitymedium');
766 //print img_picto($langs->trans("Active"), 'tick');
767 print '</td>';
768 print '<td class="center nowrap">';
769 print $form->textwithtooltip($langs->trans("Inherited"), $langs->trans("PermissionInheritedFromAGroup"));
770 print '</td>';
771 } else {
772 // Do not own permission
773 if ($caneditperms) {
774 print '<td class="center nowrap">';
775 print '<a class="reposition addexpandedmodulesinparamlist" id="'.$obj->id.'" href="'.dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id, 'action' => 'addrights', 'entity' => $entity, 'rights' => $obj->id, 'confirm' => 'yes', 'updatedmodulename' => $obj->module], true).'">';
776 //print img_edit_add($langs->trans("Add"));
777 print img_picto($langs->trans("Add"), 'switch_off');
778 print '</a>';
779 print '</td>';
780 } else {
781 print '<td class="center nowrap">';
782 print img_picto($langs->trans("Disabled"), 'switch_off', '', 0, 0, 0, '', 'opacitymedium');
783 print '</td>';
784 }
785 print '<td>';
786 print '</td>';
787 }
788 } else {
789 // Do not own permission
790 print '<!-- do not own permission -->';
791 if ($caneditperms) {
792 print '<td class="center nowrap">';
793 print '<a class="reposition addexpandedmodulesinparamlist" id="'.$obj->id.'" href="'.dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id, 'action' => 'addrights', 'entity' => $entity, 'rights' => $obj->id, 'confirm' => 'yes', 'updatedmodulename' => $obj->module], true).'">';
794 //print img_edit_add($langs->trans("Add"));
795 print img_picto($langs->trans("Add"), 'switch_off');
796 print '</a>';
797 print '</td>';
798 } else {
799 print '<td class="center nowrap">';
800 print img_picto($langs->trans("Disabled"), 'switch_off', '', 0, 0, 0, '', 'opacitymedium');
801 print '</td>';
802 }
803 print '<td>';
804 print '</td>';
805 }
806
807 // Description of permission (1 or 2 columns)
808 if (!$user->admin) {
809 print '<td colspan="2">';
810 } else {
811 print '<td>';
812 }
813
814 print $permlabel;
815 $idtouse = $obj->id;
816 if (in_array($idtouse, array(121, 122, 125, 126))) { // Force message for the 3 permission on third parties
817 $idtouse = 122;
818 }
819 if ($langs->trans("Permission".$idtouse.'b') != "Permission".$idtouse.'b') {
820 print '<br><span class="opacitymedium">'.$langs->trans("Permission".$idtouse.'b').'</span>';
821 }
822 if ($langs->trans("Permission".$obj->id.'c') != "Permission".$obj->id.'c') {
823 print '<br><span class="opacitymedium">'.$langs->trans("Permission".$obj->id.'c').'</span>';
824 }
825 if (getDolGlobalString('MAIN_USE_ADVANCED_PERMS')) {
826 if (preg_match('/_advance$/', $obj->perms)) {
827 print ' <span class="opacitymedium">('.$langs->trans("AdvancedModeOnly").')</span>';
828 }
829 }
830 // Special warning case for the permission "Allow to modify other users password"
831 if ($obj->module == 'user' && $obj->perms == 'user' && $obj->subperms == 'password') {
832 if ((!empty($object->admin) && !empty($objMod->rights_admin_allowed)) ||
833 in_array($obj->id, $permsuser) /* if edited user owns this permissions */ ||
834 (isset($permsgroupbyentitypluszero) && is_array($permsgroupbyentitypluszero) && in_array($obj->id, $permsgroupbyentitypluszero))) {
835 print ' '.img_warning($langs->trans("AllowPasswordResetBySendingANewPassByEmail"));
836 }
837 }
838 // Special warning case for the permission "Create/modify other users, groups and permissions"
839 if ($obj->module == 'user' && $obj->perms == 'user' && ($obj->subperms == 'creer' || $obj->subperms == 'create')) {
840 if ((!empty($object->admin) && !empty($objMod->rights_admin_allowed)) ||
841 in_array($obj->id, $permsuser) /* if edited user owns this permissions */ ||
842 (isset($permsgroupbyentitypluszero) && is_array($permsgroupbyentitypluszero) && in_array($obj->id, $permsgroupbyentitypluszero))) {
843 print ' '.img_warning($langs->trans("AllowAnyPrivileges"));
844 }
845 }
846 // Special case for reading bank account when you have permission to manage Chart of account
847 if ($obj->module == 'banque' && $obj->perms == 'lire') {
848 if (isModEnabled("accounting") && $object->hasRight('accounting', 'chartofaccount')) {
849 print ' '.img_warning($langs->trans("WarningReadBankAlsoAllowedIfUserHasPermission"));
850 }
851 }
852
853 print '</td>';
854
855 // Permission id
856 if ($user->admin) {
857 print '<td class="right">';
858 $htmltext = $langs->trans("ID").': '.$obj->id;
859 // hasRight() is actually checked against module_origin when set (right filed into
860 // another module's section via KEY_MODULE but still checked under the module that
861 // declared it), not the display module column, see User::loadRights().
862 $htmltextmodule = (!empty($obj->module_origin) ? $obj->module_origin : $obj->module);
863 $htmltext .= '<br>'.$langs->trans("Permission").': user->hasRight(\''.dol_escape_htmltag($htmltextmodule).'\', \''.dol_escape_htmltag($obj->perms).'\''.($obj->subperms ? ', \''.dol_escape_htmltag($obj->subperms).'\'' : '').')';
864 print $form->textwithpicto('', $htmltext, 1, 'help', 'inline-block marginrightonly');
865 //print '<span class="opacitymedium">'.$obj->id.'</span>';
866 print '</td>';
867 }
868
869 print '</tr>'."\n";
870
871 $i++;
872}
873print '</table>';
874print '</div>';
875
876print '<script>';
877print '$(".tdforbreakperms:not(.alink)").on("click", function(){
878 console.log("Click on tdforbreakperms");
879 moduletohide = $(this).data("hide-perms");
880 j = $(this).data("j");
881 if ($("#idforbreakperms_"+moduletohide).val() == 1) {
882 console.log("idforbreakperms_"+moduletohide+" has value hidden=1, so we show all lines");
883 $(".trtohide_"+moduletohide).show();
884 $(".permtoshow_"+moduletohide).hide();
885 $(".permtohide_"+moduletohide).show();
886 $(".folderperms_"+moduletohide).hide();
887 $(".folderopenperms_"+moduletohide).show();
888 $("#idforbreakperms_"+moduletohide).val("0");
889 } else if (! $(this).hasClass("tdforbreakpermsifnotempty")) {
890 console.log("idforbreakperms_"+moduletohide+" has value hidden=0, so we hide all lines");
891 $(".trtohide_"+moduletohide).hide();
892 $(".folderopenperms_"+moduletohide).hide();
893 $(".folderperms_"+moduletohide).show();
894 $(".permtoshow_"+moduletohide).show();
895 $(".permtohide_"+moduletohide).hide();
896 $("#idforbreakperms_"+moduletohide).val("1");
897 }
898
899 // Now rebuild the value for cookie
900 var hideuserperm="";
901 $(".trforbreakperms").each(function(index) {
902 //console.log( index + ": " + $( this ).data("j") + " " + $( this ).data("hide-perms") + " " + $("input[data-j="+(index+1)+"]").val());
903 if ($("input[data-j="+(index+1)+"]").val() == 1) {
904 hideuserperm=hideuserperm+","+(index+1);
905 }
906 });
907 // set cookie by js
908 date = new Date(); date.setTime(date.getTime()+(30*86400000));
909 if (hideuserperm) {
910 console.log("set cookie DOLUSER_PERMS_HIDE_GRP="+hideuserperm);
911 document.cookie = "DOLUSER_PERMS_HIDE_GRP=" + hideuserperm + "; expires=" + date.toGMTString() + "; path=/ ";
912 } else {
913 console.log("delete cookie DOLUSER_PERMS_HIDE_GRP");
914 document.cookie = "DOLUSER_PERMS_HIDE_GRP=; expires=Thu, 01-Jan-70 00:00:01 GMT; path=/ ";
915 }
916});';
917print "\n";
918
919// Button expand / collapse all
920print '$(".showallperms").on("click", function(){
921 console.log("Click on showallperms");
922
923 console.log("delete cookie DOLUSER_PERMS_HIDE_GRP from showallperms click");
924 document.cookie = "DOLUSER_PERMS_HIDE_GRP=; expires=Thu, 01-Jan-70 00:00:01 GMT; path=/ ";
925 $(".tdforbreakperms").each( function(){
926 moduletohide = $(this).data("hide-perms");
927 //console.log(moduletohide);
928 if ($("#idforbreakperms_"+moduletohide).val() != 0) {
929 $(this).trigger("click"); // emulate the click, so the cooki will be resaved
930 }
931 })
932});
933
934$(".hideallperms").on("click", function(){
935 console.log("Click on hideallperms");
936
937 $(".tdforbreakperms").each( function(){
938 moduletohide = $(this).data("hide-perms");
939 //console.log(moduletohide);
940 if ($("#idforbreakperms_"+moduletohide).val() != 1) {
941 $(this).trigger("click"); // emulate the click, so the cooki will be resaved
942 }
943 })
944});';
945print "\n";
946print '</script>';
947
948print '<style>';
949print '.switchfolderperms{
950 cursor: pointer;
951}';
952print '</style>';
953
954$parameters = array();
955$reshook = $hookmanager->executeHooks('insertExtraFooter', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
956if ($reshook < 0) {
957 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
958}
959
960
961print dol_get_fiche_end();
962
963// End of page
964llxFooter();
965$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
showModulesExludedForExternal($modules)
Show array with constants to edit.
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 manage Dolibarr users.
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.
dolBuildUrl($url, $params=[], $addtoken=false, $anchor='')
Return path of url.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0, $allowdash=0)
Clean a string to use it as a file name.
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...
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.
showValueWithClipboardCPButton($valuetocopy, $showonlyonhover=1, $texttoshow='')
Create a button to copy $valuetocopy in the clipboard (for copy and paste feature).
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
dolButtonToOpenUrlInDialogPopup($name, $label, $buttonstring, $url, $disabled='', $morecss='classlink button bordertransp', $jsonopen='', $jsonclose='', $accesskey='')
Return HTML code to output a button to open a dialog popup box.
Definition html.lib.php:415
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
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $mode=0)
Check permissions of a user to show a page and an object.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.
user_prepare_head(User $object)
Prepare array with list of tabs.