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