dolibarr 25.0.0-alpha
card.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2002-2006 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2002-2003 Jean-Louis Bergamo <jlb@j1b.org>
4 * Copyright (C) 2004-2022 Laurent Destailleur <eldy@users.sourceforge.net>
5 * Copyright (C) 2004 Eric Seigne <eric.seigne@ryxeo.com>
6 * Copyright (C) 2005-2021 Regis Houssin <regis.houssin@inodbox.com>
7 * Copyright (C) 2005 Lionel Cousteix <etm_ltd@tiscali.co.uk>
8 * Copyright (C) 2011 Herve Prot <herve.prot@symeos.com>
9 * Copyright (C) 2012-2018 Juanjo Menent <jmenent@2byte.es>
10 * Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
11 * Copyright (C) 2013-2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
12 * Copyright (C) 2015-2017 Jean-François Ferry <jfefe@aternatik.fr>
13 * Copyright (C) 2015 Ari Elbaz (elarifr) <github@accedinfo.com>
14 * Copyright (C) 2015-2026 Charlene Benke <charlene@patas-monkey.com>
15 * Copyright (C) 2016 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
16 * Copyright (C) 2018-2026 Frédéric France <frederic.france@free.fr>
17 * Copyright (C) 2018 David Beniamine <David.Beniamine@Tetras-Libre.fr>
18 * Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
19 * Copyright (C) 2026 Jose Martinez <jose.martinez@pichinov.com>
20 *
21 * This program is free software; you can redistribute it and/or modify
22 * it under the terms of the GNU General Public License as published by
23 * the Free Software Foundation; either version 3 of the License, or
24 * (at your option) any later version.
25 *
26 * This program is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU General Public License for more details.
30 *
31 * You should have received a copy of the GNU General Public License
32 * along with this program. If not, see <https://www.gnu.org/licenses/>.
33 */
34
40// Load Dolibarr environment
41require '../main.inc.php';
53require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
54require_once DOL_DOCUMENT_ROOT.'/user/class/usergroup.class.php';
55require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
56require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
57require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
58require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
59require_once DOL_DOCUMENT_ROOT.'/core/lib/usergroups.lib.php';
60require_once DOL_DOCUMENT_ROOT.'/core/lib/emailsignature.lib.php';
61require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
62require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
63require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
64require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
65require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
66if (isModEnabled('ldap')) {
67 require_once DOL_DOCUMENT_ROOT.'/core/class/ldap.class.php';
68}
69if (isModEnabled('member')) {
70 require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
71}
72if (isModEnabled('category')) {
73 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
74}
75if (isModEnabled('stock')) {
76 require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
77}
78
79// Load translation files required by page
80$langs->loadLangs(array('users', 'companies', 'ldap', 'admin', 'hrm', 'stocks', 'other'));
81
82$id = GETPOSTINT('id');
83$action = GETPOST('action', 'aZ09');
84$mode = GETPOST('mode', 'alpha');
85$confirm = GETPOST('confirm', 'alpha');
86$group = GETPOSTINT("group", 3);
87$cancel = GETPOST('cancel', 'alpha');
88$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'usercard'; // To manage different context of search
89$backtopage = GETPOST('backtopage');
90$backtopageforcancel = GETPOST('backtopageforcancel');
91$forcepasswordchange = GETPOSTINT('forcepasswordchange');
92
93if (empty($id) && $action != 'add' && $action != 'create') {
94 $id = $user->id;
95}
96
97$dateemployment = dol_mktime(0, 0, 0, GETPOSTINT('dateemploymentmonth'), GETPOSTINT('dateemploymentday'), GETPOSTINT('dateemploymentyear'));
98$dateemploymentend = dol_mktime(0, 0, 0, GETPOSTINT('dateemploymentendmonth'), GETPOSTINT('dateemploymentendday'), GETPOSTINT('dateemploymentendyear'));
99$datestartvalidity = dol_mktime(0, 0, 0, GETPOSTINT('datestartvaliditymonth'), GETPOSTINT('datestartvalidityday'), GETPOSTINT('datestartvalidityyear'));
100$dateendvalidity = dol_mktime(0, 0, 0, GETPOSTINT('dateendvaliditymonth'), GETPOSTINT('dateendvalidityday'), GETPOSTINT('dateendvalidityyear'));
101$dateofbirth = dol_mktime(0, 0, 0, GETPOSTINT('dateofbirthmonth'), GETPOSTINT('dateofbirthday'), GETPOSTINT('dateofbirthyear'));
102
103$childids = $user->getAllChildIds(1); // For test on hrm fields (like salary visibility)
104
105$object = new User($db);
106
107// fetch optionals attributes and labels
108$extrafields->fetch_name_optionals_label($object->table_element);
109
110$socialnetworks = getArrayOfSocialNetworks();
111
112// Initialize a technical object to manage hooks. Note that conf->hooks_modules contains array
113$hookmanager->initHooks(array('usercard', 'globalcard'));
114
115$error = 0;
116
117$acceptlocallinktomedia = (acceptLocalLinktoMedia() > 0 ? 1 : 0);
118
119if ($id > 0) {
120 $res = $object->fetch($id, '', '', 1);
121}
122
123// Security check
124$socid = 0;
125if ($user->socid > 0) {
126 $socid = $user->socid;
127}
128$feature2 = 'user';
129$result = restrictedArea($user, 'user', $id, 'user', $feature2);
130
131// Define value to know what current user can do on users. A test on logged user is done later to complete
132$permissiontoadd = (!empty($user->admin) || $user->hasRight("user", "user", "write")) && (empty($user->socid) || $user->socid == $object->socid);
133$permissiontoread = (!empty($user->admin) || $user->hasRight("user", "user", "read")) && (empty($user->socid) || $user->socid == $object->socid);
134$permissiontoedit = (!empty($user->admin) || $user->hasRight("user", "user", "write")) && (empty($user->socid) || $user->socid == $object->socid);
135$permissiontodisable = (!empty($user->admin) || $user->hasRight("user", "user", "delete")) && (empty($user->socid) || $user->socid == $object->socid);
136$permissiontoreadgroup = $permissiontoread;
137$permissiontoeditgroup = $permissiontoedit;
138if (getDolGlobalString('MAIN_USE_ADVANCED_PERMS')) {
139 $permissiontoreadgroup = (!empty($user->admin) || $user->hasRight("user", "group_advance", "read")) && (empty($user->socid) || $user->socid == $object->socid);
140 $permissiontoeditgroup = (!empty($user->admin) || $user->hasRight("user", "group_advance", "write")) && (empty($user->socid) || $user->socid == $object->socid);
141}
142
143$permissiontoclonesuperadmin = ($permissiontoadd && empty($user->entity));
144$permissiontocloneadmin = ($permissiontoadd && !empty($user->admin));
145$permissiontocloneuser = $permissiontoadd;
146// Can clone only in master entity if transverse mode is used
147if (getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE') && $conf->entity > 1) {
148 $permissiontoclonesuperadmin = false;
149 $permissiontocloneadmin = false;
150 $permissiontocloneuser = false;
151}
152
153if ($user->id != $id && !$permissiontoread) {
155}
156
157$caneditpasswordandsee = false;
158$caneditpasswordandsend = false;
159
160// Define value to know what current user can do on properties of edited user
161$permissiontoeditpasswordandsee = false;
162$permissiontoeditpasswordandsend = false;
163if ($id > 0) {
164 // $user is the current logged user, $id is the user we want to edit
165 $permissiontoedit = ((($user->id == $id) && $user->hasRight("user", "self", "write")) || (($user->id != $id) && $user->hasRight("user", "user", "write"))) && (empty($user->socid) || $user->socid == $object->socid);
166 $permissiontoeditpasswordandsee = ((($user->id == $id) && $user->hasRight("user", "self", "password")) || (($user->id != $id) && $user->hasRight("user", "user", "password") && $user->admin))&& (empty($user->socid) || $user->socid == $object->socid);
167 $permissiontoeditpasswordandsend = ((($user->id == $id) && $user->hasRight("user", "self", "password")) || (($user->id != $id) && $user->hasRight("user", "user", "password")))&& (empty($user->socid) || $user->socid == $object->socid);
168}
169
170// Permission to read salary and hourly rate
171$permissiontoseesalary = (empty($user->socid) && (
172 (isModEnabled('salaries') && $user->hasRight("salaries", "read") && ($id == 0 || in_array($id, $childids))) // If user is a manager of employee
173 || (isModEnabled('salaries') && $user->hasRight("salaries", "readall"))
174 || (isModEnabled('hrm') && $user->hasRight("hrm", "employee", "read")))
175 || (!isModEnabled('salaries') && !isModEnabled('hrm') && ($user->admin || $id == 0 || in_array($id, $childids))));
176
177$passwordismodified = false;
178$ldap = null;
179
180
181/*
182 * Actions
183 */
184
185$parameters = array('id' => $id, 'socid' => $socid, 'group' => $group, 'caneditgroup' => $permissiontoeditgroup);
186$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
187if ($reshook < 0) {
188 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
189}
190
191if (empty($reshook)) {
192 $backurlforlist = DOL_URL_ROOT.'/user/list.php';
193
194 if (empty($backtopage) || ($cancel && empty($id))) {
195 if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) {
196 if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) {
197 $backtopage = $backurlforlist;
198 } else {
199 $backtopage = DOL_URL_ROOT.'/user/card.php?id='.((!empty($id) && $id > 0) ? $id : '__ID__');
200 }
201 }
202 }
203
204 if ($cancel) {
205 if (!empty($backtopageforcancel)) {
206 header("Location: ".$backtopageforcancel);
207 exit;
208 } elseif (!empty($backtopage)) {
209 header("Location: ".$backtopage);
210 exit;
211 }
212 $action = '';
213 }
214
215 if ($action == 'confirm_disable' && $confirm == "yes" && $permissiontodisable) {
216 if ($id != $user->id) { // A user can't disable itself
217 $object->fetch($id);
218 if ($object->admin && empty($user->admin)) {
219 // If user to delete is an admin user and if logged user is not admin, we deny the operation.
220 $error++;
221 setEventMessages($langs->trans("OnlyAdminUsersCanDisableAdminUsers"), null, 'errors');
222 } else {
223 $object->setstatus(0);
224 header("Location: ".$_SERVER['PHP_SELF'].'?id='.$id);
225 exit;
226 }
227 }
228 }
229
230 if ($action == 'confirm_enable' && $confirm == "yes" && $permissiontodisable) {
231 $error = 0;
232
233 if ($id != $user->id) {
234 $object->fetch($id);
235
236 if (!empty($conf->file->main_limit_users)) {
237 $nb = $object->getNbOfUsers("active");
238 if ($nb >= $conf->file->main_limit_users) {
239 $error++;
240 setEventMessages($langs->trans("YourQuotaOfUsersIsReached"), null, 'errors');
241 }
242 }
243
244 if (!$error) {
245 $object->setstatus(1);
246 header("Location: ".$_SERVER['PHP_SELF'].'?id='.$id);
247 exit;
248 }
249 }
250 }
251
252 if ($action == 'confirm_delete' && $confirm == "yes" && $permissiontodisable) {
253 if ($id != $user->id) {
254 if (!GETPOSTISSET('token')) {
255 print 'Error, token required for this critical operation';
256 exit;
257 }
258
259 $object = new User($db);
260 $object->fetch($id);
261
262 if ($object->admin && empty($user->admin)) {
263 // If user to delete is an admin user and if logged user is not admin, we deny the operation.
264 $error++;
265 setEventMessages($langs->trans("OnlyAdminUsersCanDeleteAdminUsers"), null, 'errors');
266 } elseif ($object->admin && empty($object->entity) && !empty($user->entity)) {
267 // If user to delete is a superadmin user (admin + entity = 0) and logged user is not a superadmin, we deny the operation.
268 $error++;
269 setEventMessages($langs->trans("OnlySuperAdminUsersCanDeleteSuperAdminUsers"), null, 'errors');
270 } else {
271 $object->oldcopy = clone $object; // @phan-suppress-current-line PhanTypeMismatchProperty
272
273 $result = $object->delete($user);
274 if ($result < 0) {
275 $langs->load("errors");
276 setEventMessages($langs->trans("ErrorUserCannotBeDelete"), null, 'errors');
277 } else {
278 setEventMessages($langs->trans("RecordDeleted"), null);
279 header("Location: ".DOL_URL_ROOT."/user/list.php?restore_lastsearch_values=1");
280 exit;
281 }
282 }
283 }
284 }
285
286 // Action Add user
287 if ($action == 'add' && $permissiontoadd) {
288 $error = 0;
289
290 if (!GETPOST("lastname")) {
291 $error++;
292 setEventMessages($langs->trans("NameNotDefined"), null, 'errors');
293 $action = "create"; // Go back to create page
294 }
295 if (!GETPOST("login")) {
296 $error++;
297 setEventMessages($langs->trans("LoginNotDefined"), null, 'errors');
298 $action = "create"; // Go back to create page
299 }
300
301 if (!empty($conf->file->main_limit_users)) { // If option to limit users is set
302 $nb = $object->getNbOfUsers("active");
303 if ($nb >= $conf->file->main_limit_users) {
304 $error++;
305 setEventMessages($langs->trans("YourQuotaOfUsersIsReached"), null, 'errors');
306 $action = "create"; // Go back to create page
307 }
308 }
309
310 if (!$error) {
311 $object->civility_code = GETPOST("civility_code", 'aZ09');
312 $object->lastname = GETPOST("lastname", 'alphanohtml');
313 $object->firstname = GETPOST("firstname", 'alphanohtml');
314 $object->ref_employee = GETPOST("ref_employee", 'alphanohtml');
315 $object->national_registration_number = GETPOST("national_registration_number", 'alphanohtml');
316 $object->login = GETPOST("login", 'alphanohtml');
317 $object->api_key = GETPOST("api_key", 'alphanohtml');
318 $object->gender = GETPOST("gender", 'aZ09');
319 $object->admin = GETPOSTINT("admin");
320 $object->address = GETPOST('address', 'alphanohtml');
321 $object->zip = GETPOST('zipcode', 'alphanohtml');
322 $object->town = GETPOST('town', 'alphanohtml');
323 $object->country_id = GETPOSTINT('country_id');
324 $object->state_id = GETPOSTINT('state_id');
325 $object->office_phone = GETPOST("office_phone", 'alphanohtml');
326 $object->office_fax = GETPOST("office_fax", 'alphanohtml');
327 $object->user_mobile = GETPOST("user_mobile", 'alphanohtml');
328
329 if (isModEnabled('socialnetworks')) {
330 $object->socialnetworks = array();
331 foreach ($socialnetworks as $key => $value) {
332 if (GETPOST($key, 'alphanohtml')) {
333 $object->socialnetworks[$key] = GETPOST($key, 'alphanohtml');
334 }
335 }
336 }
337
338 $object->email = preg_replace('/\s+/', '', GETPOST("email", 'alphanohtml'));
339 $object->job = GETPOST("job", 'alphanohtml');
340 $object->signature = GETPOST("signature", 'restricthtml');
341 // restricthtml may swap the value with the literal 'ErrorTooManyLinksIntoHTMLString'
342 // when the html exceeds MAIN_SECURITY_MAX_IMG_IN_HTML_CONTENT (see issue #27987).
343 // Refuse the save so the literal does not end up persisted and later sent as an
344 // email body to customers.
345 if ($object->signature === 'ErrorTooManyLinksIntoHTMLString') {
346 $error++;
347 $langs->load("errors");
348 setEventMessages($langs->trans('ErrorTooManyLinksIntoHTMLString'), null, 'errors');
349 $action = 'create';
350 }
351 $object->accountancy_code = GETPOST("accountancy_code", 'alphanohtml');
352 $object->note_public = GETPOST("note_public", 'restricthtml');
353 $object->note_private = GETPOST("note_private", 'restricthtml');
354 $object->ldap_sid = GETPOST("ldap_sid", 'alphanohtml');
355 $object->fk_user = GETPOSTINT("fk_user") > 0 ? GETPOSTINT("fk_user") : 0;
356 $object->fk_user_expense_validator = GETPOSTINT("fk_user_expense_validator") > 0 ? GETPOSTINT("fk_user_expense_validator") : 0;
357 $object->fk_user_holiday_validator = GETPOSTINT("fk_user_holiday_validator") > 0 ? GETPOSTINT("fk_user_holiday_validator") : 0;
358 $object->employee = GETPOSTINT('employee');
359
360 if ($permissiontoseesalary) {
361 $object->thm = GETPOST("thm", 'alphanohtml') != '' ? GETPOSTFLOAT("thm") : '';
362 $object->thm = price2num($object->thm);
363 $object->tjm = GETPOST("tjm", 'alphanohtml') != '' ? GETPOSTFLOAT("tjm") : '';
364 $object->tjm = price2num($object->tjm);
365 $object->salary = GETPOST("salary", 'alphanohtml') != '' ? GETPOSTFLOAT("salary") : '';
366 $object->salary = price2num($object->salary);
367 $object->salaryextra = GETPOST("salaryextra", 'alphanohtml') != '' ? GETPOSTFLOAT("salaryextra") : '';
368 $object->salaryextra = price2num($object->salaryextra);
369 $object->weeklyhours = GETPOST("weeklyhours", 'alphanohtml') != '' ? GETPOSTFLOAT("weeklyhours") : '';
370 $object->weeklyhours = price2num($object->weeklyhours);
371 }
372
373 $object->color = GETPOST("color", 'alphanohtml') != '' ? str_replace('#', '', (string) GETPOST("color", 'alphanohtml')) : '';
374
375 $object->dateemployment = $dateemployment;
376 $object->dateemploymentend = $dateemploymentend;
377 $object->datestartvalidity = $datestartvalidity;
378 $object->dateendvalidity = $dateendvalidity;
379 $object->birth = $dateofbirth;
380 $object->force_pass_change = $forcepasswordchange;
381
382 $object->fk_warehouse = GETPOSTINT('fk_warehouse');
383
384 $object->lang = GETPOST('default_lang', 'aZ09');
385
386 // Fill array 'array_options' with data from add form
387 $ret = $extrafields->setOptionalsFromPost(null, $object);
388 if ($ret < 0) {
389 $error++;
390 }
391
392 // Set entity property
393 $entity = GETPOSTINT('entity');
394 if (isModEnabled('multicompany')) {
395 if (GETPOSTINT('superadmin')) {
396 $object->entity = 0;
397 } else {
398 if (getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE')) {
399 $object->entity = 1; // all users are forced into master entity
400 } else {
401 $object->entity = ($entity == '' ? 1 : $entity);
402 }
403 }
404 } else {
405 $object->entity = ($entity == '' ? 1 : $entity);
406 /*if ($user->admin && $user->entity == 0 && GETPOST("admin",'alpha'))
407 {
408 }*/
409 }
410
411 $db->begin();
412
413 $id = $object->create($user);
414 if ($id > 0) {
415 $resPass = 0;
416 if (GETPOST('password', 'password')) {
417 $resPass = $object->setPassword($user, GETPOST('password', 'password'));
418 }
419 if (is_int($resPass) && $resPass < 0) {
420 $langs->load("errors");
421 $db->rollback();
422 setEventMessages($object->error, $object->errors, 'errors');
423 $action = "create"; // Go back to create page
424 } else {
425 if (isModEnabled("category")) {
426 // Categories association
427 $usercats = GETPOST('usercats', 'array:int');
428 $object->setCategories($usercats);
429 }
430 $db->commit();
431
432 if (!empty($backtopage)) {
433 $url = str_replace('__ID__', (string) $id, $backtopage);
434 } else {
435 $url = $_SERVER['PHP_SELF'].'?id='.$id;
436 }
437 header("Location: ".$url);
438 exit;
439 }
440 } else {
441 $langs->load("errors");
442 $db->rollback();
443 setEventMessages($object->error, $object->errors, 'errors');
444 $action = "create"; // Go back to create page
445 }
446 }
447 }
448
449 // Action add usergroup
450 if (($action == 'addgroup' || $action == 'removegroup') && $permissiontoeditgroup) {
451 if ($group) {
452 $editgroup = new UserGroup($db);
453 $editgroup->fetch($group);
454 $editgroup->oldcopy = clone $editgroup; // @phan-suppress-current-line PhanTypeMismatchProperty
455
456 $object->fetch($id);
457
458 if ($action == 'addgroup') { // Test on permission already done
459 $result = $object->SetInGroup($group, $editgroup->entity);
460 }
461 if ($action == 'removegroup') { // Test on permission already done
462 $result = $object->RemoveFromGroup($group, $editgroup->entity);
463 }
464
465 if ($result > 0) {
466 $action = '';
467 } else {
468 setEventMessages($object->error, $object->errors, 'errors');
469 }
470 }
471 }
472
473 if ($action == 'update' && ($permissiontoedit || $permissiontoeditpasswordandsee)) {
474 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
475
476 if ($permissiontoedit) { // Case we can edit all field
477 $error = 0;
478
479 if (!GETPOST("lastname", 'alpha')) {
480 setEventMessages($langs->trans("NameNotDefined"), null, 'errors');
481 $action = "edit"; // Go back to create page
482 $error++;
483 }
484 if (!GETPOST("login", 'alpha')) {
485 setEventMessages($langs->trans("LoginNotDefined"), null, 'errors');
486 $action = "edit"; // Go back to create page
487 $error++;
488 }
489
490 if (!$error) {
491 $object->fetch($id);
492
493 $object->oldcopy = clone $object; // @phan-suppress-current-line PhanTypeMismatchProperty
494
495 $db->begin();
496
497 $object->civility_code = GETPOST("civility_code", 'aZ09');
498 $object->lastname = GETPOST("lastname", 'alphanohtml');
499 $object->firstname = GETPOST("firstname", 'alphanohtml');
500 // Protection against deletion of ref_employee while the field is not present in the user tab
501 if (GETPOSTISSET("ref_employee")) {
502 $object->ref_employee = GETPOST("ref_employee", 'alphanohtml');
503 }
504 // Protection against deletion of national_registration_number while the field is not present in the user tab
505 if (GETPOSTISSET("national_registration_number")) {
506 $object->national_registration_number = GETPOST("national_registration_number", 'alphanohtml');
507 }
508 $object->gender = GETPOST("gender", 'aZ09');
509 if ($permissiontoeditpasswordandsee) {
510 $object->pass = GETPOST("password", 'password');
511 }
512 if ($permissiontoeditpasswordandsee) {
513 $object->api_key = (GETPOSTISSET("api_key") ? GETPOST("api_key", 'alphanohtml') : $object->api_key);
514 }
515 if (!empty($user->admin) && $user->id != $id) {
516 // admin flag can only be set/unset by an admin user and not four ourself
517 // A test is also done later when forging sql request
518 $object->admin = GETPOSTINT("admin");
519 }
520 if ($user->admin && !$object->ldap_sid) { // same test than on edit page
521 $object->login = GETPOST("login", 'alphanohtml');
522 }
523 $object->address = GETPOST('address', 'alphanohtml');
524 $object->zip = GETPOST('zipcode', 'alphanohtml');
525 $object->town = GETPOST('town', 'alphanohtml');
526 $object->country_id = GETPOSTINT('country_id');
527 $object->state_id = GETPOSTINT('state_id');
528 $object->office_phone = GETPOST("office_phone", 'alphanohtml');
529 $object->office_fax = GETPOST("office_fax", 'alphanohtml');
530 $object->user_mobile = GETPOST("user_mobile", 'alphanohtml');
531
532 if (isModEnabled('socialnetworks')) {
533 $object->socialnetworks = array();
534 foreach ($socialnetworks as $key => $value) {
535 if (GETPOST($key, 'alphanohtml')) {
536 $object->socialnetworks[$key] = GETPOST($key, 'alphanohtml');
537 }
538 }
539 }
540
541 $object->email = preg_replace('/\s+/', '', GETPOST("email", 'alphanohtml'));
542 $object->job = GETPOST("job", 'alphanohtml');
543 $object->signature = GETPOST("signature", 'restricthtml');
544 // restricthtml may swap the value with the literal 'ErrorTooManyLinksIntoHTMLString'
545 // when the html exceeds MAIN_SECURITY_MAX_IMG_IN_HTML_CONTENT (see issue #27987).
546 // Refuse the save so the literal does not end up persisted and later sent as an
547 // email body to customers.
548 if ($object->signature === 'ErrorTooManyLinksIntoHTMLString') {
549 $error++;
550 $langs->load("errors");
551 setEventMessages($langs->trans('ErrorTooManyLinksIntoHTMLString'), null, 'errors');
552 $action = 'edit';
553 }
554 $object->accountancy_code = GETPOST("accountancy_code", 'alphanohtml');
555 $object->openid = GETPOST("openid", 'alphanohtml');
556 $object->fk_user = GETPOSTINT("fk_user") > 0 ? GETPOSTINT("fk_user") : 0;
557 $object->fk_user_expense_validator = GETPOSTINT("fk_user_expense_validator") > 0 ? GETPOSTINT("fk_user_expense_validator") : 0;
558 $object->fk_user_holiday_validator = GETPOSTINT("fk_user_holiday_validator") > 0 ? GETPOSTINT("fk_user_holiday_validator") : 0;
559 $object->employee = GETPOSTINT('employee');
560
561 // Only users allowed to see salary/HR fields can modify them (issue #32909)
562 if ($permissiontoseesalary) {
563 $object->thm = GETPOST("thm", 'alphanohtml') != '' ? GETPOSTFLOAT("thm") : '';
564 $object->thm = price2num($object->thm);
565 $object->tjm = GETPOST("tjm", 'alphanohtml') != '' ? GETPOSTFLOAT("tjm") : '';
566 $object->tjm = price2num($object->tjm);
567 $object->salary = GETPOST("salary", 'alphanohtml') != '' ? GETPOSTFLOAT("salary") : '';
568 $object->salary = price2num($object->salary);
569 $object->salaryextra = GETPOST("salaryextra", 'alphanohtml') != '' ? GETPOSTFLOAT("salaryextra") : '';
570 $object->salaryextra = price2num($object->salaryextra);
571 $object->weeklyhours = GETPOST("weeklyhours", 'alphanohtml') != '' ? GETPOSTFLOAT("weeklyhours") : '';
572 $object->weeklyhours = price2num($object->weeklyhours);
573 }
574
575 $object->color = GETPOST("color", 'alphanohtml') != '' ? str_replace('#', '', (string) GETPOST("color", 'alphanohtml')) : '';
576 $object->dateemployment = $dateemployment;
577 $object->dateemploymentend = $dateemploymentend;
578 $object->datestartvalidity = $datestartvalidity;
579 $object->dateendvalidity = $dateendvalidity;
580 $object->birth = $dateofbirth;
581 $object->force_pass_change = $forcepasswordchange;
582
583 if (isModEnabled('stock')) {
584 $object->fk_warehouse = GETPOSTINT('fk_warehouse');
585 }
586
587 $object->lang = GETPOST('default_lang', 'aZ09');
588
589 // Do we update also ->entity ?
590 if (isModEnabled('multicompany') && empty($user->entity) && !empty($user->admin)) { // If multicompany is not enabled, we never update the entity of a user.
591 if (GETPOSTINT('superadmin')) {
592 $object->entity = 0;
593 } else {
594 if (getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE')) {
595 $object->entity = 1; // all users are in master entity
596 } else {
597 // We try to change the entity of user
598 $object->entity = (GETPOSTISSET('entity') ? GETPOSTINT('entity') : $object->entity);
599 }
600 }
601 }
602
603 // Fill array 'array_options' with data from add form
604 $ret = $extrafields->setOptionalsFromPost(null, $object, '@GETPOSTISSET');
605 if ($ret < 0) {
606 $error++;
607 }
608
609 if (GETPOST('deletephoto')) {
610 $object->photo = '';
611 }
612 if (!empty($_FILES['photo']['name'])) {
613 $isimage = image_format_supported($_FILES['photo']['name']);
614 if ($isimage > 0) {
615 $object->photo = dol_sanitizeFileName($_FILES['photo']['name']);
616 if ($object->id == $user->id) {
617 $user->photo = $object->photo;
618 }
619 } else {
620 $error++;
621 $langs->load("errors");
622 setEventMessages($langs->trans("ErrorBadImageFormat"), null, 'errors');
623 dol_syslog($langs->transnoentities("ErrorBadImageFormat"), LOG_INFO);
624 }
625 }
626
627 if (!$error) {
628 $passwordismodified = 0;
629 if (!empty($object->pass)) {
630 if ($object->pass != $object->pass_indatabase && !dol_verifyHash($object->pass, $object->pass_indatabase_crypted)) {
631 $passwordismodified = 1;
632 }
633 }
634
635 $ret = $object->update($user); // This may include call to setPassword if password has changed
636 if ($ret < 0) {
637 $error++;
638 if ($db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
639 $langs->load("errors");
640 setEventMessages($langs->trans("ErrorUpdateCanceledDueToDuplicatedUniqueValue", $object->login), null, 'errors');
641 } else {
642 setEventMessages($object->error, $object->errors, 'errors');
643 $action = 'edit';
644 }
645 }
646 }
647
648 if (!$error && GETPOSTISSET('contactid')) {
649 $contactid = GETPOSTINT('contactid');
650 $socid = GETPOSTINT('socid');
651
652 if ($contactid > 0) { // The 'contactid' is used inpriority over the 'socid'
653 $contact = new Contact($db);
654 $contact->fetch($contactid);
655
656 $sql = "UPDATE ".MAIN_DB_PREFIX."user";
657 $sql .= " SET fk_socpeople=".((int) $contactid);
658 if (!empty($contact->socid)) {
659 $sql .= ", fk_soc=".((int) $contact->socid);
660 } elseif ($socid > 0) {
661 $sql .= ", fk_soc = null";
662 setEventMessages($langs->trans("WarningUserDifferentContactSocid"), null, 'warnings'); // Add message if post socid != $contact->socid
663 }
664 $sql .= " WHERE rowid = ".((int) $object->id);
665 } elseif ($socid > 0) {
666 $sql = "UPDATE ".MAIN_DB_PREFIX."user";
667 $sql .= " SET fk_socpeople=NULL, fk_soc=".((int) $socid);
668 $sql .= " WHERE rowid = ".((int) $object->id);
669 } else {
670 $sql = "UPDATE ".MAIN_DB_PREFIX."user";
671 $sql .= " SET fk_socpeople=NULL, fk_soc=NULL";
672 $sql .= " WHERE rowid = ".((int) $object->id);
673 }
674 dol_syslog("usercard::update", LOG_DEBUG);
675 $resql = $db->query($sql);
676 if (!$resql) {
677 $error++;
678 setEventMessages($db->lasterror(), null, 'errors');
679 }
680 }
681
682 if (!$error && !count($object->errors)) {
683 if (!empty($object->oldcopy->photo) && (GETPOST('deletephoto') || ($object->photo != $object->oldcopy->photo))) {
684 $fileimg = $conf->user->dir_output.'/'.get_exdir(0, 0, 0, 0, $object, 'user').'photos/'.$object->oldcopy->photo;
685 dol_delete_file($fileimg);
686
687 $dirthumbs = $conf->user->dir_output.'/'.get_exdir(0, 0, 0, 0, $object, 'user').'photos/thumbs';
688 dol_delete_dir_recursive($dirthumbs);
689 }
690
691 if (isset($_FILES['photo']['tmp_name']) && trim($_FILES['photo']['tmp_name'])) {
692 $dir = $conf->user->dir_output.'/'.get_exdir(0, 0, 0, 1, $object, 'user').'/photos';
693
694 dol_mkdir($dir);
695 $mesgs = null;
696
697 if (@is_dir($dir)) {
698 $newfile = $dir.'/'.dol_sanitizeFileName($_FILES['photo']['name']);
699 $result = dol_move_uploaded_file($_FILES['photo']['tmp_name'], $newfile, 1, 0, $_FILES['photo']['error']);
700
701 // Note: $result is a string when the file was refused and, in PHP 8, such a string compares as greater than 0
702 if (!is_numeric($result) || $result <= 0) {
703 setEventMessages($langs->trans("ErrorFailedToSaveFile"), null, 'errors');
704 } else {
705 // Create thumbs
706 $object->addThumbs($newfile);
707
708 // Index file in database
709 if (getDolGlobalString('USER_PHOTO_ALLOW_EXTERNAL_DOWNLOAD')) {
710 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
711 // the dir dirname($newfile) is directory of logo, so we should have only one file at once into index, so we delete indexes for the dir
712 deleteFilesIntoDatabaseIndex(dirname($newfile), '', '', $object);
713 // now we index the uploaded logo file
714 addFileIntoDatabaseIndex(dirname($newfile), basename($newfile), '', 'uploaded', 1, $object);
715 }
716 }
717 } else {
718 $error++;
719 $langs->load("errors");
720 setEventMessages($langs->trans("ErrorFailedToCreateDir", $dir), $mesgs, 'errors');
721 }
722 }
723 }
724
725 if (!$error && !count($object->errors)) {
726 // Then we add the associated categories
727 $categories = GETPOST('usercats', 'array:int');
728 $object->setCategories($categories);
729 }
730
731 if (!$error && !count($object->errors)) {
732 setEventMessages($langs->trans("UserModified"), null, 'mesgs');
733 $db->commit();
734
735 $login = $_SESSION["dol_login"];
736 if ($login && $login == $object->oldcopy->login && $object->oldcopy->login != $object->login) { // Current user has changed its login
737 $error++;
738 $langs->load("errors");
739 setEventMessages($langs->transnoentitiesnoconv("WarningYourLoginWasModifiedPleaseLogin"), null, 'warnings');
740 }
741 if ($passwordismodified && $object->login == $user->login) { // Current user has changed its password
742 $error++;
743 $langs->load("errors");
744 setEventMessages($langs->transnoentitiesnoconv("WarningYourPasswordWasModifiedPleaseLogin"), null, 'warnings');
745 header("Location: ".DOL_URL_ROOT.'/user/card.php?id='.$object->id);
746 exit;
747 }
748 } else {
749 $db->rollback();
750 }
751 }
752 } else {
753 if ($permissiontoeditpasswordandsee) { // Case we can edit only password
754 dol_syslog("Not allowed to change fields, only password");
755
756 $object->fetch($id);
757
758 if (GETPOST("password", "password")) { // If pass is empty, we do not change it.
759 $object->oldcopy = clone $object; // @phan-suppress-current-line PhanTypeMismatchProperty
760
761 $ret = $object->setPassword($user, GETPOST("password", "password"));
762 if (is_int($ret) && $ret < 0) {
763 setEventMessages($object->error, $object->errors, 'errors');
764 }
765 }
766 }
767 }
768 }
769
770 // Change password with a new generated one
771 if ((($action == 'confirm_password' && $confirm == 'yes' && $permissiontoeditpasswordandsee)
772 || ($action == 'confirm_passwordsend' && $confirm == 'yes' && $permissiontoeditpasswordandsend))
773 ) {
774 $object->fetch($id);
775
776 $newpassword = $object->setPassword($user, ''); // This will generate a new password
777 if (is_int($newpassword) && $newpassword < 0) {
778 // Echec
779 setEventMessages($langs->trans("ErrorFailedToSetNewPassword"), null, 'errors');
780 } else {
781 // Success
782 if ($action == 'confirm_passwordsend') { // Test on permission already done
783 if ($object->send_password($user, $newpassword) > 0) {
784 setEventMessages($langs->trans("PasswordChangedAndSentTo", $object->email), null, 'mesgs');
785 } else {
786 setEventMessages($object->error, $object->errors, 'errors');
787 }
788 } else {
789 setEventMessages($langs->trans("PasswordChangedTo", $newpassword), null, 'warnings');
790 }
791 }
792 }
793
794 // Action to initialize data from a LDAP record
795 if ($action == 'adduserldap' && $permissiontoadd) {
796 $selecteduser = GETPOST('users');
797
798 $required_fields = array(
799 getDolGlobalString('LDAP_KEY_USERS'),
800 getDolGlobalString('LDAP_FIELD_NAME'),
801 getDolGlobalString('LDAP_FIELD_FIRSTNAME'),
802 getDolGlobalString('LDAP_FIELD_LOGIN'),
803 getDolGlobalString('LDAP_FIELD_LOGIN_SAMBA'),
804 getDolGlobalString('LDAP_FIELD_PASSWORD'),
805 getDolGlobalString('LDAP_FIELD_PASSWORD_CRYPTED'),
806 getDolGlobalString('LDAP_FIELD_PHONE'),
807 getDolGlobalString('LDAP_FIELD_FAX'),
808 getDolGlobalString('LDAP_FIELD_MOBILE'),
809 getDolGlobalString('LDAP_FIELD_MAIL'),
810 getDolGlobalString('LDAP_FIELD_TITLE'),
811 getDolGlobalString('LDAP_FIELD_DESCRIPTION'),
812 getDolGlobalString('LDAP_FIELD_SID')
813 );
814 if (isModEnabled('socialnetworks')) {
815 $arrayofsocialnetworks = array('skype', 'twitter', 'facebook', 'linkedin');
816 foreach ($arrayofsocialnetworks as $socialnetwork) {
817 $required_fields[] = getDolGlobalString('LDAP_FIELD_'.strtoupper($socialnetwork));
818 }
819 }
820
821 $ldap = new Ldap();
822 $result = $ldap->connectBind();
823 if ($result >= 0) {
824 // Remove from required_fields all entries not configured in LDAP (empty) and duplicated
825 $required_fields = array_unique(array_values(array_filter($required_fields, "dol_validElement")));
826
827 $ldapusers = $ldap->getRecords($selecteduser, getDolGlobalString('LDAP_USER_DN'), getDolGlobalString('LDAP_KEY_USERS'), $required_fields);
828 //print_r($ldapusers);
829
830 if (is_array($ldapusers)) {
831 foreach ($ldapusers as $key => $attribute) {
832 $ldap_lastname = $attribute[getDolGlobalString('LDAP_FIELD_NAME')];
833 $ldap_firstname = $attribute[getDolGlobalString('LDAP_FIELD_FIRSTNAME')];
834 $ldap_login = $attribute[getDolGlobalString('LDAP_FIELD_LOGIN')];
835 $ldap_loginsmb = $attribute[getDolGlobalString('LDAP_FIELD_LOGIN_SAMBA')];
836 $ldap_pass = $attribute[getDolGlobalString('LDAP_FIELD_PASSWORD')];
837 $ldap_pass_crypted = $attribute[getDolGlobalString('LDAP_FIELD_PASSWORD_CRYPTED')];
838 $ldap_phone = $attribute[getDolGlobalString('LDAP_FIELD_PHONE')];
839 $ldap_fax = $attribute[getDolGlobalString('LDAP_FIELD_FAX')];
840 $ldap_mobile = $attribute[getDolGlobalString('LDAP_FIELD_MOBILE')];
841 $ldap_mail = $attribute[getDolGlobalString('LDAP_FIELD_MAIL')];
842 $ldap_sid = $attribute[getDolGlobalString('LDAP_FIELD_SID')];
843 $ldap_social = array();
844
845 if (isModEnabled('socialnetworks')) {
846 $arrayofsocialnetworks = array('skype', 'twitter', 'facebook', 'linkedin');
847 foreach ($arrayofsocialnetworks as $socialnetwork) {
848 $ldap_social[$socialnetwork] = $attribute[getDolGlobalString('LDAP_FIELD_'.strtoupper($socialnetwork))];
849 }
850 }
851 }
852 }
853 } else {
854 setEventMessages($ldap->error, $ldap->errors, 'errors');
855 }
856 }
857
858 if ($action == 'confirm_clone' && $confirm != 'yes') { // Test on permission not required
859 $action = '';
860 }
861 if ($action == 'confirm_clone' && $confirm == 'yes' && $permissiontocloneuser) {
862 if (!GETPOST('clone_name')) {
863 setEventMessages($langs->trans('ErrorNoCloneWithoutName'), null, 'errors');
864 } elseif (getDolGlobalString('USER_MAIL_REQUIRED') && !GETPOST('new_email')) {
865 setEventMessages($langs->trans('ErrorNoCloneWithoutEmail'), null, 'errors');
866 } else {
867 if ($object->id > 0) {
868 $error = 0;
869 $clone = dol_clone($object, 1);
870
871 $clone->id = 0;
872 $clone->email = (getDolGlobalString('USER_MAIL_REQUIRED') ? GETPOST('new_email', 'alphanohtml') : '');
873 $clone->api_key = '';
874 $clone->admin = ($user->admin ? $object->admin : 0); // If I am admin, I can clone the admin flag of a user, otherwiseadmin flag is forced to false.
875
876 $parts = explode(' ', GETPOST('clone_name'), 2);
877 $clone->firstname = $parts[0];
878 $clone->lastname = isset($parts[1]) ? $parts[1] : '';
879
880 $clone->login = substr($parts[0], 0, 1).$parts[1];
881
882 $db->begin();
883 $clone->context['createfromclone'] = 'createfromclone';
884 $id = $clone->create($user);
885 $refalreadyexists = 0;
886 if ($id > 0) {
887 if (GETPOST('clone_rights')) {
888 $result = $clone->cloneRights($object->id, $id);
889 }
890
891 if (GETPOST('clone_categories')) {
892 $result = $clone->cloneCategories($object->id, $id);
893 if ($result < 1) {
894 setEventMessages($langs->trans('ErrorUserClone'), null, 'errors');
895 setEventMessages($clone->error, $clone->errors, 'errors');
896 $error++;
897 }
898 }
899 } else {
900 if ($clone->error == 'ErrorProductAlreadyExists') {
901 $refalreadyexists++;
902 $action = "";
903
904 $mesg = $langs->trans("ErrorProductAlreadyExists", $clone->ref);
905 $mesg .= ' <a href="' . $_SERVER["PHP_SELF"] . '?ref=' . $clone->ref . '">' . $langs->trans("ShowCardHere") . '</a>.';
906 setEventMessages($mesg, null, 'errors');
907 } else {
908 setEventMessages(empty($clone->error) ? '' : $langs->trans($clone->error), $clone->errors, 'errors');
909 }
910 $error++;
911 }
912 unset($clone->context['createfromclone']);
913
914 if ($error) {
915 $db->rollback();
916 } else {
917 $db->commit();
918 $db->close();
919 header("Location: " . $_SERVER["PHP_SELF"] . "?id=" . $id);
920 exit;
921 }
922 } else {
923 dol_print_error($db, $object->error, $object->errors);
924 }
925 }
926 $action = 'clone';
927 }
928
929 // Actions to send emails
930 $triggersendname = 'USER_SENTBYMAIL';
931 $paramname = 'id'; // Name of param key to open the card
932 $mode = 'emailfromuser';
933 $trackid = 'use'.$id;
934 include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
935
936 // Actions to build doc
937 $upload_dir = $conf->user->dir_output;
938 include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
939
940 // Actions when printing a doc from card
941 include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
942}
943
944
945/*
946 * View
947 */
948
949$form = new Form($db);
950$formother = new FormOther($db);
951$formcompany = new FormCompany($db);
952$formadmin = new FormAdmin($db);
953$formfile = new FormFile($db);
954$formproduct = null;
955if (isModEnabled('stock')) {
956 $formproduct = new FormProduct($db);
957}
958
959// Count nb of users
960$nbofusers = 1;
961$sql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX.'user WHERE entity IN ('.getEntity('user').')';
962$resql = $db->query($sql);
963if ($resql) {
964 $obj = $db->fetch_object($resql);
965 if ($obj) {
966 $nbofusers = $obj->nb;
967 }
968} else {
969 dol_print_error($db);
970}
971
972if ($object->id > 0) {
973 $person_name = !empty($object->firstname) ? $object->lastname.", ".$object->firstname : $object->lastname;
974 $title = $person_name." - ".$langs->trans('Card');
975} else {
976 if (GETPOSTINT('employee')) {
977 $title = $langs->trans("NewEmployee");
978 } else {
979 $title = $langs->trans("NewUser");
980 }
981}
982$help_url = '';
983$text = null;
984
985llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-user page-card');
986
987if ($action == 'create' || $action == 'adduserldap') {
988 print load_fiche_titre($title, '', 'user');
989
990 print '<span class="opacitymedium">'.$langs->trans("CreateInternalUserDesc", $langs->transnoentities("CreateExternalUser"))."</span><br>\n";
991 print "<br>";
992
993
994 if (isModEnabled('ldap') && (getDolGlobalInt('LDAP_SYNCHRO_ACTIVE') === Ldap::SYNCHRO_LDAP_TO_DOLIBARR)) {
995 $liste = array();
996
997 // Show form to add an account from LDAP if sync LDAP -> Dolibarr is set
998 $ldap = new Ldap();
999 $result = $ldap->connectBind();
1000 if ($result >= 0) {
1001 $required_fields = array(
1002 getDolGlobalString('LDAP_KEY_USERS'),
1003 getDolGlobalString('LDAP_FIELD_FULLNAME'),
1004 getDolGlobalString('LDAP_FIELD_NAME'),
1005 getDolGlobalString('LDAP_FIELD_FIRSTNAME'),
1006 getDolGlobalString('LDAP_FIELD_LOGIN'),
1007 getDolGlobalString('LDAP_FIELD_LOGIN_SAMBA'),
1008 getDolGlobalString('LDAP_FIELD_PASSWORD'),
1009 getDolGlobalString('LDAP_FIELD_PASSWORD_CRYPTED'),
1010 getDolGlobalString('LDAP_FIELD_PHONE'),
1011 getDolGlobalString('LDAP_FIELD_FAX'),
1012 getDolGlobalString('LDAP_FIELD_MOBILE'),
1013 getDolGlobalString('LDAP_FIELD_SKYPE'),
1014 getDolGlobalString('LDAP_FIELD_MAIL'),
1015 getDolGlobalString('LDAP_FIELD_TITLE'),
1016 getDolGlobalString('LDAP_FIELD_DESCRIPTION'),
1017 getDolGlobalString('LDAP_FIELD_SID')
1018 );
1019
1020 // Remove from required_fields all entries not configured in LDAP (empty) and duplicated
1021 $required_fields = array_unique(array_values(array_filter($required_fields, "dol_validElement")));
1022
1023 // Get from LDAP database an array of results
1024 $ldapusers = $ldap->getRecords('*', getDolGlobalString('LDAP_USER_DN'), getDolGlobalString('LDAP_KEY_USERS'), $required_fields, 1);
1025
1026 if (is_array($ldapusers)) {
1027 foreach ($ldapusers as $key => $ldapuser) {
1028 // Define the label string for this user
1029 $label = '';
1030 foreach ($required_fields as $value) {
1031 if ($value === getDolGlobalString('LDAP_FIELD_PASSWORD') || $value === getDolGlobalString('LDAP_FIELD_PASSWORD_CRYPTED')) {
1032 $label .= $value."=******* ";
1033 } elseif ($value) {
1034 $label .= $value."=".$ldapuser[$value]." ";
1035 }
1036 }
1037 $liste[$key] = $label;
1038 }
1039 } else {
1040 setEventMessages($ldap->error, $ldap->errors, 'errors');
1041 }
1042 } else {
1043 setEventMessages($ldap->error, $ldap->errors, 'errors');
1044 }
1045
1046 // If user list is full, we show drop-down list
1047 print "\n\n<!-- Form liste LDAP debut -->\n";
1048
1049 print '<form name="add_user_ldap" action="'.$_SERVER["PHP_SELF"].'" method="post">';
1050 print '<input type="hidden" name="token" value="'.newToken().'">';
1051 print '<table class="border centpercent"><tr>';
1052 print '<td width="160">';
1053 print $langs->trans("LDAPUsers");
1054 print '</td>';
1055 print '<td>';
1056 print '<input type="hidden" name="action" value="adduserldap">';
1057 if (is_array($liste) && count($liste)) {
1058 print $form->selectarray('users', $liste, '', 1, 0, 0, '', 0, 0, 0, '', 'maxwidth500');
1059 print ajax_combobox('users');
1060 }
1061 print '</td><td class="center">';
1062 print '<input type="submit" class="button" value="'.dol_escape_htmltag($langs->trans('Get')).'"'.(count($liste) ? '' : ' disabled').'>';
1063 print '</td></tr></table>';
1064 print '</form>';
1065
1066 print "\n<!-- Form liste LDAP fin -->\n\n";
1067 print '<br>';
1068 }
1069
1070
1071 print '<form action="'.$_SERVER['PHP_SELF'].'" method="POST" name="createuser">';
1072 print '<input type="hidden" name="token" value="'.newToken().'">';
1073 print '<input type="hidden" name="action" value="add">';
1074 if (!empty($backtopage)) {
1075 print '<input type="hidden" name="backtopage" value="'.dol_escape_htmltag($backtopage).'">';
1076 }
1077 if (!empty($backtopageforcancel)) {
1078 print '<input type="hidden" name="backtopageforcancel" value="'.dol_escape_htmltag($backtopageforcancel).'">';
1079 }
1080 if (!empty($ldap_sid)) {
1081 print '<input type="hidden" name="ldap_sid" value="'.dol_escape_htmltag($ldap_sid).'">';
1082 }
1083 print '<input type="hidden" name="entity" value="'.$conf->entity.'">';
1084
1085 print dol_get_fiche_head(array(), '', '', 0, '');
1086
1087 dol_set_focus('#lastname');
1088
1089 print '<table class="border centpercent">';
1090
1091 // Civility
1092 if (getDolGlobalString('MAIN_USE_TITLE_FOR_USER')) {
1093 print '<tr><td><label for="civility_code">'.$langs->trans("UserTitle").'</label></td><td>';
1094 print $formcompany->select_civility(GETPOSTISSET("civility_code") ? GETPOST("civility_code", 'aZ09') : $object->civility_code, 'civility_code');
1095 print '</td></tr>';
1096 }
1097
1098 // Lastname
1099 print '<tr>';
1100 print '<td class="titlefieldcreate"><span class="fieldrequired">'.$langs->trans("Lastname").'</span></td>';
1101 print '<td>';
1102 if (!empty($ldap_lastname)) {
1103 print '<input type="hidden" id="lastname" name="lastname" value="'.dol_escape_htmltag($ldap_lastname).'">';
1104 print $ldap_lastname;
1105 } else {
1106 print '<input class="minwidth100 maxwidth150onsmartphone createloginauto" type="text" id="lastname" name="lastname" value="'.dol_escape_htmltag(GETPOST('lastname', 'alphanohtml')).'">';
1107 }
1108 print '</td></tr>';
1109
1110 // Firstname
1111 print '<tr><td>'.$langs->trans("Firstname").'</td>';
1112 print '<td>';
1113 if (!empty($ldap_firstname)) {
1114 print '<input type="hidden" name="firstname" value="'.dol_escape_htmltag($ldap_firstname).'">';
1115 print $ldap_firstname;
1116 } else {
1117 print '<input id="firstname" class="minwidth100 maxwidth150onsmartphone createloginauto" type="text" name="firstname" value="'.dol_escape_htmltag(GETPOST('firstname', 'alphanohtml')).'">';
1118 }
1119 print '</td></tr>';
1120
1121 // Login
1122 print '<tr><td><span class="fieldrequired">'.$langs->trans("Login").'</span></td>';
1123 print '<td>';
1124 if (!empty($ldap_login)) {
1125 print '<input type="hidden" name="login" value="'.dol_escape_htmltag($ldap_login).'">';
1126 print $ldap_login;
1127 } elseif (!empty($ldap_loginsmb)) {
1128 print '<input type="hidden" name="login" value="'.dol_escape_htmltag($ldap_loginsmb).'">';
1129 print $ldap_loginsmb;
1130 } else {
1131 print '<input id="login" class="maxwidth200 maxwidth150onsmartphone" maxsize="24" type="text" name="login" value="'.dol_escape_htmltag(GETPOST('login', 'alphanohtml')).'" spellcheck="false">';
1132 }
1133 print '</td></tr>';
1134
1135 if (!empty($conf->use_javascript_ajax)) {
1136 // Add code to generate the login when creating a new user.
1137 // Best rule to generate would be to use the same rule than dol_buildlogin() but currently it is a PHP function not available in js.
1138 // TODO Implement a function dol_buildlogin in javascript like the version in PHP.
1139 $charforseparator = getDolGlobalString("MAIN_USER_SEPARATOR_CHAR_FOR_GENERATED_LOGIN", '.');
1140 if ($charforseparator == 'none') {
1141 $charforseparator = '';
1142 }
1143 print '<script>
1144 jQuery(document).ready(function() {
1145 $(".createloginauto").on("keyup", function() {
1146 console.log(".createloginauto change: We generate login when we have a lastname");
1147
1148 lastname = $("#lastname").val().toLowerCase();
1149 ';
1150 if (getDolGlobalString('MAIN_BUILD_LOGIN_RULE') == 'flastname') {
1151 print ' firstname = $("#firstname").val().toLowerCase().replace(/\s+/g, \'\').trim()[0];';
1152 $charforseparator = '';
1153 } elseif (getDolGlobalString('MAIN_BUILD_LOGIN_RULE') == 'f.lastname') {
1154 print ' firstname = $("#firstname").val().toLowerCase().replace(/\s+/g, \'\').trim()[0];';
1155 } else {
1156 print ' firstname = $("#firstname").val().toLowerCase().replace(/\s+/g, \'\').trim();';
1157 }
1158 print '
1159 login = "";
1160 if (lastname) {
1161 if (firstname) {
1162 login = firstname + \''. dol_escape_js($charforseparator).'\';
1163 }
1164 login += lastname.replace(/\s+/g, \'\').trim();
1165 }
1166 $("#login").val(login);
1167 })
1168 });
1169 </script>';
1170 }
1171
1172 $generated_password = '';
1173 if (empty($ldap_sid)) { // ldap_sid is for activedirectory
1174 $generated_password = getRandomPassword(false);
1175 }
1176 $password = (GETPOSTISSET('password') ? GETPOST('password') : $generated_password);
1177
1178 // Administrator
1179 if (!empty($user->admin)) {
1180 print '<tr><td>'.$form->textwithpicto($langs->trans("Administrator"), $langs->trans("AdministratorDesc"), 1, 'help').'</td>';
1181 print '<td>';
1182 print $form->selectyesno('admin', GETPOST('admin'), 1, false, 0, 1);
1183
1184 if (isModEnabled('multicompany') && !$user->entity) {
1185 if (!empty($conf->use_javascript_ajax)) {
1186 print '<script type="text/javascript">
1187 $(function() {
1188 $("select[name=admin]").change(function() {
1189 if ( $(this).val() == 0 ) {
1190 $("input[name=superadmin]")
1191 .prop("disabled", true)
1192 .prop("checked", false);
1193 $("select[name=entity]")
1194 .prop("disabled", false);
1195 } else {
1196 $("input[name=superadmin]")
1197 .prop("disabled", false);
1198 }
1199 });
1200 $("input[name=superadmin]").change(function() {
1201 if ( $(this).is(":checked") ) {
1202 $("select[name=entity]")
1203 .prop("disabled", true);
1204 } else {
1205 $("select[name=entity]")
1206 .prop("disabled", false);
1207 }
1208 });
1209 });
1210 </script>';
1211 }
1212 $checked = (GETPOSTINT('superadmin') ? ' checked' : '');
1213 $disabled = (GETPOSTINT('superadmin') ? '' : ' disabled');
1214 print '<input type="checkbox" name="superadmin" id="superadmin" value="1"'.$checked.$disabled.' /> <label for="superadmin">'.$langs->trans("SuperAdministrator").'</span>';
1215 }
1216 print "</td></tr>\n";
1217 }
1218
1219 // Gender
1220 print '<tr><td>'.$langs->trans("Gender").'</td>';
1221 print '<td>';
1222 $arraygender = array('man' => $langs->trans("Genderman"), 'woman' => $langs->trans("Genderwoman"), 'other' => $langs->trans("Genderother"));
1223 print $form->selectarray('gender', $arraygender, GETPOST('gender'), 1);
1224 print '</td></tr>';
1225
1226 // Employee
1227 $defaultemployee = '1';
1228 print '<tr>';
1229 print '<td>'.$langs->trans('Employee').'</td><td>';
1230 print '<input type="checkbox" name="employee" value="1"'.(GETPOST('employee') == '1' ? ' checked="checked"' : (($defaultemployee && !GETPOSTISSET('login')) ? ' checked="checked"' : '')).'>';
1231 //print $form->selectyesno("employee", (GETPOST('employee') != '' ?GETPOST('employee') : $defaultemployee), 1);
1232 print '</td></tr>';
1233
1234 // Hierarchy
1235 print '<tr><td class="titlefieldcreate">'.$langs->trans("HierarchicalResponsible").'</td>';
1236 print '<td>';
1237 print img_picto('', 'user', 'class="pictofixedwidth"').$form->select_dolusers($object->fk_user, 'fk_user', 1, array($object->id), 0, '', '', (string) $conf->entity, 0, 0, '', 0, '', 'maxwidth300 widthcentpercentminusx');
1238 print '</td>';
1239 print "</tr>\n";
1240
1241 // Expense report validator
1242 if (isModEnabled('expensereport')) {
1243 print '<tr><td class="titlefieldcreate">';
1244 $text = $langs->trans("ForceUserExpenseValidator");
1245 print $form->textwithpicto($text, $langs->trans("ValidatorIsSupervisorByDefault"), 1, 'help');
1246 print '</td>';
1247 print '<td>';
1248 print img_picto('', 'user', 'class="pictofixedwidth"').$form->select_dolusers($object->fk_user_expense_validator, 'fk_user_expense_validator', 1, array($object->id), 0, '', '', (string) $conf->entity, 0, 0, '', 0, '', 'maxwidth300 widthcentpercentminusx');
1249 print '</td>';
1250 print "</tr>\n";
1251 }
1252
1253 // Holiday request validator
1254 if (isModEnabled('holiday')) {
1255 print '<tr><td class="titlefieldcreate">';
1256 $text = $langs->trans("ForceUserHolidayValidator");
1257 print $form->textwithpicto($text, $langs->trans("ValidatorIsSupervisorByDefault"), 1, 'help');
1258 print '</td>';
1259 print '<td>';
1260 print img_picto('', 'user', 'class="pictofixedwidth"').$form->select_dolusers($object->fk_user_holiday_validator, 'fk_user_holiday_validator', 1, array($object->id), 0, '', '', (string) $conf->entity, 0, 0, '', 0, '', 'maxwidth300 widthcentpercentminusx');
1261 print '</td>';
1262 print "</tr>\n";
1263 }
1264
1265 // External user
1266 print '<tr><td>'.$langs->trans("ExternalUser").' ?</td>';
1267 print '<td>';
1268 print $form->textwithpicto($langs->trans("Internal"), $langs->trans("InternalExternalDesc"), 1, 'help', '', 0, 2);
1269 print '</td></tr>';
1270
1271
1272 print '</table><hr><table class="border centpercent">';
1273
1274
1275 // Date validity
1276 print '<tr><td class="titlefieldcreate">'.$langs->trans("RangeOfLoginValidity").'</td>';
1277 print '<td>';
1278 print $form->selectDate($datestartvalidity, 'datestartvalidity', 0, 0, 1, 'formdatestartvalidity', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("from"));
1279
1280 print ' &nbsp; ';
1281
1282 print $form->selectDate($dateendvalidity, 'dateendvalidity', 0, 0, 1, 'formdateendvalidity', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to"));
1283 print '</td>';
1284 print "</tr>\n";
1285
1286 // Password
1287 print '<tr><td class="fieldrequired">'.$langs->trans("Password").'</td>';
1288 print '<td>';
1289 $valuetoshow = '';
1290 if (preg_match('/ldap/', $dolibarr_main_authentication)) {
1291 $valuetoshow .= ($valuetoshow ? ' + ' : '').$langs->trans("PasswordOfUserInLDAP").' (hidden)';
1292 }
1293 if (preg_match('/http/', $dolibarr_main_authentication)) {
1294 $valuetoshow .= ($valuetoshow ? ' + ' : '').$langs->trans("HTTPBasicPassword");
1295 }
1296 if (preg_match('/dolibarr/', $dolibarr_main_authentication) || preg_match('/forceuser/', $dolibarr_main_authentication)) {
1297 if (!empty($ldap_pass)) { // For very old system compatibility. Now clear password can't be viewed from LDAP read
1298 $valuetoshow .= ($valuetoshow ? ' + ' : '').'<input type="hidden" name="password" value="'.dol_escape_htmltag($ldap_pass).'">'; // Dolibarr password is preffiled with LDAP known password
1299 $valuetoshow .= preg_replace('/./i', '*', $ldap_pass);
1300 } else {
1301 // We do not use a field password but a field text to show new password to use.
1302 $valuetoshow .= ($valuetoshow ? ' + '.$langs->trans("DolibarrPassword") : '').'<input class="minwidth300 maxwidth400 widthcentpercentminusx" maxlength="128" type="text" id="password" name="password" value="'.dol_escape_htmltag($password).'" autocomplete="new-password" spellcheck="false">';
1303 if (!empty($conf->use_javascript_ajax)) {
1304 $valuetoshow .= img_picto($langs->transnoentities('Generate'), 'refresh', 'id="generate_password" class="linkobject paddingleft"');
1305 }
1306 }
1307 }
1308 // Other form for user password
1309 $parameters = array('valuetoshow' => $valuetoshow, 'password' => $password, 'caneditpasswordandsee' => $permissiontoeditpasswordandsee, 'caneditpasswordandsend' => $permissiontoeditpasswordandsend);
1310 $reshook = $hookmanager->executeHooks('printUserPasswordField', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1311 if ($reshook > 0) {
1312 $valuetoshow = $hookmanager->resPrint; // to replace
1313 } else {
1314 $valuetoshow .= $hookmanager->resPrint; // to add
1315 }
1316
1317 print $valuetoshow;
1318 print '</td></tr>';
1319
1320 // Force update on next login -- only on dolibarr auth context
1321 if ($_SESSION["dol_authmode"] == 'dolibarr') {
1322 print '<tr><td class="titlefieldcreate"></td>';
1323 print '<td>';
1324 //$permissiontoselfeditpassword = $object->hasRight('user', 'self', 'password');
1325 $permissiontoselfeditpassword = 1; // In creation, we suppose it to true
1326 if ($permissiontoselfeditpassword) { // @phpstan-ignore-line because value is forced
1327 print '<input type="checkbox" name="forcepasswordchange" id="forcepasswordchange" value="1"'.(GETPOST('forcepasswordchange') == '1' ? ' checked="checked"' : '').'>';
1328 print '<label class="opacitymedium" for="forcepasswordchange">'.$langs->trans("ForcePasswordChange").'</label>';
1329 } else {
1330 print '<input type="checkbox" name="forcepasswordchange" value="1" class="colorgrey valignmiddle" disabled>';
1331 print $form->textwithpicto('<span class="opacitymedium">'.$langs->trans("ForcePasswordChange").'</span>', $langs->trans("UserDoesNotHaveRightsToChangeHisPassword"));
1332 }
1333 print '</td>';
1334 print "</tr>\n";
1335 }
1336
1337 if (!getDolGlobalString('API_IN_TOKEN_TABLE')) {
1338 if (isModEnabled('api')) {
1339 // API key
1340 //$generated_password = getRandomPassword(false);
1341 print '<tr><td>'.$langs->trans("ApiKey").'</td>';
1342 print '<td>';
1343 print '<input class="minwidth300 maxwidth400 widthcentpercentminusx" minlength="12" maxlength="128" type="text" id="api_key" name="api_key" value="'.GETPOST('api_key', 'alphanohtml').'" autocomplete="off" spellcheck="false">';
1344 if (!empty($conf->use_javascript_ajax)) {
1345 print img_picto($langs->transnoentities('Generate'), 'refresh', 'id="generate_api_key" class="linkobject paddingleft"');
1346 }
1347 print '</td></tr>';
1348 } else {
1349 // PARTIAL WORKAROUND
1350 $generated_fake_api_key = getRandomPassword(false);
1351 print '<input type="hidden" name="api_key" value="'.$generated_fake_api_key.'">';
1352 }
1353 }
1354
1355 print '</table><hr><table class="border centpercent">';
1356
1357
1358 // Address
1359 print '<tr><td class="tdtop titlefieldcreate">'.$form->editfieldkey('Address', 'address', '', $object, 0).'</td>';
1360 print '<td><textarea name="address" id="address" class="quatrevingtpercent" rows="3" wrap="soft">';
1361 print $object->address;
1362 print '</textarea></td></tr>';
1363
1364 // Zip
1365 print '<tr><td>'.$form->editfieldkey('Zip', 'zipcode', '', $object, 0).'</td><td>';
1366 print $formcompany->select_ziptown($object->zip, 'zipcode', array('town', 'selectcountry_id', 'state_id'), 6);
1367 print '</td></tr>';
1368
1369 // Town
1370 print '<tr><td>'.$form->editfieldkey('Town', 'town', '', $object, 0).'</td><td>';
1371 print $formcompany->select_ziptown($object->town, 'town', array('zipcode', 'selectcountry_id', 'state_id'));
1372 print '</td></tr>';
1373
1374 // Country
1375 print '<tr><td>'.$form->editfieldkey('Country', 'selectcountry_id', '', $object, 0).'</td><td class="maxwidthonsmartphone">';
1376 print img_picto('', 'country', 'class="pictofixedwidth"');
1377 print $form->select_country((GETPOST('country_id') != '' ? GETPOST('country_id') : $object->country_id), 'country_id');
1378 if ($user->admin) {
1379 print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
1380 }
1381 print '</td></tr>';
1382
1383 // State
1384 if (!getDolGlobalString('USER_DISABLE_STATE')) {
1385 print '<tr><td>'.$form->editfieldkey('State', 'state_id', '', $object, 0).'</td><td class="maxwidthonsmartphone">';
1386 print img_picto('', 'state', 'class="pictofixedwidth"');
1387 print $formcompany->select_state_ajax('country_id', $object->state_id, $object->country_id, 'state_id');
1388 print '</td></tr>';
1389 }
1390
1391 // Tel
1392 print '<tr><td>'.$langs->trans("PhonePro").'</td>';
1393 print '<td>';
1394 if (!empty($ldap_phone)) {
1395 print img_picto('', 'object_phoning', 'class="pictofixedwidth"');
1396 print '<input type="hidden" name="office_phone" value="'.dol_escape_htmltag($ldap_phone).'">';
1397 print $ldap_phone;
1398 } else {
1399 print $form->showPhoneInput($object->office_phone, 'office_phone', $object->country_id, 'object_phoning', 'maxwidth200 widthcentpercentminusx');
1400 }
1401 print '</td></tr>';
1402
1403 // Tel portable
1404 print '<tr><td>'.$langs->trans("PhoneMobile").'</td>';
1405 print '<td>';
1406 if (!empty($ldap_mobile)) {
1407 print img_picto('', 'object_phoning_mobile', 'class="pictofixedwidth"');
1408 print '<input type="hidden" name="user_mobile" value="'.dol_escape_htmltag($ldap_mobile).'">';
1409 print $ldap_mobile;
1410 } else {
1411 print $form->showPhoneInput($object->user_mobile, 'user_mobile', $object->country_id, 'object_phoning_mobile', 'maxwidth200 widthcentpercentminusx');
1412 }
1413 print '</td></tr>';
1414
1415 // Fax
1416 print '<tr><td>'.$langs->trans("Fax").'</td>';
1417 print '<td>';
1418 if (!empty($ldap_fax)) {
1419 print img_picto('', 'object_phoning_fax', 'class="pictofixedwidth"');
1420 print '<input type="hidden" name="office_fax" value="'.dol_escape_htmltag($ldap_fax).'">';
1421 print $ldap_fax;
1422 } else {
1423 print $form->showPhoneInput($object->office_fax, 'office_fax', $object->country_id, 'object_phoning_fax', 'maxwidth200 widthcentpercentminusx');
1424 }
1425 print '</td></tr>';
1426
1427 // EMail
1428 print '<tr><td'.(getDolGlobalString('USER_MAIL_REQUIRED') ? ' class="fieldrequired"' : '').'>'.$langs->trans("EMail").'</td>';
1429 print '<td>';
1430 print img_picto('', 'object_email', 'class="pictofixedwidth"');
1431 if (!empty($ldap_mail)) {
1432 print '<input type="hidden" name="email" value="'.dol_escape_htmltag($ldap_mail).'">';
1433 print $ldap_mail;
1434 } else {
1435 print '<input type="text" name="email" class="maxwidth500 widthcentpercentminusx" value="'.dol_escape_htmltag(GETPOST('email', 'alphanohtml')).'" spellcheck="false">';
1436 }
1437 print '</td></tr>';
1438
1439 // Social networks
1440 if (isModEnabled('socialnetworks')) {
1441 foreach ($socialnetworks as $key => $value) {
1442 if ($value['active']) {
1443 print '<tr><td>'.$langs->trans($value['label']).'</td>';
1444 print '<td>';
1445 if (!empty($value['icon'])) {
1446 print '<span class="fab '.$value['icon'].' pictofixedwidth"></span>';
1447 }
1448 if (!empty($ldap_social[$key])) {
1449 print '<input type="hidden" name="'.$key.'" value="'.$ldap_social[$key].'">';
1450 print $ldap_social[$key];
1451 } else {
1452 print '<input class="maxwidth200 widthcentpercentminusx" type="text" name="'.$key.'" value="'.GETPOST($key, 'alphanohtml').'">';
1453 }
1454 print '</td></tr>';
1455 } else {
1456 // if social network is not active but value exist we do not want to loose it
1457 if (!empty($ldap_social[$key])) {
1458 print '<input type="hidden" name="'.$key.'" value="'.$ldap_social[$key].'">';
1459 } else {
1460 print '<input type="hidden" name="'.$key.'" value="'.GETPOST($key, 'alphanohtml').'">';
1461 }
1462 }
1463 }
1464 }
1465
1466 // Accountancy code
1467 if (isModEnabled('accounting')) {
1468 print '<tr><td>'.$langs->trans("AccountancyCode").'</td>';
1469 print '<td>';
1470 print '<input type="text" class="maxwidthonsmartphone" name="accountancy_code" value="'.dol_escape_htmltag(GETPOST('accountancy_code', 'alphanohtml')).'">';
1471 print '</td></tr>';
1472 }
1473
1474 // User color
1475 if (isModEnabled('agenda')) {
1476 print '<tr><td>'.$langs->trans("Color").'</td>';
1477 print '<td>';
1478 print $formother->selectColor(GETPOSTISSET('color') ? GETPOST('color', 'alphanohtml') : $object->color, 'color', null, 1, array(), 'hideifnotset');
1479 print '</td></tr>';
1480 }
1481
1482 // Categories
1483 if (isModEnabled('category') && $user->hasRight("categorie", "read")) {
1484 print '<tr><td>'.$form->editfieldkey('Categories', 'usercats', '', $object, 0).'</td><td>';
1485 print $form->selectCategories(Categorie::TYPE_USER, 'usercats', $object);
1486 print "</td></tr>";
1487 }
1488
1489 // Default language
1490 if (getDolGlobalInt('MAIN_MULTILANGS')) {
1491 print '<tr><td>'.$form->editfieldkey('DefaultLang', 'default_lang', '', $object, 0, 'string', '', 0, 0, 'id', $langs->trans("WarningNotLangOfInterface", $langs->transnoentitiesnoconv("UserGUISetup"))).'</td>';
1492 print '<td class="maxwidthonsmartphone">'."\n";
1493 print img_picto('', 'language', 'class="pictofixedwidth"').$formadmin->select_language(GETPOST('default_lang', 'alpha') ? GETPOST('default_lang', 'alpha') : ($object->lang ? $object->lang : ''), 'default_lang', 0, array(), 1, 0, 0, 'maxwidth300 widthcentpercentminusx');
1494 print '</td>';
1495 print '</tr>';
1496 }
1497
1498 // Multicompany
1499 if (isModEnabled('multicompany') && isset($mc) && is_object($mc)) {
1500 // This is now done with hook formObjectOptions. Keep this code for backward compatibility with old multicompany module
1501 if (!method_exists($mc, 'formObjectOptions')) {
1502 if (!getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE') && $conf->entity == 1 && $user->admin && !$user->entity) { // condition must be same for create and edit mode
1503 print "<tr>".'<td>'.$langs->trans("Entity").'</td>';
1504 print "<td>".$mc->select_entities($conf->entity);
1505 print "</td></tr>\n";
1506 } else {
1507 print '<input type="hidden" name="entity" value="'.$conf->entity.'" />';
1508 }
1509 }
1510 }
1511
1512 // Other attributes
1513 $parameters = array();
1514 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_add.tpl.php';
1515
1516 // Signature
1517 print '<tr><td class="tdtop">'.$langs->trans("Signature").'</td>';
1518 print '<td class="wordbreak">';
1519 require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
1520
1521 $doleditor = new DolEditor('signature', GETPOST('signature', 'restricthtml'), '', 138, 'dolibarr_notes', 'In', true, $acceptlocallinktomedia, !getDolGlobalString('FCKEDITOR_ENABLE_USERSIGN') ? 0 : 1, ROWS_4, '90%');
1522 print $doleditor->Create(1);
1523 print '</td></tr>';
1524
1525 // Note private
1526 print '<tr><td class="tdtop">';
1527 print $langs->trans("NotePublic");
1528 print '</td><td>';
1529 require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
1530 $doleditor = new DolEditor('note_public', GETPOSTISSET('note_public') ? GETPOST('note_public', 'restricthtml') : '', '', 100, 'dolibarr_notes', '', false, true, getDolGlobalString('FCKEDITOR_ENABLE_NOTE_PUBLIC'), ROWS_3, '90%');
1531 $doleditor->Create();
1532 print "</td></tr>\n";
1533
1534 // Note private
1535 print '<tr><td class="tdtop">';
1536 print $langs->trans("NotePrivate");
1537 print '</td><td>';
1538 require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
1539 $doleditor = new DolEditor('note_private', GETPOSTISSET('note_private') ? GETPOST('note_private', 'restricthtml') : '', '', 100, 'dolibarr_notes', '', false, true, getDolGlobalString('FCKEDITOR_ENABLE_NOTE_PRIVATE'), ROWS_3, '90%');
1540 $doleditor->Create();
1541 print "</td></tr>\n";
1542
1543 print '</table><hr><table class="border centpercent">';
1544
1545
1546 // TODO Move this into tab RH (HierarchicalResponsible must be on both tab)
1547
1548 // Default warehouse
1549 if (isModEnabled('stock') && getDolGlobalString('MAIN_DEFAULT_WAREHOUSE_USER')) {
1550 print '<tr><td>'.$langs->trans("DefaultWarehouse").'</td><td>';
1551 print $formproduct->selectWarehouses($object->fk_warehouse, 'fk_warehouse', 'warehouseopen', 1);
1552 print '</td></tr>';
1553 }
1554
1555 // Position/Job
1556 print '<tr><td class="titlefieldcreate">'.$langs->trans("PostOrFunction").'</td>';
1557 print '<td>';
1558 print '<input class="maxwidth200 maxwidth150onsmartphone" type="text" name="job" value="'.dol_escape_htmltag(GETPOST('job', 'alphanohtml')).'">';
1559 print '</td></tr>';
1560
1561 if ($permissiontoseesalary) {
1562 $langs->load("salaries");
1563
1564 // THM
1565 print '<tr><td>';
1566 $text = $langs->trans("THM");
1567 print $form->textwithpicto($text, $langs->trans("THMDescription"), 1, 'help', 'classthm');
1568 print '</td>';
1569 print '<td>';
1570 print '<input size="8" type="text" name="thm" value="'.dol_escape_htmltag(GETPOST('thm')).'"> <span class="opacitymedium">'.$langs->getCurrencySymbol().'</span>';
1571 print '</td>';
1572 print "</tr>\n";
1573
1574 // TJM
1575 print '<tr><td>';
1576 $text = $langs->trans("TJM");
1577 print $form->textwithpicto($text, $langs->trans("TJMDescription"), 1, 'help', 'classtjm');
1578 print '</td>';
1579 print '<td>';
1580 print '<input size="8" type="text" name="tjm" value="'.dol_escape_htmltag(GETPOST('tjm')).'"> <span class="opacitymedium">'.$langs->getCurrencySymbol().'</span>';
1581 print '</td>';
1582 print "</tr>\n";
1583
1584 // Salary
1585 print '<tr><td>'.$langs->trans("Salary").'</td>';
1586 print '<td>';
1587 print img_picto('', 'salary', 'class="pictofixedwidth paddingright"').'<input class="width100" type="text" name="salary" value="'.dol_escape_htmltag(GETPOST('salary')).'"> <span class="opacitymedium">'.$langs->getCurrencySymbol().'</span>';
1588 print '</td>';
1589 print "</tr>\n";
1590 }
1591
1592 // Weeklyhours
1593 print '<tr><td>'.$langs->trans("WeeklyHours").'</td>';
1594 print '<td>';
1595 print '<input size="8" type="text" name="weeklyhours" value="'.dol_escape_htmltag(GETPOST('weeklyhours')).'">';
1596 print '</td>';
1597 print "</tr>\n";
1598
1599 // Date employment
1600 print '<tr><td>'.$langs->trans("DateOfEmployment").'</td>';
1601 print '<td>';
1602 print $form->selectDate($dateemployment, 'dateemployment', 0, 0, 1, 'formdateemployment', 1, 1, 0, '', '', '', '', 1, '', $langs->trans("from"));
1603
1604 print ' - ';
1605
1606 print $form->selectDate($dateemploymentend, 'dateemploymentend', 0, 0, 1, 'formdateemploymentend', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to"));
1607 print '</td>';
1608 print "</tr>\n";
1609
1610 // Date birth
1611 print '<tr><td>'.$langs->trans("DateOfBirth").'</td>';
1612 print '<td>';
1613 print $form->selectDate($dateofbirth, 'dateofbirth', 0, 0, 1, 'createuser', 1, 0, 0, '', '', '', '', 1, '', '', 'tzserver');
1614 print '</td>';
1615 print "</tr>\n";
1616
1617 print "</table>\n";
1618
1619 print dol_get_fiche_end();
1620
1621 print $form->buttonsSaveCancel("CreateUser");
1622
1623 print "</form>";
1624} else {
1625 // View and edit mode
1626 if ($id > 0) {
1627 $res = $object->fetch($id, '', '', 1);
1628 if ($res < 0) {
1629 recordNotFound('', 0);
1630 }
1631 $res = $object->fetch_optionals();
1632
1633 // Check if user has rights
1634 if (!getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE')) {
1635 $object->loadRights();
1636 if (empty($object->nb_rights) && $object->status != 0 && empty($object->admin)) {
1637 setEventMessages($langs->trans('UserHasNoPermissions'), null, 'warnings');
1638 }
1639 }
1640
1641 $passDoNotExpire = 0;
1642 $statutUACF = '';
1643 $userChangePassNextLogon = 0;
1644 $userDisabled = 0;
1645 // Connection ldap
1646 // pour recuperer passDoNotExpire et userChangePassNextLogon
1647 if (isModEnabled('ldap') && !empty($object->ldap_sid)) {
1648 $ldap = new Ldap();
1649 $result = $ldap->connectBind();
1650 if ($result > 0) {
1651 $userSearchFilter = '(' . getDolGlobalString('LDAP_FILTER_CONNECTION').'('.$ldap->getUserIdentifier().'='.$object->login.'))';
1652 $entries = $ldap->fetch($object->login, $userSearchFilter);
1653 if (!$entries) {
1654 setEventMessages($ldap->error, $ldap->errors, 'errors');
1655 }
1656
1657 // Check options of user account
1658 if (count($ldap->uacf) > 0) {
1659 foreach ($ldap->uacf as $key => $statut) {
1660 if ($key == 65536) {
1661 $passDoNotExpire = 1;
1662 $statutUACF = $statut;
1663 }
1664 }
1665 } else {
1666 $userDisabled = 1;
1667 $statutUACF = "ACCOUNTDISABLE";
1668 }
1669
1670 if ($ldap->pwdlastset == 0) {
1671 $userChangePassNextLogon = 1;
1672 }
1673 }
1674 }
1675
1676 // Show tabs
1677 if ($mode == 'employee') { // For HRM module development
1678 $title = $langs->trans("Employee");
1679 $linkback = '<a href="'.DOL_URL_ROOT.'/hrm/employee/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
1680 } else {
1681 $title = $langs->trans("User");
1682 $linkback = '';
1683
1684 if ($user->hasRight("user", "user", "read") || $user->admin) {
1685 $linkback = '<a href="'.DOL_URL_ROOT.'/user/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
1686 }
1687 }
1688
1689 $head = user_prepare_head($object);
1690
1691 // Confirmation reinitialisation password
1692 if ($action == 'password') {
1693 print $form->formconfirm(dolBuildUrl($_SERVER['PHP_SELF'], ['id' => $object->id]), $langs->trans("ReinitPassword"), $langs->trans("ConfirmReinitPassword", $object->login), "confirm_password", '', 0, 1);
1694 }
1695
1696 // Confirmation envoi password
1697 if ($action == 'passwordsend') {
1698 print $form->formconfirm(dolBuildUrl($_SERVER['PHP_SELF'], ['id' => $object->id]), $langs->trans("SendNewPassword"), $langs->trans("ConfirmSendNewPassword", $object->login), "confirm_passwordsend", '', 0, 1);
1699 }
1700
1701 // Confirm deactivation
1702 if ($action == 'disable') {
1703 print $form->formconfirm(dolBuildUrl($_SERVER['PHP_SELF'], ['id' => $object->id]), $langs->trans("DisableAUser"), $langs->trans("ConfirmDisableUser", $object->login), "confirm_disable", '', 0, 1);
1704 }
1705
1706 // Confirm activation
1707 if ($action == 'enable') {
1708 print $form->formconfirm(dolBuildUrl($_SERVER['PHP_SELF'], ['id' => $object->id]), $langs->trans("EnableAUser"), $langs->trans("ConfirmEnableUser", $object->login), "confirm_enable", '', 0, 1);
1709 }
1710
1711 // Confirmation delete
1712 if ($action == 'delete') {
1713 print $form->formconfirm(dolBuildUrl($_SERVER['PHP_SELF'], ['id' => $object->id]), $langs->trans("DeleteAUser"), $langs->trans("ConfirmDeleteUser", $object->login), "confirm_delete", '', 0, 1);
1714 }
1715
1716 // Confirmation clone
1717 if (($action == 'clone' && (empty($conf->use_javascript_ajax) || !empty($conf->dol_use_jmobile))) // Output when action = clone if jmobile or no js
1718 || (!empty($conf->use_javascript_ajax) && empty($conf->dol_use_jmobile))) { // Always output when not jmobile nor js
1719 // Define confirmation messages
1720 $formquestionclone = array(
1721 'text' => $langs->trans("ConfirmClone"),
1722 0 => array('type' => 'text', 'name' => 'clone_name', 'label' => $langs->trans("NewNameUserClone"), 'morecss' => 'width200'),
1723 1 => array('type' => 'checkbox', 'name' => 'clone_rights', 'label' => $langs->trans("CloneUserRights"), 'value' => 0),
1724 2 => array('type' => 'checkbox', 'name' => 'clone_categories', 'label' => $langs->trans("CloneCategoriesProduct"), 'value' => 0),
1725 );
1726 if (getDolGlobalString('USER_MAIL_REQUIRED')) {
1727 $newElement = array('type' => 'text', 'name' => 'new_email', 'label' => $langs->trans("NewEmailUserClone"), 'morecss' => 'width200');
1728 array_splice($formquestionclone, 2, 0, array($newElement));
1729 }
1730 print $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmUserClone', $object->firstname.' '.$object->lastname), 'confirm_clone', $formquestionclone, 'yes', 'action-clone', 350, 600);
1731 }
1732
1733
1734 // View mode
1735 if ($action != 'edit') {
1736 print dol_get_fiche_head($head, 'user', $title, -1, 'user', 0, '', '', 0, '', 1);
1737
1738 $morehtmlref = '<a href="'.dolBuildUrl(DOL_URL_ROOT.'/user/vcard.php', ['id' => $object->id, 'output' => 'file', 'file' => dol_sanitizeFileName($object->getFullName($langs).'.vcf')]).'" class="refid valignmiddle" rel="noopener">';
1739 $morehtmlref .= img_picto($langs->trans("Download").' '.$langs->trans("VCard").' ('.$langs->trans("AddToContacts").')', 'vcard', 'class="valignmiddle marginleftonly paddingrightonly"');
1740 $morehtmlref .= '</a>';
1741
1742 $urltovirtualcard = '/user/virtualcard.php?id='.((int) $object->id);
1743 $morehtmlref .= dolButtonToOpenUrlInDialogPopup('publicvirtualcard', $langs->transnoentitiesnoconv("PublicVirtualCardUrl").' - '.$object->getFullName($langs), img_picto($langs->trans("PublicVirtualCardUrl"), 'card', 'class="valignmiddle marginleftonly paddingrightonly"'), $urltovirtualcard, '', 'refid valignmiddle nohover');
1744
1745 dol_banner_tab($object, 'id', $linkback, $user->hasRight("user", "user", "read") || $user->admin, 'rowid', 'ref', $morehtmlref);
1746
1747 print '<div class="fichecenter">';
1748 print '<div class="fichehalfleft">';
1749
1750 print '<div class="underbanner clearboth"></div>';
1751 print '<table class="border tableforfield centpercent">';
1752
1753 // Login
1754 print '<tr><td class="titlefieldmiddle">'.$langs->trans("Login").'</td>';
1755 if (!empty($object->ldap_sid) && $object->status == User::STATUS_DISABLED) {
1756 print '<td class="error">';
1757 print $langs->trans("LoginAccountDisableInDolibarr");
1758 print '</td>';
1759 } else {
1760 print '<td>';
1761 $addadmin = '';
1762 if (isModEnabled('multicompany') && !empty($object->admin) && empty($object->entity)) {
1763 $addadmin .= img_picto($langs->trans("SuperAdministratorDesc"), "superadmin", 'class="paddingleft valignmiddle"');
1764 } elseif (!empty($object->admin)) {
1765 $addadmin .= img_picto($langs->trans("AdministratorDesc"), "admin", 'class="paddingleft valignmiddle"');
1766 }
1767 print showValueWithClipboardCPButton($object->login).$addadmin;
1768 print '</td>';
1769 }
1770 print '</tr>'."\n";
1771
1772 // Type
1773 print '<tr><td>';
1774 $text = $langs->trans("Type");
1775 print $form->textwithpicto($text, $langs->trans("InternalExternalDesc"));
1776 print '</td><td>';
1777 $type = $langs->trans("Internal");
1778 if ($object->socid > 0) {
1779 $type = $langs->trans("External");
1780 }
1781 print '<span class="badgeneutral">';
1782 print $type;
1783 if ($object->ldap_sid) {
1784 print ' ('.$langs->trans("DomainUser").')';
1785 }
1786 print '</span>';
1787 print '</td></tr>'."\n";
1788
1789 // Ldap sid
1790 if ($object->ldap_sid && is_object($ldap)) {
1791 print '<tr><td>'.$langs->trans("Type").'</td><td>';
1792 print $langs->trans("DomainUser", $ldap->domainFQDN);
1793 print '</td></tr>'."\n";
1794 }
1795
1796 // Employee
1797 print '<tr><td>'.$langs->trans("Employee").'</td><td>';
1798 if (getDolGlobalInt('MAIN_OPTIMIZEFORTEXTBROWSER') < 2) {
1799 print '<input type="checkbox" disabled name="employee" value="1"'.($object->employee ? ' checked="checked"' : '').'>';
1800 } else {
1801 print yn($object->employee);
1802 }
1803 print '</td></tr>'."\n";
1804
1805 // TODO This is also available into the tab RH
1806 if ($nbofusers > 1) {
1807 // Hierarchy
1808 print '<tr><td>'.$langs->trans("HierarchicalResponsible").'</td>';
1809 print '<td>';
1810 if (empty($object->fk_user)) {
1811 print '<span class="opacitymedium">'.$langs->trans("None").'</span>';
1812 } else {
1813 $huser = new User($db);
1814 if ($object->fk_user > 0) {
1815 $huser->fetch($object->fk_user);
1816 print $huser->getNomUrl(-1);
1817 } else {
1818 print '<span class="opacitymedium">'.$langs->trans("None").'</span>';
1819 }
1820 }
1821 print '</td>';
1822 print "</tr>\n";
1823
1824 // Expense report validator
1825 if (isModEnabled('expensereport')) {
1826 print '<tr><td>';
1827 $text = $langs->trans("ForceUserExpenseValidator");
1828 print $form->textwithpicto($text, $langs->trans("ValidatorIsSupervisorByDefault"), 1, 'help');
1829 print '</td>';
1830 print '<td>';
1831 if (!empty($object->fk_user_expense_validator)) {
1832 $evuser = new User($db);
1833 $evuser->fetch($object->fk_user_expense_validator);
1834 print $evuser->getNomUrl(-1);
1835 }
1836 print '</td>';
1837 print "</tr>\n";
1838 }
1839
1840 // Holiday request validator
1841 if (isModEnabled('holiday')) {
1842 print '<tr><td>';
1843 $text = $langs->trans("ForceUserHolidayValidator");
1844 print $form->textwithpicto($text, $langs->trans("ValidatorIsSupervisorByDefault"), 1, 'help');
1845 print '</td>';
1846 print '<td>';
1847 if (!empty($object->fk_user_holiday_validator)) {
1848 $hvuser = new User($db);
1849 $hvuser->fetch($object->fk_user_holiday_validator);
1850 print $hvuser->getNomUrl(-1);
1851 }
1852 print '</td>';
1853 print "</tr>\n";
1854 }
1855 }
1856
1857 // Position/Job
1858 print '<tr><td>'.$langs->trans("PostOrFunction").'</td>';
1859 print '<td>'.dol_escape_htmltag($object->job).'</td>';
1860 print '</tr>'."\n";
1861
1862 // Weeklyhours
1863 print '<tr><td>'.$langs->trans("WeeklyHours").'</td>';
1864 print '<td>';
1865 print price2num($object->weeklyhours);
1866 print '</td>';
1867 print "</tr>\n";
1868
1869 // Sensitive salary/value information
1870 if ($permissiontoseesalary) {
1871 $langs->load("salaries");
1872
1873 // Salary
1874 print '<tr><td>'.$langs->trans("Salary").'</td>';
1875 print '<td>';
1876 print($object->salary != '' ? img_picto('', 'salary', 'class="pictofixedwidth paddingright"').'<span class="amount">'.price($object->salary, 0, $langs, 1, -1, -1, $conf->currency) : '').'</span>';
1877 print '</td>';
1878 print "</tr>\n";
1879
1880 // THM
1881 print '<tr><td>';
1882 $text = $langs->trans("THM");
1883 print $form->textwithpicto($text, $langs->trans("THMDescription"), 1, 'help', 'classthm');
1884 print '</td>';
1885 print '<td>';
1886 print($object->thm != '' ? '<span class="amount">'.price($object->thm, 0, $langs, 1, -1, -1, $conf->currency).'</span>' : '');
1887 print '</td>';
1888 print "</tr>\n";
1889
1890 // TJM
1891 print '<tr><td>';
1892 $text = $langs->trans("TJM");
1893 print $form->textwithpicto($text, $langs->trans("TJMDescription"), 1, 'help', 'classtjm');
1894 print '</td>';
1895 print '<td>';
1896 print($object->tjm != '' ? '<span class="amount">'.price($object->tjm, 0, $langs, 1, -1, -1, $conf->currency).'</span>' : '');
1897 print '</td>';
1898 print "</tr>\n";
1899 }
1900
1901 // Date employment
1902 print '<tr><td>'.$langs->trans("DateOfEmployment").'</td>';
1903 print '<td>';
1904 if ($object->dateemployment) {
1905 print '<span class="opacitymedium">'.$langs->trans("FromDate").'</span> ';
1906 print dol_print_date($object->dateemployment, 'day');
1907 }
1908 if ($object->dateemploymentend) {
1909 print '<span class="opacitymedium"> - '.$langs->trans("To").'</span> ';
1910 print dol_print_date($object->dateemploymentend, 'day');
1911 }
1912 print '</td>';
1913 print "</tr>\n";
1914
1915 // Date of birth
1916 print '<tr><td>'.$langs->trans("DateOfBirth").'</td>';
1917 print '<td>';
1918 print dol_print_date($object->birth, 'day', 'tzserver');
1919 print '</td>';
1920 print "</tr>\n";
1921
1922 // Default warehouse
1923 if (isModEnabled('stock') && getDolGlobalString('MAIN_DEFAULT_WAREHOUSE_USER')) {
1924 require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
1925 print '<tr><td>'.$langs->trans("DefaultWarehouse").'</td><td>';
1926 if ($object->fk_warehouse > 0) {
1927 $warehousestatic = new Entrepot($db);
1928 $warehousestatic->fetch($object->fk_warehouse);
1929 print $warehousestatic->getNomUrl(1);
1930 }
1931 print '</td></tr>';
1932 }
1933
1934 print '</table>';
1935
1936 print '</div>';
1937 print '<div class="fichehalfright">';
1938
1939 print '<div class="underbanner clearboth"></div>';
1940
1941 print '<table class="border tableforfield centpercent">';
1942
1943 // Color user
1944 if (isModEnabled('agenda')) {
1945 print '<tr><td class="titlefieldmax45">'.$langs->trans("Color").'</td>';
1946 print '<td>';
1947 print $formother->showColor($object->color, '');
1948 print '</td>';
1949 print "</tr>\n";
1950 }
1951
1952 // Categories
1953 if (isModEnabled('category') && $user->hasRight("categorie", "read")) {
1954 print '<tr><td>'.$langs->trans("Categories").'</td>';
1955 print '<td>';
1956 print $form->showCategories($object->id, Categorie::TYPE_USER, 1);
1957 print '</td></tr>';
1958 }
1959
1960 // Default language
1961 if (getDolGlobalInt('MAIN_MULTILANGS')) {
1962 $langs->load("languages");
1963 require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
1964 print '<tr><td>';
1965 print $form->textwithpicto($langs->trans("DefaultLang"), $langs->trans("WarningNotLangOfInterface", $langs->transnoentitiesnoconv("UserGUISetup")));
1966 print '</td><td>';
1967 //$s=picto_from_langcode($object->default_lang);
1968 //print ($s?$s.' ':'');
1969 $labellang = ($object->lang ? $langs->trans('Language_'.$object->lang) : '');
1970 print picto_from_langcode($object->lang, 'class="paddingrightonly saturatemedium opacitylow"');
1971 print $labellang;
1972 print '</td></tr>';
1973 }
1974
1975 if (isset($conf->file->main_authentication) && preg_match('/openid/', $conf->file->main_authentication) && getDolGlobalString('MAIN_OPENIDURL_PERUSER')) {
1976 print '<tr><td>'.$langs->trans("OpenIDURL").'</td>';
1977 print '<td>'.$object->openid.'</td>';
1978 print "</tr>\n";
1979 }
1980
1981 // Multicompany
1982 if (isModEnabled('multicompany') && isset($mc) && is_object($mc)) {
1983 // This is now done with hook formObjectOptions. Keep this code for backward compatibility with old multicompany module
1984 if (!method_exists($mc, 'formObjectOptions')) {
1985 if (isModEnabled('multicompany') && !getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE') && $conf->entity == 1 && $user->admin && !$user->entity) {
1986 print '<tr><td>'.$langs->trans("Entity").'</td><td>';
1987 if (empty($object->entity)) {
1988 print $langs->trans("AllEntities");
1989 } else {
1990 $mc->getInfo($object->entity);
1991 print $mc->label;
1992 }
1993 print "</td></tr>\n";
1994 }
1995 }
1996 }
1997
1998 // Other attributes
1999 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
2000
2001 // Company / Contact
2002 if (isModEnabled("societe")) {
2003 print '<tr><td>'.$langs->trans("LinkToCompanyContact").'</td>';
2004 print '<td>';
2005 $s = '';
2006 if (!empty($object->socid) && $object->socid > 0) {
2007 $societe = new Societe($db);
2008 $societe->fetch($object->socid);
2009 if ($societe->id > 0) {
2010 $s .= $societe->getNomUrl(1, '');
2011 }
2012 } else {
2013 $s .= '<span class="opacitymedium hideonsmartphone">'.$langs->trans("ThisUserIsNot").'</span>';
2014 }
2015 if (!empty($object->contact_id)) {
2016 $contact = new Contact($db);
2017 $contact->fetch($object->contact_id);
2018 if ($contact->id > 0) {
2019 if ($object->socid > 0 && $s) {
2020 $s .= ' / ';
2021 } else {
2022 $s .= '<br>';
2023 }
2024 $s .= $contact->getNomUrl(1, '');
2025 }
2026 }
2027 print $s;
2028 print '</td>';
2029 print '</tr>'."\n";
2030 }
2031
2032 // Module Adherent
2033 if (isModEnabled('member')) {
2034 $langs->load("members");
2035 print '<tr><td>'.$langs->trans("LinkedToDolibarrMember").'</td>';
2036 print '<td>';
2037 if ($object->fk_member) {
2038 $adh = new Adherent($db);
2039 $adh->fetch($object->fk_member);
2040 $adh->ref = $adh->getFullname($langs); // Force to show login instead of id
2041 print $adh->getNomUrl(-1);
2042 } else {
2043 print '<span class="opacitymedium hideonsmartphone">'.$langs->trans("UserNotLinkedToMember").'</span>';
2044 }
2045 print '</td>';
2046 print '</tr>'."\n";
2047 }
2048
2049 // Signature
2050 print '<tr><td class="tdtop">'.$langs->trans('Signature').'</td><td class="wordbreak">';
2051 print dol_htmlentitiesbr($object->signature);
2052 if (!empty($object->signature)) {
2053 print dolGetSignatureQualityBadge($object->signature, $langs);
2054 }
2055 print "</td></tr>\n";
2056
2057 print "</table>\n";
2058
2059
2060 // Credentials section
2061
2062 // MAIN_SECURITY_ALLOW_TOTP=1 to enabled 2FA
2063 // API_IN_TOKEN_TABLE=1 to enable use of oaut_token table for API tokens
2064
2065 print '<br>';
2066 print '<!-- credential section -->'."\n";
2067 print '<div class="div-table-responsive-no-min">';
2068 print '<table class="noborder tableforfield centpercent">';
2069
2070 // Title line
2071 print '<tr class="liste_titre"><th class="liste_titre" colspan="2">';
2072 print '<div class="centpercent display-flex">';
2073 print '<div class="left inline-block">';
2074 print img_picto('', 'security', 'class="paddingleft pictofixedwidth"').$langs->trans("SecurityForConnection");
2075 print '</div>';
2076 print '</div>';
2077 print '</th>';
2078 print '</tr>';
2079
2080 // Date login validity
2081 print '<tr class="nooddeven"><td class="titlefieldmax45 nowraponall">'.$langs->trans("RangeOfLoginValidity").'</td>';
2082 print '<td>';
2083 if ($object->datestartvalidity) {
2084 print '<span class="opacitymedium">'.$langs->trans("FromDate").'</span> ';
2085 print dol_print_date($object->datestartvalidity, 'day');
2086 }
2087 if ($object->dateendvalidity) {
2088 print '<span class="opacitymedium"> - '.$langs->trans("To").'</span> ';
2089 print dol_print_date($object->dateendvalidity, 'day');
2090 }
2091 print '</td>';
2092 print "</tr>\n";
2093
2094 // Force update on next login only on dolibarr auth mode
2095 if ($_SESSION["dol_authmode"] == 'dolibarr') {
2096 print '<tr><td class="titlefieldcreate">'.$form->textwithpicto($langs->trans("PasswordToChange"), $langs->trans("ForcePasswordChange")).'</td>';
2097 print '<td>';
2098 $permissiontoselfeditpassword = $object->hasRight('user', 'self', 'password');
2099 if ($permissiontoselfeditpassword) {
2100 if (getDolGlobalInt('MAIN_OPTIMIZEFORTEXTBROWSER') < 2) {
2101 print '<input type="checkbox" class="colorgrey" disabled name="forcepasswordchange" value="1"'.($object->force_pass_change ? ' checked="checked"' : '').'>';
2102 //print $langs->trans("AtNextLogin");
2103 print '<span class="opacitymedium">'.yn($object->force_pass_change).'</span>';
2104 } else {
2105 print yn($object->force_pass_change);
2106 print '<span class="opacitymedium">'.yn($object->force_pass_change).'</span>';
2107 }
2108 } else {
2109 print '<input type="checkbox" name="forcepasswordchange" value="1" disabled class="valignmiddle">';
2110 print '<span class="opacitymedium" title="'.$langs->trans("UserDoesNotHaveRightsToChangeHisPassword").'">'.$langs->trans("No").'</span>';
2111 }
2112 print '</td>';
2113 print "</tr>\n";
2114 }
2115
2116 // Password for LDAP or HTTP Basic
2117 $valuetoshow = '';
2118 if (preg_match('/ldap/', $dolibarr_main_authentication)) {
2119 if (!empty($object->ldap_sid)) {
2120 if ($passDoNotExpire) {
2121 $valuetoshow .= ($valuetoshow ? (' '.$langs->trans("or").' ') : '').$langs->trans("LdapUacf_".$statutUACF);
2122 } elseif ($userChangePassNextLogon) {
2123 $valuetoshow .= ($valuetoshow ? (' '.$langs->trans("or").' ') : '').'<span class="warning">'.$langs->trans("UserMustChangePassNextLogon", $ldap->domainFQDN).'</span>';
2124 } elseif ($userDisabled) {
2125 $valuetoshow .= ($valuetoshow ? (' '.$langs->trans("or").' ') : '').'<span class="warning">'.$langs->trans("LdapUacf_".$statutUACF, $ldap->domainFQDN).'</span>';
2126 } else {
2127 $valuetoshow .= ($valuetoshow ? (' '.$langs->trans("or").' ') : '').$langs->trans("PasswordOfUserInLDAP");
2128 }
2129 } else {
2130 $valuetoshow .= ($valuetoshow ? (' '.$langs->trans("or").' ') : '').$langs->trans("PasswordOfUserInLDAP");
2131 }
2132 }
2133 if (preg_match('/http/', $dolibarr_main_authentication)) {
2134 $valuetoshow .= ($valuetoshow ? (' '.$langs->trans("or").' ') : '').$langs->trans("HTTPBasicPassword");
2135 }
2136
2137 // Other info for user password
2138 $parameters = array('valuetoshow' => $valuetoshow, 'caneditpasswordandsee' => $permissiontoeditpasswordandsee, 'caneditpasswordandsend' => $permissiontoeditpasswordandsend);
2139 $reshook = $hookmanager->executeHooks('printUserPasswordField', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2140 if ($reshook > 0) {
2141 $valuetoshow = $hookmanager->resPrint; // to replace
2142 } else {
2143 $valuetoshow .= $hookmanager->resPrint; // to add
2144 }
2145
2146 if (dol_string_nohtmltag($valuetoshow)) { // If there is a real visible content to show
2147 print '<tr class="nooddeven"><td class="titlefieldmiddle">'.$langs->trans("Password").'</td>';
2148 print '<td class="wordbreak">';
2149 print $valuetoshow;
2150 print "</td>";
2151 print '</tr>'."\n";
2152 }
2153
2154 // Token for 2FA
2155 if (getDolGlobalString('MAIN_SECURITY_ALLOW_TOTP') && $permissiontoeditpasswordandsee) {
2156 print '<tr class="nooddeven"><td>'.$langs->trans("2FA").'</td>';
2157 print '<td>';
2158 print '<div class="centpercent display-flex">';
2159 print '<span class="badge badge-info">999</span>';
2160 print '<div class="left inline-block">';
2161 $s = '<!-- MAIN_SECURITY_ALLOW_TOTP --><span class="fa fa-pen valignmiddle btnTitle-icon"></span>';
2162 print dolButtonToOpenUrlInDialogPopup('openpopuptoaddcredential', $langs->transnoentitiesnoconv("Edit"), $s, '/user/credentials.php?userid='.$object->id.'&token='.newToken());
2163 print '</span></span>';
2164 print '</td></tr>';
2165 }
2166
2167 // Token for OAuth
2168 $tmparrayofauthmode = explode(',', $dolibarr_main_authentication);
2169 foreach ($tmparrayofauthmode as $tmpauthmode) {
2170 $langs->load("oauth");
2171
2172 $tmpauthmode = trim($tmpauthmode);
2173 if (preg_match('/oauth/', $tmpauthmode)) {
2174 $nameofservice = preg_replace('/oauth/', '', $tmpauthmode);
2175 print '<tr class="nooddeven">';
2176 print '<td class="titlefieldmiddle">'.$langs->trans("OAUTH_ID");
2177 print ' '.ucfirst($nameofservice).' ';
2178 print '</td>';
2179
2180 $constoauthlogin = 'OAUTH_'.strtoupper($nameofservice).'-Login_ID';
2181 print '<td class="tdoverflowmax200" title="'.dolPrintHTMLForAttribute(getDolGlobalString($constoauthlogin)).'">';
2182 if (getDolGlobalString($constoauthlogin)) {
2183 print getDolGlobalString($constoauthlogin);
2184 }
2185 print '</td>';
2186 print "</tr>\n";
2187
2188 // Alternative email for OAuth2 login
2189 if (!empty($object->email_oauth2)) {
2190 print '<tr class="nooddeven"><td class="titlefieldmiddle">'.$langs->trans("AlternativeEmailForOAuth2").'</td>';
2191 print '<td>';
2192 print dol_print_email($object->email_oauth2);
2193 print '</td>';
2194 print "</tr>\n";
2195 }
2196 }
2197 }
2198
2199 // Token for API
2200 if (isModEnabled('api') && ($user->id == $id || $user->admin)) {
2201 print '<tr class="nooddeven"><td>'.$langs->trans("ApiKey").'</td>';
2202 print '<td>';
2203 if (getDolGlobalString('API_IN_TOKEN_TABLE')) {
2204 print '<div class="centpercent display-flex">';
2205 print '<span class="badge badge-info marginleftonly marginrightonly">0</span>';
2206 /*print '<a href="'.DOL_URL_ROOT.'/user/api_token/list.php?id='.$object->id.'">';
2207 print $langs->trans("APIKeys");
2208 print '</a>';*/
2209 print '<div class="left inline-block">';
2210 $s = '<!-- API_IN_TOKEN_TABLE --><span class="fa fa-pen valignmiddle btnTitle-icon"></span>';
2211 print dolButtonToOpenUrlInDialogPopup('openpopuptoaddapitoken', $langs->transnoentitiesnoconv("APIKeys"), $s, '/user/api_token/list.php?id='.$object->id.'&token='.newToken());
2212 print '</div>';
2213 print '</div>';
2214 } else {
2215 if (!empty($object->api_key)) {
2216 print '<span class="opacitymedium marginrightonly">';
2217 print showValueWithClipboardCPButton($object->api_key, 1, $langs->transnoentities("Hidden")); // TODO Add an option to also reveal the hash, not only copy paste
2218 print '</span>';
2219 }
2220 if ($object->api_key && (getDolGlobalString('API_ENABLE_COUNT_CALLS') || !empty($dolibarr_api_count_always_enabled))) {
2221 print '<span class="badge badge-info marginleftonly marginrightonly" title="'.$langs->trans("TotalAPICall").'">';
2222 print getDolUserInt('API_COUNT_CALL');
2223 print '</span>';
2224 }
2225 }
2226 print '</td></tr>';
2227 }
2228
2229 // Show private information about login
2230 if ((getDolGlobalInt('MAIN_ENABLE_LOGINS_PRIVACY') == 0) || (getDolGlobalInt('MAIN_ENABLE_LOGINS_PRIVACY') == 1 && $object->id == $user->id)) {
2231 print '<tr class="nooddeven"><td>'.$langs->trans("LastConnexion").'</td>';
2232 print '<td>';
2233 if ($object->datepreviouslogin) {
2234 print $form->textwithpicto(dol_print_date($object->datepreviouslogin, "dayhour", "tzuserrel"), $langs->trans("Previous"));
2235 }
2236 if ($object->datelastlogin) {
2237 if ($object->datepreviouslogin) {
2238 print ' &nbsp; &nbsp; ';
2239 }
2240 print $form->textwithpicto(dol_print_date($object->datelastlogin, "dayhour", "tzuserrel"), $langs->trans("Currently"));
2241 }
2242 print '</td>';
2243 print "</tr>\n";
2244 }
2245
2246 print '</table>';
2247 print '</div>';
2248
2249 // Add more object block
2250 $parameters = array('caneditpasswordandsee' => $permissiontoeditpasswordandsee, 'caneditpasswordandsend' => $permissiontoeditpasswordandsend);
2251 $reshook = $hookmanager->executeHooks('addMoreObjectBlock', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2252 if ($reshook > 0) {
2253 print $hookmanager->resPrint;
2254 }
2255
2256 print '</div>';
2257
2258 print '</div>';
2259 print '<div class="clearboth"></div>';
2260
2261
2262 print dol_get_fiche_end();
2263
2264
2265 /*
2266 * Buttons actions
2267 */
2268 print '<div class="tabsAction">';
2269
2270 $parameters = array();
2271 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2272 if (empty($reshook)) {
2273 $params = array(
2274 'attr' => array(
2275 'title' => '',
2276 'class' => 'classfortooltip'
2277 )
2278 );
2279
2280 if (empty($user->socid)) {
2281 $canSendMail = false;
2282 if (!empty($object->email)) {
2283 $langs->load("mails");
2284 $canSendMail = true;
2285 unset($params['attr']['title']);
2286 } else {
2287 $langs->load("mails");
2288 $params['attr']['title'] = $langs->trans('NoEMail');
2289 }
2290 print dolGetButtonAction('', $langs->trans('SendMail'), 'email', dolBuildUrl($_SERVER['PHP_SELF'], ['id' => $object->id, 'action' => 'presend', 'mode' => 'init']) . '#formmailbeforetitle', '', $canSendMail, $params);
2291 }
2292
2293 if ($permissiontoedit && (!isModEnabled('multicompany') || !$user->entity || ($object->entity == $conf->entity) || (getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE') && $object->entity == 1))) {
2294 if (getDolGlobalString('MAIN_ONLY_LOGIN_ALLOWED')) {
2295 $params['attr']['title'] = $langs->trans('DisabledInMonoUserMode');
2296 print dolGetButtonAction($langs->trans('Modify'), '', 'default', dolBuildUrl($_SERVER['PHP_SELF']).'#', '', false, $params);
2297 } else {
2298 unset($params['attr']['title']);
2299 print dolGetButtonAction($langs->trans('Modify'), '', 'default', dolBuildUrl($_SERVER['PHP_SELF'], ['id' => $object->id, 'action' => 'edit'], true), '', true, $params);
2300 }
2301 } elseif ($permissiontoeditpasswordandsee && !$object->ldap_sid &&
2302 (!isModEnabled('multicompany') || !$user->entity || ($object->entity == $conf->entity) || (getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE') && $object->entity == 1))) {
2303 unset($params['attr']['title']);
2304 print dolGetButtonAction($langs->trans('Modify'), '', 'default', dolBuildUrl($_SERVER['PHP_SELF'], ['id' => $object->id, 'action' => 'edit'], true), '', true, $params);
2305 }
2306
2307 // If we have a password generator engine enabled
2308 $params = array(
2309 'attr' => array(
2310 'title' => '',
2311 'class' => 'classfortooltip'
2312 )
2313 );
2314 // Clone user
2315 // a simple user can not clone an admin or superadmin and a simple admin can not clone a superadmin
2316 if ((empty($object->entity) && $permissiontoclonesuperadmin) || (!empty($object->admin) && !empty($object->entity) && $permissiontocloneadmin) || ($permissiontocloneuser && empty($object->admin) && !empty($object->entity))) {
2317 $cloneButtonId = '';
2318 $cloneUserUrl = '';
2319
2320 if (!empty($conf->use_javascript_ajax) && empty($conf->dol_use_jmobile)) {
2321 $cloneUserUrl = '';
2322 $cloneButtonId = 'action-clone';
2323 }
2324 print dolGetButtonAction($langs->trans('ToClone'), $langs->trans('ToClone'), 'clone', $cloneUserUrl, $cloneButtonId, $user->hasRight('user', 'user', 'write'), array('attr' => array('class' => 'reposition')));
2325 }
2326
2327 if (getDolGlobalString('USER_PASSWORD_GENERATED') != 'none') {
2328 if ($object->status == $object::STATUS_DISABLED) {
2329 $params['attr']['title'] = $langs->trans('UserDisabled');
2330 print dolGetButtonAction($langs->trans('ReinitPassword'), '', 'default', dolBuildUrl($_SERVER['PHP_SELF']).'#', '', false, $params);
2331 } elseif (($user->id != $id && $permissiontoeditpasswordandsee) && $object->login && !$object->ldap_sid &&
2332 ((!isModEnabled('multicompany') && $object->entity == $user->entity) || !$user->entity || ($object->entity == $conf->entity) || (getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE') && $object->entity == 1))) {
2333 unset($params['attr']['title']);
2334 print dolGetButtonAction($langs->trans('ReinitPassword'), '', 'default', dolBuildUrl($_SERVER['PHP_SELF'], ['id' => $object->id, 'action' => 'password'], true), '', true, $params);
2335 }
2336
2337 if ($object->status == $object::STATUS_DISABLED) {
2338 $params['attr']['title'] = $langs->trans('UserDisabled');
2339 print dolGetButtonAction($langs->trans('SendNewPassword'), '', 'default', $_SERVER['PHP_SELF'].'#', '', false, $params);
2340 } elseif (($user->id != $id && $permissiontoeditpasswordandsend) && $object->login && !$object->ldap_sid &&
2341 ((!isModEnabled('multicompany') && $object->entity == $user->entity) || !$user->entity || ($object->entity == $conf->entity) || (getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE') && $object->entity == 1))) {
2342 if ($object->email) {
2343 unset($params['attr']['title']);
2344 print dolGetButtonAction($langs->trans('SendNewPassword'), '', 'default', dolBuildUrl($_SERVER['PHP_SELF'], ['id' => $object->id, 'action' => 'passwordsend'], true), '', true, $params);
2345 } else {
2346 $params['attr']['title'] = $langs->trans('NoEMail');
2347 print dolGetButtonAction($langs->trans('SendNewPassword'), '', 'default', $_SERVER['PHP_SELF'].'#', '', false, $params);
2348 }
2349 }
2350 }
2351
2352 if ($user->id != $id && $permissiontodisable && $object->status == User::STATUS_DISABLED &&
2353 ((!isModEnabled('multicompany') && $object->entity == $user->entity) || !$user->entity || ($object->entity == $conf->entity) || (getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE') && $object->entity == 1))) {
2354 unset($params['attr']['title']);
2355 print dolGetButtonAction($langs->trans('Reactivate'), '', 'default', dolBuildUrl($_SERVER['PHP_SELF'], ['id' => $object->id, 'action' => 'enable'], true), '', true, $params);
2356 }
2357 // Disable user
2358 if ($user->id != $id && $permissiontodisable && $object->status == User::STATUS_ENABLED &&
2359 ((!isModEnabled('multicompany') && $object->entity == $user->entity) || !$user->entity || ($object->entity == $conf->entity) || (getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE') && $object->entity == 1))) {
2360 unset($params['attr']['title']);
2361 print dolGetButtonAction($langs->trans('DisableUser'), '', 'default', dolBuildUrl($_SERVER['PHP_SELF'], ['id' => $object->id, 'action' => 'disable'], true), '', true, $params);
2362 } else {
2363 if ($user->id == $id) {
2364 $params['attr']['title'] = $langs->trans('CantDisableYourself');
2365 print dolGetButtonAction($langs->trans('DisableUser'), '', 'default', $_SERVER['PHP_SELF'].'#', '', false, $params);
2366 }
2367 }
2368 // Delete
2369 if ($user->id != $id && $permissiontodisable &&
2370 ((!isModEnabled('multicompany') && $object->entity == $user->entity) || !$user->entity || ($object->entity == $conf->entity) || (getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE') && $object->entity == 1))) {
2371 if ($user->admin || !$object->admin) { // If user edited is admin, delete is possible on for an admin
2372 unset($params['attr']['title']);
2373 print dolGetButtonAction($langs->trans('DeleteUser'), '', 'default', dolBuildUrl($_SERVER['PHP_SELF'], ['action' => 'delete', 'id' => $object->id], true), '', true, array('attr' => array('class' => 'reposition')));
2374 } else {
2375 $params['attr']['title'] = $langs->trans('MustBeAdminToDeleteOtherAdmin');
2376 print dolGetButtonAction($langs->trans('DeleteUser'), '', 'default', dolBuildUrl($_SERVER['PHP_SELF'], ['action' => 'delete', 'id' => $object->id], true), '', false, array('attr' => array('class' => 'reposition')));
2377 }
2378 }
2379 }
2380
2381 print "</div>\n";
2382
2383
2384
2385 // Select mail models is same action as presend
2386 if (GETPOST('modelselected')) {
2387 $action = 'presend';
2388 }
2389
2390 // Presend form
2391 $modelmail = 'user';
2392 $defaulttopic = 'Information';
2393 $diroutput = $conf->user->dir_output;
2394 $trackid = 'use'.$object->id;
2395
2396 include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
2397
2398 if ($action != 'presend' && $action != 'send') {
2399 /*
2400 * List of groups of user
2401 */
2402
2403 if ($permissiontoreadgroup) {
2404 print '<!-- Group section -->'."\n";
2405
2406 print load_fiche_titre($langs->trans("ListOfGroupsForUser"), '', '');
2407
2408 // We select the groups that the users belongs to
2409 $exclude = array();
2410
2411 $usergroup = new UserGroup($db);
2412 $groupslist = $usergroup->listGroupsForUser($object->id, false);
2413
2414 if (!empty($groupslist)) {
2415 foreach ($groupslist as $groupforuser) {
2416 $exclude[] = $groupforuser->id;
2417 }
2418 }
2419
2420 // Other form for add user to group
2421 $parameters = array('caneditgroup' => $permissiontoeditgroup, 'groupslist' => $groupslist, 'exclude' => $exclude);
2422 $reshook = $hookmanager->executeHooks('formAddUserToGroup', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2423 print $hookmanager->resPrint;
2424
2425 if (empty($reshook)) {
2426 if ($permissiontoeditgroup) {
2427 print '<form action="'.$_SERVER['PHP_SELF'].'?id='.$id.'" method="POST">'."\n";
2428 print '<input type="hidden" name="token" value="'.newToken().'" />';
2429 print '<input type="hidden" name="action" value="addgroup" />';
2430 print '<input type="hidden" name="page_y" value="" />';
2431 }
2432
2433 print '<!-- List of groups of the user -->'."\n";
2434 print '<table class="noborder centpercent">'."\n";
2435 print '<tr class="liste_titre">';
2436 //print '<th class="liste_titre">'.$langs->trans("Groups").'</th>'."\n";
2437 print '<th class="liste_titre right" colspan="2">';
2438 if ($permissiontoeditgroup) {
2439 print $form->select_dolgroups(0, 'group', 1, $exclude, 0, '', array(), (string) $object->entity, false, 'maxwidth150');
2440 print ' &nbsp; ';
2441 print '<input type="hidden" name="entity" value="'.$conf->entity.'" />';
2442 print '<input type="submit" class="button buttongen button-add reposition" value="'.$langs->trans("Add").'" />';
2443 }
2444 print '</th></tr>'."\n";
2445
2446 // List of groups of user
2447 if (!empty($groupslist)) {
2448 foreach ($groupslist as $group) {
2449 print '<tr class="oddeven">';
2450 print '<td class="tdoverflowmax200">';
2451 if ($permissiontoeditgroup) {
2452 print $group->getNomUrl(1);
2453 } else {
2454 print img_object($langs->trans("ShowGroup"), "group").' '.$group->name;
2455 }
2456 print '</td>';
2457 print '<td class="right">';
2458 if ($permissiontoeditgroup) {
2459 print '<a class="reposition" href="'.dolBuildUrl($_SERVER['PHP_SELF'], ['id' => $object->id, 'action' => 'removegroup', 'group' => $group->id], true).'">';
2460 print img_picto($langs->trans("RemoveFromGroup"), 'unlink');
2461 print '</a>';
2462 } else {
2463 print "&nbsp;";
2464 }
2465 print "</td></tr>\n";
2466 }
2467 } else {
2468 print '<tr class="oddeven"><td colspan="2"><span class="opacitymedium">'.$langs->trans("None").'</span></td></tr>';
2469 }
2470
2471 print "</table>";
2472
2473 if ($permissiontoeditgroup) {
2474 print '</form>';
2475 }
2476 print "<br>";
2477 }
2478 }
2479 }
2480 }
2481
2482 /*
2483 * Edit mode
2484 */
2485 if ($action == 'edit' && ($permissiontoedit || $permissiontoeditpasswordandsee)) {
2486 print '<form action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'" method="POST" name="updateuser" enctype="multipart/form-data">';
2487 print '<input type="hidden" name="token" value="'.newToken().'">';
2488 print '<input type="hidden" name="action" value="update">';
2489 print '<input type="hidden" name="entity" value="'.$object->entity.'">';
2490
2491 print dol_get_fiche_head($head, 'user', $title, 0, 'user');
2492
2493 print '<table class="border centpercent">';
2494
2495 // Ref/ID
2496 if (getDolGlobalString('MAIN_SHOW_TECHNICAL_ID')) {
2497 print '<tr><td class="titlefieldcreate">'.$langs->trans("Ref").'</td>';
2498 print '<td>';
2499 print $object->id;
2500 print '</td>';
2501 print '</tr>';
2502 }
2503
2504 // Lastname
2505 print "<tr>";
2506 print '<td class="titlefieldcreate fieldrequired">'.$langs->trans("Lastname").'</td>';
2507 print '<td>';
2508 if ($permissiontoedit && !$object->ldap_sid) {
2509 print '<input class="minwidth100" type="text" class="flat" name="lastname" value="'.$object->lastname.'">';
2510 } else {
2511 print '<input type="hidden" name="lastname" value="'.$object->lastname.'">';
2512 print $object->lastname;
2513 }
2514 print '</td>';
2515 print '</tr>';
2516
2517 // Firstname
2518 print '<tr><td>'.$langs->trans("Firstname").'</td>';
2519 print '<td>';
2520 if ($permissiontoedit && !$object->ldap_sid) {
2521 print '<input class="minwidth100" type="text" class="flat" name="firstname" value="'.$object->firstname.'">';
2522 } else {
2523 print '<input type="hidden" name="firstname" value="'.$object->firstname.'">';
2524 print $object->firstname;
2525 }
2526 print '</td></tr>';
2527
2528 // Login
2529 print "<tr>".'<td><span class="fieldrequired">'.$langs->trans("Login").'</span></td>';
2530 print '<td>';
2531 if ($user->admin && !$object->ldap_sid) {
2532 print '<input maxlength="50" type="text" class="flat" name="login" value="'.$object->login.'" spellcheck="false">';
2533 } else {
2534 print '<input type="hidden" name="login" value="'.$object->login.'">';
2535 print $object->login;
2536 }
2537 print '</td>';
2538 print '</tr>';
2539
2540 // External user ?
2541 print '<tr><td>'.$langs->trans("ExternalUser").' ?</td>';
2542 print '<td>';
2543 if ($user->id == $object->id || !$user->admin) {
2544 // Read mode
2545 $type = $langs->trans("Internal");
2546 if ($object->socid) {
2547 $type = $langs->trans("External");
2548 }
2549 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
2550 print $form->textwithpicto($type, $langs->trans("InternalExternalDesc"));
2551 if ($object->ldap_sid) {
2552 print ' ('.$langs->trans("DomainUser").')';
2553 }
2554 } else {
2555 // Select mode
2556 $type = 0;
2557 if ($object->contact_id) {
2558 $type = $object->contact_id;
2559 }
2560
2561 $eventsCompanyContact = array();
2562 $eventsCompanyContact[] = array('method' => 'getContacts', 'url' => dol_buildpath('/core/ajax/contacts.php?showempty=1&token='.currentToken(), 1), 'htmlname' => 'contactid', 'params' => array('add-customer-contact' => 'disabled'));
2563 if ($object->socid > 0 && !($object->contact_id > 0)) { // external user but no link to a contact
2564 print img_picto('', 'company', 'class="pictofixedwidth"');
2565 print $form->select_company($object->socid, 'socid', '', '&nbsp;', 0, 0, $eventsCompanyContact, 0, 'widthcentpercentminusxx maxwidth300');
2566 print '<span class="clearbothonsmartphone"></span>';
2567 print img_picto('', 'contact', 'class="pictofixedwidth"');
2568 print $form->select_contact(0, 0, 'contactid', 1, '', '', 1, 'minwidth100imp widthcentpercentminusxx maxwidth300', true, 1);
2569 if ($object->ldap_sid) {
2570 print ' ('.$langs->trans("DomainUser").')';
2571 }
2572 } elseif ($object->socid > 0 && $object->contact_id > 0) { // external user with a link to a contact
2573 print img_picto('', 'company', 'class="pictofixedwidth"');
2574 print $form->select_company($object->socid, 'socid', '', '&nbsp;', 0, 0, $eventsCompanyContact, 0, 'widthcentpercentminusxx maxwidth300'); // We keep thirdparty empty, contact is already set
2575 print '<span class="clearbothonsmartphone"></span>';
2576 print img_picto('', 'contact', 'class="pictofixedwidth"');
2577 print $form->select_contact(0, $object->contact_id, 'contactid', 1, '', '', 1, 'minwidth100imp widthcentpercentminusxx maxwidth300', true, 1);
2578 if ($object->ldap_sid) {
2579 print ' ('.$langs->trans("DomainUser").')';
2580 }
2581 } elseif (!($object->socid > 0) && $object->contact_id > 0) { // internal user with a link to a contact
2582 print img_picto('', 'company', 'class="pictofixedwidth"');
2583 print $form->select_company(0, 'socid', '', '&nbsp;', 0, 0, $eventsCompanyContact, 0, 'widthcentpercentminusxx maxwidth300'); // We keep thirdparty empty, contact is already set
2584 print '<span class="clearbothonsmartphone"></span>';
2585 print img_picto('', 'contact', 'class="pictofixedwidth"');
2586 print $form->select_contact(0, $object->contact_id, 'contactid', 1, '', '', 1, 'minwidth100imp widthcentpercentminusxx maxwidth300', true, 1);
2587 if ($object->ldap_sid) {
2588 print ' ('.$langs->trans("DomainUser").')';
2589 }
2590 } else { // $object->socid is not > 0 here
2591 print img_picto('', 'company', 'class="pictofixedwidth"');
2592 print $form->select_company(0, 'socid', '', '&nbsp;', 0, 0, $eventsCompanyContact, 0, 'widthcentpercentminusxx maxwidth300'); // We keep thirdparty empty, contact is already set
2593 print '<span class="clearbothonsmartphone"></span>';
2594 print img_picto('', 'contact', 'class="pictofixedwidth"');
2595 print $form->select_contact(0, 0, 'contactid', 1, '', '', 1, 'minwidth100imp widthcentpercentminusxx maxwidth300', true, 1);
2596 }
2597 }
2598 print '</td></tr>';
2599
2600 // Administrator
2601 print '<tr><td>'.$form->textwithpicto($langs->trans("Administrator"), $langs->trans("AdministratorDesc")).'</td>';
2602 if ($object->socid > 0) {
2603 $langs->load("admin");
2604 print '<td>';
2605 print '<input type="hidden" name="admin" value="'.$object->admin.'">'.yn($object->admin);
2606 print ' <span class="opacitymedium">('.$langs->trans("ExternalUser").')</span>';
2607 print '</td></tr>';
2608 } else {
2609 print '<td>';
2610 $nbAdmin = $user->getNbOfUsers('active', '', 1);
2611 $nbSuperAdmin = $user->getNbOfUsers('active', 'superadmin', 1);
2612 if ($user->admin // Need to be admin to allow downgrade of an admin
2613 && ($user->id != $object->id) // Don't downgrade ourself
2614 && (
2615 (!isModEnabled('multicompany') && $nbAdmin >= 1)
2616 || (isModEnabled('multicompany') && (($object->entity > 0 || ($user->entity == 0 && $object->entity == 0)) || $nbSuperAdmin > 1)) // Don't downgrade a superadmin if alone
2617 )
2618 ) {
2619 print $form->selectyesno('admin', $object->admin, 1, false, 0, 1);
2620
2621 if (isModEnabled('multicompany') && !$user->entity) {
2622 if ($conf->use_javascript_ajax) {
2623 print '<script type="text/javascript">
2624 $(function() {
2625 var admin = $("select[name=admin]").val();
2626 if (admin == 0) {
2627 $("input[name=superadmin]")
2628 .prop("disabled", true)
2629 .prop("checked", false);
2630 }
2631 if ($("input[name=superadmin]").is(":checked")) {
2632 $("select[name=entity]")
2633 .prop("disabled", true);
2634 }
2635 $("select[name=admin]").change(function() {
2636 if ( $(this).val() == 0 ) {
2637 $("input[name=superadmin]")
2638 .prop("disabled", true)
2639 .prop("checked", false);
2640 $("select[name=entity]")
2641 .prop("disabled", false);
2642 } else {
2643 $("input[name=superadmin]")
2644 .prop("disabled", false);
2645 }
2646 });
2647 $("input[name=superadmin]").change(function() {
2648 if ( $(this).is(":checked")) {
2649 $("select[name=entity]")
2650 .prop("disabled", true);
2651 } else {
2652 $("select[name=entity]")
2653 .prop("disabled", false);
2654 }
2655 });
2656 });
2657 </script>';
2658 }
2659
2660 $checked = (($object->admin && !$object->entity) ? ' checked' : '');
2661 print '<input type="checkbox" name="superadmin" id="superadmin" value="1"'.$checked.' /> <label for="superadmin">'.$langs->trans("SuperAdministrator").'</span>';
2662 }
2663 } else {
2664 $yn = yn($object->admin);
2665 print '<input type="hidden" name="admin" value="'.$object->admin.'">';
2666 print '<input type="hidden" name="superadmin" value="'.(empty($object->entity) ? 1 : 0).'">';
2667 if (isModEnabled('multicompany') && empty($object->entity)) {
2668 print $form->textwithpicto($yn, $langs->trans("DontDowngradeSuperAdmin"), 1, 'warning');
2669 } else {
2670 print $yn;
2671 }
2672 }
2673 print '</td></tr>';
2674 }
2675
2676 // Civility
2677 if (getDolGlobalString('MAIN_USE_TITLE_FOR_USER')) {
2678 print '<tr><td class="titlefieldcreate"><label for="civility_code">'.$langs->trans("UserTitle").'</label></td><td>';
2679 if ($permissiontoedit && !$object->ldap_sid) {
2680 print $formcompany->select_civility(GETPOSTISSET("civility_code") ? GETPOST("civility_code", 'aZ09') : $object->civility_code, 'civility_code');
2681 } elseif ($object->civility_code) {
2682 print $langs->trans("Civility".$object->civility_code);
2683 }
2684 print '</td></tr>';
2685 }
2686
2687 // Gender
2688 print '<tr><td>'.$langs->trans("Gender").'</td>';
2689 print '<td>';
2690 $arraygender = array('man' => $langs->trans("Genderman"), 'woman' => $langs->trans("Genderwoman"), 'other' => $langs->trans("Genderother"));
2691 if ($permissiontoedit) {
2692 print $form->selectarray('gender', $arraygender, GETPOSTISSET('gender') ? GETPOST('gender') : $object->gender, 1);
2693 } else {
2694 print $arraygender[$object->gender];
2695 }
2696 print '</td></tr>';
2697
2698 // Employee
2699 print '<tr>';
2700 print '<td>'.$form->editfieldkey('Employee', 'employee', '', $object, 0).'</td><td>';
2701 if ($permissiontoedit) {
2702 print '<input type="checkbox" name="employee" value="1"'.($object->employee ? ' checked="checked"' : '').'>';
2703 //print $form->selectyesno("employee", $object->employee, 1);
2704 } else {
2705 print '<input type="checkbox" name="employee" disabled value="1"'.($object->employee ? ' checked="checked"' : '').'>';
2706 /*if ($object->employee) {
2707 print $langs->trans("Yes");
2708 } else {
2709 print $langs->trans("No");
2710 }*/
2711 }
2712 print '</td></tr>';
2713
2714 if ($nbofusers > 1) {
2715 // Hierarchy
2716 print '<tr><td class="titlefieldcreate">'.$langs->trans("HierarchicalResponsible").'</td>';
2717 print '<td>';
2718 if ($permissiontoedit) {
2719 print img_picto('', 'user', 'class="pictofixedwidth"').$form->select_dolusers(GETPOSTISSET('fk_user') ? GETPOSTINT('fk_user') : $object->fk_user, 'fk_user', 1, array($object->id), 0, '', '', (string) $object->entity, 0, 0, '', 0, '', 'widthcentpercentminusx maxwidth300');
2720 } else {
2721 print '<input type="hidden" name="fk_user" value="'.$object->fk_user.'">';
2722 $huser = new User($db);
2723 $huser->fetch($object->fk_user);
2724 print $huser->getNomUrl(-1);
2725 }
2726 print '</td>';
2727 print "</tr>\n";
2728
2729 // Expense report validator
2730 if (isModEnabled('expensereport')) {
2731 print '<tr><td class="titlefieldcreate">';
2732 $text = $langs->trans("ForceUserExpenseValidator");
2733 print $form->textwithpicto($text, $langs->trans("ValidatorIsSupervisorByDefault"), 1, 'help');
2734 print '</td>';
2735 print '<td>';
2736 if ($permissiontoedit) {
2737 print img_picto('', 'user', 'class="pictofixedwidth"').$form->select_dolusers($object->fk_user_expense_validator, 'fk_user_expense_validator', 1, array($object->id), 0, '', '', (string) $object->entity, 0, 0, '', 0, '', 'widthcentpercentminusx maxwidth300');
2738 } else {
2739 print '<input type="hidden" name="fk_user_expense_validator" value="'.$object->fk_user_expense_validator.'">';
2740 $evuser = new User($db);
2741 $evuser->fetch($object->fk_user_expense_validator);
2742 print $evuser->getNomUrl(-1);
2743 }
2744 print '</td>';
2745 print "</tr>\n";
2746 }
2747
2748 // Holiday request validator
2749 if (isModEnabled('holiday')) {
2750 print '<tr><td class="titlefieldcreate">';
2751 $text = $langs->trans("ForceUserHolidayValidator");
2752 print $form->textwithpicto($text, $langs->trans("ValidatorIsSupervisorByDefault"), 1, 'help');
2753 print '</td>';
2754 print '<td>';
2755 if ($permissiontoedit) {
2756 print img_picto('', 'user', 'class="pictofixedwidth"').$form->select_dolusers($object->fk_user_holiday_validator, 'fk_user_holiday_validator', 1, array($object->id), 0, '', '', (string) $object->entity, 0, 0, '', 0, '', 'widthcentpercentminusx maxwidth300');
2757 } else {
2758 print '<input type="hidden" name="fk_user_holiday_validator" value="'.$object->fk_user_holiday_validator.'">';
2759 $hvuser = new User($db);
2760 $hvuser->fetch($object->fk_user_holiday_validator);
2761 print $hvuser->getNomUrl(-1);
2762 }
2763 print '</td>';
2764 print "</tr>\n";
2765 }
2766 }
2767
2768 print '</table>';
2769
2770
2771 print '<hr>';
2772
2773
2774 print '<table class="border centpercent">';
2775
2776 // Date access validity
2777 print '<tr><td class="titlefieldcreate">'.$langs->trans("RangeOfLoginValidity").'</td>';
2778 print '<td>';
2779 if ($permissiontoedit) {
2780 print $form->selectDate($datestartvalidity ? $datestartvalidity : $object->datestartvalidity, 'datestartvalidity', 0, 0, 1, 'formdatestartvalidity', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("from"));
2781 } else {
2782 print dol_print_date($object->datestartvalidity, 'day');
2783 }
2784 print ' &nbsp; ';
2785
2786 if ($permissiontoedit) {
2787 print $form->selectDate($dateendvalidity ? $dateendvalidity : $object->dateendvalidity, 'dateendvalidity', 0, 0, 1, 'formdateendvalidity', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to"));
2788 } else {
2789 print dol_print_date($object->dateendvalidity, 'day');
2790 }
2791 print '</td>';
2792 print "</tr>\n";
2793
2794 // Set checkbxo to update on next login (only on dolibarr auth mode)
2795 $sforcepass = '';
2796 $permissiontoselfeditpassword = $object->hasRight('user', 'self', 'password');
2797 if ($permissiontoselfeditpassword) {
2798 if ($permissiontoedit) {
2799 $sforcepass .= '<input type="checkbox" name="forcepasswordchange" id="forcepasswordchange" value="1"'.($object->force_pass_change ? ' checked="checked"' : '').'>';
2800 $sforcepass .= '<label class="opacitylow small" for="forcepasswordchange">'.$langs->trans("ForcePasswordChange").'</label>';
2801 } else {
2802 $sforcepass .= '<input type="checkbox" name="forcepasswordchange" class="colorgrey" disabled value="1"'.($object->force_pass_change ? ' checked="checked"' : '').'>';
2803 $sforcepass .= '<span class="small">'.$langs->trans("ForcePasswordChange").'</small>';
2804 }
2805 } else {
2806 $sforcepass .= '<input type="checkbox" name="forcepasswordchange" value="1" class="colorgrey" disabled>';
2807 $sforcepass .= '<span class="opacitymedium small" title="'.$langs->trans("UserDoesNotHaveRightsToChangeHisPassword").'">'.$langs->trans("ForcePasswordChange").'</span>';
2808 }
2809
2810 // Pass
2811 print '<tr><td class="titlefieldcreate">'.$langs->trans("Password").'</td>';
2812 print '<td>';
2813 $valuetoshow = '';
2814 if (preg_match('/ldap/', $dolibarr_main_authentication)) {
2815 $valuetoshow .= ($valuetoshow ? (' '.$langs->trans("or").' ') : '').$langs->trans("PasswordOfUserInLDAP");
2816 }
2817 if (preg_match('/http/', $dolibarr_main_authentication)) {
2818 $valuetoshow .= ($valuetoshow ? (' '.$langs->trans("or").' ') : '').$form->textwithpicto((string) $text, $langs->trans("DolibarrInHttpAuthenticationSoPasswordUseless", (string) $dolibarr_main_authentication), 1, 'warning');
2819 }
2820 if (preg_match('/dolibarr/', $dolibarr_main_authentication) || preg_match('/forceuser/', $dolibarr_main_authentication)) {
2821 if ($permissiontoeditpasswordandsee) {
2822 $valuetoshow .= ($valuetoshow ? (' '.$langs->trans("or").' ') : '').'<input maxlength="128" type="password" class="minwidth300 maxwidth400 widthcentpercentminusx" id="password" name="password" value="'.dol_escape_htmltag($object->pass).'" autocomplete="new-password" spellcheck="false">';
2823 if (!empty($conf->use_javascript_ajax)) {
2824 $valuetoshow .= img_picto((getDolGlobalString('USER_PASSWORD_GENERATED') === 'none' ? $langs->transnoentities('NoPasswordGenerationRuleConfigured') : $langs->transnoentities('Generate')), 'refresh', 'id="generate_password" class="paddingleft'.(getDolGlobalString('USER_PASSWORD_GENERATED') === 'none' ? ' ' : ' linkobject').'"');
2825 }
2826 } else {
2827 $valuetoshow .= ($valuetoshow ? (' '.$langs->trans("or").' ') : '').preg_replace('/./i', '*', $object->pass);
2828 }
2829 }
2830 // Other form for user password
2831 $parameters = array('valuetoshow' => $valuetoshow, 'caneditpasswordandsee' => $permissiontoeditpasswordandsee, 'caneditpasswordandsend' => $permissiontoeditpasswordandsend);
2832 $reshook = $hookmanager->executeHooks('printUserPasswordField', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2833 if ($reshook > 0) {
2834 $valuetoshow = $hookmanager->resPrint; // to replace
2835 } else {
2836 $valuetoshow .= $hookmanager->resPrint; // to add
2837 }
2838
2839 print $valuetoshow;
2840 /*
2841 if ($_SESSION["dol_authmode"] == 'dolibarr') {
2842 print '<div class="inline-block marginleftonly paddingtop paddingbottom">'.$sforcepass.'</div>';
2843 }*/
2844 print "</td></tr>\n";
2845
2846 // Force update on next login only on dolibarr auth mode
2847 if ($_SESSION["dol_authmode"] == 'dolibarr') {
2848 print '<tr class="valigntop">';
2849 if ($conf->dol_optimize_smallscreen) {
2850 print '<td colspan="2">';
2851 } else {
2852 print '<td></td>';
2853 print '<td>';
2854 }
2855 print $sforcepass;
2856 print '</td></tr>';
2857 }
2858
2859 // API key
2860 if (!getDolGlobalString('API_IN_TOKEN_TABLE')) {
2861 if (isModEnabled('api')) {
2862 print '<tr><td>'.$langs->trans("ApiKey").'</td>';
2863 print '<td>';
2864 if ($permissiontoeditpasswordandsee) {
2865 print '<input class="minwidth300 maxwidth400 widthcentpercentminusx" minlength="12" maxlength="128" type="text" id="api_key" name="api_key" value="'.$object->api_key.'" autocomplete="off" spellcheck="false">';
2866 if (!empty($conf->use_javascript_ajax)) {
2867 print img_picto($langs->transnoentities('Generate'), 'refresh', 'id="generate_api_key" class="linkobject paddingleft"');
2868 }
2869 }
2870 print '</td></tr>';
2871 }
2872 }
2873
2874 // OpenID url
2875 if (isset($conf->file->main_authentication) && preg_match('/openid/', $conf->file->main_authentication) && getDolGlobalString('MAIN_OPENIDURL_PERUSER')) {
2876 print "<tr>".'<td>'.$langs->trans("OpenIDURL").'</td>';
2877 print '<td>';
2878 if ($permissiontoedit) {
2879 print '<input class="minwidth100" type="url" name="openid" class="flat" value="'.$object->openid.'">';
2880 } else {
2881 print '<input type="hidden" name="openid" value="'.$object->openid.'">';
2882 print $object->openid;
2883 }
2884 print '</td></tr>';
2885 }
2886
2887 print '</table>';
2888
2889
2890 print '<hr>';
2891
2892
2893 print '<table class="border centpercent">';
2894
2895 // Address
2896 print '<tr><td class="tdtop titlefieldcreate">'.$form->editfieldkey('Address', 'address', '', $object, 0).'</td>';
2897 print '<td>';
2898 if ($permissiontoedit) {
2899 print '<textarea name="address" id="address" class="quatrevingtpercent" rows="3" wrap="soft">';
2900 }
2901 print dol_escape_htmltag(GETPOSTISSET('address') ? GETPOST('address') : $object->address, 0, 1);
2902 if ($permissiontoedit) {
2903 print '</textarea>';
2904 }
2905 print '</td></tr>';
2906
2907 // Zip
2908 print '<tr><td>'.$form->editfieldkey('Zip', 'zipcode', '', $object, 0).'</td><td>';
2909 if ($permissiontoedit) {
2910 print $formcompany->select_ziptown((GETPOSTISSET('zipcode') ? GETPOST('zipcode') : $object->zip), 'zipcode', array('town', 'selectcountry_id', 'state_id'), 6);
2911 } else {
2912 print $object->zip;
2913 }
2914 print '</td></tr>';
2915
2916 // Town
2917 print '<tr><td>'.$form->editfieldkey('Town', 'town', '', $object, 0).'</td><td>';
2918 if ($permissiontoedit) {
2919 print $formcompany->select_ziptown((GETPOSTISSET('town') ? GETPOST('town') : $object->town), 'town', array('zipcode', 'selectcountry_id', 'state_id'));
2920 } else {
2921 print $object->town;
2922 }
2923 print '</td></tr>';
2924
2925 // Country
2926 print '<tr><td>'.$form->editfieldkey('Country', 'selectcountry_id', '', $object, 0).'</td><td>';
2927 print img_picto('', 'country', 'class="pictofixedwidth"');
2928 if ($permissiontoedit) {
2929 print $form->select_country((GETPOST('country_id') != '' ? GETPOST('country_id') : $object->country_id), 'country_id');
2930 if ($user->admin) {
2931 print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
2932 }
2933 } else {
2934 $countrylabel = getCountry($object->country_id, '0');
2935 print $countrylabel;
2936 }
2937 print '</td></tr>';
2938
2939 // State
2940 if (!getDolGlobalString('USER_DISABLE_STATE')) {
2941 print '<tr><td class="tdoverflow">'.$form->editfieldkey('State', 'state_id', '', $object, 0).'</td><td>';
2942 if ($permissiontoedit) {
2943 print img_picto('', 'state', 'class="pictofixedwidth"');
2944 print $formcompany->select_state_ajax('country_id', $object->state_id, $object->country_id, 'state_id');
2945 } else {
2946 print $object->state;
2947 }
2948 print '</td></tr>';
2949 }
2950
2951 // Tel pro
2952 print "<tr>".'<td>'.$langs->trans("PhonePro").'</td>';
2953 print '<td>';
2954 if ($permissiontoedit && empty($object->ldap_sid)) {
2955 print $form->showPhoneInput($object->office_phone, 'office_phone', $object->country_id, 'phoning', 'maxwidth200 widthcentpercentminusx');
2956 } else {
2957 print img_picto('', 'phoning', 'class="pictofixedwidth"');
2958 print '<input type="hidden" name="office_phone" value="'.$object->office_phone.'">';
2959 print $object->office_phone;
2960 }
2961 print '</td></tr>';
2962
2963 // Tel mobile
2964 print "<tr>".'<td>'.$langs->trans("PhoneMobile").'</td>';
2965 print '<td>';
2966 if ($permissiontoedit && empty($object->ldap_sid)) {
2967 print $form->showPhoneInput($object->user_mobile, 'user_mobile', $object->country_id, 'phoning_mobile', 'maxwidth200 widthcentpercentminusx');
2968 } else {
2969 print img_picto('', 'phoning_mobile', 'class="pictofixedwidth"');
2970 print '<input type="hidden" name="user_mobile" value="'.$object->user_mobile.'">';
2971 print $object->user_mobile;
2972 }
2973 print '</td></tr>';
2974
2975 // Fax
2976 print "<tr>".'<td>'.$langs->trans("Fax").'</td>';
2977 print '<td>';
2978 if ($permissiontoedit && empty($object->ldap_sid)) {
2979 print $form->showPhoneInput($object->office_fax, 'office_fax', $object->country_id, 'phoning_fax', 'maxwidth200 widthcentpercentminusx');
2980 } else {
2981 print img_picto('', 'phoning_fax', 'class="pictofixedwidth"');
2982 print '<input type="hidden" name="office_fax" value="'.$object->office_fax.'">';
2983 print $object->office_fax;
2984 }
2985 print '</td></tr>';
2986
2987 // EMail
2988 print "<tr>".'<td'.(getDolGlobalString('USER_MAIL_REQUIRED') ? ' class="fieldrequired"' : '').'>'.$langs->trans("EMail").'</td>';
2989 print '<td>';
2990 print img_picto('', 'object_email', 'class="pictofixedwidth"');
2991 if ($permissiontoedit && empty($object->ldap_sid)) {
2992 print '<input class="minwidth100 maxwidth500 widthcentpercentminusx" type="text" name="email" class="flat" value="'.$object->email.'">';
2993 } else {
2994 print '<input type="hidden" name="email" value="'.$object->email.'">';
2995 print $object->email;
2996 }
2997 print '</td></tr>';
2998
2999 if (isModEnabled('socialnetworks')) {
3000 foreach ($socialnetworks as $key => $value) {
3001 if ($value['active']) {
3002 print '<tr><td>'.$langs->trans($value['label']).'</td>';
3003 print '<td>';
3004 if (!empty($value['icon'])) {
3005 print '<span class="fab '.$value['icon'].' pictofixedwidth"></span>';
3006 }
3007 if ($permissiontoedit && empty($object->ldap_sid)) {
3008 print '<input type="text" name="'.$key.'" class="flat maxwidth200 widthcentpercentminusx" value="'.(isset($object->socialnetworks[$key]) ? $object->socialnetworks[$key] : '').'">';
3009 } else {
3010 print '<input type="hidden" name="'.$key.'" value="'.$object->socialnetworks[$key].'">';
3011 print $object->socialnetworks[$key];
3012 }
3013 print '</td></tr>';
3014 } else {
3015 // if social network is not active but value exist we do not want to loose it
3016 print '<input type="hidden" name="'.$key.'" value="'.(isset($object->socialnetworks[$key]) ? $object->socialnetworks[$key] : '').'">';
3017 }
3018 }
3019 }
3020
3021 print '</table>';
3022
3023
3024 print '<hr>';
3025
3026
3027 print '<table class="border centpercent">';
3028 // Default warehouse
3029 if (isModEnabled('stock') && getDolGlobalString('MAIN_DEFAULT_WAREHOUSE_USER')) {
3030 print '<tr><td class="titlefieldcreate">'.$langs->trans("DefaultWarehouse").'</td><td>';
3031 print $formproduct->selectWarehouses($object->warehouse_id, 'fk_warehouse', 'warehouseopen', 1);
3032 print ' <a href="'.DOL_URL_ROOT.'/product/stock/card.php?action=create&token='.newToken().'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$object->id.'&action=edit&token='.newToken()).'"><span class="fa fa-plus-circle valignmiddle paddingleft" title="'.$langs->trans("AddWarehouse").'"></span></a>';
3033 print '</td></tr>';
3034 }
3035
3036 // Accountancy code
3037 if (isModEnabled('accounting')) {
3038 print "<tr>";
3039 print '<td class="titlefieldcreate">'.$langs->trans("AccountancyCode").'</td>';
3040 print '<td>';
3041 if ($permissiontoedit) {
3042 print '<input type="text" class="flat maxwidth300" name="accountancy_code" value="'.$object->accountancy_code.'">';
3043 } else {
3044 print '<input type="hidden" name="accountancy_code" value="'.$object->accountancy_code.'">';
3045 print $object->accountancy_code;
3046 }
3047 print '</td>';
3048 print "</tr>";
3049 }
3050
3051 // User color
3052 if (isModEnabled('agenda')) {
3053 print '<tr><td class="titlefieldcreate">'.$langs->trans("ColorUser").'</td>';
3054 print '<td>';
3055 if ($permissiontoedit) {
3056 print $formother->selectColor(GETPOSTISSET('color') ? GETPOST('color', 'alphanohtml') : $object->color, 'color', null, 1, array(), 'hideifnotset');
3057 } else {
3058 print $formother->showColor($object->color, '');
3059 }
3060 print '</td></tr>';
3061 }
3062
3063 // Photo
3064 print '<tr>';
3065 print '<td class="titlefieldcreate">'.$langs->trans("Photo").'</td>';
3066 print '<td>';
3067 print $form->showphoto('userphoto', $object, 60, 0, (int) $permissiontoedit, 'photowithmargin', 'small', 1, 0, 'user', 1);
3068 print '</td>';
3069 print '</tr>';
3070
3071 // Categories
3072 if (isModEnabled('category') && $user->hasRight("categorie", "read")) {
3073 print '<tr><td>'.$form->editfieldkey('Categories', 'usercats', '', $object, 0).'</td>';
3074 print '<td>';
3075 if ($permissiontoedit) {
3076 print $form->selectCategories(Categorie::TYPE_USER, 'usercats', $object);
3077 } else {
3078 print $form->showCategories($object->id, Categorie::TYPE_USER, 1);
3079 }
3080 print "</td></tr>";
3081 }
3082
3083 // Default language
3084 if (getDolGlobalInt('MAIN_MULTILANGS')) {
3085 print '<tr><td>'.$form->editfieldkey('DefaultLang', 'default_lang', '', $object, 0, 'string', '', 0, 0, 'id', $langs->trans("WarningNotLangOfInterface", $langs->transnoentitiesnoconv("UserGUISetup"))).'</td><td colspan="3">'."\n";
3086 print img_picto('', 'language', 'class="pictofixedwidth"').$formadmin->select_language($object->lang, 'default_lang', 0, array(), '1', 0, 0, 'widthcentpercentminusx maxwidth300');
3087 print '</td>';
3088 print '</tr>';
3089 }
3090
3091 // Status
3092 print '<tr><td>'.$langs->trans("Status").'</td>';
3093 print '<td>';
3094 print $object->getLibStatut(4);
3095 print '</td></tr>';
3096
3097 // Company / Contact
3098 /* Disabled, this is already on field "External user ?"
3099 if (isModEnabled("societe")) {
3100 print '<tr><td>'.$langs->trans("LinkToCompanyContact").'</td>';
3101 print '<td>';
3102 if ($object->socid > 0) {
3103 $societe = new Societe($db);
3104 $societe->fetch($object->socid);
3105 print $societe->getNomUrl(1, '');
3106 if ($object->contact_id) {
3107 $contact = new Contact($db);
3108 $contact->fetch($object->contact_id);
3109 print ' / <a href="'.DOL_URL_ROOT.'/contact/card.php?id='.$object->contact_id.'">'.img_object($langs->trans("ShowContact"), 'contact').' '.dol_trunc($contact->getFullName($langs), 32).'</a>';
3110 }
3111 } else {
3112 print '<span class="opacitymedium hideonsmartphone">'.$langs->trans("ThisUserIsNot").'</span>';
3113 }
3114 print ' <span class="opacitymedium hideonsmartphone">('.$langs->trans("UseTypeFieldToChange").')</span>';
3115 print '</td>';
3116 print "</tr>\n";
3117 }
3118 */
3119
3120 // Module Adherent
3121 if (isModEnabled('member')) {
3122 $langs->load("members");
3123 print '<tr><td>'.$langs->trans("LinkedToDolibarrMember").'</td>';
3124 print '<td>';
3125 if ($object->fk_member) {
3126 $adh = new Adherent($db);
3127 $adh->fetch($object->fk_member);
3128 $adh->ref = $adh->login; // Force to show login instead of id
3129 print $adh->getNomUrl(1);
3130 } else {
3131 print '<span class="opacitymedium hideonsmartphone">'.$langs->trans("UserNotLinkedToMember").'</span>';
3132 }
3133 print '</td>';
3134 print "</tr>\n";
3135 }
3136
3137 // Multicompany
3138 // TODO check if user not linked with the current entity before change entity (thirdparty, invoice, etc.) !!
3139 if (isModEnabled('multicompany') && isset($mc) && is_object($mc)) {
3140 // This is now done with hook formObjectOptions. Keep this code for backward compatibility with old multicompany module
3141 if (!method_exists($mc, 'formObjectOptions')) {
3142 if (empty($conf->multicompany->transverse_mode) && $conf->entity == 1 && $user->admin && !$user->entity) {
3143 print "<tr>".'<td>'.$langs->trans("Entity").'</td>';
3144 print "<td>".$mc->select_entities($object->entity, 'entity', '', false, true, false, false, true); // last parameter 1 means, show also a choice 0=>'all entities'
3145 print "</td></tr>\n";
3146 } else {
3147 print '<input type="hidden" name="entity" value="'.$conf->entity.'" />';
3148 }
3149 }
3150 }
3151
3152 // Other attributes
3153 $parameters = array('colspan' => ' colspan="2"');
3154 //include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_edit.tpl.php'; // We do not use common tpl here because we need a special test on $permissiontoedit
3155 $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
3156 print $hookmanager->resPrint;
3157 if (empty($reshook)) {
3158 if ($permissiontoedit) {
3159 print $object->showOptionals($extrafields, 'edit');
3160 } else {
3161 print $object->showOptionals($extrafields, 'view');
3162 }
3163 }
3164
3165 // Signature
3166 print '<tr><td class="tdtop">'.$langs->trans("Signature").'</td>';
3167 print '<td>';
3168 if ($permissiontoedit) {
3169 require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
3170
3171 $doleditor = new DolEditor('signature', $object->signature, '', 138, 'dolibarr_notes', 'In', false, $acceptlocallinktomedia, !getDolGlobalString('FCKEDITOR_ENABLE_USERSIGN') ? 0 : 1, ROWS_4, '90%');
3172 print $doleditor->Create(1);
3173 } else {
3174 print dol_htmlentitiesbr($object->signature);
3175 if (!empty($object->signature)) {
3176 print dolGetSignatureQualityBadge($object->signature, $langs);
3177 }
3178 }
3179 print '</td></tr>';
3180
3181 print '</table>';
3182
3183
3184 print '<hr>';
3185
3186
3187 print '<table class="border centpercent">';
3188
3189
3190 // TODO Move this into tab RH (HierarchicalResponsible must be on both tab)
3191
3192 // Position/Job
3193 print '<tr><td class="titlefieldcreate">'.$langs->trans("PostOrFunction").'</td>';
3194 print '<td>';
3195 if ($permissiontoedit) {
3196 print '<input type="text" class="minwidth300 maxwidth500" name="job" value="'.dol_escape_htmltag($object->job).'">';
3197 } else {
3198 print '<input type="hidden" name="job" value="'.dol_escape_htmltag($object->job).'">';
3199 print dol_escape_htmltag($object->job);
3200 }
3201 print '</td></tr>';
3202
3203 // Weeklyhours
3204 print '<tr><td>'.$langs->trans("WeeklyHours").'</td>';
3205 print '<td>';
3206 if ($permissiontoedit) {
3207 print '<input size="8" type="text" name="weeklyhours" value="'.price2num(GETPOST('weeklyhours') ? GETPOST('weeklyhours') : $object->weeklyhours).'">';
3208 } else {
3209 print price2num($object->weeklyhours);
3210 }
3211 print '</td>';
3212 print "</tr>\n";
3213
3214 // Sensitive salary/value information
3215 if ($permissiontoseesalary) {
3216 $langs->load("salaries");
3217
3218 // Salary
3219 print '<tr><td>'.$langs->trans("Salary").'</td>';
3220 print '<td>';
3221 print img_picto('', 'salary', 'class="pictofixedwidth paddingright"').'<input size="8" type="text" name="salary" value="'.price2num(GETPOST('salary') ? GETPOST('salary') : $object->salary).'">';
3222 print ' <span class="opacitymedium">'.$langs->getCurrencySymbol().'</span>';
3223 print '</td>';
3224 print "</tr>\n";
3225
3226 // THM
3227 print '<tr><td>';
3228 $text = $langs->trans("THM");
3229 print $form->textwithpicto($text, $langs->trans("THMDescription"), 1, 'help', 'classthm');
3230 print '</td>';
3231 print '<td>';
3232 if ($permissiontoedit) {
3233 print '<input size="8" type="text" name="thm" value="'.price2num(GETPOST('thm') ? GETPOST('thm') : $object->thm).'">';
3234 print ' <span class="opacitymedium">'.$langs->getCurrencySymbol().'</span>';
3235 } else {
3236 print($object->thm != '' ? price($object->thm, 0, $langs, 1, -1, -1, $conf->currency) : '');
3237 }
3238 print '</td>';
3239 print "</tr>\n";
3240
3241 // TJM
3242 print '<tr><td>';
3243 $text = $langs->trans("TJM");
3244 print $form->textwithpicto($text, $langs->trans("TJMDescription"), 1, 'help', 'classthm');
3245 print '</td>';
3246 print '<td>';
3247 if ($permissiontoedit) {
3248 print '<input size="8" type="text" name="tjm" value="'.price2num(GETPOST('tjm') ? GETPOST('tjm') : $object->tjm).'">';
3249 print ' <span class="opacitymedium">'.$langs->getCurrencySymbol().'</span>';
3250 } else {
3251 print($object->tjm != '' ? price($object->tjm, 0, $langs, 1, -1, -1, $conf->currency) : '');
3252 }
3253 print '</td>';
3254 print "</tr>\n";
3255 }
3256
3257 // Date employment
3258 print '<tr><td>'.$langs->trans("DateEmployment").'</td>';
3259 print '<td>';
3260 if ($permissiontoedit) {
3261 print $form->selectDate($dateemployment ? $dateemployment : $object->dateemployment, 'dateemployment', 0, 0, 1, 'formdateemployment', 1, 1, 0, '', '', '', '', 1, '', $langs->trans("from"));
3262 } else {
3263 print dol_print_date($object->dateemployment, 'day');
3264 }
3265
3266 if ($dateemployment && $dateemploymentend) {
3267 print ' - ';
3268 }
3269
3270 if ($permissiontoedit) {
3271 print $form->selectDate($dateemploymentend ? $dateemploymentend : $object->dateemploymentend, 'dateemploymentend', 0, 0, 1, 'formdateemploymentend', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to"));
3272 } else {
3273 print dol_print_date($object->dateemploymentend, 'day');
3274 }
3275 print '</td>';
3276 print "</tr>\n";
3277
3278 // Date birth
3279 print '<tr><td>'.$langs->trans("DateOfBirth").'</td>';
3280 print '<td>';
3281 if ($permissiontoedit) {
3282 echo $form->selectDate($dateofbirth ? $dateofbirth : $object->birth, 'dateofbirth', 0, 0, 1, 'updateuser', 1, 0, 0, '', '', '', '', 1, '', '', 'tzserver');
3283 } else {
3284 print dol_print_date($object->birth, 'day', 'tzserver');
3285 }
3286 print '</td>';
3287 print "</tr>\n";
3288
3289 print '</table>';
3290
3291 print dol_get_fiche_end();
3292
3293 print '<div class="center">';
3294 print '<input value="'.$langs->trans("Save").'" class="button button-save" type="submit" name="save">';
3295 print '&nbsp; &nbsp; &nbsp;';
3296 print '<input value="'.$langs->trans("Cancel").'" class="button button-cancel" type="submit" name="cancel">';
3297 print '</div>';
3298
3299 print '</form>';
3300 }
3301
3302 if ($action != 'edit' && $action != 'presend') {
3303 print '<div class="fichecenter"><div class="fichehalfleft">';
3304
3305 // Generated documents
3306 $filename = dol_sanitizeFileName($object->ref);
3307 $filedir = $conf->user->dir_output."/".dol_sanitizeFileName($object->ref);
3308 $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id;
3309 $genallowed = $user->hasRight("user", "user", "read");
3310 $delallowed = $user->hasRight("user", "user", "write");
3311
3312
3313 if ($object->socid) {
3314 $societe = new Societe($db);
3315 $societe->fetch($object->socid);
3316 } else {
3317 $societe = null;
3318 }
3319
3320 print $formfile->showdocuments('user', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 0, 0, 0, 28, 0, '', '', '', !is_object($societe) || empty($societe->default_lang) ? '' : $societe->default_lang);
3321 $somethingshown = $formfile->numoffiles;
3322
3323 $MAXEVENT = 10;
3324
3325 $morehtmlcenter = '<div class="nowraponall">';
3326 $morehtmlcenter .= dolGetButtonTitle($langs->trans('FullConversation'), '', 'fa fa-comments imgforviewmode', DOL_URL_ROOT.'/user/messaging.php?id='.$object->id);
3327 $morehtmlcenter .= dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-bars imgforviewmode', DOL_URL_ROOT.'/user/agenda.php?id='.$object->id);
3328 $morehtmlcenter .= '</div>';
3329
3330 print '</div><div class="fichehalfright">';
3331
3332 // List of actions on element
3333 include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
3334 $formactions = new FormActions($db);
3335 $somethingshown = $formactions->showactions($object, 'user', $socid, 1, 'listactions', $MAXEVENT, '', $morehtmlcenter, $object->id);
3336
3337 print '</div></div>';
3338 }
3339
3340 if (isModEnabled('ldap') && !empty($object->ldap_sid)) {
3341 $ldap->unbind();
3342 }
3343 }
3344}
3345
3346// Add button to autosuggest a key
3347include_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
3348$usegenericrule = getDolGlobalString('USER_PASSWORD_GENERATED') == 'none' ? 1 : 0;
3349print dolJSToSetRandomPassword('password', 'generate_password', $usegenericrule);
3350if (isModEnabled('api')) {
3351 print dolJSToSetRandomPassword('api_key', 'generate_api_key', 1);
3352}
3353
3354// End of page
3355llxFooter();
3356$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
$propal type
'integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]',...
Definition propal.php:280
ajax_combobox($htmlname, $events=array(), $minLengthToAutocomplete=0, $forcefocus=0, $widthTypeOfAutocomplete='resolve', $idforemptyvalue='-1', $morecss='', $placeholder='')
Convert a html select field into an ajax combobox.
Definition ajax.lib.php:477
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 members of a foundation.
Class to manage contact/addresses.
Class to manage a WYSIWYG editor.
Class to manage warehouses.
Class to manage building of HTML components.
Class to generate html code for admin pages.
Class to build HTML component for third parties management Only common components are here.
Class to offer components to list and upload files.
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 with static methods for building HTML components related to products Only components common to ...
Class to manage LDAP features.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage user groups.
Class to manage Dolibarr users.
getCountry($searchkey, $withcode='', $dbtouse=null, $outputlangs=null, $entconv=1, $searchlabel='')
Return country label, code or id from an id, code or label.
dolGetSignatureQualityBadge($html, $outputlangs=null)
Build a ready to print HTML badge summarising the quality of an email signature, with a collapsible l...
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $object=null, $allowdotdot=false, $indexdatabase=1, $nolog=0)
Remove a file or several files with a mask.
addFileIntoDatabaseIndex($dir, $file, $fullpathorig='', $mode='uploaded', $setsharekey=0, $object=null, $forceFullTextIndexation='')
Add a file into database index.
dol_delete_dir_recursive($dir, $count=0, $nophperrors=0, $onlysub=0, &$countdeleted=0, $indexdatabase=1, $nolog=0, $level=0)
Remove a directory $dir and its subdirectories (or only files and subdirectories)
dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disablevirusscan=0, $uploaderrorcode=0, $nohook=0, $keyforsourcefile='addedfile', $upload_dir='', $mode=0)
Check validity of a file upload from an GUI page, and move it to its final destination.
deleteFilesIntoDatabaseIndex($dir, $file, $mode='uploaded', $object=null)
Delete files into database index using search criteria.
acceptLocalLinktoMedia()
Check the syntax of some PHP code.
recordNotFound($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Displays an error page when a record is not found.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
dol_print_email($email, $contactid=0, $socid=0, $addlink=0, $max=0, $showinvalid=2, $withpicto=0, $morecss='paddingrightonly')
Show EMail link formatted for HTML output.
getDolUserInt($key, $default=0, $tmpuser=null)
Return Dolibarr user constant int value.
dol_string_nohtmltag($stringtoclean, $removelinefeed=1, $pagecodeto='UTF-8', $strip_tags=0, $removedoublespaces=1)
Clean a string from all HTML tags and entities.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
currentToken()
Return the value of token currently saved into session with name 'token'.
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.
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_escape_js($stringtoescape, $mode=0, $noescapebackslashn=0)
Returns text escaped for inclusion into JavaScript code.
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.
GETPOSTFLOAT($paramname, $rounding='', $option=2)
Return the value of a $_GET or $_POST supervariable, converted into float.
getArrayOfSocialNetworks()
Get array of social network dictionary.
GETPOSTINT($paramname, $method=0, $nodefault=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_clone($srcobject, $native=2)
Create a clone of instance of object (new instance with same value for each properties) With native =...
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
dol_htmlentitiesbr($stringtoencode, $nl2brmode=0, $pagecodefrom='UTF-8', $removelasteolbr=1)
This function is called to encode a string into a HTML string but differs from htmlentities because a...
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
get_exdir($num, $level, $alpha, $withoutslash, $object, $modulepart='')
Return a path to have a the directory according to object where files are stored.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
getEntity($element, $shared=1, $currentobject=null)
Get list of entity id to use.
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
treeview li table
No Email.
div refaddress div address
a disabled
picto_from_langcode($codelang, $moreatt='', $notitlealt=0)
Return img flag of country for a language code or country code.
showValueWithClipboardCPButton($valuetocopy, $showonlyonhover=1, $texttoshow='')
Create a button to copy $valuetocopy in the clipboard (for copy and paste feature).
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:540
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:435
dolGetButtonTitle($label, $helpText='', $iconClass='fa fa-file', $url='', $id='', $status=1, $params=array())
Function dolGetButtonTitle : this kind of buttons are used in title in list.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
Definition html.lib.php:738
dol_set_focus($selector)
Set focus onto field with selector (similar behaviour of 'autofocus' HTML5 tag)
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='', $morecssonpicto='widthpictotitle')
Load a title with picto.
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)
Definition html.lib.php:181
image_format_supported($file, $acceptsvg=0)
Return if a filename is file name of a supported image format.
$conf db user
Active Directory does not allow anonymous connections.
Definition repair.php:141
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition repair.php:140
dolJSToSetRandomPassword($htmlname, $htmlnameofbutton='generate_token', $generic=1)
Output javascript to autoset a generated password using default module into a HTML element.
getRandomPassword($generic=false, $replaceambiguouschars=null, $length=32)
Return a generated password using default module.
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $nodie=0, $mode='')
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.
dol_verifyHash($chain, $hash, $type='0')
Compute a hash and compare it to the given one For backward compatibility reasons,...
user_prepare_head(User $object)
Prepare array with list of tabs.