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