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