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