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