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