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