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