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