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