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