dolibarr  16.0.1
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-2020 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-2016 Alexandre Spangaro <aspangaro@open-dsi.fr>
12  * Copyright (C) 2015-2017 Jean-François Ferry <jfefe@aternatik.fr>
13  * Copyright (C) 2015 Ari Elbaz (elarifr) <github@accedinfo.com>
14  * Copyright (C) 2015-2018 Charlene Benke <charlie@patas-monkey.com>
15  * Copyright (C) 2016 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
16  * Copyright (C) 2018-2021 Frédéric France <frederic.france@netlogic.fr>
17  * Copyright (C) 2018 David Beniamine <David.Beniamine@Tetras-Libre.fr>
18  *
19  * This program is free software; you can redistribute it and/or modify
20  * it under the terms of the GNU General Public License as published by
21  * the Free Software Foundation; either version 3 of the License, or
22  * (at your option) any later version.
23  *
24  * This program is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27  * GNU General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License
30  * along with this program. If not, see <https://www.gnu.org/licenses/>.
31  */
32 
38 require '../main.inc.php';
39 require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
40 require_once DOL_DOCUMENT_ROOT.'/user/class/usergroup.class.php';
41 require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
42 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
43 require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
44 require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
45 require_once DOL_DOCUMENT_ROOT.'/core/lib/usergroups.lib.php';
46 require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
47 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
48 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
49 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
50 require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
51 if (!empty($conf->ldap->enabled)) {
52  require_once DOL_DOCUMENT_ROOT.'/core/class/ldap.class.php';
53 }
54 if (!empty($conf->adherent->enabled)) {
55  require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
56 }
57 if (!empty($conf->categorie->enabled)) {
58  require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
59 }
60 if (!empty($conf->stock->enabled)) {
61  require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
62 }
63 
64 $id = GETPOST('id', 'int');
65 $action = GETPOST('action', 'aZ09');
66 $mode = GETPOST('mode', 'alpha');
67 $confirm = GETPOST('confirm', 'alpha');
68 $group = GETPOST("group", "int", 3);
69 $cancel = GETPOST('cancel', 'alpha');
70 $contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'useracard'; // To manage different context of search
71 
72 $dateemployment = dol_mktime(0, 0, 0, GETPOST('dateemploymentmonth', 'int'), GETPOST('dateemploymentday', 'int'), GETPOST('dateemploymentyear', 'int'));
73 $dateemploymentend = dol_mktime(0, 0, 0, GETPOST('dateemploymentendmonth', 'int'), GETPOST('dateemploymentendday', 'int'), GETPOST('dateemploymentendyear', 'int'));
74 $datestartvalidity = dol_mktime(0, 0, 0, GETPOST('datestartvaliditymonth', 'int'), GETPOST('datestartvalidityday', 'int'), GETPOST('datestartvalidityyear', 'int'));
75 $dateendvalidity = dol_mktime(0, 0, 0, GETPOST('dateendvaliditymonth', 'int'), GETPOST('dateendvalidityday', 'int'), GETPOST('dateendvalidityyear', 'int'));
76 $dateofbirth = dol_mktime(0, 0, 0, GETPOST('dateofbirthmonth', 'int'), GETPOST('dateofbirthday', 'int'), GETPOST('dateofbirthyear', 'int'));
77 
78 // Define value to know what current user can do on users
79 $canadduser = (!empty($user->admin) || $user->rights->user->user->creer);
80 $canreaduser = (!empty($user->admin) || $user->rights->user->user->lire);
81 $canedituser = (!empty($user->admin) || $user->rights->user->user->creer);
82 $candisableuser = (!empty($user->admin) || $user->rights->user->user->supprimer);
83 $canreadgroup = $canreaduser;
84 $caneditgroup = $canedituser;
85 if (!empty($conf->global->MAIN_USE_ADVANCED_PERMS)) {
86  $canreadgroup = (!empty($user->admin) || $user->rights->user->group_advance->read);
87  $caneditgroup = (!empty($user->admin) || $user->rights->user->group_advance->write);
88 }
89 
90 $childids = $user->getAllChildIds(1); // For later, test on salary visibility
91 
92 // Define value to know what current user can do on properties of edited user
93 if ($id > 0) {
94  // $user is the current logged user, $id is the user we want to edit
95  $caneditfield = ((($user->id == $id) && $user->rights->user->self->creer) || (($user->id != $id) && $user->rights->user->user->creer));
96  $caneditpassword = ((($user->id == $id) && $user->rights->user->self->password) || (($user->id != $id) && $user->rights->user->user->password));
97 }
98 
99 // Security check
100 $socid = 0;
101 if ($user->socid > 0) {
102  $socid = $user->socid;
103 }
104 $feature2 = 'user';
105 $result = restrictedArea($user, 'user', $id, 'user', $feature2);
106 
107 if ($user->id != $id && !$canreaduser) {
108  accessforbidden();
109 }
110 
111 // Load translation files required by page
112 $langs->loadLangs(array('users', 'companies', 'ldap', 'admin', 'hrm', 'stocks', 'other'));
113 
114 $object = new User($db);
115 $extrafields = new ExtraFields($db);
116 
117 // fetch optionals attributes and labels
118 $extrafields->fetch_name_optionals_label($object->table_element);
119 
120 $socialnetworks = getArrayOfSocialNetworks();
121 
122 // Initialize technical object to manage hooks. Note that conf->hooks_modules contains array
123 $hookmanager->initHooks(array('usercard', 'globalcard'));
124 
125 $error = 0;
126 
127 
132 $parameters = array('id' => $id, 'socid' => $socid, 'group' => $group, 'caneditgroup' => $caneditgroup);
133 $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
134 if ($reshook < 0) {
135  setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
136 }
137 
138 if (empty($reshook)) {
139  $backurlforlist = DOL_URL_ROOT.'/user/list.php';
140 
141  if (empty($backtopage) || ($cancel && empty($id))) {
142  if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) {
143  if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) {
144  $backtopage = $backurlforlist;
145  } else {
146  $backtopage = DOL_URL_ROOT.'/user/card.php?id='.((!empty($id) && $id > 0) ? $id : '__ID__');
147  }
148  }
149  }
150 
151  if ($cancel) {
152  if (!empty($backtopageforcancel)) {
153  header("Location: ".$backtopageforcancel);
154  exit;
155  } elseif (!empty($backtopage)) {
156  header("Location: ".$backtopage);
157  exit;
158  }
159  $action = '';
160  }
161 
162  if ($action == 'confirm_disable' && $confirm == "yes" && $candisableuser) {
163  if ($id != $user->id) { // A user can't disable itself
164  $object->fetch($id);
165  if ($object->admin && empty($user->admin)) {
166  // If user to delete is an admin user and if logged user is not admin, we deny the operation.
167  $error++;
168  setEventMessages($langs->trans("OnlyAdminUsersCanDisableAdminUsers"), null, 'errors');
169  } else {
170  $object->setstatus(0);
171  header("Location: ".$_SERVER['PHP_SELF'].'?id='.$id);
172  exit;
173  }
174  }
175  }
176 
177  if ($action == 'confirm_enable' && $confirm == "yes" && $candisableuser) {
178  $error = 0;
179 
180  if ($id != $user->id) {
181  $object->fetch($id);
182 
183  if (!empty($conf->file->main_limit_users)) {
184  $nb = $object->getNbOfUsers("active");
185  if ($nb >= $conf->file->main_limit_users) {
186  $error++;
187  setEventMessages($langs->trans("YourQuotaOfUsersIsReached"), null, 'errors');
188  }
189  }
190 
191  if (!$error) {
192  $object->setstatus(1);
193  header("Location: ".$_SERVER['PHP_SELF'].'?id='.$id);
194  exit;
195  }
196  }
197  }
198 
199  if ($action == 'confirm_delete' && $confirm == "yes" && $candisableuser) {
200  if ($id != $user->id) {
201  if (!GETPOSTISSET('token')) {
202  print 'Error, token required for this critical operation';
203  exit;
204  }
205 
206  $object = new User($db);
207  $object->fetch($id);
208  $object->oldcopy = clone $object;
209 
210  $result = $object->delete($user);
211  if ($result < 0) {
212  $langs->load("errors");
213  setEventMessages($langs->trans("ErrorUserCannotBeDelete"), null, 'errors');
214  } else {
215  setEventMessages($langs->trans("RecordDeleted"), null);
216  header("Location: ".DOL_URL_ROOT."/user/list.php?restore_lastsearch_values=1");
217  exit;
218  }
219  }
220  }
221 
222  // Action Add user
223  if ($action == 'add' && $canadduser) {
224  $error = 0;
225 
226  if (!GETPOST("lastname")) {
227  $error++;
228  setEventMessages($langs->trans("NameNotDefined"), null, 'errors');
229  $action = "create"; // Go back to create page
230  }
231  if (!GETPOST("login")) {
232  $error++;
233  setEventMessages($langs->trans("LoginNotDefined"), null, 'errors');
234  $action = "create"; // Go back to create page
235  }
236 
237  if (!empty($conf->file->main_limit_users)) { // If option to limit users is set
238  $nb = $object->getNbOfUsers("active");
239  if ($nb >= $conf->file->main_limit_users) {
240  $error++;
241  setEventMessages($langs->trans("YourQuotaOfUsersIsReached"), null, 'errors');
242  $action = "create"; // Go back to create page
243  }
244  }
245 
246  if (!$error) {
247  $object->civility_code = GETPOST("civility_code", 'aZ09');
248  $object->lastname = GETPOST("lastname", 'alphanohtml');
249  $object->firstname = GETPOST("firstname", 'alphanohtml');
250  $object->ref_employee = GETPOST("ref_employee", 'alphanohtml');
251  $object->national_registration_number = GETPOST("national_registration_number", 'alphanohtml');
252  $object->login = GETPOST("login", 'alphanohtml');
253  $object->api_key = GETPOST("api_key", 'alphanohtml');
254  $object->gender = GETPOST("gender", 'aZ09');
255  $object->admin = GETPOST("admin", 'int');
256  $object->address = GETPOST('address', 'alphanohtml');
257  $object->zip = GETPOST('zipcode', 'alphanohtml');
258  $object->town = GETPOST('town', 'alphanohtml');
259  $object->country_id = GETPOST('country_id', 'int');
260  $object->state_id = GETPOST('state_id', 'int');
261  $object->office_phone = GETPOST("office_phone", 'alphanohtml');
262  $object->office_fax = GETPOST("office_fax", 'alphanohtml');
263  $object->user_mobile = GETPOST("user_mobile", 'alphanohtml');
264 
265  if (!empty($conf->socialnetworks->enabled)) {
266  $object->socialnetworks = array();
267  foreach ($socialnetworks as $key => $value) {
268  if (GETPOST($key, 'alphanohtml')) {
269  $object->socialnetworks[$key] = GETPOST($key, 'alphanohtml');
270  }
271  }
272  }
273 
274  $object->email = preg_replace('/\s+/', '', GETPOST("email", 'alphanohtml'));
275  $object->job = GETPOST("job", 'alphanohtml');
276  $object->signature = GETPOST("signature", 'restricthtml');
277  $object->accountancy_code = GETPOST("accountancy_code", 'alphanohtml');
278  $object->note = GETPOST("note", 'restricthtml');
279  $object->note_private = GETPOST("note", 'restricthtml');
280  $object->ldap_sid = GETPOST("ldap_sid", 'alphanohtml');
281  $object->fk_user = GETPOST("fk_user", 'int') > 0 ? GETPOST("fk_user", 'int') : 0;
282  $object->fk_user_expense_validator = GETPOST("fk_user_expense_validator", 'int') > 0 ? GETPOST("fk_user_expense_validator", 'int') : 0;
283  $object->fk_user_holiday_validator = GETPOST("fk_user_holiday_validator", 'int') > 0 ? GETPOST("fk_user_holiday_validator", 'int') : 0;
284  $object->employee = GETPOST('employee', 'alphanohtml');
285 
286  $object->thm = GETPOST("thm", 'alphanohtml') != '' ? GETPOST("thm", 'alphanohtml') : '';
287  $object->thm = price2num($object->thm);
288  $object->tjm = GETPOST("tjm", 'alphanohtml') != '' ? GETPOST("tjm", 'alphanohtml') : '';
289  $object->tjm = price2num($object->tjm);
290  $object->salary = GETPOST("salary", 'alphanohtml') != '' ? GETPOST("salary", 'alphanohtml') : '';
291  $object->salary = price2num($object->salary);
292  $object->salaryextra = GETPOST("salaryextra", 'alphanohtml') != '' ? GETPOST("salaryextra", 'alphanohtml') : '';
293  $object->weeklyhours = GETPOST("weeklyhours", 'alphanohtml') != '' ? GETPOST("weeklyhours", 'alphanohtml') : '';
294 
295  $object->color = GETPOST("color", 'alphanohtml') != '' ? GETPOST("color", 'alphanohtml') : '';
296 
297  $object->dateemployment = $dateemployment;
298  $object->dateemploymentend = $dateemploymentend;
299  $object->datestartvalidity = $datestartvalidity;
300  $object->dateendvalidity = $dateendvalidity;
301  $object->birth = $dateofbirth;
302 
303  $object->fk_warehouse = GETPOST('fk_warehouse', 'int');
304 
305  $object->lang = GETPOST('default_lang', 'aZ09');
306 
307  // Fill array 'array_options' with data from add form
308  $ret = $extrafields->setOptionalsFromPost(null, $object);
309  if ($ret < 0) {
310  $error++;
311  }
312 
313  // Set entity property
314  $entity = GETPOST('entity', 'int');
315  if (!empty($conf->multicompany->enabled)) {
316  if (GETPOST('superadmin', 'int')) {
317  $object->entity = 0;
318  } else {
319  if (!empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
320  $object->entity = 1; // all users are forced into master entity
321  } else {
322  $object->entity = ($entity == '' ? 1 : $entity);
323  }
324  }
325  } else {
326  $object->entity = ($entity == '' ? 1 : $entity);
327  /*if ($user->admin && $user->entity == 0 && GETPOST("admin",'alpha'))
328  {
329  }*/
330  }
331 
332  $db->begin();
333 
334  $id = $object->create($user);
335  if ($id > 0) {
336  $resPass = 0;
337  if (GETPOST('password', 'none')) {
338  $resPass = $object->setPassword($user, GETPOST('password', 'none'));
339  }
340  if ($resPass < 0) {
341  $langs->load("errors");
342  $db->rollback();
343  setEventMessages($object->error, $object->errors, 'errors');
344  $action = "create"; // Go back to create page
345  } else {
346  if (! empty($conf->categorie->enabled)) {
347  // Categories association
348  $usercats = GETPOST('usercats', 'array');
349  $object->setCategories($usercats);
350  }
351  $db->commit();
352 
353  header("Location: ".$_SERVER['PHP_SELF'].'?id='.$id);
354  exit;
355  }
356  } else {
357  $langs->load("errors");
358  $db->rollback();
359  setEventMessages($object->error, $object->errors, 'errors');
360  $action = "create"; // Go back to create page
361  }
362  }
363  }
364 
365  // Action add usergroup
366  if (($action == 'addgroup' || $action == 'removegroup') && $caneditgroup) {
367  if ($group) {
368  $editgroup = new UserGroup($db);
369  $editgroup->fetch($group);
370  $editgroup->oldcopy = clone $editgroup;
371 
372  $object->fetch($id);
373  if ($action == 'addgroup') {
374  $result = $object->SetInGroup($group, $editgroup->entity);
375  }
376  if ($action == 'removegroup') {
377  $result = $object->RemoveFromGroup($group, $editgroup->entity);
378  }
379 
380  if ($result > 0) {
381  $action = '';
382  } else {
383  setEventMessages($object->error, $object->errors, 'errors');
384  }
385  }
386  }
387 
388  if ($action == 'update' && !$cancel) {
389  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
390 
391  if ($caneditfield) { // Case we can edit all field
392  $error = 0;
393 
394  if (!GETPOST("lastname", 'alpha')) {
395  setEventMessages($langs->trans("NameNotDefined"), null, 'errors');
396  $action = "edit"; // Go back to create page
397  $error++;
398  }
399  if (!GETPOST("login", 'alpha')) {
400  setEventMessages($langs->trans("LoginNotDefined"), null, 'errors');
401  $action = "edit"; // Go back to create page
402  $error++;
403  }
404 
405  if (!$error) {
406  $object->fetch($id);
407 
408  $object->oldcopy = clone $object;
409 
410  $db->begin();
411 
412  $object->civility_code = GETPOST("civility_code", 'aZ09');
413  $object->lastname = GETPOST("lastname", 'alphanohtml');
414  $object->firstname = GETPOST("firstname", 'alphanohtml');
415  $object->ref_employee = GETPOST("ref_employee", 'alphanohtml');
416  $object->national_registration_number = GETPOST("national_registration_number", 'alphanohtml');
417  $object->gender = GETPOST("gender", 'aZ09');
418  $object->pass = GETPOST("password", 'none'); // We can keep 'none' for password fields
419  $object->api_key = (GETPOST("api_key", 'alphanohtml')) ? GETPOST("api_key", 'alphanohtml') : $object->api_key;
420  if (!empty($user->admin)) { // admin flag can only be set/unset by an admin user. A test is also done later when forging sql request
421  $object->admin = GETPOST("admin", "int");
422  }
423  if ($user->admin && !$object->ldap_sid) { // same test than on edit page
424  $object->login = GETPOST("login", 'alphanohtml');
425  }
426  $object->address = GETPOST('address', 'alphanohtml');
427  $object->zip = GETPOST('zipcode', 'alphanohtml');
428  $object->town = GETPOST('town', 'alphanohtml');
429  $object->country_id = GETPOST('country_id', 'int');
430  $object->state_id = GETPOST('state_id', 'int');
431  $object->office_phone = GETPOST("office_phone", 'alphanohtml');
432  $object->office_fax = GETPOST("office_fax", 'alphanohtml');
433  $object->user_mobile = GETPOST("user_mobile", 'alphanohtml');
434 
435  if (!empty($conf->socialnetworks->enabled)) {
436  $object->socialnetworks = array();
437  foreach ($socialnetworks as $key => $value) {
438  if (GETPOST($key, 'alphanohtml')) {
439  $object->socialnetworks[$key] = GETPOST($key, 'alphanohtml');
440  }
441  }
442  }
443 
444  $object->email = preg_replace('/\s+/', '', GETPOST("email", 'alphanohtml'));
445  $object->job = GETPOST("job", 'alphanohtml');
446  $object->signature = GETPOST("signature", 'restricthtml');
447  $object->accountancy_code = GETPOST("accountancy_code", 'alphanohtml');
448  $object->openid = GETPOST("openid", 'alphanohtml');
449  $object->fk_user = GETPOST("fk_user", 'int') > 0 ? GETPOST("fk_user", 'int') : 0;
450  $object->fk_user_expense_validator = GETPOST("fk_user_expense_validator", 'int') > 0 ? GETPOST("fk_user_expense_validator", 'int') : 0;
451  $object->fk_user_holiday_validator = GETPOST("fk_user_holiday_validator", 'int') > 0 ? GETPOST("fk_user_holiday_validator", 'int') : 0;
452  $object->employee = GETPOST('employee', 'int');
453 
454  $object->thm = GETPOST("thm", 'alphanohtml') != '' ? GETPOST("thm", 'alphanohtml') : '';
455  $object->thm = price2num($object->thm);
456  $object->tjm = GETPOST("tjm", 'alphanohtml') != '' ? GETPOST("tjm", 'alphanohtml') : '';
457  $object->thm = price2num($object->thm);
458  $object->salary = GETPOST("salary", 'alphanohtml') != '' ? GETPOST("salary", 'alphanohtml') : '';
459  $object->salary = price2num($object->salary);
460  $object->salaryextra = GETPOST("salaryextra", 'alphanohtml') != '' ? GETPOST("salaryextra", 'alphanohtml') : '';
461  $object->salaryextra = price2num($object->salaryextra);
462  $object->weeklyhours = GETPOST("weeklyhours", 'alphanohtml') != '' ? GETPOST("weeklyhours", 'alphanohtml') : '';
463  $object->weeklyhours = price2num($object->weeklyhours);
464 
465  $object->color = GETPOST("color", 'alphanohtml') != '' ? GETPOST("color", 'alphanohtml') : '';
466  $object->dateemployment = $dateemployment;
467  $object->dateemploymentend = $dateemploymentend;
468  $object->datestartvalidity = $datestartvalidity;
469  $object->dateendvalidity = $dateendvalidity;
470  $object->birth = $dateofbirth;
471 
472  if (!empty($conf->stock->enabled)) {
473  $object->fk_warehouse = GETPOST('fk_warehouse', 'int');
474  }
475 
476  $object->lang = GETPOST('default_lang', 'aZ09');
477 
478  // Do we update also ->entity ?
479  if (!empty($conf->multicompany->enabled) && empty($user->entity) && !empty($user->admin)) { // If multicompany is not enabled, we never update the entity of a user.
480  if (GETPOST('superadmin', 'int')) {
481  $object->entity = 0;
482  } else {
483  if (!empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
484  $object->entity = 1; // all users are in master entity
485  } else {
486  // We try to change the entity of user
487  $object->entity = (GETPOSTISSET('entity') ? GETPOSTINT('entity') : $object->entity);
488  }
489  }
490  }
491 
492  // Fill array 'array_options' with data from add form
493  $ret = $extrafields->setOptionalsFromPost(null, $object, '@GETPOSTISSET');
494  if ($ret < 0) {
495  $error++;
496  }
497 
498  if (GETPOST('deletephoto')) {
499  $object->photo = '';
500  }
501  if (!empty($_FILES['photo']['name'])) {
502  $isimage = image_format_supported($_FILES['photo']['name']);
503  if ($isimage > 0) {
504  $object->photo = dol_sanitizeFileName($_FILES['photo']['name']);
505  } else {
506  $error++;
507  $langs->load("errors");
508  setEventMessages($langs->trans("ErrorBadImageFormat"), null, 'errors');
509  dol_syslog($langs->transnoentities("ErrorBadImageFormat"), LOG_INFO);
510  }
511  }
512 
513  if (!$error) {
514  $ret = $object->update($user);
515  if ($ret < 0) {
516  $error++;
517  if ($db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
518  $langs->load("errors");
519  setEventMessages($langs->trans("ErrorLoginAlreadyExists", $object->login), null, 'errors');
520  } else {
521  setEventMessages($object->error, $object->errors, 'errors');
522  $action = 'edit';
523  }
524  }
525  }
526 
527  if (!$error && GETPOSTISSET('contactid')) {
528  $contactid = GETPOST('contactid', 'int');
529  $socid = GETPOST('socid', 'int');
530 
531  if ($contactid > 0) { // The 'contactid' is used inpriority over the 'socid'
532  $contact = new Contact($db);
533  $contact->fetch($contactid);
534 
535  $sql = "UPDATE ".MAIN_DB_PREFIX."user";
536  $sql .= " SET fk_socpeople=".((int) $contactid);
537  if (!empty($contact->socid)) {
538  $sql .= ", fk_soc=".((int) $contact->socid);
539  }
540  $sql .= " WHERE rowid = ".((int) $object->id);
541  } elseif ($socid > 0) {
542  $sql = "UPDATE ".MAIN_DB_PREFIX."user";
543  $sql .= " SET fk_socpeople=NULL, fk_soc=".((int) $socid);
544  $sql .= " WHERE rowid = ".((int) $object->id);
545  } else {
546  $sql = "UPDATE ".MAIN_DB_PREFIX."user";
547  $sql .= " SET fk_socpeople=NULL, fk_soc=NULL";
548  $sql .= " WHERE rowid = ".((int) $object->id);
549  }
550  dol_syslog("usercard::update", LOG_DEBUG);
551  $resql = $db->query($sql);
552  if (!$resql) {
553  $error++;
554  setEventMessages($db->lasterror(), null, 'errors');
555  }
556  }
557 
558  if (!$error && !count($object->errors)) {
559  if (GETPOST('deletephoto') && $object->oldcopy->photo) {
560  $fileimg = $conf->user->dir_output.'/'.get_exdir(0, 0, 0, 0, $object, 'user').'photos/'.$object->oldcopy->photo;
561  $dirthumbs = $conf->user->dir_output.'/'.get_exdir(0, 0, 0, 0, $object, 'user').'photos/thumbs';
562  dol_delete_file($fileimg);
563  dol_delete_dir_recursive($dirthumbs);
564  }
565 
566  if (isset($_FILES['photo']['tmp_name']) && trim($_FILES['photo']['tmp_name'])) {
567  $dir = $conf->user->dir_output.'/'.get_exdir(0, 0, 0, 1, $object, 'user').'/photos';
568 
569  dol_mkdir($dir);
570 
571  if (@is_dir($dir)) {
572  $newfile = $dir.'/'.dol_sanitizeFileName($_FILES['photo']['name']);
573  $result = dol_move_uploaded_file($_FILES['photo']['tmp_name'], $newfile, 1, 0, $_FILES['photo']['error']);
574 
575  if (!($result > 0)) {
576  setEventMessages($langs->trans("ErrorFailedToSaveFile"), null, 'errors');
577  } else {
578  // Create thumbs
579  $object->addThumbs($newfile);
580  }
581  } else {
582  $error++;
583  $langs->load("errors");
584  setEventMessages($langs->trans("ErrorFailedToCreateDir", $dir), $mesgs, 'errors');
585  }
586  }
587  }
588 
589  if (!$error && !count($object->errors)) {
590  // Then we add the associated categories
591  $categories = GETPOST('usercats', 'array');
592  $object->setCategories($categories);
593  }
594 
595  if (!$error && !count($object->errors)) {
596  setEventMessages($langs->trans("UserModified"), null, 'mesgs');
597  $db->commit();
598 
599  $login = $_SESSION["dol_login"];
600  if ($login && $login == $object->oldcopy->login && $object->oldcopy->login != $object->login) { // Current user has changed its login
601  $error++;
602  $langs->load("errors");
603  setEventMessages($langs->transnoentitiesnoconv("WarningYourLoginWasModifiedPleaseLogin"), null, 'warnings');
604  }
605  } else {
606  $db->rollback();
607  }
608  }
609  } else {
610  if ($caneditpassword) { // Case we can edit only password
611  dol_syslog("Not allowed to change fields, only password");
612 
613  $object->fetch($id);
614 
615  if (GETPOST("password", "none")) { // If pass is empty, we do not change it.
616  $object->oldcopy = clone $object;
617 
618  $ret = $object->setPassword($user, GETPOST("password", "none"));
619  if ($ret < 0) {
620  setEventMessages($object->error, $object->errors, 'errors');
621  }
622  }
623  }
624  }
625  }
626 
627  // Change password with a new generated one
628  if ((($action == 'confirm_password' && $confirm == 'yes')
629  || ($action == 'confirm_passwordsend' && $confirm == 'yes')) && $caneditpassword
630  ) {
631  $object->fetch($id);
632 
633  $newpassword = $object->setPassword($user, ''); // This will generate a new password
634  if ($newpassword < 0) {
635  // Echec
636  setEventMessages($langs->trans("ErrorFailedToSetNewPassword"), null, 'errors');
637  } else {
638  // Succes
639  if ($action == 'confirm_passwordsend' && $confirm == 'yes') {
640  if ($object->send_password($user, $newpassword) > 0) {
641  setEventMessages($langs->trans("PasswordChangedAndSentTo", $object->email), null, 'mesgs');
642  } else {
643  setEventMessages($object->error, $object->errors, 'errors');
644  }
645  } else {
646  setEventMessages($langs->trans("PasswordChangedTo", $newpassword), null, 'warnings');
647  }
648  }
649  }
650 
651  // Action initialisation donnees depuis record LDAP
652  if ($action == 'adduserldap' && $canadduser) {
653  $selecteduser = GETPOST('users');
654 
655  $required_fields = array(
656  $conf->global->LDAP_KEY_USERS,
657  $conf->global->LDAP_FIELD_NAME,
658  $conf->global->LDAP_FIELD_FIRSTNAME,
659  $conf->global->LDAP_FIELD_LOGIN,
660  $conf->global->LDAP_FIELD_LOGIN_SAMBA,
661  $conf->global->LDAP_FIELD_PASSWORD,
662  $conf->global->LDAP_FIELD_PASSWORD_CRYPTED,
663  $conf->global->LDAP_FIELD_PHONE,
664  $conf->global->LDAP_FIELD_FAX,
665  $conf->global->LDAP_FIELD_MOBILE,
666  $conf->global->LDAP_FIELD_SKYPE,
667  $conf->global->LDAP_FIELD_MAIL,
668  $conf->global->LDAP_FIELD_TITLE,
669  $conf->global->LDAP_FIELD_DESCRIPTION,
670  $conf->global->LDAP_FIELD_SID
671  );
672 
673  $ldap = new Ldap();
674  $result = $ldap->connect_bind();
675  if ($result >= 0) {
676  // Remove from required_fields all entries not configured in LDAP (empty) and duplicated
677  $required_fields = array_unique(array_values(array_filter($required_fields, "dol_validElement")));
678 
679  $ldapusers = $ldap->getRecords($selecteduser, $conf->global->LDAP_USER_DN, $conf->global->LDAP_KEY_USERS, $required_fields);
680  //print_r($ldapusers);
681 
682  if (is_array($ldapusers)) {
683  foreach ($ldapusers as $key => $attribute) {
684  $ldap_lastname = $attribute[$conf->global->LDAP_FIELD_NAME];
685  $ldap_firstname = $attribute[$conf->global->LDAP_FIELD_FIRSTNAME];
686  $ldap_login = $attribute[$conf->global->LDAP_FIELD_LOGIN];
687  $ldap_loginsmb = $attribute[$conf->global->LDAP_FIELD_LOGIN_SAMBA];
688  $ldap_pass = $attribute[$conf->global->LDAP_FIELD_PASSWORD];
689  $ldap_pass_crypted = $attribute[$conf->global->LDAP_FIELD_PASSWORD_CRYPTED];
690  $ldap_phone = $attribute[$conf->global->LDAP_FIELD_PHONE];
691  $ldap_fax = $attribute[$conf->global->LDAP_FIELD_FAX];
692  $ldap_mobile = $attribute[$conf->global->LDAP_FIELD_MOBILE];
693  $ldap_social['skype'] = $attribute[$conf->global->LDAP_FIELD_SKYPE];
694  $ldap_social['twitter'] = $attribute[$conf->global->LDAP_FIELD_TWITTER];
695  $ldap_social['facebook'] = $attribute[$conf->global->LDAP_FIELD_FACEBOOK];
696  $ldap_social['linkedin'] = $attribute[$conf->global->LDAP_FIELD_LINKEDIN];
697  $ldap_mail = $attribute[$conf->global->LDAP_FIELD_MAIL];
698  $ldap_sid = $attribute[$conf->global->LDAP_FIELD_SID];
699  }
700  }
701  } else {
702  setEventMessages($ldap->error, $ldap->errors, 'errors');
703  }
704  }
705 
706  // Actions to send emails
707  $triggersendname = 'USER_SENTBYMAIL';
708  $paramname = 'id'; // Name of param key to open the card
709  $mode = 'emailfromuser';
710  $trackid = 'use'.$id;
711  include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
712 
713  // Actions to build doc
714  $upload_dir = $conf->user->dir_output;
715  $permissiontoadd = $user->rights->user->user->creer;
716  include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
717 }
718 
719 
720 /*
721  * View
722  */
723 
724 $form = new Form($db);
725 $formother = new FormOther($db);
726 $formcompany = new FormCompany($db);
727 $formadmin = new FormAdmin($db);
728 $formfile = new FormFile($db);
729 if (!empty($conf->stock->enabled)) {
730  $formproduct = new FormProduct($db);
731 }
732 
733 llxHeader('', $langs->trans("UserCard"));
734 
735 if ($action == 'create' || $action == 'adduserldap') {
736  print load_fiche_titre($langs->trans("NewUser"), '', 'user');
737 
738  print '<span class="opacitymedium">'.$langs->trans("CreateInternalUserDesc")."</span><br>\n";
739  print "<br>";
740 
741 
742  if (!empty($conf->ldap->enabled) && (isset($conf->global->LDAP_SYNCHRO_ACTIVE) && getDolGlobalInt('LDAP_SYNCHRO_ACTIVE') === Ldap::SYNCHRO_LDAP_TO_DOLIBARR)) {
743  // Show form to add an account from LDAP if sync LDAP -> Dolibarr is set
744  $ldap = new Ldap();
745  $result = $ldap->connect_bind();
746  if ($result >= 0) {
747  $required_fields = array(
748  $conf->global->LDAP_KEY_USERS,
749  $conf->global->LDAP_FIELD_FULLNAME,
750  $conf->global->LDAP_FIELD_NAME,
751  $conf->global->LDAP_FIELD_FIRSTNAME,
752  $conf->global->LDAP_FIELD_LOGIN,
753  $conf->global->LDAP_FIELD_LOGIN_SAMBA,
754  $conf->global->LDAP_FIELD_PASSWORD,
755  $conf->global->LDAP_FIELD_PASSWORD_CRYPTED,
756  $conf->global->LDAP_FIELD_PHONE,
757  $conf->global->LDAP_FIELD_FAX,
758  $conf->global->LDAP_FIELD_MOBILE,
759  $conf->global->LDAP_FIELD_SKYPE,
760  $conf->global->LDAP_FIELD_MAIL,
761  $conf->global->LDAP_FIELD_TITLE,
762  $conf->global->LDAP_FIELD_DESCRIPTION,
763  $conf->global->LDAP_FIELD_SID
764  );
765 
766  // Remove from required_fields all entries not configured in LDAP (empty) and duplicated
767  $required_fields = array_unique(array_values(array_filter($required_fields, "dol_validElement")));
768 
769  // Get from LDAP database an array of results
770  $ldapusers = $ldap->getRecords('*', $conf->global->LDAP_USER_DN, $conf->global->LDAP_KEY_USERS, $required_fields, 1);
771 
772  if (is_array($ldapusers)) {
773  $liste = array();
774  foreach ($ldapusers as $key => $ldapuser) {
775  // Define the label string for this user
776  $label = '';
777  foreach ($required_fields as $value) {
778  if ($value === $conf->global->LDAP_FIELD_PASSWORD || $value === $conf->global->LDAP_FIELD_PASSWORD_CRYPTED) {
779  $label .= $value."=******* ";
780  } elseif ($value) {
781  $label .= $value."=".$ldapuser[$value]." ";
782  }
783  }
784  $liste[$key] = $label;
785  }
786  } else {
787  setEventMessages($ldap->error, $ldap->errors, 'errors');
788  }
789  } else {
790  setEventMessages($ldap->error, $ldap->errors, 'errors');
791  }
792 
793  // If user list is full, we show drop-down list
794  print "\n\n<!-- Form liste LDAP debut -->\n";
795 
796  print '<form name="add_user_ldap" action="'.$_SERVER["PHP_SELF"].'" method="post">';
797  print '<input type="hidden" name="token" value="'.newToken().'">';
798  print '<table class="border centpercent"><tr>';
799  print '<td width="160">';
800  print $langs->trans("LDAPUsers");
801  print '</td>';
802  print '<td>';
803  print '<input type="hidden" name="action" value="adduserldap">';
804  if (is_array($liste) && count($liste)) {
805  print $form->selectarray('users', $liste, '', 1, 0, 0, '', 0, 0, 0, '', 'maxwidth500');
806  print ajax_combobox('users');
807  }
808  print '</td><td class="center">';
809  print '<input type="submit" class="button" value="'.dol_escape_htmltag($langs->trans('Get')).'"'.(count($liste) ? '' : ' disabled').'>';
810  print '</td></tr></table>';
811  print '</form>';
812 
813  print "\n<!-- Form liste LDAP fin -->\n\n";
814  print '<br>';
815  }
816 
817 
818  print '<form action="'.$_SERVER['PHP_SELF'].'" method="POST" name="createuser">';
819  print '<input type="hidden" name="token" value="'.newToken().'">';
820  print '<input type="hidden" name="action" value="add">';
821  if (!empty($ldap_sid)) {
822  print '<input type="hidden" name="ldap_sid" value="'.dol_escape_htmltag($ldap_sid).'">';
823  }
824  print '<input type="hidden" name="entity" value="'.$conf->entity.'">';
825 
826  print dol_get_fiche_head('', '', '', 0, '');
827 
828  dol_set_focus('#lastname');
829 
830  print '<table class="border centpercent">';
831 
832  // Civility
833  print '<tr><td><label for="civility_code">'.$langs->trans("UserTitle").'</label></td><td colspan="3">';
834  print $formcompany->select_civility(GETPOSTISSET("civility_code") ? GETPOST("civility_code", 'aZ09') : $object->civility_code, 'civility_code');
835  print '</td></tr>';
836 
837  // Lastname
838  print '<tr>';
839  print '<td class="titlefieldcreate"><span class="fieldrequired">'.$langs->trans("Lastname").'</span></td>';
840  print '<td>';
841  if (!empty($ldap_lastname)) {
842  print '<input type="hidden" id="lastname" name="lastname" value="'.dol_escape_htmltag($ldap_lastname).'">';
843  print $ldap_lastname;
844  } else {
845  print '<input class="minwidth100 maxwidth150onsmartphone" type="text" id="lastname" name="lastname" value="'.dol_escape_htmltag(GETPOST('lastname', 'alphanohtml')).'">';
846  }
847  print '</td></tr>';
848 
849  // Firstname
850  print '<tr><td>'.$langs->trans("Firstname").'</td>';
851  print '<td>';
852  if (!empty($ldap_firstname)) {
853  print '<input type="hidden" name="firstname" value="'.dol_escape_htmltag($ldap_firstname).'">';
854  print $ldap_firstname;
855  } else {
856  print '<input class="minwidth100 maxwidth150onsmartphone" type="text" name="firstname" value="'.dol_escape_htmltag(GETPOST('firstname', 'alphanohtml')).'">';
857  }
858  print '</td></tr>';
859 
860  // Login
861  print '<tr><td><span class="fieldrequired">'.$langs->trans("Login").'</span></td>';
862  print '<td>';
863  if (!empty($ldap_login)) {
864  print '<input type="hidden" name="login" value="'.dol_escape_htmltag($ldap_login).'">';
865  print $ldap_login;
866  } elseif (!empty($ldap_loginsmb)) {
867  print '<input type="hidden" name="login" value="'.dol_escape_htmltag($ldap_loginsmb).'">';
868  print $ldap_loginsmb;
869  } else {
870  print '<input class="maxwidth200 maxwidth150onsmartphone" maxsize="24" type="text" name="login" value="'.dol_escape_htmltag(GETPOST('login', 'alphanohtml')).'">';
871  }
872  print '</td></tr>';
873 
874  $generated_password = '';
875  if (empty($ldap_sid)) { // ldap_sid is for activedirectory
876  $generated_password = getRandomPassword(false);
877  }
878  $password = (GETPOSTISSET('password') ?GETPOST('password') : $generated_password);
879 
880  // Administrator
881  if (!empty($user->admin)) {
882  print '<tr><td>'.$langs->trans("Administrator").'</td>';
883  print '<td>';
884  print $form->selectyesno('admin', GETPOST('admin'), 1);
885 
886  if (!empty($conf->multicompany->enabled) && !$user->entity) {
887  if (!empty($conf->use_javascript_ajax)) {
888  print '<script type="text/javascript">
889  $(function() {
890  $("select[name=admin]").change(function() {
891  if ( $(this).val() == 0 ) {
892  $("input[name=superadmin]")
893  .prop("disabled", true)
894  .prop("checked", false);
895  $("select[name=entity]")
896  .prop("disabled", false);
897  } else {
898  $("input[name=superadmin]")
899  .prop("disabled", false);
900  }
901  });
902  $("input[name=superadmin]").change(function() {
903  if ( $(this).is(":checked") ) {
904  $("select[name=entity]")
905  .prop("disabled", true);
906  } else {
907  $("select[name=entity]")
908  .prop("disabled", false);
909  }
910  });
911  });
912  </script>';
913  }
914  $checked = (GETPOST('superadmin', 'int') ? ' checked' : '');
915  $disabled = (GETPOST('superadmin', 'int') ? '' : ' disabled');
916  print '<input type="checkbox" name="superadmin" id="superadmin" value="1"'.$checked.$disabled.' /> <label for="superadmin">'.$langs->trans("SuperAdministrator").'</span>';
917  }
918  print "</td></tr>\n";
919  }
920 
921  // Gender
922  print '<tr><td>'.$langs->trans("Gender").'</td>';
923  print '<td>';
924  $arraygender = array('man'=>$langs->trans("Genderman"), 'woman'=>$langs->trans("Genderwoman"), 'other'=>$langs->trans("Genderother"));
925  print $form->selectarray('gender', $arraygender, GETPOST('gender'), 1);
926  print '</td></tr>';
927 
928  // Employee
929  $defaultemployee = '1';
930  print '<tr>';
931  print '<td>'.$langs->trans('Employee').'</td><td>';
932  print '<input type="checkbox" name="employee" value="1"'.(GETPOST('employee') == '1' ? ' checked="checked"' : (($defaultemployee && !GETPOSTISSET('login')) ? ' checked="checked"' : '')).'>';
933  //print $form->selectyesno("employee", (GETPOST('employee') != '' ?GETPOST('employee') : $defaultemployee), 1);
934  print '</td></tr>';
935 
936  // Hierarchy
937  print '<tr><td class="titlefieldcreate">'.$langs->trans("HierarchicalResponsible").'</td>';
938  print '<td>';
939  print img_picto('', 'user', 'class="pictofixedwidth"').$form->select_dolusers($object->fk_user, 'fk_user', 1, array($object->id), 0, '', 0, $conf->entity, 0, 0, '', 0, '', 'maxwidth300 widthcentpercentminusx');
940  print '</td>';
941  print "</tr>\n";
942 
943  // Expense report validator
944  if (!empty($conf->expensereport->enabled)) {
945  print '<tr><td class="titlefieldcreate">';
946  $text = $langs->trans("ForceUserExpenseValidator");
947  print $form->textwithpicto($text, $langs->trans("ValidatorIsSupervisorByDefault"), 1, 'help');
948  print '</td>';
949  print '<td>';
950  print img_picto('', 'user', 'class="pictofixedwidth"').$form->select_dolusers($object->fk_user_expense_validator, 'fk_user_expense_validator', 1, array($object->id), 0, '', 0, $conf->entity, 0, 0, '', 0, '', 'maxwidth300 widthcentpercentminusx');
951  print '</td>';
952  print "</tr>\n";
953  }
954 
955  // Holiday request validator
956  if (!empty($conf->holiday->enabled)) {
957  print '<tr><td class="titlefieldcreate">';
958  $text = $langs->trans("ForceUserHolidayValidator");
959  print $form->textwithpicto($text, $langs->trans("ValidatorIsSupervisorByDefault"), 1, 'help');
960  print '</td>';
961  print '<td>';
962  print img_picto('', 'user', 'class="pictofixedwidth"').$form->select_dolusers($object->fk_user_holiday_validator, 'fk_user_holiday_validator', 1, array($object->id), 0, '', 0, $conf->entity, 0, 0, '', 0, '', 'maxwidth300 widthcentpercentminusx');
963  print '</td>';
964  print "</tr>\n";
965  }
966 
967  // External user
968  print '<tr><td>'.$langs->trans("ExternalUser").' ?</td>';
969  print '<td>';
970  print $form->textwithpicto($langs->trans("Internal"), $langs->trans("InternalExternalDesc"), 1, 'help', '', 0, 2);
971  print '</td></tr>';
972 
973 
974  print '</table><hr><table class="border centpercent">';
975 
976 
977  // Date validity
978  print '<tr><td class="titlefieldcreate">'.$langs->trans("RangeOfLoginValidity").'</td>';
979  print '<td>';
980  print $form->selectDate($datestartvalidity, 'datestartvalidity', 0, 0, 1, 'formdatestartvalidity', 1, 1);
981 
982  print ' &nbsp; ';
983 
984  print $form->selectDate($dateendvalidity, 'dateendvalidity', 0, 0, 1, 'formdateendvalidity', 1, 0);
985  print '</td>';
986  print "</tr>\n";
987 
988  // Password
989  print '<tr><td class="fieldrequired">'.$langs->trans("Password").'</td>';
990  print '<td>';
991  $valuetoshow = '';
992  if (preg_match('/ldap/', $dolibarr_main_authentication)) {
993  $valuetoshow .= ($valuetoshow ? ', ' : '').$langs->trans("PasswordOfUserInLDAP");
994  }
995  if (preg_match('/http/', $dolibarr_main_authentication)) {
996  $valuetoshow .= ($valuetoshow ? ', ' : '').$langs->trans("HTTPBasicPassword");
997  }
998  if (preg_match('/dolibarr/', $dolibarr_main_authentication)) {
999  if (!empty($ldap_pass)) { // For very old system comaptibilty. Now clear password can't be viewed from LDAP read
1000  $valuetoshow .= ($valuetoshow ? ', ' : '').'<input type="hidden" name="password" value="'.dol_escape_htmltag($ldap_pass).'">'; // Dolibarr password is preffiled with LDAP known password
1001  $valuetoshow .= preg_replace('/./i', '*', $ldap_pass);
1002  } else {
1003  // We do not use a field password but a field text to show new password to use.
1004  $valuetoshow .= ($valuetoshow ? ', ' : '').'<input maxsize="32" type="text" name="password" value="'.dol_escape_htmltag($password).'" autocomplete="new-password">';
1005  }
1006  }
1007 
1008  // Other form for user password
1009  $parameters = array('valuetoshow' => $valuetoshow, 'password' => $password);
1010  $reshook = $hookmanager->executeHooks('printUserPasswordField', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1011  if ($reshook > 0) {
1012  $valuetoshow = $hookmanager->resPrint; // to replace
1013  } else {
1014  $valuetoshow .= $hookmanager->resPrint; // to add
1015  }
1016 
1017  print $valuetoshow;
1018  print '</td></tr>';
1019 
1020  if (!empty($conf->api->enabled)) {
1021  // API key
1022  //$generated_password = getRandomPassword(false);
1023  print '<tr><td>'.$langs->trans("ApiKey").'</td>';
1024  print '<td>';
1025  print '<input class="minwidth300 widthcentpercentminusx" maxsize="32" type="text" id="api_key" name="api_key" value="'.GETPOST('api_key', 'alphanohtml').'" autocomplete="off">';
1026  if (!empty($conf->use_javascript_ajax)) {
1027  print '&nbsp;'.img_picto($langs->trans('Generate'), 'refresh', 'id="generate_api_key" class="linkobject"');
1028  }
1029  print '</td></tr>';
1030  } else {
1031  // PARTIAL WORKAROUND
1032  $generated_fake_api_key = getRandomPassword(false);
1033  print '<input type="hidden" name="api_key" value="'.$generated_fake_api_key.'">';
1034  }
1035 
1036 
1037  print '</table><hr><table class="border centpercent">';
1038 
1039 
1040  // Address
1041  print '<tr><td class="tdtop titlefieldcreate">'.$form->editfieldkey('Address', 'address', '', $object, 0).'</td>';
1042  print '<td><textarea name="address" id="address" class="quatrevingtpercent" rows="3" wrap="soft">';
1043  print $object->address;
1044  print '</textarea></td></tr>';
1045 
1046  // Zip
1047  print '<tr><td>'.$form->editfieldkey('Zip', 'zipcode', '', $object, 0).'</td><td>';
1048  print $formcompany->select_ziptown($object->zip, 'zipcode', array('town', 'selectcountry_id', 'state_id'), 6);
1049  print '</td></tr>';
1050 
1051  // Town
1052  print '<tr><td>'.$form->editfieldkey('Town', 'town', '', $object, 0).'</td><td>';
1053  print $formcompany->select_ziptown($object->town, 'town', array('zipcode', 'selectcountry_id', 'state_id'));
1054  print '</td></tr>';
1055 
1056  // Country
1057  print '<tr><td>'.$form->editfieldkey('Country', 'selectcountry_id', '', $object, 0).'</td><td class="maxwidthonsmartphone">';
1058  print img_picto('', 'country', 'class="pictofixedwidth"');
1059  print $form->select_country((GETPOST('country_id') != '' ?GETPOST('country_id') : $object->country_id));
1060  if ($user->admin) {
1061  print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
1062  }
1063  print '</td></tr>';
1064 
1065  // State
1066  if (empty($conf->global->USER_DISABLE_STATE)) {
1067  print '<tr><td>'.$form->editfieldkey('State', 'state_id', '', $object, 0).'</td><td class="maxwidthonsmartphone">';
1068  print img_picto('', 'state', 'class="pictofixedwidth"');
1069  print $formcompany->select_state($object->state_id, $object->country_code, 'state_id');
1070  print '</td></tr>';
1071  }
1072 
1073  // Tel
1074  print '<tr><td>'.$langs->trans("PhonePro").'</td>';
1075  print '<td>';
1076  print img_picto('', 'object_phoning', 'class="pictofixedwidth"');
1077  if (!empty($ldap_phone)) {
1078  print '<input type="hidden" name="office_phone" value="'.dol_escape_htmltag($ldap_phone).'">';
1079  print $ldap_phone;
1080  } else {
1081  print '<input class="maxwidth200 widthcentpercentminusx" type="text" name="office_phone" value="'.dol_escape_htmltag(GETPOST('office_phone', 'alphanohtml')).'">';
1082  }
1083  print '</td></tr>';
1084 
1085  // Tel portable
1086  print '<tr><td>'.$langs->trans("PhoneMobile").'</td>';
1087  print '<td>';
1088  print img_picto('', 'object_phoning_mobile', 'class="pictofixedwidth"');
1089  if (!empty($ldap_mobile)) {
1090  print '<input type="hidden" name="user_mobile" value="'.dol_escape_htmltag($ldap_mobile).'">';
1091  print $ldap_mobile;
1092  } else {
1093  print '<input class="maxwidth200 widthcentpercentminusx" type="text" name="user_mobile" value="'.dol_escape_htmltag(GETPOST('user_mobile', 'alphanohtml')).'">';
1094  }
1095  print '</td></tr>';
1096 
1097  // Fax
1098  print '<tr><td>'.$langs->trans("Fax").'</td>';
1099  print '<td>';
1100  print img_picto('', 'object_phoning_fax', 'class="pictofixedwidth"');
1101  if (!empty($ldap_fax)) {
1102  print '<input type="hidden" name="office_fax" value="'.dol_escape_htmltag($ldap_fax).'">';
1103  print $ldap_fax;
1104  } else {
1105  print '<input class="maxwidth200 widthcentpercentminusx" type="text" name="office_fax" value="'.dol_escape_htmltag(GETPOST('office_fax', 'alphanohtml')).'">';
1106  }
1107  print '</td></tr>';
1108 
1109  // EMail
1110  print '<tr><td'.(!empty($conf->global->USER_MAIL_REQUIRED) ? ' class="fieldrequired"' : '').'>'.$langs->trans("EMail").'</td>';
1111  print '<td>';
1112  print img_picto('', 'object_email', 'class="pictofixedwidth"');
1113  if (!empty($ldap_mail)) {
1114  print '<input type="hidden" name="email" value="'.dol_escape_htmltag($ldap_mail).'">';
1115  print $ldap_mail;
1116  } else {
1117  print '<input type="text" name="email" class="maxwidth500 widthcentpercentminusx" value="'.dol_escape_htmltag(GETPOST('email', 'alphanohtml')).'">';
1118  }
1119  print '</td></tr>';
1120 
1121  // Social networks
1122  if (!empty($conf->socialnetworks->enabled)) {
1123  foreach ($socialnetworks as $key => $value) {
1124  if ($value['active']) {
1125  print '<tr><td>'.$langs->trans($value['label']).'</td>';
1126  print '<td>';
1127  if (!empty($value['icon'])) {
1128  print '<span class="fa '.$value['icon'].' pictofixedwidth"></span>';
1129  }
1130  if (!empty($ldap_social[$key])) {
1131  print '<input type="hidden" name="'.$key.'" value="'.$ldap_social[$key].'">';
1132  print $ldap_social[$key];
1133  } else {
1134  print '<input class="maxwidth200 widthcentpercentminusx" type="text" name="'.$key.'" value="'.GETPOST($key, 'alphanohtml').'">';
1135  }
1136  print '</td></tr>';
1137  } else {
1138  // if social network is not active but value exist we do not want to loose it
1139  if (!empty($ldap_social[$key])) {
1140  print '<input type="hidden" name="'.$key.'" value="'.$ldap_social[$key].'">';
1141  } else {
1142  print '<input type="hidden" name="'.$key.'" value="'.GETPOST($key, 'alphanohtml').'">';
1143  }
1144  }
1145  }
1146  }
1147 
1148  // Accountancy code
1149  if (!empty($conf->accounting->enabled)) {
1150  print '<tr><td>'.$langs->trans("AccountancyCode").'</td>';
1151  print '<td>';
1152  print '<input type="text" class="maxwidthonsmartphone" name="accountancy_code" value="'.dol_escape_htmltag(GETPOST('accountancy_code', 'alphanohtml')).'">';
1153  print '</td></tr>';
1154  }
1155 
1156  // User color
1157  if (isModEnabled('agenda')) {
1158  print '<tr><td>'.$langs->trans("ColorUser").'</td>';
1159  print '<td>';
1160  print $formother->selectColor(GETPOSTISSET('color') ?GETPOST('color', 'alphanohtml') : $object->color, 'color', null, 1, '', 'hideifnotset');
1161  print '</td></tr>';
1162  }
1163 
1164  // Categories
1165  if (!empty($conf->categorie->enabled) && !empty($user->rights->categorie->lire)) {
1166  print '<tr><td>'.$form->editfieldkey('Categories', 'usercats', '', $object, 0).'</td><td>';
1167  $cate_arbo = $form->select_all_categories('user', null, 'parent', null, null, 1);
1168  print img_picto('', 'category', 'class="pictofixedwidth"').$form->multiselectarray('usercats', $cate_arbo, GETPOST('usercats', 'array'), 0, 0, 'maxwdith300 widthcentpercentminusx', 0, '90%');
1169  print "</td></tr>";
1170  }
1171 
1172  if (!empty($conf->global->MAIN_MULTILANGS)) {
1173  print '<tr><td>'.$form->editfieldkey('DefaultLang', 'default_lang', '', $object, 0, 'string', '', 0, 0, 'id', $langs->trans("WarningNotLangOfInterface", $langs->transnoentitiesnoconv("UserGUISetup"))).'</td>';
1174  print '<td class="maxwidthonsmartphone">'."\n";
1175  print img_picto('', 'language', 'class="pictofixedwidth"').$formadmin->select_language(GETPOST('default_lang', 'alpha') ?GETPOST('default_lang', 'alpha') : ($object->lang ? $object->lang : ''), 'default_lang', 0, 0, 1, 0, 0, 'maxwidth200onsmartphone widthcentpercentminusx');
1176  print '</td>';
1177  print '</tr>';
1178  }
1179 
1180  // Multicompany
1181  if (!empty($conf->multicompany->enabled) && is_object($mc)) {
1182  // This is now done with hook formObjectOptions. Keep this code for backward compatibility with old multicompany module
1183  if (!method_exists($mc, 'formObjectOptions')) {
1184  if (empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) && $conf->entity == 1 && $user->admin && !$user->entity) { // condition must be same for create and edit mode
1185  print "<tr>".'<td>'.$langs->trans("Entity").'</td>';
1186  print "<td>".$mc->select_entities($conf->entity);
1187  print "</td></tr>\n";
1188  } else {
1189  print '<input type="hidden" name="entity" value="'.$conf->entity.'" />';
1190  }
1191  }
1192  }
1193 
1194  // Other attributes
1195  $parameters = array();
1196  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_add.tpl.php';
1197 
1198  // Note
1199  print '<tr><td class="tdtop">';
1200  print $langs->trans("Note");
1201  print '</td><td>';
1202  require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
1203  $doleditor = new DolEditor('note', GETPOSTISSET('note') ? GETPOST('note', 'restricthtml') : '', '', 120, 'dolibarr_notes', '', false, true, getDolGlobalString('FCKEDITOR_ENABLE_SOCIETE'), ROWS_3, '90%');
1204  $doleditor->Create();
1205  print "</td></tr>\n";
1206 
1207  // Signature
1208  print '<tr><td class="tdtop">'.$langs->trans("Signature").'</td>';
1209  print '<td class="wordbreak">';
1210  require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
1211  $doleditor = new DolEditor('signature', GETPOST('signature', 'restricthtml'), '', 138, 'dolibarr_notes', 'In', true, true, empty($conf->global->FCKEDITOR_ENABLE_USERSIGN) ? 0 : 1, ROWS_4, '90%');
1212  print $doleditor->Create(1);
1213  print '</td></tr>';
1214 
1215 
1216  print '</table><hr><table class="border centpercent">';
1217 
1218 
1219  // TODO Move this into tab RH (HierarchicalResponsible must be on both tab)
1220 
1221  // Default warehouse
1222  if (!empty($conf->stock->enabled) && !empty($conf->global->MAIN_DEFAULT_WAREHOUSE_USER)) {
1223  print '<tr><td>'.$langs->trans("DefaultWarehouse").'</td><td>';
1224  print $formproduct->selectWarehouses($object->fk_warehouse, 'fk_warehouse', 'warehouseopen', 1);
1225  print '</td></tr>';
1226  }
1227 
1228  // Position/Job
1229  print '<tr><td class="titlefieldcreate">'.$langs->trans("PostOrFunction").'</td>';
1230  print '<td>';
1231  print '<input class="maxwidth200 maxwidth150onsmartphone" type="text" name="job" value="'.dol_escape_htmltag(GETPOST('job', 'alphanohtml')).'">';
1232  print '</td></tr>';
1233 
1234  if ((!empty($conf->salaries->enabled) && !empty($user->rights->salaries->read) && in_array($id, $childids))
1235  || (!empty($conf->salaries->enabled) && !empty($user->rights->salaries->readall))
1236  || (!empty($conf->hrm->enabled) && !empty($user->rights->hrm->employee->read))) {
1237  $langs->load("salaries");
1238 
1239  // THM
1240  print '<tr><td>';
1241  $text = $langs->trans("THM");
1242  print $form->textwithpicto($text, $langs->trans("THMDescription"), 1, 'help', 'classthm');
1243  print '</td>';
1244  print '<td>';
1245  print '<input size="8" type="text" name="thm" value="'.dol_escape_htmltag(GETPOST('thm')).'"> '.$langs->getCurrencySymbol($conf->currency);
1246  print '</td>';
1247  print "</tr>\n";
1248 
1249  // TJM
1250  print '<tr><td>';
1251  $text = $langs->trans("TJM");
1252  print $form->textwithpicto($text, $langs->trans("TJMDescription"), 1, 'help', 'classtjm');
1253  print '</td>';
1254  print '<td>';
1255  print '<input size="8" type="text" name="tjm" value="'.dol_escape_htmltag(GETPOST('tjm')).'"> '.$langs->getCurrencySymbol($conf->currency);
1256  print '</td>';
1257  print "</tr>\n";
1258 
1259  // Salary
1260  print '<tr><td>'.$langs->trans("Salary").'</td>';
1261  print '<td>';
1262  print img_picto('', 'salary', 'class="pictofixedwidth paddingright"').'<input size="8" type="text" name="salary" value="'.dol_escape_htmltag(GETPOST('salary')).'"> '.$langs->getCurrencySymbol($conf->currency);
1263  print '</td>';
1264  print "</tr>\n";
1265  }
1266 
1267  // Weeklyhours
1268  print '<tr><td>'.$langs->trans("WeeklyHours").'</td>';
1269  print '<td>';
1270  print '<input size="8" type="text" name="weeklyhours" value="'.dol_escape_htmltag(GETPOST('weeklyhours')).'">';
1271  print '</td>';
1272  print "</tr>\n";
1273 
1274  // Date employment
1275  print '<tr><td>'.$langs->trans("DateEmployment").'</td>';
1276  print '<td>';
1277  print $form->selectDate($dateemployment, 'dateemployment', 0, 0, 1, 'formdateemployment', 1, 1);
1278 
1279  print ' - ';
1280 
1281  print $form->selectDate($dateemploymentend, 'dateemploymentend', 0, 0, 1, 'formdateemploymentend', 1, 0);
1282  print '</td>';
1283  print "</tr>\n";
1284 
1285  // Date birth
1286  print '<tr><td>'.$langs->trans("DateOfBirth").'</td>';
1287  print '<td>';
1288  print $form->selectDate($dateofbirth, 'dateofbirth', 0, 0, 1, 'createuser', 1, 0, 0, '', 0, '', '', 1, '', '', 'tzserver');
1289  print '</td>';
1290  print "</tr>\n";
1291 
1292  print "</table>\n";
1293 
1294  print dol_get_fiche_end();
1295 
1296  print $form->buttonsSaveCancel("CreateUser");
1297 
1298  print "</form>";
1299 } else {
1300  // View and edit mode
1301  if ($id > 0) {
1302  $res = $object->fetch($id, '', '', 1);
1303  if ($res < 0) {
1304  dol_print_error($db, $object->error);
1305  exit;
1306  }
1307  $res = $object->fetch_optionals();
1308 
1309  // Check if user has rights
1310  if (empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
1311  $object->getrights();
1312  if (empty($object->nb_rights) && $object->statut != 0 && empty($object->admin)) {
1313  setEventMessages($langs->trans('UserHasNoPermissions'), null, 'warnings');
1314  }
1315  }
1316 
1317  // Connexion ldap
1318  // pour recuperer passDoNotExpire et userChangePassNextLogon
1319  if (!empty($conf->ldap->enabled) && !empty($object->ldap_sid)) {
1320  $ldap = new Ldap();
1321  $result = $ldap->connect_bind();
1322  if ($result > 0) {
1323  $userSearchFilter = '('.$conf->global->LDAP_FILTER_CONNECTION.'('.$ldap->getUserIdentifier().'='.$object->login.'))';
1324  $entries = $ldap->fetch($object->login, $userSearchFilter);
1325  if (!$entries) {
1326  setEventMessages($ldap->error, $ldap->errors, 'errors');
1327  }
1328 
1329  $passDoNotExpire = 0;
1330  $userChangePassNextLogon = 0;
1331  $userDisabled = 0;
1332  $statutUACF = '';
1333 
1334  // Check options of user account
1335  if (count($ldap->uacf) > 0) {
1336  foreach ($ldap->uacf as $key => $statut) {
1337  if ($key == 65536) {
1338  $passDoNotExpire = 1;
1339  $statutUACF = $statut;
1340  }
1341  }
1342  } else {
1343  $userDisabled = 1;
1344  $statutUACF = "ACCOUNTDISABLE";
1345  }
1346 
1347  if ($ldap->pwdlastset == 0) {
1348  $userChangePassNextLogon = 1;
1349  }
1350  }
1351  }
1352 
1353  // Show tabs
1354  if ($mode == 'employee') { // For HRM module development
1355  $title = $langs->trans("Employee");
1356  $linkback = '<a href="'.DOL_URL_ROOT.'/hrm/employee/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
1357  } else {
1358  $title = $langs->trans("User");
1359  $linkback = '';
1360 
1361  if ($user->rights->user->user->lire || $user->admin) {
1362  $linkback = '<a href="'.DOL_URL_ROOT.'/user/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
1363  }
1364  }
1365 
1366  $head = user_prepare_head($object);
1367 
1368  /*
1369  * Confirmation reinitialisation mot de passe
1370  */
1371  if ($action == 'password') {
1372  print $form->formconfirm($_SERVER['PHP_SELF']."?id=$object->id", $langs->trans("ReinitPassword"), $langs->trans("ConfirmReinitPassword", $object->login), "confirm_password", '', 0, 1);
1373  }
1374 
1375  /*
1376  * Confirmation envoi mot de passe
1377  */
1378  if ($action == 'passwordsend') {
1379  print $form->formconfirm($_SERVER['PHP_SELF']."?id=$object->id", $langs->trans("SendNewPassword"), $langs->trans("ConfirmSendNewPassword", $object->login), "confirm_passwordsend", '', 0, 1);
1380  }
1381 
1382  /*
1383  * Confirm deactivation
1384  */
1385  if ($action == 'disable') {
1386  print $form->formconfirm($_SERVER['PHP_SELF']."?id=$object->id", $langs->trans("DisableAUser"), $langs->trans("ConfirmDisableUser", $object->login), "confirm_disable", '', 0, 1);
1387  }
1388 
1389  /*
1390  * Confirm activation
1391  */
1392  if ($action == 'enable') {
1393  print $form->formconfirm($_SERVER['PHP_SELF']."?id=$object->id", $langs->trans("EnableAUser"), $langs->trans("ConfirmEnableUser", $object->login), "confirm_enable", '', 0, 1);
1394  }
1395 
1396  /*
1397  * Confirmation suppression
1398  */
1399  if ($action == 'delete') {
1400  print $form->formconfirm($_SERVER['PHP_SELF']."?id=$object->id", $langs->trans("DeleteAUser"), $langs->trans("ConfirmDeleteUser", $object->login), "confirm_delete", '', 0, 1);
1401  }
1402 
1403  /*
1404  * Fiche en mode visu
1405  */
1406  if ($action != 'edit') {
1407  print dol_get_fiche_head($head, 'user', $title, -1, 'user');
1408 
1409  $morehtmlref = '<a href="'.DOL_URL_ROOT.'/user/vcard.php?id='.$object->id.'" class="refid">';
1410  $morehtmlref .= img_picto($langs->trans("Download").' '.$langs->trans("VCard"), 'vcard.png', 'class="valignmiddle marginleftonly paddingrightonly"');
1411  $morehtmlref .= '</a>';
1412 
1413  dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin, 'rowid', 'ref', $morehtmlref);
1414 
1415  print '<div class="fichecenter">';
1416  print '<div class="fichehalfleft">';
1417 
1418  print '<div class="underbanner clearboth"></div>';
1419  print '<table class="border tableforfield" width="100%">';
1420 
1421  // Login
1422  print '<tr><td class="titlefieldmiddle">'.$langs->trans("Login").'</td>';
1423  if (!empty($object->ldap_sid) && $object->statut == 0) {
1424  print '<td class="error">';
1425  print $langs->trans("LoginAccountDisableInDolibarr");
1426  print '</td>';
1427  } else {
1428  print '<td>';
1429  $addadmin = '';
1430  if (property_exists($object, 'admin')) {
1431  if (!empty($conf->multicompany->enabled) && !empty($object->admin) && empty($object->entity)) {
1432  $addadmin .= img_picto($langs->trans("SuperAdministratorDesc"), "redstar", 'class="paddingleft"');
1433  } elseif (!empty($object->admin)) {
1434  $addadmin .= img_picto($langs->trans("AdministratorDesc"), "star", 'class="paddingleft"');
1435  }
1436  }
1437  print showValueWithClipboardCPButton($object->login).$addadmin;
1438  print '</td>';
1439  }
1440  print '</tr>'."\n";
1441 
1442  // Type
1443  print '<tr><td>';
1444  $text = $langs->trans("Type");
1445  print $form->textwithpicto($text, $langs->trans("InternalExternalDesc"));
1446  print '</td><td>';
1447  $type = $langs->trans("Internal");
1448  if ($object->socid > 0) {
1449  $type = $langs->trans("External");
1450  }
1451  print '<span class="badgeneutral">';
1452  print $type;
1453  if ($object->ldap_sid) {
1454  print ' ('.$langs->trans("DomainUser").')';
1455  }
1456  print '</span>';
1457  print '</td></tr>'."\n";
1458 
1459  // Ldap sid
1460  if ($object->ldap_sid) {
1461  print '<tr><td>'.$langs->trans("Type").'</td><td>';
1462  print $langs->trans("DomainUser", $ldap->domainFQDN);
1463  print '</td></tr>'."\n";
1464  }
1465 
1466  // Employee
1467  print '<tr><td>'.$langs->trans("Employee").'</td><td>';
1468  print '<input type="checkbox" disabled name="employee" value="1"'.($object->employee ? ' checked="checked"' : '').'>';
1469  //print yn($object->employee);
1470  print '</td></tr>'."\n";
1471 
1472  // TODO This is also available into the tab RH
1473 
1474  // Hierarchy
1475  print '<tr><td>'.$langs->trans("HierarchicalResponsible").'</td>';
1476  print '<td>';
1477  if (empty($object->fk_user)) {
1478  print '<span class="opacitymedium">'.$langs->trans("None").'</span>';
1479  } else {
1480  $huser = new User($db);
1481  if ($object->fk_user > 0) {
1482  $huser->fetch($object->fk_user);
1483  print $huser->getNomUrl(1);
1484  } else {
1485  print '<span class="opacitymedium">'.$langs->trans("None").'</span>';
1486  }
1487  }
1488  print '</td>';
1489  print "</tr>\n";
1490 
1491  // Expense report validator
1492  if (!empty($conf->expensereport->enabled)) {
1493  print '<tr><td>';
1494  $text = $langs->trans("ForceUserExpenseValidator");
1495  print $form->textwithpicto($text, $langs->trans("ValidatorIsSupervisorByDefault"), 1, 'help');
1496  print '</td>';
1497  print '<td>';
1498  if (!empty($object->fk_user_expense_validator)) {
1499  $evuser = new User($db);
1500  $evuser->fetch($object->fk_user_expense_validator);
1501  print $evuser->getNomUrl(1);
1502  }
1503  print '</td>';
1504  print "</tr>\n";
1505  }
1506 
1507  // Holiday request validator
1508  if (!empty($conf->holiday->enabled)) {
1509  print '<tr><td>';
1510  $text = $langs->trans("ForceUserHolidayValidator");
1511  print $form->textwithpicto($text, $langs->trans("ValidatorIsSupervisorByDefault"), 1, 'help');
1512  print '</td>';
1513  print '<td>';
1514  if (!empty($object->fk_user_holiday_validator)) {
1515  $hvuser = new User($db);
1516  $hvuser->fetch($object->fk_user_holiday_validator);
1517  print $hvuser->getNomUrl(1);
1518  }
1519  print '</td>';
1520  print "</tr>\n";
1521  }
1522 
1523  // Position/Job
1524  print '<tr><td>'.$langs->trans("PostOrFunction").'</td>';
1525  print '<td>'.dol_escape_htmltag($object->job).'</td>';
1526  print '</tr>'."\n";
1527 
1528  // Weeklyhours
1529  print '<tr><td>'.$langs->trans("WeeklyHours").'</td>';
1530  print '<td>';
1531  print price2num($object->weeklyhours);
1532  print '</td>';
1533  print "</tr>\n";
1534 
1535  // Sensitive salary/value information
1536  if ((empty($user->socid) && in_array($id, $childids)) // A user can always see salary/value information for its subordinates
1537  || (!empty($conf->salaries->enabled) && !empty($user->rights->salaries->readall))
1538  || (!empty($conf->hrm->enabled) && !empty($user->rights->hrm->employee->read))) {
1539  $langs->load("salaries");
1540 
1541  // Salary
1542  print '<tr><td>'.$langs->trans("Salary").'</td>';
1543  print '<td>';
1544  print ($object->salary != '' ? img_picto('', 'salary', 'class="pictofixedwidth paddingright"').'<span class="amount">'.price($object->salary, '', $langs, 1, -1, -1, $conf->currency) : '').'</span>';
1545  print '</td>';
1546  print "</tr>\n";
1547 
1548  // THM
1549  print '<tr><td>';
1550  $text = $langs->trans("THM");
1551  print $form->textwithpicto($text, $langs->trans("THMDescription"), 1, 'help', 'classthm');
1552  print '</td>';
1553  print '<td>';
1554  print ($object->thm != '' ?price($object->thm, '', $langs, 1, -1, -1, $conf->currency) : '');
1555  print '</td>';
1556  print "</tr>\n";
1557 
1558  // TJM
1559  print '<tr><td>';
1560  $text = $langs->trans("TJM");
1561  print $form->textwithpicto($text, $langs->trans("TJMDescription"), 1, 'help', 'classtjm');
1562  print '</td>';
1563  print '<td>';
1564  print ($object->tjm != '' ?price($object->tjm, '', $langs, 1, -1, -1, $conf->currency) : '');
1565  print '</td>';
1566  print "</tr>\n";
1567  }
1568 
1569  // Date employment
1570  print '<tr><td>'.$langs->trans("DateOfEmployment").'</td>';
1571  print '<td>';
1572  if ($object->dateemployment) {
1573  print '<span class="opacitymedium">'.$langs->trans("FromDate").'</span> ';
1574  print dol_print_date($object->dateemployment, 'day');
1575  }
1576  if ($object->dateemploymentend) {
1577  print '<span class="opacitymedium"> - '.$langs->trans("To").'</span> ';
1578  print dol_print_date($object->dateemploymentend, 'day');
1579  }
1580  print '</td>';
1581  print "</tr>\n";
1582 
1583  // Date of birth
1584  print '<tr><td>'.$langs->trans("DateOfBirth").'</td>';
1585  print '<td>';
1586  print dol_print_date($object->birth, 'day', 'tzserver');
1587  print '</td>';
1588  print "</tr>\n";
1589 
1590  // Default warehouse
1591  if (!empty($conf->stock->enabled) && !empty($conf->global->MAIN_DEFAULT_WAREHOUSE_USER)) {
1592  require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
1593  print '<tr><td>'.$langs->trans("DefaultWarehouse").'</td><td>';
1594  if ($object->fk_warehouse > 0) {
1595  $warehousestatic = new Entrepot($db);
1596  $warehousestatic->fetch($object->fk_warehouse);
1597  print $warehousestatic->getNomUrl(1);
1598  }
1599  print '</td></tr>';
1600  }
1601 
1602  print '</table>';
1603 
1604  print '</div>';
1605  print '<div class="fichehalfright">';
1606 
1607  print '<div class="underbanner clearboth"></div>';
1608 
1609  print '<table class="border tableforfield centpercent">';
1610 
1611  // Color user
1612  if (isModEnabled('agenda')) {
1613  print '<tr><td class="titlefield">'.$langs->trans("ColorUser").'</td>';
1614  print '<td>';
1615  print $formother->showColor($object->color, '');
1616  print '</td>';
1617  print "</tr>\n";
1618  }
1619 
1620  // Categories
1621  if (!empty($conf->categorie->enabled) && !empty($user->rights->categorie->lire)) {
1622  print '<tr><td class="titlefield">'.$langs->trans("Categories").'</td>';
1623  print '<td colspan="3">';
1624  print $form->showCategories($object->id, Categorie::TYPE_USER, 1);
1625  print '</td></tr>';
1626  }
1627 
1628  // Default language
1629  if (!empty($conf->global->MAIN_MULTILANGS)) {
1630  $langs->load("languages");
1631  require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
1632  print '<tr><td class="titlefield">';
1633  print $form->textwithpicto($langs->trans("DefaultLang"), $langs->trans("WarningNotLangOfInterface", $langs->transnoentitiesnoconv("UserGUISetup")));
1634  print '</td><td>';
1635  //$s=picto_from_langcode($object->default_lang);
1636  //print ($s?$s.' ':'');
1637  $labellang = ($object->lang ? $langs->trans('Language_'.$object->lang) : '');
1638  print $labellang;
1639  print '</td></tr>';
1640  }
1641 
1642  if (isset($conf->file->main_authentication) && preg_match('/openid/', $conf->file->main_authentication) && !empty($conf->global->MAIN_OPENIDURL_PERUSER)) {
1643  print '<tr><td>'.$langs->trans("OpenIDURL").'</td>';
1644  print '<td>'.$object->openid.'</td>';
1645  print "</tr>\n";
1646  }
1647 
1648  // Multicompany
1649  if (!empty($conf->multicompany->enabled) && is_object($mc)) {
1650  // This is now done with hook formObjectOptions. Keep this code for backward compatibility with old multicompany module
1651  if (!method_exists($mc, 'formObjectOptions')) {
1652  if (!empty($conf->multicompany->enabled) && empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) && $conf->entity == 1 && $user->admin && !$user->entity) {
1653  print '<tr><td>'.$langs->trans("Entity").'</td><td>';
1654  if (empty($object->entity)) {
1655  print $langs->trans("AllEntities");
1656  } else {
1657  $mc->getInfo($object->entity);
1658  print $mc->label;
1659  }
1660  print "</td></tr>\n";
1661  }
1662  }
1663  }
1664 
1665  // Other attributes
1666  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
1667 
1668  // Company / Contact
1669  if (!empty($conf->societe->enabled)) {
1670  print '<tr><td>'.$langs->trans("LinkToCompanyContact").'</td>';
1671  print '<td>';
1672  $s = '';
1673  if (isset($object->socid) && $object->socid > 0) {
1674  $societe = new Societe($db);
1675  $societe->fetch($object->socid);
1676  if ($societe->id > 0) {
1677  $s .= $societe->getNomUrl(1, '');
1678  }
1679  } else {
1680  $s .= '<span class="opacitymedium hideonsmartphone">'.$langs->trans("ThisUserIsNot").'</span>';
1681  }
1682  if (!empty($object->contact_id)) {
1683  $contact = new Contact($db);
1684  $contact->fetch($object->contact_id);
1685  if ($contact->id > 0) {
1686  if ($object->socid > 0 && $s) {
1687  $s .= ' / ';
1688  } else {
1689  $s .= '<br>';
1690  }
1691  $s .= $contact->getNomUrl(1, '');
1692  }
1693  }
1694  print $s;
1695  print '</td>';
1696  print '</tr>'."\n";
1697  }
1698 
1699  // Module Adherent
1700  if (!empty($conf->adherent->enabled)) {
1701  $langs->load("members");
1702  print '<tr><td>'.$langs->trans("LinkedToDolibarrMember").'</td>';
1703  print '<td>';
1704  if ($object->fk_member) {
1705  $adh = new Adherent($db);
1706  $adh->fetch($object->fk_member);
1707  $adh->ref = $adh->getFullname($langs); // Force to show login instead of id
1708  print $adh->getNomUrl(-1);
1709  } else {
1710  print '<span class="opacitymedium hideonsmartphone">'.$langs->trans("UserNotLinkedToMember").'</span>';
1711  }
1712  print '</td>';
1713  print '</tr>'."\n";
1714  }
1715 
1716  // Signature
1717  print '<tr><td class="tdtop">'.$langs->trans('Signature').'</td><td class="wordbreak">';
1718  print dol_htmlentitiesbr($object->signature);
1719  print "</td></tr>\n";
1720 
1721  print "</table>\n";
1722 
1723  // Credentials
1724  print '<div class="div-table-responsive-no-min">';
1725  print '<table class="border tableforfield margintable centpercent">';
1726  print '<tr class="liste_titre"><td class="liste_titre">';
1727  print img_picto('', 'security', 'class="paddingleft pictofixedwidth"').$langs->trans("Credentials");
1728  print '</td>';
1729  print '<td class="liste_titre"></td>';
1730  print '</tr>';
1731 
1732  // Date login validity
1733  print '<tr><td>'.$langs->trans("RangeOfLoginValidity").'</td>';
1734  print '<td>';
1735  if ($object->datestartvalidity) {
1736  print '<span class="opacitymedium">'.$langs->trans("FromDate").'</span> ';
1737  print dol_print_date($object->datestartvalidity, 'day');
1738  }
1739  if ($object->dateendvalidity) {
1740  print '<span class="opacitymedium"> - '.$langs->trans("To").'</span> ';
1741  print dol_print_date($object->dateendvalidity, 'day');
1742  }
1743  print '</td>';
1744  print "</tr>\n";
1745 
1746  // Password
1747  print '<tr><td class="titlefield">'.$langs->trans("Password").'</td>';
1748 
1749  print '<td class="wordbreak">';
1750  $valuetoshow = '';
1751  if (preg_match('/ldap/', $dolibarr_main_authentication)) {
1752  if (!empty($object->ldap_sid)) {
1753  if ($passDoNotExpire) {
1754  $valuetoshow .= ($valuetoshow ? (' '.$langs->trans("or").' ') : '').$langs->trans("LdapUacf_".$statutUACF);
1755  } elseif ($userChangePassNextLogon) {
1756  $valuetoshow .= ($valuetoshow ? (' '.$langs->trans("or").' ') : '').'<span class="warning">'.$langs->trans("UserMustChangePassNextLogon", $ldap->domainFQDN).'</span>';
1757  } elseif ($userDisabled) {
1758  $valuetoshow .= ($valuetoshow ? (' '.$langs->trans("or").' ') : '').'<span class="warning">'.$langs->trans("LdapUacf_".$statutUACF, $ldap->domainFQDN).'</span>';
1759  } else {
1760  $valuetoshow .= ($valuetoshow ? (' '.$langs->trans("or").' ') : '').$langs->trans("PasswordOfUserInLDAP");
1761  }
1762  } else {
1763  $valuetoshow .= ($valuetoshow ? (' '.$langs->trans("or").' ') : '').$langs->trans("PasswordOfUserInLDAP");
1764  }
1765  }
1766  if (preg_match('/http/', $dolibarr_main_authentication)) {
1767  $valuetoshow .= ($valuetoshow ? (' '.$langs->trans("or").' ') : '').$langs->trans("HTTPBasicPassword");
1768  }
1769  if (preg_match('/dolibarr/', $dolibarr_main_authentication)) {
1770  if ($object->pass) {
1771  $valuetoshow .= ($valuetoshow ? (' '.$langs->trans("or").' ') : '');
1772  $valuetoshow .= '<span class="opacitymedium">'.$langs->trans("Hidden").'</span>';
1773  } else {
1774  if ($user->admin && $user->id == $object->id) {
1775  $valuetoshow .= ($valuetoshow ? (' '.$langs->trans("or").' ') : '');
1776  //$valuetoshow .= '<span class="opacitymedium">'.$langs->trans("Crypted").' - </span>';
1777  $valuetoshow .= '<span class="opacitymedium">'.$langs->trans("Hidden").'</span>';
1778  // TODO Add a feature to reveal the hash
1779  $valuetoshow .= '<!-- Crypted into '.$object->pass_indatabase_crypted.' -->';
1780  } else {
1781  $valuetoshow .= ($valuetoshow ? (' '.$langs->trans("or").' ') : '').'<span class="opacitymedium">'.$langs->trans("Hidden").'</span>';
1782  }
1783  }
1784  }
1785 
1786  // Other form for user password
1787  $parameters = array('valuetoshow' => $valuetoshow);
1788  $reshook = $hookmanager->executeHooks('printUserPasswordField', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1789  if ($reshook > 0) {
1790  $valuetoshow = $hookmanager->resPrint; // to replace
1791  } else {
1792  $valuetoshow .= $hookmanager->resPrint; // to add
1793  }
1794 
1795  print $valuetoshow;
1796  print "</td>";
1797  print '</tr>'."\n";
1798 
1799  // API key
1800  if (!empty($conf->api->enabled) && ($user->id == $id || $user->admin || $user->rights->api->apikey->generate)) {
1801  print '<tr><td>'.$langs->trans("ApiKey").'</td>';
1802  print '<td>';
1803  if (!empty($object->api_key)) {
1804  print '<span class="opacitymedium">';
1805  print showValueWithClipboardCPButton($object->api_key, 1, $langs->trans("Hidden")); // TODO Add an option to also reveal the hash, not only copy paste
1806  print '</span>';
1807  }
1808  print '</td></tr>';
1809  }
1810 
1811  print '<tr><td class="titlefield">'.$langs->trans("LastConnexion").'</td>';
1812  print '<td>';
1813  if ($object->datepreviouslogin) {
1814  print dol_print_date($object->datepreviouslogin, "dayhour").' <span class="opacitymedium">('.$langs->trans("Previous").')</span>, ';
1815  }
1816  if ($object->datelastlogin) {
1817  print dol_print_date($object->datelastlogin, "dayhour").' <span class="opacitymedium">('.$langs->trans("Currently").')</span>';
1818  }
1819  print '</td>';
1820  print "</tr>\n";
1821 
1822  print '</table></div>';
1823 
1824  print '</div>';
1825 
1826  print '</div>';
1827  print '<div style="clear:both"></div>';
1828 
1829 
1830  print dol_get_fiche_end();
1831 
1832 
1833  /*
1834  * Buttons actions
1835  */
1836  print '<div class="tabsAction">';
1837 
1838  $parameters = array();
1839  $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1840  if (empty($reshook)) {
1841  if (empty($user->socid)) {
1842  $canSendMail = false;
1843  $params = array(
1844  'attr' => array(
1845  'title' => '',
1846  'class' => 'classfortooltip'
1847  )
1848  );
1849  if (!empty($object->email)) {
1850  $langs->load("mails");
1851  $canSendMail = true;
1852  } else {
1853  $langs->load("mails");
1854  $params['attr']['title'] = $langs->trans('NoEMail');
1855  }
1856  print dolGetButtonAction($langs->trans('SendMail'), '', 'default', $_SERVER['PHP_SELF'] . '?id=' . $object->id . '&action=presend&mode=init#formmailbeforetitle', '', $canSendMail, $params);
1857  }
1858 
1859  if ($caneditfield && (empty($conf->multicompany->enabled) || !$user->entity || ($object->entity == $conf->entity) || ($conf->global->MULTICOMPANY_TRANSVERSE_MODE && $object->entity == 1))) {
1860  $params = array(
1861  'attr' => array(
1862  'title' => '',
1863  'class' => 'classfortooltip'
1864  )
1865  );
1866  if (!empty($conf->global->MAIN_ONLY_LOGIN_ALLOWED)) {
1867  $params['attr']['title'] = $langs->trans('DisabledInMonoUserMode');
1868  print dolGetButtonAction($langs->trans('Modify'), '', 'default', $_SERVER['PHP_SELF'].'#', '', false, $params);
1869  } else {
1870  print dolGetButtonAction($langs->trans('Modify'), '', 'default', $_SERVER['PHP_SELF'].'?id='.$object->id.'&amp;action=edit&token='.newToken(), '', true, $params);
1871  }
1872  } elseif ($caneditpassword && !$object->ldap_sid &&
1873  (empty($conf->multicompany->enabled) || !$user->entity || ($object->entity == $conf->entity) || ($conf->global->MULTICOMPANY_TRANSVERSE_MODE && $object->entity == 1))) {
1874  $params = array(
1875  'attr' => array(
1876  'title' => '',
1877  'class' => 'classfortooltip'
1878  )
1879  );
1880  print dolGetButtonAction($langs->trans('Modify'), '', 'default', $_SERVER['PHP_SELF'].'?id='.$object->id.'&amp;action=edit', '', true, $params);
1881  }
1882 
1883  // Si on a un gestionnaire de generation de mot de passe actif
1884  $params = array(
1885  'attr' => array(
1886  'title' => '',
1887  'class' => 'classfortooltip'
1888  )
1889  );
1890  if ($conf->global->USER_PASSWORD_GENERATED != 'none') {
1891  if ($object->statut == 0) {
1892  $params['attr']['title'] = $langs->trans('UserDisabled');
1893  print dolGetButtonAction($langs->trans('ReinitPassword'), '', 'default', $_SERVER['PHP_SELF'].'#', '', false, $params);
1894  } elseif (($user->id != $id && $caneditpassword) && $object->login && !$object->ldap_sid &&
1895  ((empty($conf->multicompany->enabled) && $object->entity == $user->entity) || !$user->entity || ($object->entity == $conf->entity) || ($conf->global->MULTICOMPANY_TRANSVERSE_MODE && $object->entity == 1))) {
1896  print dolGetButtonAction($langs->trans('ReinitPassword'), '', 'default', $_SERVER['PHP_SELF'].'?id='.$object->id.'&action=password&token='.newToken(), '', true, $params);
1897  }
1898 
1899  if ($object->statut == 0) {
1900  $params['attr']['title'] = $langs->trans('UserDisabled');
1901  print dolGetButtonAction($langs->trans('SendNewPassword'), '', 'default', $_SERVER['PHP_SELF'].'#', '', false, $params);
1902  } elseif (($user->id != $id && $caneditpassword) && $object->login && !$object->ldap_sid &&
1903  ((empty($conf->multicompany->enabled) && $object->entity == $user->entity) || !$user->entity || ($object->entity == $conf->entity) || ($conf->global->MULTICOMPANY_TRANSVERSE_MODE && $object->entity == 1))) {
1904  if ($object->email) {
1905  print dolGetButtonAction($langs->trans('SendNewPassword'), '', 'default', $_SERVER['PHP_SELF'].'?id='.$object->id.'&action=passwordsend&token='.newToken(), '', true, $params);
1906  } else {
1907  $params['attr']['title'] = $langs->trans('NoEMail');
1908  print dolGetButtonAction($langs->trans('SendNewPassword'), '', 'default', $_SERVER['PHP_SELF'].'#', '', false, $params);
1909  }
1910  }
1911  }
1912 
1913  // Enable user
1914  $params = array(
1915  'attr' => array(
1916  'title' => '',
1917  'class' => 'classfortooltip'
1918  )
1919  );
1920  if ($user->id <> $id && $candisableuser && $object->statut == 0 &&
1921  ((empty($conf->multicompany->enabled) && $object->entity == $user->entity) || !$user->entity || ($object->entity == $conf->entity) || ($conf->global->MULTICOMPANY_TRANSVERSE_MODE && $object->entity == 1))) {
1922  print dolGetButtonAction($langs->trans('Reactivate'), '', 'default', $_SERVER['PHP_SELF'] . '?id=' . $object->id . '&action=enable&token='.newToken(), '', true, $params);
1923  }
1924  // Disable user
1925  if ($user->id <> $id && $candisableuser && $object->statut == 1 &&
1926  ((empty($conf->multicompany->enabled) && $object->entity == $user->entity) || !$user->entity || ($object->entity == $conf->entity) || ($conf->global->MULTICOMPANY_TRANSVERSE_MODE && $object->entity == 1))) {
1927  print dolGetButtonAction($langs->trans('DisableUser'), '', 'default', $_SERVER['PHP_SELF'] . '?id=' . $object->id . '&action=disable&token='.newToken(), '', true, $params);
1928  } else {
1929  if ($user->id == $id) {
1930  $params['attr']['title'] = $langs->trans('CantDisableYourself');
1931  print dolGetButtonAction($langs->trans('DisableUser'), '', 'default', $_SERVER['PHP_SELF'].'#', '', false, $params);
1932  }
1933  }
1934  // Delete
1935  if ($user->id <> $id && $candisableuser &&
1936  ((empty($conf->multicompany->enabled) && $object->entity == $user->entity) || !$user->entity || ($object->entity == $conf->entity) || ($conf->global->MULTICOMPANY_TRANSVERSE_MODE && $object->entity == 1))) {
1937  if ($user->admin || !$object->admin) { // If user edited is admin, delete is possible on for an admin
1938  print dolGetButtonAction($langs->trans('DeleteUser'), '', 'default', $_SERVER['PHP_SELF'].'?action=delete&token='.newToken().'&id='.$object->id, '', true, $params);
1939  } else {
1940  $params['attr']['title'] = $langs->trans('MustBeAdminToDeleteOtherAdmin');
1941  print dolGetButtonAction($langs->trans('DeleteUser'), '', 'default', $_SERVER['PHP_SELF'].'?action=delete&token='.newToken().'&id='.$object->id, '', false, $params);
1942  }
1943  }
1944  }
1945 
1946  print "</div>\n";
1947 
1948 
1949 
1950  // Select mail models is same action as presend
1951  if (GETPOST('modelselected')) {
1952  $action = 'presend';
1953  }
1954 
1955  // Presend form
1956  $modelmail = 'user';
1957  $defaulttopic = 'Information';
1958  $diroutput = $conf->user->dir_output;
1959  $trackid = 'use'.$object->id;
1960 
1961  include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
1962 
1963  if ($action != 'presend' && $action != 'send') {
1964  /*
1965  * List of groups of user
1966  */
1967 
1968  if ($canreadgroup) {
1969  print '<!-- Group section -->'."\n";
1970 
1971  print load_fiche_titre($langs->trans("ListOfGroupsForUser"), '', '');
1972 
1973  // On selectionne les groupes auquel fait parti le user
1974  $exclude = array();
1975 
1976  $usergroup = new UserGroup($db);
1977  $groupslist = $usergroup->listGroupsForUser($object->id, false);
1978 
1979  if (!empty($groupslist)) {
1980  foreach ($groupslist as $groupforuser) {
1981  $exclude[] = $groupforuser->id;
1982  }
1983  }
1984 
1985  // Other form for add user to group
1986  $parameters = array('caneditgroup' => $caneditgroup, 'groupslist' => $groupslist, 'exclude' => $exclude);
1987  $reshook = $hookmanager->executeHooks('formAddUserToGroup', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1988  print $hookmanager->resPrint;
1989 
1990  if (empty($reshook)) {
1991  if ($caneditgroup) {
1992  print '<form action="'.$_SERVER['PHP_SELF'].'?id='.$id.'" method="POST">'."\n";
1993  print '<input type="hidden" name="token" value="'.newToken().'" />';
1994  print '<input type="hidden" name="action" value="addgroup" />';
1995  print '<input type="hidden" name="page_y" value="" />';
1996  }
1997 
1998  print '<table class="noborder centpercent">'."\n";
1999  print '<tr class="liste_titre"><th class="liste_titre">'.$langs->trans("Groups").'</th>'."\n";
2000  print '<th class="liste_titre right">';
2001  if ($caneditgroup) {
2002  print $form->select_dolgroups('', 'group', 1, $exclude, 0, '', '', $object->entity);
2003  print ' &nbsp; ';
2004  print '<input type="hidden" name="entity" value="'.$conf->entity.'" />';
2005  print '<input type="submit" class="button buttongen button-add reposition" value="'.$langs->trans("Add").'" />';
2006  }
2007  print '</th></tr>'."\n";
2008 
2009  // List of groups of user
2010  if (!empty($groupslist)) {
2011  foreach ($groupslist as $group) {
2012  print '<tr class="oddeven">';
2013  print '<td>';
2014  if ($caneditgroup) {
2015  print $group->getNomUrl(1);
2016  } else {
2017  print img_object($langs->trans("ShowGroup"), "group").' '.$group->name;
2018  }
2019  print '</td>';
2020  print '<td class="right">';
2021  if ($caneditgroup) {
2022  print '<a class="reposition" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=removegroup&token='.newToken().'&group='.((int) $group->id).'">';
2023  print img_picto($langs->trans("RemoveFromGroup"), 'unlink');
2024  print '</a>';
2025  } else {
2026  print "&nbsp;";
2027  }
2028  print "</td></tr>\n";
2029  }
2030  } else {
2031  print '<tr class="oddeven"><td colspan="3" class="opacitymedium">'.$langs->trans("None").'</td></tr>';
2032  }
2033 
2034  print "</table>";
2035 
2036  if ($caneditgroup) {
2037  print '</form>';
2038  }
2039  print "<br>";
2040  }
2041  }
2042  }
2043  }
2044 
2045  /*
2046  * Card in edit mode
2047  */
2048  if ($action == 'edit' && ($canedituser || $caneditfield || $caneditpassword || ($user->id == $object->id))) {
2049  print '<form action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'" method="POST" name="updateuser" enctype="multipart/form-data">';
2050  print '<input type="hidden" name="token" value="'.newToken().'">';
2051  print '<input type="hidden" name="action" value="update">';
2052  print '<input type="hidden" name="entity" value="'.$object->entity.'">';
2053 
2054  print dol_get_fiche_head($head, 'user', $title, 0, 'user');
2055 
2056  print '<table class="border centpercent">';
2057 
2058  // Ref/ID
2059  if (!empty($conf->global->MAIN_SHOW_TECHNICAL_ID)) {
2060  print '<tr><td class="titlefieldcreate">'.$langs->trans("Ref").'</td>';
2061  print '<td>';
2062  print $object->id;
2063  print '</td>';
2064  print '</tr>';
2065  }
2066 
2067  // Civility
2068  print '<tr><td class="titlefieldcreate"><label for="civility_code">'.$langs->trans("UserTitle").'</label></td><td colspan="3">';
2069  if ($caneditfield && !$object->ldap_sid) {
2070  print $formcompany->select_civility(GETPOSTISSET("civility_code") ? GETPOST("civility_code", 'aZ09') : $object->civility_code, 'civility_code');
2071  } elseif ($object->civility_code) {
2072  print $langs->trans("Civility".$object->civility_code);
2073  }
2074  print '</td></tr>';
2075 
2076  // Lastname
2077  print "<tr>";
2078  print '<td class="titlefieldcreate fieldrequired">'.$langs->trans("Lastname").'</td>';
2079  print '<td>';
2080  if ($caneditfield && !$object->ldap_sid) {
2081  print '<input class="minwidth100" type="text" class="flat" name="lastname" value="'.$object->lastname.'">';
2082  } else {
2083  print '<input type="hidden" name="lastname" value="'.$object->lastname.'">';
2084  print $object->lastname;
2085  }
2086  print '</td>';
2087  print '</tr>';
2088 
2089  // Firstname
2090  print "<tr>".'<td>'.$langs->trans("Firstname").'</td>';
2091  print '<td>';
2092  if ($caneditfield && !$object->ldap_sid) {
2093  print '<input class="minwidth100" type="text" class="flat" name="firstname" value="'.$object->firstname.'">';
2094  } else {
2095  print '<input type="hidden" name="firstname" value="'.$object->firstname.'">';
2096  print $object->firstname;
2097  }
2098  print '</td></tr>';
2099 
2100  // Login
2101  print "<tr>".'<td><span class="fieldrequired">'.$langs->trans("Login").'</span></td>';
2102  print '<td>';
2103  if ($user->admin && !$object->ldap_sid) {
2104  print '<input maxlength="50" type="text" class="flat" name="login" value="'.$object->login.'">';
2105  } else {
2106  print '<input type="hidden" name="login" value="'.$object->login.'">';
2107  print $object->login;
2108  }
2109  print '</td>';
2110  print '</tr>';
2111 
2112  // Administrator
2113  print '<tr><td>'.$langs->trans("Administrator").'</td>';
2114  if ($object->socid > 0) {
2115  $langs->load("admin");
2116  print '<td>';
2117  print '<input type="hidden" name="admin" value="'.$object->admin.'">'.yn($object->admin);
2118  print ' ('.$langs->trans("ExternalUser").')';
2119  print '</td></tr>';
2120  } else {
2121  print '<td>';
2122  $nbAdmin = $user->getNbOfUsers('active', '', 1);
2123  $nbSuperAdmin = $user->getNbOfUsers('active', 'superadmin', 1);
2124  //var_dump($nbAdmin);
2125  //var_dump($nbSuperAdmin);
2126  if ($user->admin // Need to be admin to allow downgrade of an admin
2127  && ($user->id != $object->id) // Don't downgrade ourself
2128  && (
2129  (empty($conf->multicompany->enabled) && $nbAdmin >= 1)
2130  || (!empty($conf->multicompany->enabled) && (($object->entity > 0 || ($user->entity == 0 && $object->entity == 0)) || $nbSuperAdmin > 1)) // Don't downgrade a superadmin if alone
2131  )
2132  ) {
2133  print $form->selectyesno('admin', $object->admin, 1);
2134 
2135  if (!empty($conf->multicompany->enabled) && !$user->entity) {
2136  if ($conf->use_javascript_ajax) {
2137  print '<script type="text/javascript">
2138  $(function() {
2139  var admin = $("select[name=admin]").val();
2140  if (admin == 0) {
2141  $("input[name=superadmin]")
2142  .prop("disabled", true)
2143  .prop("checked", false);
2144  }
2145  if ($("input[name=superadmin]").is(":checked")) {
2146  $("select[name=entity]")
2147  .prop("disabled", true);
2148  }
2149  $("select[name=admin]").change(function() {
2150  if ( $(this).val() == 0 ) {
2151  $("input[name=superadmin]")
2152  .prop("disabled", true)
2153  .prop("checked", false);
2154  $("select[name=entity]")
2155  .prop("disabled", false);
2156  } else {
2157  $("input[name=superadmin]")
2158  .prop("disabled", false);
2159  }
2160  });
2161  $("input[name=superadmin]").change(function() {
2162  if ( $(this).is(":checked")) {
2163  $("select[name=entity]")
2164  .prop("disabled", true);
2165  } else {
2166  $("select[name=entity]")
2167  .prop("disabled", false);
2168  }
2169  });
2170  });
2171  </script>';
2172  }
2173 
2174  $checked = (($object->admin && !$object->entity) ? ' checked' : '');
2175  print '<input type="checkbox" name="superadmin" id="superadmin" value="1"'.$checked.' /> <label for="superadmin">'.$langs->trans("SuperAdministrator").'</span>';
2176  }
2177  } else {
2178  $yn = yn($object->admin);
2179  print '<input type="hidden" name="admin" value="'.$object->admin.'">';
2180  print '<input type="hidden" name="superadmin" value="'.(empty($object->entity) ? 1 : 0).'">';
2181  if (!empty($conf->multicompany->enabled) && empty($object->entity)) {
2182  print $form->textwithpicto($yn, $langs->trans("DontDowngradeSuperAdmin"), 1, 'warning');
2183  } else {
2184  print $yn;
2185  }
2186  }
2187  print '</td></tr>';
2188  }
2189 
2190  // Gender
2191  print '<tr><td>'.$langs->trans("Gender").'</td>';
2192  print '<td>';
2193  $arraygender = array('man'=>$langs->trans("Genderman"), 'woman'=>$langs->trans("Genderwoman"), 'other'=>$langs->trans("Genderother"));
2194  if ($caneditfield) {
2195  print $form->selectarray('gender', $arraygender, GETPOSTISSET('gender') ?GETPOST('gender') : $object->gender, 1);
2196  } else {
2197  print $arraygender[$object->gender];
2198  }
2199  print '</td></tr>';
2200 
2201  // Employee
2202  print '<tr>';
2203  print '<td>'.$form->editfieldkey('Employee', 'employee', '', $object, 0).'</td><td>';
2204  if ($caneditfield) {
2205  print '<input type="checkbox" name="employee" value="1"'.($object->employee ? ' checked="checked"' : '').'>';
2206  //print $form->selectyesno("employee", $object->employee, 1);
2207  } else {
2208  print '<input type="checkbox" name="employee" disabled value="1"'.($object->employee ? ' checked="checked"' : '').'>';
2209  /*if ($object->employee) {
2210  print $langs->trans("Yes");
2211  } else {
2212  print $langs->trans("No");
2213  }*/
2214  }
2215  print '</td></tr>';
2216 
2217  // Hierarchy
2218  print '<tr><td class="titlefield">'.$langs->trans("HierarchicalResponsible").'</td>';
2219  print '<td>';
2220  if ($caneditfield) {
2221  print img_picto('', 'user').$form->select_dolusers($object->fk_user, 'fk_user', 1, array($object->id), 0, '', 0, $object->entity, 0, 0, '', 0, '', 'widthcentpercentminusx maxwidth300');
2222  } else {
2223  print '<input type="hidden" name="fk_user" value="'.$object->fk_user.'">';
2224  $huser = new User($db);
2225  $huser->fetch($object->fk_user);
2226  print $huser->getNomUrl(1);
2227  }
2228  print '</td>';
2229  print "</tr>\n";
2230 
2231  // Expense report validator
2232  if (!empty($conf->expensereport->enabled)) {
2233  print '<tr><td class="titlefield">';
2234  $text = $langs->trans("ForceUserExpenseValidator");
2235  print $form->textwithpicto($text, $langs->trans("ValidatorIsSupervisorByDefault"), 1, 'help');
2236  print '</td>';
2237  print '<td>';
2238  if ($caneditfield) {
2239  print img_picto('', 'user').$form->select_dolusers($object->fk_user_expense_validator, 'fk_user_expense_validator', 1, array($object->id), 0, '', 0, $object->entity, 0, 0, '', 0, '', 'widthcentpercentminusx maxwidth300');
2240  } else {
2241  print '<input type="hidden" name="fk_user_expense_validator" value="'.$object->fk_user_expense_validator.'">';
2242  $evuser = new User($db);
2243  $evuser->fetch($object->fk_user_expense_validator);
2244  print $evuser->getNomUrl(1);
2245  }
2246  print '</td>';
2247  print "</tr>\n";
2248  }
2249 
2250  // Holiday request validator
2251  if (!empty($conf->holiday->enabled)) {
2252  print '<tr><td class="titlefield">';
2253  $text = $langs->trans("ForceUserHolidayValidator");
2254  print $form->textwithpicto($text, $langs->trans("ValidatorIsSupervisorByDefault"), 1, 'help');
2255  print '</td>';
2256  print '<td>';
2257  if ($caneditfield) {
2258  print img_picto('', 'user').$form->select_dolusers($object->fk_user_holiday_validator, 'fk_user_holiday_validator', 1, array($object->id), 0, '', 0, $object->entity, 0, 0, '', 0, '', 'widthcentpercentminusx maxwidth300');
2259  } else {
2260  print '<input type="hidden" name="fk_user_holiday_validator" value="'.$object->fk_user_holiday_validator.'">';
2261  $hvuser = new User($db);
2262  $hvuser->fetch($object->fk_user_holiday_validator);
2263  print $hvuser->getNomUrl(1);
2264  }
2265  print '</td>';
2266  print "</tr>\n";
2267  }
2268 
2269  // External user ?
2270  print '<tr><td>'.$langs->trans("ExternalUser").' ?</td>';
2271  print '<td>';
2272  if ($user->id == $object->id || !$user->admin) {
2273  // Read mode
2274  $type = $langs->trans("Internal");
2275  if ($object->socid) {
2276  $type = $langs->trans("External");
2277  }
2278  print $form->textwithpicto($type, $langs->trans("InternalExternalDesc"));
2279  if ($object->ldap_sid) {
2280  print ' ('.$langs->trans("DomainUser").')';
2281  }
2282  } else {
2283  // Select mode
2284  $type = 0;
2285  if ($object->contact_id) {
2286  $type = $object->contact_id;
2287  }
2288 
2289  if ($object->socid > 0 && !($object->contact_id > 0)) { // external user but no link to a contact
2290  print img_picto('', 'company').$form->select_company($object->socid, 'socid', '', '&nbsp;');
2291  print img_picto('', 'contact').$form->selectcontacts(0, 0, 'contactid', 1, '', '', 1, '', false, 1);
2292  if ($object->ldap_sid) {
2293  print ' ('.$langs->trans("DomainUser").')';
2294  }
2295  } elseif ($object->socid > 0 && $object->contact_id > 0) { // external user with a link to a contact
2296  print img_picto('', 'company').$form->select_company($object->socid, 'socid', '', '&nbsp;'); // We keep thirdparty empty, contact is already set
2297  print img_picto('', 'contact').$form->selectcontacts(0, $object->contact_id, 'contactid', 1, '', '', 1, '', false, 1);
2298  if ($object->ldap_sid) {
2299  print ' ('.$langs->trans("DomainUser").')';
2300  }
2301  } elseif (!($object->socid > 0) && $object->contact_id > 0) { // internal user with a link to a contact
2302  print img_picto('', 'company').$form->select_company(0, 'socid', '', '&nbsp;'); // We keep thirdparty empty, contact is already set
2303  print img_picto('', 'contact').$form->selectcontacts(0, $object->contact_id, 'contactid', 1, '', '', 1, '', false, 1);
2304  if ($object->ldap_sid) {
2305  print ' ('.$langs->trans("DomainUser").')';
2306  }
2307  } else { // $object->socid is not > 0 here
2308  print img_picto('', 'company').$form->select_company(0, 'socid', '', '&nbsp;'); // We keep thirdparty empty, contact is already set
2309  print img_picto('', 'contact').$form->selectcontacts(0, 0, 'contactid', 1, '', '', 1, '', false, 1);
2310  }
2311  }
2312  print '</td></tr>';
2313 
2314 
2315  print '</table><hr><table class="border centpercent">';
2316 
2317 
2318  // Date access validity
2319  print '<tr><td>'.$langs->trans("RangeOfLoginValidity").'</td>';
2320  print '<td>';
2321  if ($caneditfield) {
2322  print $form->selectDate($datestartvalidity ? $datestartvalidity : $object->datestartvalidity, 'datestartvalidity', 0, 0, 1, 'formdatestartvalidity', 1, 1, 0, '', '', '', '', 1, '', '');
2323  } else {
2324  print dol_print_date($object->datestartvalidity, 'day');
2325  }
2326 
2327  /*if ($datestartvalidity && $dateendvalidity) {
2328  print ' - ';
2329  }*/
2330  print ' &nbsp; ';
2331 
2332  if ($caneditfield) {
2333  print $form->selectDate($dateendvalidity ? $datendevalidity : $object->dateendvalidity, 'dateendvalidity', 0, 0, 1, 'formdateendvalidity', 1, 0, 0, '', '', '', '', 1, '', '');
2334  } else {
2335  print dol_print_date($object->dateendvalidity, 'day');
2336  }
2337  print '</td>';
2338  print "</tr>\n";
2339 
2340  // Pass
2341  print '<tr><td class="titlefieldcreate">'.$langs->trans("Password").'</td>';
2342  print '<td>';
2343  $valuetoshow = '';
2344  if (preg_match('/ldap/', $dolibarr_main_authentication)) {
2345  $valuetoshow .= ($valuetoshow ? (' '.$langs->trans("or").' ') : '').$langs->trans("PasswordOfUserInLDAP");
2346  }
2347  if (preg_match('/http/', $dolibarr_main_authentication)) {
2348  $valuetoshow .= ($valuetoshow ? (' '.$langs->trans("or").' ') : '').$form->textwithpicto($text, $langs->trans("DolibarrInHttpAuthenticationSoPasswordUseless", $dolibarr_main_authentication), 1, 'warning');
2349  }
2350  if (preg_match('/dolibarr/', $dolibarr_main_authentication)) {
2351  if ($caneditpassword) {
2352  $valuetoshow .= ($valuetoshow ? (' '.$langs->trans("or").' ') : '').'<input maxlength="128" type="password" class="flat" name="password" value="'.dol_escape_htmltag($object->pass).'" autocomplete="new-password">';
2353  } else {
2354  $valuetoshow .= ($valuetoshow ? (' '.$langs->trans("or").' ') : '').preg_replace('/./i', '*', $object->pass);
2355  }
2356  }
2357 
2358  // Other form for user password
2359  $parameters = array('valuetoshow' => $valuetoshow, 'caneditpassword' => $caneditpassword);
2360  $reshook = $hookmanager->executeHooks('printUserPasswordField', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2361  if ($reshook > 0) {
2362  $valuetoshow = $hookmanager->resPrint; // to replace
2363  } else {
2364  $valuetoshow .= $hookmanager->resPrint; // to add
2365  }
2366 
2367  print $valuetoshow;
2368  print "</td></tr>\n";
2369 
2370  // API key
2371  if (!empty($conf->api->enabled) && ($user->id == $id || $user->admin || $user->rights->api->apikey->generate)) {
2372  print '<tr><td>'.$langs->trans("ApiKey").'</td>';
2373  print '<td>';
2374  print '<input class="minwidth300" maxsize="32" type="text" id="api_key" name="api_key" value="'.$object->api_key.'" autocomplete="off">';
2375  if (!empty($conf->use_javascript_ajax)) {
2376  print '&nbsp;'.img_picto($langs->trans('Generate'), 'refresh', 'id="generate_api_key" class="linkobject"');
2377  }
2378  print '</td></tr>';
2379  }
2380 
2381  // OpenID url
2382  if (isset($conf->file->main_authentication) && preg_match('/openid/', $conf->file->main_authentication) && !empty($conf->global->MAIN_OPENIDURL_PERUSER)) {
2383  print "<tr>".'<td>'.$langs->trans("OpenIDURL").'</td>';
2384  print '<td>';
2385  if ($caneditfield) {
2386  print '<input class="minwidth100" type="url" name="openid" class="flat" value="'.$object->openid.'">';
2387  } else {
2388  print '<input type="hidden" name="openid" value="'.$object->openid.'">';
2389  print $object->openid;
2390  }
2391  print '</td></tr>';
2392  }
2393 
2394  print '</table><hr><table class="border centpercent">';
2395 
2396 
2397  // Address
2398  print '<tr><td class="tdtop titlefieldcreate">'.$form->editfieldkey('Address', 'address', '', $object, 0).'</td>';
2399  print '<td>';
2400  if ($caneditfield) {
2401  print '<textarea name="address" id="address" class="quatrevingtpercent" rows="3" wrap="soft">';
2402  }
2403  print $object->address;
2404  if ($caneditfield) {
2405  print '</textarea>';
2406  }
2407  print '</td></tr>';
2408 
2409  // Zip
2410  print '<tr><td>'.$form->editfieldkey('Zip', 'zipcode', '', $object, 0).'</td><td>';
2411  if ($caneditfield) {
2412  print $formcompany->select_ziptown($object->zip, 'zipcode', array('town', 'selectcountry_id', 'state_id'), 6);
2413  } else {
2414  print $object->zip;
2415  }
2416  print '</td></tr>';
2417 
2418  // Town
2419  print '<tr><td>'.$form->editfieldkey('Town', 'town', '', $object, 0).'</td><td>';
2420  if ($caneditfield) {
2421  print $formcompany->select_ziptown($object->town, 'town', array('zipcode', 'selectcountry_id', 'state_id'));
2422  } else {
2423  print $object->town;
2424  }
2425  print '</td></tr>';
2426 
2427  // Country
2428  print '<tr><td>'.$form->editfieldkey('Country', 'selectcounty_id', '', $object, 0).'</td><td>';
2429  if ($caneditfield) {
2430  print $form->select_country((GETPOST('country_id') != '' ?GETPOST('country_id') : $object->country_id), 'country_id');
2431  if ($user->admin) {
2432  print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
2433  }
2434  } else {
2435  $countrylabel = getCountry($object->country_id, '0');
2436  print $countrylabel;
2437  }
2438  print '</td></tr>';
2439 
2440  // State
2441  if (empty($conf->global->USER_DISABLE_STATE)) {
2442  print '<tr><td class="tdoverflow">'.$form->editfieldkey('State', 'state_id', '', $object, 0).'</td><td>';
2443  if ($caneditfield) {
2444  print img_picto('', 'state', 'class="pictofixedwidth"');
2445  print $formcompany->select_state($object->state_id, $object->country_code, 'state_id');
2446  } else {
2447  print $object->state_label;
2448  }
2449  print '</td></tr>';
2450  }
2451 
2452  // Tel pro
2453  print "<tr>".'<td>'.$langs->trans("PhonePro").'</td>';
2454  print '<td>';
2455  print img_picto('', 'phoning', 'class="pictofixedwidth"');
2456  if ($caneditfield && empty($object->ldap_sid)) {
2457  print '<input type="text" name="office_phone" class="flat maxwidth200" value="'.$object->office_phone.'">';
2458  } else {
2459  print '<input type="hidden" name="office_phone" value="'.$object->office_phone.'">';
2460  print $object->office_phone;
2461  }
2462  print '</td></tr>';
2463 
2464  // Tel mobile
2465  print "<tr>".'<td>'.$langs->trans("PhoneMobile").'</td>';
2466  print '<td>';
2467  print img_picto('', 'phoning_mobile', 'class="pictofixedwidth"');
2468  if ($caneditfield && empty($object->ldap_sid)) {
2469  print '<input type="text" name="user_mobile" class="flat maxwidth200" value="'.$object->user_mobile.'">';
2470  } else {
2471  print '<input type="hidden" name="user_mobile" value="'.$object->user_mobile.'">';
2472  print $object->user_mobile;
2473  }
2474  print '</td></tr>';
2475 
2476  // Fax
2477  print "<tr>".'<td>'.$langs->trans("Fax").'</td>';
2478  print '<td>';
2479  print img_picto('', 'phoning_fax', 'class="pictofixedwidth"');
2480  if ($caneditfield && empty($object->ldap_sid)) {
2481  print '<input type="text" name="office_fax" class="flat maxwidth200" value="'.$object->office_fax.'">';
2482  } else {
2483  print '<input type="hidden" name="office_fax" value="'.$object->office_fax.'">';
2484  print $object->office_fax;
2485  }
2486  print '</td></tr>';
2487 
2488  // EMail
2489  print "<tr>".'<td'.(!empty($conf->global->USER_MAIL_REQUIRED) ? ' class="fieldrequired"' : '').'>'.$langs->trans("EMail").'</td>';
2490  print '<td>';
2491  print img_picto('', 'object_email', 'class="pictofixedwidth"');
2492  if ($caneditfield && empty($object->ldap_sid)) {
2493  print '<input class="minwidth100 maxwidth500 widthcentpercentminusx" type="text" name="email" class="flat" value="'.$object->email.'">';
2494  } else {
2495  print '<input type="hidden" name="email" value="'.$object->email.'">';
2496  print $object->email;
2497  }
2498  print '</td></tr>';
2499 
2500  if (!empty($conf->socialnetworks->enabled)) {
2501  foreach ($socialnetworks as $key => $value) {
2502  if ($value['active']) {
2503  print '<tr><td>'.$langs->trans($value['label']).'</td>';
2504  print '<td>';
2505  if (!empty($value['icon'])) {
2506  print '<span class="fa '.$value['icon'].' pictofixedwidth"></span>';
2507  }
2508  if ($caneditfield && empty($object->ldap_sid)) {
2509  print '<input type="text" name="'.$key.'" class="flat maxwidth200" value="'.(isset($object->socialnetworks[$key])?$object->socialnetworks[$key]:'').'">';
2510  } else {
2511  print '<input type="hidden" name="'.$key.'" value="'.$object->socialnetworks[$key].'">';
2512  print $object->socialnetworks[$key];
2513  }
2514  print '</td></tr>';
2515  } else {
2516  // if social network is not active but value exist we do not want to loose it
2517  print '<input type="hidden" name="'.$key.'" value="'.(isset($object->socialnetworks[$key])?$object->socialnetworks[$key]:'').'">';
2518  }
2519  }
2520  }
2521 
2522  print '</table><hr><table class="border centpercent">';
2523 
2524  // Default warehouse
2525  if (!empty($conf->stock->enabled) && !empty($conf->global->MAIN_DEFAULT_WAREHOUSE_USER)) {
2526  print '<tr><td class="titlefield">'.$langs->trans("DefaultWarehouse").'</td><td>';
2527  print $formproduct->selectWarehouses($object->fk_warehouse, 'fk_warehouse', 'warehouseopen', 1);
2528  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>';
2529  print '</td></tr>';
2530  }
2531 
2532  // Accountancy code
2533  if (!empty($conf->accounting->enabled)) {
2534  print "<tr>";
2535  print '<td class="titlefieldcreate">'.$langs->trans("AccountancyCode").'</td>';
2536  print '<td>';
2537  if ($caneditfield) {
2538  print '<input type="text" class="flat maxwidth300" name="accountancy_code" value="'.$object->accountancy_code.'">';
2539  } else {
2540  print '<input type="hidden" name="accountancy_code" value="'.$object->accountancy_code.'">';
2541  print $object->accountancy_code;
2542  }
2543  print '</td>';
2544  print "</tr>";
2545  }
2546 
2547  // User color
2548  if (isModEnabled('agenda')) {
2549  print '<tr><td class="titlefieldcreate">'.$langs->trans("ColorUser").'</td>';
2550  print '<td>';
2551  if ($caneditfield) {
2552  print $formother->selectColor(GETPOSTISSET('color') ?GETPOST('color', 'alphanohtml') : $object->color, 'color', null, 1, '', 'hideifnotset');
2553  } else {
2554  print $formother->showColor($object->color, '');
2555  }
2556  print '</td></tr>';
2557  }
2558 
2559  // Photo
2560  print '<tr>';
2561  print '<td class="titlefieldcreate">'.$langs->trans("Photo").'</td>';
2562  print '<td>';
2563  print $form->showphoto('userphoto', $object, 60, 0, $caneditfield, 'photowithmargin', 'small', 1, 0, 'user', 1);
2564  print '</td>';
2565  print '</tr>';
2566 
2567  // Categories
2568  if (!empty($conf->categorie->enabled) && !empty($user->rights->categorie->lire)) {
2569  print '<tr><td>'.$form->editfieldkey('Categories', 'usercats', '', $object, 0).'</td>';
2570  print '<td>';
2571  print img_picto('', 'category', 'class="pictofixedwidth"');
2572  $cate_arbo = $form->select_all_categories(Categorie::TYPE_USER, null, null, null, null, 1);
2573  $c = new Categorie($db);
2574  $cats = $c->containing($object->id, Categorie::TYPE_USER);
2575  foreach ($cats as $cat) {
2576  $arrayselected[] = $cat->id;
2577  }
2578  if ($caneditfield) {
2579  print $form->multiselectarray('usercats', $cate_arbo, $arrayselected, '', 0, '', 0, '90%');
2580  } else {
2581  print $form->showCategories($object->id, Categorie::TYPE_USER, 1);
2582  }
2583  print "</td></tr>";
2584  }
2585 
2586  // Default language
2587  if (!empty($conf->global->MAIN_MULTILANGS)) {
2588  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";
2589  print img_picto('', 'language', 'class="pictofixedwidth"').$formadmin->select_language($object->lang, 'default_lang', 0, null, '1', 0, 0, 'widthcentpercentminusx maxwidth300');
2590  print '</td>';
2591  print '</tr>';
2592  }
2593 
2594  // Status
2595  print '<tr><td>'.$langs->trans("Status").'</td>';
2596  print '<td>';
2597  print $object->getLibStatut(4);
2598  print '</td></tr>';
2599 
2600  // Company / Contact
2601  if (!empty($conf->societe->enabled)) {
2602  print '<tr><td>'.$langs->trans("LinkToCompanyContact").'</td>';
2603  print '<td>';
2604  if ($object->socid > 0) {
2605  $societe = new Societe($db);
2606  $societe->fetch($object->socid);
2607  print $societe->getNomUrl(1, '');
2608  if ($object->contact_id) {
2609  $contact = new Contact($db);
2610  $contact->fetch($object->contact_id);
2611  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>';
2612  }
2613  } else {
2614  print '<span class="opacitymedium hideonsmartphone">'.$langs->trans("ThisUserIsNot").'</span>';
2615  }
2616  print ' <span class="opacitymedium hideonsmartphone">('.$langs->trans("UseTypeFieldToChange").')</span>';
2617  print '</td>';
2618  print "</tr>\n";
2619  }
2620 
2621  // Module Adherent
2622  if (!empty($conf->adherent->enabled)) {
2623  $langs->load("members");
2624  print '<tr><td>'.$langs->trans("LinkedToDolibarrMember").'</td>';
2625  print '<td>';
2626  if ($object->fk_member) {
2627  $adh = new Adherent($db);
2628  $adh->fetch($object->fk_member);
2629  $adh->ref = $adh->login; // Force to show login instead of id
2630  print $adh->getNomUrl(1);
2631  } else {
2632  print '<span class="opacitymedium hideonsmartphone">'.$langs->trans("UserNotLinkedToMember").'</span>';
2633  }
2634  print '</td>';
2635  print "</tr>\n";
2636  }
2637 
2638  // Multicompany
2639  // TODO check if user not linked with the current entity before change entity (thirdparty, invoice, etc.) !!
2640  if (!empty($conf->multicompany->enabled) && is_object($mc)) {
2641  // This is now done with hook formObjectOptions. Keep this code for backward compatibility with old multicompany module
2642  if (!method_exists($mc, 'formObjectOptions')) {
2643  if (empty($conf->multicompany->transverse_mode) && $conf->entity == 1 && $user->admin && !$user->entity) {
2644  print "<tr>".'<td>'.$langs->trans("Entity").'</td>';
2645  print "<td>".$mc->select_entities($object->entity, 'entity', '', 0, 1, false, false, 1); // last parameter 1 means, show also a choice 0=>'all entities'
2646  print "</td></tr>\n";
2647  } else {
2648  print '<input type="hidden" name="entity" value="'.$conf->entity.'" />';
2649  }
2650  }
2651  }
2652 
2653  // Other attributes
2654  $parameters = array('colspan' => ' colspan="2"');
2655  //include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_edit.tpl.php'; // We do not use common tpl here because we need a special test on $caneditfield
2656  $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2657  print $hookmanager->resPrint;
2658  if (empty($reshook)) {
2659  if ($caneditfield) {
2660  print $object->showOptionals($extrafields, 'edit');
2661  } else {
2662  print $object->showOptionals($extrafields, 'view');
2663  }
2664  }
2665 
2666  // Signature
2667  print '<tr><td class="tdtop">'.$langs->trans("Signature").'</td>';
2668  print '<td>';
2669  if ($caneditfield) {
2670  require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
2671  $doleditor = new DolEditor('signature', $object->signature, '', 138, 'dolibarr_notes', 'In', false, true, empty($conf->global->FCKEDITOR_ENABLE_USERSIGN) ? 0 : 1, ROWS_4, '90%');
2672  print $doleditor->Create(1);
2673  } else {
2674  print dol_htmlentitiesbr($object->signature);
2675  }
2676  print '</td></tr>';
2677 
2678 
2679  print '</table>';
2680 
2681  print '<hr>';
2682 
2683 
2684  print '<table class="border centpercent">';
2685 
2686 
2687  // TODO Move this into tab RH (HierarchicalResponsible must be on both tab)
2688 
2689  // Position/Job
2690  print '<tr><td class="titlefieldcreate">'.$langs->trans("PostOrFunction").'</td>';
2691  print '<td>';
2692  if ($caneditfield) {
2693  print '<input type="text" class="minwidth300 maxwidth500" name="job" value="'.dol_escape_htmltag($object->job).'">';
2694  } else {
2695  print '<input type="hidden" name="job" value="'.dol_escape_htmltag($object->job).'">';
2696  print dol_escape_htmltag($object->job);
2697  }
2698  print '</td></tr>';
2699 
2700  // Weeklyhours
2701  print '<tr><td>'.$langs->trans("WeeklyHours").'</td>';
2702  print '<td>';
2703  if ($caneditfield) {
2704  print '<input size="8" type="text" name="weeklyhours" value="'.price2num(GETPOST('weeklyhours') ?GETPOST('weeklyhours') : $object->weeklyhours).'">';
2705  } else {
2706  print price2num($object->weeklyhours);
2707  }
2708  print '</td>';
2709  print "</tr>\n";
2710 
2711  // Sensitive salary/value information
2712  if ((empty($user->socid) && in_array($id, $childids)) // A user can always see salary/value information for its subordinates
2713  || (!empty($conf->salaries->enabled) && !empty($user->rights->salaries->readall))
2714  || (!empty($conf->hrm->enabled) && !empty($user->rights->hrm->employee->read))) {
2715  $langs->load("salaries");
2716 
2717  // Salary
2718  print '<tr><td>'.$langs->trans("Salary").'</td>';
2719  print '<td>';
2720  print img_picto('', 'salary', 'class="pictofixedwidth paddingright"').'<input size="8" type="text" name="salary" value="'.price2num(GETPOST('salary') ?GETPOST('salary') : $object->salary).'">';
2721  print '</td>';
2722  print "</tr>\n";
2723 
2724  // THM
2725  print '<tr><td>';
2726  $text = $langs->trans("THM");
2727  print $form->textwithpicto($text, $langs->trans("THMDescription"), 1, 'help', 'classthm');
2728  print '</td>';
2729  print '<td>';
2730  if ($caneditfield) {
2731  print '<input size="8" type="text" name="thm" value="'.price2num(GETPOST('thm') ?GETPOST('thm') : $object->thm).'">';
2732  } else {
2733  print ($object->thm != '' ?price($object->thm, '', $langs, 1, -1, -1, $conf->currency) : '');
2734  }
2735  print '</td>';
2736  print "</tr>\n";
2737 
2738  // TJM
2739  print '<tr><td>';
2740  $text = $langs->trans("TJM");
2741  print $form->textwithpicto($text, $langs->trans("TJMDescription"), 1, 'help', 'classthm');
2742  print '</td>';
2743  print '<td>';
2744  if ($caneditfield) {
2745  print '<input size="8" type="text" name="tjm" value="'.price2num(GETPOST('tjm') ?GETPOST('tjm') : $object->tjm).'">';
2746  } else {
2747  print ($object->tjm != '' ?price($object->tjm, '', $langs, 1, -1, -1, $conf->currency) : '');
2748  }
2749  print '</td>';
2750  print "</tr>\n";
2751  }
2752 
2753  // Date employment
2754  print '<tr><td>'.$langs->trans("DateEmployment").'</td>';
2755  print '<td>';
2756  if ($caneditfield) {
2757  print $form->selectDate($dateemployment ? $dateemployment : $object->dateemployment, 'dateemployment', 0, 0, 1, 'formdateemployment', 1, 1);
2758  } else {
2759  print dol_print_date($object->dateemployment, 'day');
2760  }
2761 
2762  if ($dateemployment && $dateemploymentend) {
2763  print ' - ';
2764  }
2765 
2766  if ($caneditfield) {
2767  print $form->selectDate($dateemploymentend ? $dateemploymentend : $object->dateemploymentend, 'dateemploymentend', 0, 0, 1, 'formdateemploymentend', 1, 0);
2768  } else {
2769  print dol_print_date($object->dateemploymentend, 'day');
2770  }
2771  print '</td>';
2772  print "</tr>\n";
2773 
2774  // Date birth
2775  print '<tr><td>'.$langs->trans("DateOfBirth").'</td>';
2776  print '<td>';
2777  if ($caneditfield) {
2778  echo $form->selectDate($dateofbirth ? $dateofbirth : $object->birth, 'dateofbirth', 0, 0, 1, 'updateuser', 1, 0, 0, '', '', '', '', 1, '', '', 'tzserver');
2779  } else {
2780  print dol_print_date($object->birth, 'day', 'tzserver');
2781  }
2782  print '</td>';
2783  print "</tr>\n";
2784 
2785  print '</table>';
2786 
2787  print dol_get_fiche_end();
2788 
2789  print '<div class="center">';
2790  print '<input value="'.$langs->trans("Save").'" class="button button-save" type="submit" name="save">';
2791  print '&nbsp; &nbsp; &nbsp;';
2792  print '<input value="'.$langs->trans("Cancel").'" class="button button-cancel" type="submit" name="cancel">';
2793  print '</div>';
2794 
2795  print '</form>';
2796  }
2797 
2798  if ($action != 'edit' && $action != 'presend') {
2799  print '<div class="fichecenter"><div class="fichehalfleft">';
2800 
2801  // Generated documents
2802  $filename = dol_sanitizeFileName($object->ref);
2803  $filedir = $conf->user->dir_output."/".dol_sanitizeFileName($object->ref);
2804  $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id;
2805  $genallowed = $user->rights->user->user->lire;
2806  $delallowed = $user->rights->user->user->creer;
2807 
2808  print $formfile->showdocuments('user', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', 0, '', empty($soc->default_lang) ? '' : $soc->default_lang);
2809  $somethingshown = $formfile->numoffiles;
2810 
2811  // Show links to link elements
2812  $linktoelem = $form->showLinkToObjectBlock($object, null, null);
2813  $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
2814 
2815  print '</div><div class="fichehalfright">';
2816 
2817  // List of actions on element
2818  include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
2819  $formactions = new FormActions($db);
2820  $somethingshown = $formactions->showactions($object, 'user', $socid, 1);
2821 
2822  print '</div></div>';
2823  }
2824 
2825  if (!empty($conf->ldap->enabled) && !empty($object->ldap_sid)) {
2826  $ldap->unbind();
2827  }
2828  }
2829 }
2830 
2831 if (!empty($conf->api->enabled) && !empty($conf->use_javascript_ajax)) {
2832  print "\n".'<script type="text/javascript">';
2833  print '$(document).ready(function () {
2834  $("#generate_api_key").click(function() {
2835  $.get( "'.DOL_URL_ROOT.'/core/ajax/security.php", {
2836  action: \'getrandompassword\',
2837  generic: true
2838  },
2839  function(token) {
2840  $("#api_key").val(token);
2841  });
2842  });
2843  });';
2844  print '</script>';
2845 }
2846 
2847 // End of page
2848 llxFooter();
2849 $db->close();
GETPOST($paramname, $check= 'alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
getDolGlobalInt($key, $default=0)
Return dolibarr global constant int value.
if(preg_match('/set_([a-z0-9_\-]+)/i', $action, $reg)) if(preg_match('/del_([a-z0-9_\-]+)/i', $action, $reg)) if($action== 'set') elseif($action== 'specimen') elseif($action== 'setmodel') elseif($action== 'del') elseif($action== 'setdoc') $formactions
View.
showValueWithClipboardCPButton($valuetocopy, $showonlyonhover=1, $texttoshow= '')
Create a button to copy $valuetocopy in the clipboard (for copy and paste feature).
yn($yesno, $case=1, $color=0)
Return yes or no in current language.
if($cancel &&!$id) if($action== 'add'&&!$cancel) if($action== 'delete') if($id) $form
Actions.
Definition: card.php:142
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm= 'auto', $check=1)
Return a timestamp date built from detailed informations (by default a local PHP server timestamp) Re...
Class to manage building of HTML components.
dol_mkdir($dir, $dataroot= '', $newmask= '')
Creation of a directory (this can create recursive subdir)
Class to manage contact/addresses.
getArrayOfSocialNetworks()
Get array of social network dictionary.
Class to manage Dolibarr users.
Definition: user.class.php:44
if(!function_exists('utf8_encode')) if(!function_exists('utf8_decode')) getDolGlobalString($key, $default= '')
Return dolibarr global constant string value.
if(!defined('NOREQUIRESOC')) if(!defined('NOREQUIRETRAN')) if(!defined('NOCSRFCHECK')) if(!defined('NOTOKENRENEWAL')) if(!defined('NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined('NOREQUIREAJAX')) llxHeader()
Empty header.
Definition: wrapper.php:59
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...
dolGetButtonAction($label, $html= '', $actionType= 'default', $url= '', $id= '', $userRight=1, $params=array())
Function dolGetButtonAction.
Class to manage user groups.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags= '', $escapeonlyhtmltags=0)
Returns text escaped for inclusion in HTML alt or title tags, or into values of HTML input fields...
image_format_supported($file, $acceptsvg=0)
Return if a filename is file name of a supported image format.
Definition: images.lib.php:58
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...
Class to generate html code for admin pages.
Class with static methods for building HTML components related to products Only components common to ...
Class to build HTML component for third parties management Only common components are here...
Class to manage standard extra fields.
setEventMessages($mesg, $mesgs, $style= 'mesgs', $messagekey= '')
Set event messages in dol_events session object.
Class to manage generation of HTML components Only common components must be here.
user_prepare_head(User $object)
Prepare array with list of tabs.
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form...
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage categories.
info_admin($text, $infoonimgalt=0, $nodiv=0, $admin= '1', $morecss= 'hideonsmartphone', $textfordropdown= '')
Show information for admin users or standard users.
load_fiche_titre($titre, $morehtmlright= '', $picto= 'generic', $pictoisfullpath=0, $id= '', $morecssontable= '', $morehtmlcenter= '')
Load a title with picto.
price2num($amount, $rounding= '', $option=0)
Function that return a number with universal decimal format (decimal separator is &#39;...
dol_delete_dir_recursive($dir, $count=0, $nophperrors=0, $onlysub=0, &$countdeleted=0, $indexdatabase=1, $nolog=0)
Remove a directory $dir and its subdirectories (or only files and subdirectories) ...
Definition: files.lib.php:1382
img_picto($titlealt, $picto, $moreatt= '', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt= '', $morecss= '', $marginleftonlyshort=2)
Show picto whatever it&#39;s its name (generic function)
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename= '', $restricttologhandler= '', $logcontext=null)
Write log message into outputs.
Classe permettant la generation de composants html autre Only common components are here...
get_exdir($num, $level, $alpha, $withoutslash, $object, $modulepart= '')
Return a path to have a the directory according to object where files are stored. ...
Class to manage members of a foundation.
GETPOSTINT($paramname, $method=0)
Return value of a param into GET or POST supervariable.
img_object($titlealt, $picto, $moreatt= '', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
getRandomPassword($generic=false, $replaceambiguouschars=null, $length=32)
Return a generated password using default module.
accessforbidden($message= '', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program Calling this function terminate execution ...
dol_sanitizeFileName($str, $newstr= '_', $unaccent=1)
Clean a string to use it as a file name.
const SYNCHRO_LDAP_TO_DOLIBARR
Ldap to Dolibarr synchronization.
Definition: ldap.class.php:138
Class to offer components to list and upload files.
dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disablevirusscan=0, $uploaderrorcode=0, $nohook=0, $varfiles= 'addedfile', $upload_dir= '')
Make control on an uploaded file from an GUI page and move it to final destination.
Definition: files.lib.php:1091
ajax_combobox($htmlname, $events=array(), $minLengthToAutocomplete=0, $forcefocus=0, $widthTypeOfAutocomplete= 'resolve', $idforemptyvalue= '-1')
Convert a html select field into an ajax combobox.
Definition: ajax.lib.php:429
restrictedArea($user, $features, $objectid=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.
if(isModEnabled('facture')&&!empty($user->rights->facture->lire)) if((isModEnabled('fournisseur')&&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)&&$user->rights->fournisseur->facture->lire)||(isModEnabled('supplier_invoice')&&$user->rights->supplier_invoice->lire)) if(isModEnabled('don')&&!empty($user->rights->don->lire)) if(isModEnabled('tax')&&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture')&&isModEnabled('commande')&&$user->rights->commande->lire &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $resql
Social contributions to pay.
Definition: index.php:742
dol_get_fiche_head($links=array(), $active= '', $title= '', $notab=0, $picto= '', $pictoisfullpath=0, $morehtmlright= '', $morecss= '', $limittoshow=0, $moretabssuffix= '')
Show tabs of a record.
Class to manage LDAP features.
Definition: ldap.class.php:34
dol_print_date($time, $format= '', $tzoutput= 'auto', $outputlangs= '', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
dol_print_error($db= '', $error= '', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
newToken()
Return the value of token currently saved into session with name &#39;newtoken&#39;.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
isModEnabled($module)
Is Dolibarr module enabled.
Class to manage a WYSIWYG editor.
dol_trunc($string, $size=40, $trunc= 'right', $stringencoding= 'UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding &#39;…&#39; if string larger than length. ...
dol_banner_tab($object, $paramid, $morehtml= '', $shownav=1, $fieldid= 'rowid', $fieldref= 'ref', $morehtmlref= '', $moreparam= '', $nodbprefix=0, $morehtmlleft= '', $morehtmlstatus= '', $onlybanner=0, $morehtmlright= '')
Show tab footer of a card.
llxFooter()
Empty footer.
Definition: wrapper.php:73
dol_set_focus($selector)
Set focus onto field with selector (similar behaviour of &#39;autofocus&#39; HTML5 tag)
getCountry($searchkey, $withcode= '', $dbtouse=0, $outputlangs= '', $entconv=1, $searchlabel= '')
Return country label, code or id from an id, code or label.
dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $object=null, $allowdotdot=false, $indexdatabase=1, $nolog=0)
Remove a file or several files with a mask.
Definition: files.lib.php:1230
Class to manage warehouses.