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