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