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