dolibarr  16.0.1
list.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2002-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3  * Copyright (C) 2004-2021 Laurent Destailleur <eldy@users.sourceforge.net>
4  * Copyright (C) 2005-2017 Regis Houssin <regis.houssin@inodbox.com>
5  * Copyright (C) 2015 Alexandre Spangaro <aspangaro@open-dsi.fr>
6  * Copyright (C) 2016 Marcos GarcĂ­a <marcosgdf@gmail.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <https://www.gnu.org/licenses/>.
20  */
21 
28 require '../main.inc.php';
29 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
30 if (!empty($conf->categorie->enabled)) {
31  require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
32 }
33 
34 // Load translation files required by page
35 $langs->loadLangs(array('users', 'companies', 'hrm', 'salaries'));
36 
37 $action = GETPOST('action', 'aZ09') ?GETPOST('action', 'aZ09') : 'view'; // The action 'add', 'create', 'edit', 'update', 'view', ...
38 $massaction = GETPOST('massaction', 'alpha'); // The bulk action (combo box choice into lists)
39 $show_files = GETPOST('show_files', 'int'); // Show files area generated by bulk actions ?
40 $confirm = GETPOST('confirm', 'alpha'); // Result of a confirmation
41 $cancel = GETPOST('cancel', 'alpha'); // We click on a Cancel button
42 $toselect = GETPOST('toselect', 'array'); // Array of ids of elements selected into a list
43 $contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'userlist'; // To manage different context of search
44 $backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page
45 $optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print')
46 
47 // Security check (for external users)
48 $socid = 0;
49 if ($user->socid > 0) {
50  $socid = $user->socid;
51 }
52 
53 // Load mode employee
54 $mode = GETPOST("mode", 'alpha');
55 
56 // Load variable for pagination
57 $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
58 $sortfield = GETPOST('sortfield', 'aZ09comma');
59 $sortorder = GETPOST('sortorder', 'aZ09comma');
60 $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
61 if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha')) {
62  // If $page is not defined, or '' or -1 or if we click on clear filters
63  $page = 0;
64 }
65 $offset = $limit * $page;
66 $pageprev = $page - 1;
67 $pagenext = $page + 1;
68 
69 // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
70 $object = new User($db);
71 $extrafields = new ExtraFields($db);
72 $diroutputmassaction = $conf->user->dir_output.'/temp/massgeneration/'.$user->id;
73 $hookmanager->initHooks(array('userlist'));
74 
75 // Fetch optionals attributes and labels
76 $extrafields->fetch_name_optionals_label($object->table_element);
77 
78 $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
79 
80 if (!$sortfield) {
81  $sortfield = "u.login";
82 }
83 if (!$sortorder) {
84  $sortorder = "ASC";
85 }
86 
87 // Initialize array of search criterias
88 $search_all = GETPOST('search_all', 'alphanohtml') ? GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml');
89 $search = array();
90 foreach ($object->fields as $key => $val) {
91  if (GETPOST('search_'.$key, 'alpha') !== '') {
92  $search[$key] = GETPOST('search_'.$key, 'alpha');
93  }
94  if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
95  $search[$key.'_dtstart'] = dol_mktime(0, 0, 0, GETPOST('search_'.$key.'_dtstartmonth', 'int'), GETPOST('search_'.$key.'_dtstartday', 'int'), GETPOST('search_'.$key.'_dtstartyear', 'int'));
96  $search[$key.'_dtend'] = dol_mktime(23, 59, 59, GETPOST('search_'.$key.'_dtendmonth', 'int'), GETPOST('search_'.$key.'_dtendday', 'int'), GETPOST('search_'.$key.'_dtendyear', 'int'));
97  }
98 }
99 
100 $userstatic = new User($db);
101 $companystatic = new Societe($db);
102 $form = new Form($db);
103 
104 // List of fields to search into when doing a "search in all"
105 $fieldstosearchall = array(
106  'u.login'=>"Login",
107  'u.lastname'=>"Lastname",
108  'u.firstname'=>"Firstname",
109  'u.accountancy_code'=>"AccountancyCode",
110  'u.office_phone'=>"PhonePro",
111  'u.user_mobile'=>"PhoneMobile",
112  'u.email'=>"EMail",
113  'u.note'=>"Note",
114 );
115 if (!empty($conf->api->enabled)) {
116  $fieldstosearchall['u.api_key'] = "ApiKey";
117 }
118 
119 // Definition of fields for list
120 $arrayfields = array(
121  'u.login'=>array('label'=>"Login", 'checked'=>1, 'position'=>10),
122  'u.lastname'=>array('label'=>"Lastname", 'checked'=>1, 'position'=>15),
123  'u.firstname'=>array('label'=>"Firstname", 'checked'=>1, 'position'=>20),
124  'u.entity'=>array('label'=>"Entity", 'checked'=>1, 'position'=>50, 'enabled'=>(!empty($conf->multicompany->enabled) && empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE))),
125  'u.gender'=>array('label'=>"Gender", 'checked'=>0, 'position'=>22),
126  'u.employee'=>array('label'=>"Employee", 'checked'=>($mode == 'employee' ? 1 : 0), 'position'=>25),
127  'u.fk_user'=>array('label'=>"HierarchicalResponsible", 'checked'=>1, 'position'=>27),
128  'u.accountancy_code'=>array('label'=>"AccountancyCode", 'checked'=>0, 'position'=>30),
129  'u.office_phone'=>array('label'=>"PhonePro", 'checked'=>1, 'position'=>31),
130  'u.user_mobile'=>array('label'=>"PhoneMobile", 'checked'=>1, 'position'=>32),
131  'u.email'=>array('label'=>"EMail", 'checked'=>1, 'position'=>35),
132  'u.api_key'=>array('label'=>"ApiKey", 'checked'=>0, 'position'=>40, "enabled"=>(!empty($conf->api->enabled) && $user->admin)),
133  'u.fk_soc'=>array('label'=>"Company", 'checked'=>($contextpage == 'employeelist' ? 0 : 1), 'position'=>45),
134  'u.salary'=>array('label'=>"Salary", 'checked'=>1, 'position'=>80, 'enabled'=>(!empty($conf->salaries->enabled) && !empty($user->rights->salaries->readall))),
135  'u.datelastlogin'=>array('label'=>"LastConnexion", 'checked'=>1, 'position'=>100),
136  'u.datepreviouslogin'=>array('label'=>"PreviousConnexion", 'checked'=>0, 'position'=>110),
137  'u.datec'=>array('label'=>"DateCreation", 'checked'=>0, 'position'=>500),
138  'u.tms'=>array('label'=>"DateModificationShort", 'checked'=>0, 'position'=>500),
139  'u.statut'=>array('label'=>"Status", 'checked'=>1, 'position'=>1000),
140 );
141 // Extra fields
142 include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_list_array_fields.tpl.php';
143 
144 $object->fields = dol_sort_array($object->fields, 'position');
145 $arrayfields = dol_sort_array($arrayfields, 'position');
146 
147 // Init search fields
148 $sall = trim((GETPOST('search_all', 'alphanohtml') != '') ? GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml'));
149 $search_user = GETPOST('search_user', 'alpha');
150 $search_login = GETPOST('search_login', 'alpha');
151 $search_lastname = GETPOST('search_lastname', 'alpha');
152 $search_firstname = GETPOST('search_firstname', 'alpha');
153 $search_gender = GETPOST('search_gender', 'alpha');
154 $search_employee = GETPOST('search_employee', 'alpha');
155 $search_accountancy_code = GETPOST('search_accountancy_code', 'alpha');
156 $search_phonepro = GETPOST('search_phonepro', 'alpha');
157 $search_phonemobile = GETPOST('search_phonemobile', 'alpha');
158 $search_email = GETPOST('search_email', 'alpha');
159 $search_api_key = GETPOST('search_api_key', 'alphanohtml');
160 $search_statut = GETPOST('search_statut', 'intcomma');
161 $search_thirdparty = GETPOST('search_thirdparty', 'alpha');
162 $search_warehouse = GETPOST('search_warehouse', 'alpha');
163 $search_supervisor = GETPOST('search_supervisor', 'intcomma');
164 $optioncss = GETPOST('optioncss', 'alpha');
165 $search_categ = GETPOST("search_categ", 'int');
166 $catid = GETPOST('catid', 'int');
167 
168 // Default search
169 if ($search_statut == '') {
170  $search_statut = '1';
171 }
172 if ($mode == 'employee' && !GETPOSTISSET('search_employee')) {
173  $search_employee = 1;
174 }
175 
176 // Define value to know what current user can do on users
177 $permissiontoadd = (!empty($user->admin) || $user->rights->user->user->creer);
178 $canreaduser = (!empty($user->admin) || $user->rights->user->user->lire);
179 $canedituser = (!empty($user->admin) || $user->rights->user->user->creer);
180 $candisableuser = (!empty($user->admin) || $user->rights->user->user->supprimer);
181 $canreadgroup = $canreaduser;
182 $caneditgroup = $canedituser;
183 if (!empty($conf->global->MAIN_USE_ADVANCED_PERMS)) {
184  $canreadgroup = (!empty($user->admin) || $user->rights->user->group_advance->read);
185  $caneditgroup = (!empty($user->admin) || $user->rights->user->group_advance->write);
186 }
187 
188 $error = 0;
189 
190 // Permission to list
191 if ($mode == 'employee') {
192  if (empty($user->rights->salaries->read)) {
193  accessforbidden();
194  }
195 } else {
196  if (empty($user->rights->user->user->lire) && empty($user->admin)) {
197  accessforbidden();
198  }
199 }
200 
201 $childids = $user->getAllChildIds(1);
202 
203 
204 /*
205  * Actions
206  */
207 
208 if (GETPOST('cancel', 'alpha')) {
209  $action = 'list';
210  $massaction = '';
211 }
212 if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') {
213  $massaction = '';
214 }
215 
216 $parameters = array();
217 $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
218 if ($reshook < 0) {
219  setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
220 }
221 
222 if (empty($reshook)) {
223  // Selection of new fields
224  include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
225 
226  // Purge search criteria
227  if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers
228  $search_user = "";
229  $search_login = "";
230  $search_lastname = "";
231  $search_firstname = "";
232  $search_gender = "";
233  $search_employee = "";
234  $search_accountancy_code = "";
235  $search_phonepro = "";
236  $search_phonemobile = "";
237  $search_email = "";
238  $search_statut = "";
239  $search_thirdparty = "";
240  $search_warehouse = "";
241  $search_supervisor = "";
242  $search_api_key = "";
243  $search_datelastlogin = "";
244  $search_datepreviouslogin = "";
245  $search_date_creation = "";
246  $search_date_update = "";
247  $search_categ = 0;
248  $toselect = array();
249  $search_array_options = array();
250  }
251  if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')
252  || GETPOST('button_search_x', 'alpha') || GETPOST('button_search.x', 'alpha') || GETPOST('button_search', 'alpha')) {
253  $massaction = ''; // Protection to avoid mass action if we force a new search during a mass action confirmation
254  }
255 
256  // Mass actions
257  $objectclass = 'User';
258  $objectlabel = 'User';
259  $uploaddir = $conf->user->dir_output;
260  include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
261 
262  // Disable or Enable records
263  if (!$error && ($massaction == 'disable' || $massaction == 'reactivate') && $permissiontoadd) {
264  $objecttmp = new User($db);
265 
266  if (!$error) {
267  $db->begin();
268 
269  $nbok = 0;
270  foreach ($toselect as $toselectid) {
271  if ($toselectid == $user->id) {
272  setEventMessages($langs->trans($massaction == 0 ? 'CantDisableYourself' : 'CanEnableYourself'), null, 'errors');
273  $error++;
274  break;
275  }
276 
277  $result = $objecttmp->fetch($toselectid);
278  if ($result > 0) {
279  if ($objecttmp->admin) {
280  setEventMessages($langs->trans($massaction == 0 ? 'CantDisableAnAdminUserWithMassActions' : 'CantEnableAnAdminUserWithMassActions', $objecttmp->login), null, 'errors');
281  $error++;
282  break;
283  }
284 
285  $result = $objecttmp->setstatus($massaction == 'disable' ? 0 : 1);
286  if ($result == 0) {
287  // Nothing is done
288  } elseif ($result < 0) {
289  setEventMessages($objecttmp->error, $objecttmp->errors, 'errors');
290  $error++;
291  break;
292  } else {
293  $nbok++;
294  }
295  } else {
296  setEventMessages($objecttmp->error, $objecttmp->errors, 'errors');
297  $error++;
298  break;
299  }
300  }
301 
302  if (!$error && !empty($conf->file->main_limit_users)) {
303  $nb = $object->getNbOfUsers("active");
304  if ($nb >= $conf->file->main_limit_users) {
305  $error++;
306  setEventMessages($langs->trans("YourQuotaOfUsersIsReached"), null, 'errors');
307  }
308  }
309 
310  if (!$error) {
311  if ($nbok > 1) {
312  setEventMessages($langs->trans("RecordsModified", $nbok), null, 'mesgs');
313  } else {
314  setEventMessages($langs->trans("RecordsModified", $nbok), null, 'mesgs');
315  }
316  $db->commit();
317  } else {
318  $db->rollback();
319  }
320  }
321  }
322 }
323 
324 
325 /*
326  * View
327  */
328 
329 $formother = new FormOther($db);
330 $user2 = new User($db);
331 
332 $now = dol_now();
333 
334 $help_url = 'EN:Module_Users|FR:Module_Utilisateurs|ES:M&oacute;dulo_Usuarios|DE:Modul_Benutzer';
335 if ($contextpage == 'employeelist' && $search_employee == 1) {
336  $title = $langs->trans("Employees");
337 } else {
338  $title = $langs->trans("Users");
339 }
340 $morejs = array();
341 $morecss = array();
342 $morehtmlright = "";
343 
344 // Build and execute select
345 // --------------------------------------------------------------------
346 $sql = "SELECT DISTINCT u.rowid, u.lastname, u.firstname, u.admin, u.fk_soc, u.login, u.office_phone, u.user_mobile, u.email, u.api_key, u.accountancy_code, u.gender, u.employee, u.photo,";
347 $sql .= " u.salary, u.datelastlogin, u.datepreviouslogin,";
348 $sql .= " u.ldap_sid, u.statut as status, u.entity,";
349 $sql .= " u.tms as date_update, u.datec as date_creation,";
350 $sql .= " u2.rowid as id2, u2.login as login2, u2.firstname as firstname2, u2.lastname as lastname2, u2.admin as admin2, u2.fk_soc as fk_soc2, u2.office_phone as ofice_phone2, u2.user_mobile as user_mobile2, u2.email as email2, u2.gender as gender2, u2.photo as photo2, u2.entity as entity2, u2.statut as status2,";
351 $sql .= " s.nom as name, s.canvas";
352 // Add fields from extrafields
353 if (!empty($extrafields->attributes[$object->table_element]['label'])) {
354  foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
355  $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key." as options_".$key : '');
356  }
357 }
358 // Add fields from hooks
359 $parameters = array();
360 $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object); // Note that $action and $object may have been modified by hook
361 $sql .= preg_replace('/^,/', '', $hookmanager->resPrint);
362 $sql = preg_replace('/,\s*$/', '', $sql);
363 $sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as u";
364 if (isset($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) {
365  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (u.rowid = ef.fk_object)";
366 }
367 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON u.fk_soc = s.rowid";
368 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u2 ON u.fk_user = u2.rowid";
369 if (!empty($search_categ) || !empty($catid)) {
370  $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX."categorie_user as cu ON u.rowid = cu.fk_user"; // We'll need this table joined to the select in order to filter by categ
371 }
372 // Add table from hooks
373 $parameters = array();
374 $reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object); // Note that $action and $object may have been modified by hook
375 $sql .= $hookmanager->resPrint;
376 if ($reshook > 0) {
377  $sql .= $hookmanager->resPrint;
378 }
379 $sql .= " WHERE u.entity IN (".getEntity($object->element).")";
380 if ($socid > 0) {
381  $sql .= " AND u.fk_soc = ".((int) $socid);
382 }
383 //if ($search_user != '') $sql.=natural_search(array('u.login', 'u.lastname', 'u.firstname'), $search_user);
384 if ($search_supervisor > 0) {
385  $sql .= " AND u.fk_user IN (".$db->sanitize($search_supervisor).")";
386 }
387 if ($search_thirdparty != '') {
388  $sql .= natural_search(array('s.nom'), $search_thirdparty);
389 }
390 if ($search_warehouse > 0) {
391  $sql .= natural_search(array('u.fk_warehouse'), $search_warehouse);
392 }
393 if ($search_login != '') {
394  $sql .= natural_search("u.login", $search_login);
395 }
396 if ($search_lastname != '') {
397  $sql .= natural_search("u.lastname", $search_lastname);
398 }
399 if ($search_firstname != '') {
400  $sql .= natural_search("u.firstname", $search_firstname);
401 }
402 if ($search_gender != '' && $search_gender != '-1') {
403  $sql .= " AND u.gender = '".$db->escape($search_gender)."'"; // Cannot use natural_search as looking for %man% also includes woman
404 }
405 if (is_numeric($search_employee) && $search_employee >= 0) {
406  $sql .= ' AND u.employee = '.(int) $search_employee;
407 }
408 if ($search_accountancy_code != '') {
409  $sql .= natural_search("u.accountancy_code", $search_accountancy_code);
410 }
411 if ($search_phonepro != '') {
412  $sql .= natural_search("u.office_phone", $search_phonepro);
413 }
414 if ($search_phonemobile != '') {
415  $sql .= natural_search("u.user_mobile", $search_phonemobile);
416 }
417 if ($search_email != '') {
418  $sql .= natural_search("u.email", $search_email);
419 }
420 if ($search_api_key != '') {
421  $sql .= natural_search("u.api_key", $search_api_key);
422 }
423 if ($search_statut != '' && $search_statut >= 0) {
424  $sql .= " AND u.statut IN (".$db->sanitize($search_statut).")";
425 }
426 if ($sall) {
427  $sql .= natural_search(array_keys($fieldstosearchall), $sall);
428 }
429 if ($catid > 0) {
430  $sql .= " AND cu.fk_categorie = ".((int) $catid);
431 }
432 if ($catid == -2) {
433  $sql .= " AND cu.fk_categorie IS NULL";
434 }
435 if ($search_categ > 0) {
436  $sql .= " AND cu.fk_categorie = ".((int) $search_categ);
437 }
438 if ($search_categ == -2) {
439  $sql .= " AND cu.fk_categorie IS NULL";
440 }
441 if ($search_warehouse > 0) {
442  $sql .= " AND u.fk_warehouse = ".((int) $search_warehouse);
443 }
444 if ($mode == 'employee' && empty($user->rights->salaries->readall)) {
445  $sql .= " AND u.rowid IN (".$db->sanitize(join(',', $childids)).")";
446 }
447 // Add where from extra fields
448 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
449 // Add where from hooks
450 $parameters = array();
451 $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object); // Note that $action and $object may have been modified by hook
452 $sql .= $hookmanager->resPrint;
453 
454 // Count total nb of records
455 $nbtotalofrecords = '';
456 if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
457  /* This old and fast method to get and count full list returns all record so use a high amount of memory.
458  $resql = $db->query($sql);
459  $nbtotalofrecords = $db->num_rows($resql);
460  */
461  /* The slow method does not consume memory on mysql (not tested on pgsql) */
462  /*$resql = $db->query($sql, 0, 'auto', 1);
463  while ($db->fetch_object($resql)) {
464  if (empty($nbtotalofrecords)) {
465  $nbtotalofrecords = 1; // We can't make +1 because init value is ''
466  } else {
467  $nbtotalofrecords++;
468  }
469  }*/
470  /* The fast and low memory method to get and count full list converts the sql into a sql count */
471  $sqlforcount = preg_replace('/^SELECT[a-zA-Z0-9\._\s\(\),=<>\:\-\']+\sFROM/', 'SELECT COUNT(*) as nbtotalofrecords FROM', $sql);
472  $resql = $db->query($sqlforcount);
473  if ($resql) {
474  $objforcount = $db->fetch_object($resql);
475  $nbtotalofrecords = $objforcount->nbtotalofrecords;
476  } else {
477  dol_print_error($db);
478  }
479 
480  if (($page * $limit) > $nbtotalofrecords) { // if total of record found is smaller than page * limit, goto and load page 0
481  $page = 0;
482  $offset = 0;
483  }
484  $db->free($resql);
485 }
486 
487 // Complete request and execute it with limit
488 $sql .= $db->order($sortfield, $sortorder);
489 if ($limit) {
490  $sql .= $db->plimit($limit + 1, $offset);
491 }
492 
493 $resql = $db->query($sql);
494 if (!$resql) {
495  dol_print_error($db);
496  exit;
497 }
498 
499 $num = $db->num_rows($resql);
500 
501 // Direct jump if only one record found
502 if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $search_all && !$page) {
503  $obj = $db->fetch_object($resql);
504  $id = $obj->rowid;
505  header("Location: ".DOL_URL_ROOT.'/user/card.php?id='.$id);
506  exit;
507 }
508 
509 // Output page
510 // --------------------------------------------------------------------
511 
512 llxHeader('', $title, $help_url, '', 0, 0, $morejs, $morecss, '', 'bodyforlist');
513 
514 $arrayofselected = is_array($toselect) ? $toselect : array();
515 
516 $param = '';
517 if (!empty($mode)) {
518  $param .= '&amp;mode='.urlencode($mode);
519 }
520 if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
521  $param .= '&amp;contextpage='.urlencode($contextpage);
522 }
523 if ($limit > 0 && $limit != $conf->liste_limit) {
524  $param .= '&amp;limit='.urlencode($limit);
525 }
526 if ($sall != '') {
527  $param .= '&amp;sall='.urlencode($sall);
528 }
529 if ($search_user != '') {
530  $param .= "&amp;search_user=".urlencode($search_user);
531 }
532 if ($search_login != '') {
533  $param .= "&amp;search_login=".urlencode($search_login);
534 }
535 if ($search_lastname != '') {
536  $param .= "&amp;search_lastname=".urlencode($search_lastname);
537 }
538 if ($search_firstname != '') {
539  $param .= "&amp;search_firstname=".urlencode($search_firstname);
540 }
541 if ($search_gender != '' && $search_gender != '-1') {
542  $param .= "&amp;search_gender=".urlencode($search_gender);
543 }
544 if ($search_employee != '' && $search_employee != '-1') {
545  $param .= "&amp;search_employee=".urlencode($search_employee);
546 }
547 if ($search_accountancy_code != '') {
548  $param .= "&amp;search_accountancy_code=".urlencode($search_accountancy_code);
549 }
550 if ($search_phonepro != '') {
551  $param .= "&amp;search_phonepro=".urlencode($search_phonepro);
552 }
553 if ($search_phonemobile != '') {
554  $param .= "&amp;search_phonemobile=".urlencode($search_phonemobile);
555 }
556 if ($search_email != '') {
557  $param .= "&amp;search_email=".urlencode($search_email);
558 }
559 if ($search_api_key != '') {
560  $param .= "&amp;search_api_key=".urlencode($search_api_key);
561 }
562 if ($search_supervisor > 0) {
563  $param .= "&amp;search_supervisor=".urlencode($search_supervisor);
564 }
565 if ($search_statut != '') {
566  $param .= "&amp;search_statut=".urlencode($search_statut);
567 }
568 if ($optioncss != '') {
569  $param .= '&amp;optioncss='.urlencode($optioncss);
570 }
571 if ($search_categ > 0) {
572  $param .= '&amp;search_categ='.urlencode($search_categ);
573 }
574 if ($search_warehouse > 0) {
575  $param .= '&amp;search_warehouse='.urlencode($search_warehouse);
576 }
577 // Add $param from extra fields
578 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
579 
580 // List of mass actions available
581 $arrayofmassactions = array();
582 if ($permissiontoadd) {
583  $arrayofmassactions['disable'] = img_picto('', 'close_title', 'class="pictofixedwidth"').$langs->trans("DisableUser");
584 }
585 if ($permissiontoadd) {
586  $arrayofmassactions['reactivate'] = img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("Reactivate");
587 }
588 if (isModEnabled('category') && $permissiontoadd) {
589  $arrayofmassactions['preaffecttag'] = img_picto('', 'category', 'class="pictofixedwidth"').$langs->trans("AffectTag");
590 }
591 //if ($permissiontodelete) $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
592 
593 if (GETPOST('nomassaction', 'int') || in_array($massaction, array('presend', 'predelete', 'preaffecttag'))) {
594  $arrayofmassactions = array();
595 }
596 $massactionbutton = $form->selectMassAction('', $arrayofmassactions);
597 
598 print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">'."\n";
599 if ($optioncss != '') {
600  print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
601 }
602 print '<input type="hidden" name="token" value="'.newToken().'">';
603 print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
604 print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
605 print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
606 print '<input type="hidden" name="page" value="'.$page.'">';
607 print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
608 print '<input type="hidden" name="mode" value="'.$mode.'">';
609 
610 $url = DOL_URL_ROOT.'/user/card.php?action=create'.($mode == 'employee' ? '&employee=1' : '').'&leftmenu=';
611 if (!empty($socid)) {
612  $url .= '&socid='.urlencode($socid);
613 }
614 
615 $newcardbutton = '';
616 $newcardbutton .= dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-bars paddingleft imgforviewmode', DOL_URL_ROOT.'/user/list.php?mode=common'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ((empty($mode) || $mode == 'common') ? 2 : 1), array('morecss'=>'reposition'));
617 $newcardbutton .= dolGetButtonTitle($langs->trans('HierarchicView'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT.'/user/hierarchy.php?mode=hierarchy'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', (($mode == 'hierarchy') ? 2 : 1), array('morecss'=>'reposition'));
618 $newcardbutton .= dolGetButtonTitle($langs->trans('ViewKanban'), '', 'fa fa-th-list imgforviewmode', $_SERVER["PHP_SELF"].'?mode=kanban'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ($mode == 'kanban' ? 2 : 1), array('morecss'=>'reposition'));
619 $newcardbutton .= dolGetButtonTitleSeparator();
620 $newcardbutton .= dolGetButtonTitle($langs->trans('NewUser'), '', 'fa fa-plus-circle', $url, '', $permissiontoadd);
621 
622 /*$moreparam = array('morecss'=>'btnTitleSelected');
623 $morehtmlright = dolGetButtonTitle($langs->trans("List"), '', 'fa fa-list paddingleft imgforviewmode', DOL_URL_ROOT.'/user/list.php'.(($search_statut != '' && $search_statut >= 0) ? '?search_statut='.$search_statut : ''), '', 1, $moreparam);
624 $moreparam = array('morecss'=>'marginleftonly');
625 $morehtmlright .= dolGetButtonTitle($langs->trans("HierarchicView"), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT.'/user/hierarchy.php'.(($search_statut != '' && $search_statut >= 0) ? '?search_statut='.$search_statut : ''), '', 1, $moreparam);
626 */
627 print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'user', 0, $morehtmlright.' '.$newcardbutton, '', $limit, 0, 0, 1);
628 
629 
630 
631 // Add code for pre mass action (confirmation or email presend form)
632 $topicmail = "SendUserRef";
633 $modelmail = "user";
634 $objecttmp = new User($db);
635 $trackid = 'use'.$object->id;
636 include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
637 
638 if (!empty($catid)) {
639  print "<div id='ways'>";
640  $c = new Categorie($db);
641  $ways = $c->print_all_ways(' &gt; ', 'user/list.php');
642  print " &gt; ".$ways[0]."<br>\n";
643  print "</div><br>";
644 }
645 
646 if ($search_all) {
647  foreach ($fieldstosearchall as $key => $val) {
648  $fieldstosearchall[$key] = $langs->trans($val);
649  }
650  print '<!-- Search done like if USER_QUICKSEARCH_ON_FIELDS = '.$setupstring.' -->'."\n";
651  print '<div class="divsearchfieldfilter">'.$langs->trans("FilterOnInto", $search_all).join(', ', $fieldstosearchall).'</div>';
652 }
653 
654 $moreforfilter = '';
655 /*$moreforfilter.='<div class="divsearchfield">';
656  $moreforfilter.= $langs->trans('MyFilter') . ': <input type="text" name="search_myfield" value="'.dol_escape_htmltag($search_myfield).'">';
657  $moreforfilter.= '</div>';*/
658 
659 // Filter on categories
660 if (!empty($conf->categorie->enabled) && $user->rights->categorie->lire) {
661  $moreforfilter .= '<div class="divsearchfield">';
662  $tmptitle = $langs->trans('Category');
663  $moreforfilter .= img_picto($langs->trans("Category"), 'category', 'class="pictofixedwidth"').$formother->select_categories(Categorie::TYPE_USER, $search_categ, 'search_categ', 1, $tmptitle);
664  $moreforfilter .= '</div>';
665 }
666 // Filter on warehouse
667 if (!empty($conf->stock->enabled) && !empty($conf->global->MAIN_DEFAULT_WAREHOUSE_USER)) {
668  require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
669  $formproduct = new FormProduct($db);
670  $moreforfilter .= '<div class="divsearchfield">';
671  $tmptitle = $langs->trans('Warehouse');
672  $moreforfilter .= img_picto($tmptitle, 'stock', 'class="pictofixedwidth"').$formproduct->selectWarehouses($search_warehouse, 'search_warehouse', '', $tmptitle, 0, 0, $tmptitle);
673  $moreforfilter .= '</div>';
674 }
675 
676 $parameters = array();
677 $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook
678 if (empty($reshook)) {
679  $moreforfilter .= $hookmanager->resPrint;
680 } else {
681  $moreforfilter = $hookmanager->resPrint;
682 }
683 
684 if (!empty($moreforfilter)) {
685  print '<div class="liste_titre liste_titre_bydiv centpercent">';
686  print $moreforfilter;
687  print '</div>';
688 }
689 
690 $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
691 $selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN', '')); // This also change content of $arrayfields
692 $selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : '');
693 
694 print '<div class="div-table-responsive">'; // You can use div-table-responsive-no-min if you dont need reserved height for your table
695 print '<table class="tagtable nobottomiftotal liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n";
696 
697 // Fields title search
698 // --------------------------------------------------------------------
699 print '<tr class="liste_titre">';
700 // Action column
701 if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) {
702  print '<td class="liste_titre maxwidthsearch">';
703  $searchpicto = $form->showFilterButtons('left');
704  print $searchpicto;
705  print '</td>';
706 }
707 if (!empty($arrayfields['u.login']['checked'])) {
708  print '<td class="liste_titre"><input type="text" name="search_login" class="maxwidth50" value="'.$search_login.'"></td>';
709 }
710 if (!empty($arrayfields['u.lastname']['checked'])) {
711  print '<td class="liste_titre"><input type="text" name="search_lastname" class="maxwidth50" value="'.$search_lastname.'"></td>';
712 }
713 if (!empty($arrayfields['u.firstname']['checked'])) {
714  print '<td class="liste_titre"><input type="text" name="search_firstname" class="maxwidth50" value="'.$search_firstname.'"></td>';
715 }
716 if (!empty($arrayfields['u.gender']['checked'])) {
717  print '<td class="liste_titre center">';
718  $arraygender = array('man'=>$langs->trans("Genderman"), 'woman'=>$langs->trans("Genderwoman"), 'other'=>$langs->trans("Genderother"));
719  print $form->selectarray('search_gender', $arraygender, $search_gender, 1);
720  print '</td>';
721 }
722 if (!empty($arrayfields['u.employee']['checked'])) {
723  print '<td class="liste_titre">';
724  print $form->selectyesno('search_employee', $search_employee, 1, false, 1);
725  print '</td>';
726 }
727 // Supervisor
728 if (!empty($arrayfields['u.fk_user']['checked'])) {
729  print '<td class="liste_titre">';
730  print $form->select_dolusers($search_supervisor, 'search_supervisor', 1, array(), 0, '', 0, 0, 0, 0, '', 0, '', 'maxwidth150');
731  print '</td>';
732 }
733 if (!empty($arrayfields['u.accountancy_code']['checked'])) {
734  print '<td class="liste_titre"><input type="text" name="search_accountancy_code" class="maxwidth50" value="'.$search_accountancy_code.'"></td>';
735 }
736 if (!empty($arrayfields['u.office_phone']['checked'])) {
737  print '<td class="liste_titre"><input type="text" name="search_phonepro" class="maxwidth50" value="'.$search_phonepro.'"></td>';
738 }
739 if (!empty($arrayfields['u.user_mobile']['checked'])) {
740  print '<td class="liste_titre"><input type="text" name="search_phonemobile" class="maxwidth50" value="'.$search_phonemobile.'"></td>';
741 }
742 if (!empty($arrayfields['u.email']['checked'])) {
743  print '<td class="liste_titre"><input type="text" name="search_email" class="maxwidth75" value="'.$search_email.'"></td>';
744 }
745 if (!empty($arrayfields['u.api_key']['checked'])) {
746  print '<td class="liste_titre"><input type="text" name="search_api_key" class="maxwidth50" value="'.$search_api_key.'"></td>';
747 }
748 if (!empty($arrayfields['u.fk_soc']['checked'])) {
749  print '<td class="liste_titre"><input type="text" name="search_thirdparty" class="maxwidth75" value="'.$search_thirdparty.'"></td>';
750 }
751 if (!empty($arrayfields['u.entity']['checked'])) {
752  print '<td class="liste_titre"></td>';
753 }
754 if (!empty($arrayfields['u.salary']['checked'])) {
755  print '<td class="liste_titre"></td>';
756 }
757 if (!empty($arrayfields['u.datelastlogin']['checked'])) {
758  print '<td class="liste_titre"></td>';
759 }
760 if (!empty($arrayfields['u.datepreviouslogin']['checked'])) {
761  print '<td class="liste_titre"></td>';
762 }
763 // Extra fields
764 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php';
765 // Fields from hook
766 $parameters = array('arrayfields'=>$arrayfields);
767 $reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object); // Note that $action and $object may have been modified by hook
768 print $hookmanager->resPrint;
769 if (!empty($arrayfields['u.datec']['checked'])) {
770  // Date creation
771  print '<td class="liste_titre">';
772  print '</td>';
773 }
774 if (!empty($arrayfields['u.tms']['checked'])) {
775  // Date modification
776  print '<td class="liste_titre">';
777  print '</td>';
778 }
779 if (!empty($arrayfields['u.statut']['checked'])) {
780  // Status
781  print '<td class="liste_titre center">';
782  print $form->selectarray('search_statut', array('-1'=>'', '0'=>$langs->trans('Disabled'), '1'=>$langs->trans('Enabled')), $search_statut, 0, 0, 0, '', 0, 0, 0, '', 'minwidth75imp');
783  print '</td>';
784 }
785 // Action column
786 if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) {
787  print '<td class="liste_titre maxwidthsearch">';
788  $searchpicto = $form->showFilterButtons();
789  print $searchpicto;
790  print '</td>';
791 }
792 print '</tr>'."\n";
793 
794 $totalarray = array();
795 $totalarray['nbfield'] = 0;
796 
797 // Fields title label
798 // --------------------------------------------------------------------
799 print '<tr class="liste_titre">';
800 if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) {
801  print getTitleFieldOfList(($mode != 'kanban' ? $selectedfields : ''), 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
802  $totalarray['nbfield']++;
803 }
804 if (!empty($arrayfields['u.login']['checked'])) {
805  print_liste_field_titre("Login", $_SERVER['PHP_SELF'], "u.login", $param, "", "", $sortfield, $sortorder);
806  $totalarray['nbfield']++;
807 }
808 if (!empty($arrayfields['u.lastname']['checked'])) {
809  print_liste_field_titre("Lastname", $_SERVER['PHP_SELF'], "u.lastname", $param, "", "", $sortfield, $sortorder);
810  $totalarray['nbfield']++;
811 }
812 if (!empty($arrayfields['u.firstname']['checked'])) {
813  print_liste_field_titre("FirstName", $_SERVER['PHP_SELF'], "u.firstname", $param, "", "", $sortfield, $sortorder);
814  $totalarray['nbfield']++;
815 }
816 if (!empty($arrayfields['u.gender']['checked'])) {
817  print_liste_field_titre("Gender", $_SERVER['PHP_SELF'], "u.gender", $param, "", "", $sortfield, $sortorder, 'center ');
818  $totalarray['nbfield']++;
819 }
820 if (!empty($arrayfields['u.employee']['checked'])) {
821  print_liste_field_titre("Employee", $_SERVER['PHP_SELF'], "u.employee", $param, "", "", $sortfield, $sortorder, 'center ');
822  $totalarray['nbfield']++;
823 }
824 if (!empty($arrayfields['u.fk_user']['checked'])) {
825  print_liste_field_titre("HierarchicalResponsible", $_SERVER['PHP_SELF'], "u.fk_user", $param, "", "", $sortfield, $sortorder);
826  $totalarray['nbfield']++;
827 }
828 if (!empty($arrayfields['u.accountancy_code']['checked'])) {
829  print_liste_field_titre("AccountancyCode", $_SERVER['PHP_SELF'], "u.accountancy_code", $param, "", "", $sortfield, $sortorder);
830  $totalarray['nbfield']++;
831 }
832 if (!empty($arrayfields['u.office_phone']['checked'])) {
833  print_liste_field_titre("PhonePro", $_SERVER['PHP_SELF'], "u.office_phone", $param, "", "", $sortfield, $sortorder);
834  $totalarray['nbfield']++;
835 }
836 if (!empty($arrayfields['u.user_mobile']['checked'])) {
837  print_liste_field_titre("PhoneMobile", $_SERVER['PHP_SELF'], "u.user_mobile", $param, "", "", $sortfield, $sortorder);
838  $totalarray['nbfield']++;
839 }
840 if (!empty($arrayfields['u.email']['checked'])) {
841  print_liste_field_titre("EMail", $_SERVER['PHP_SELF'], "u.email", $param, "", "", $sortfield, $sortorder);
842  $totalarray['nbfield']++;
843 }
844 if (!empty($arrayfields['u.api_key']['checked'])) {
845  print_liste_field_titre("ApiKey", $_SERVER['PHP_SELF'], "u.api_key", $param, "", "", $sortfield, $sortorder);
846  $totalarray['nbfield']++;
847 }
848 if (!empty($arrayfields['u.fk_soc']['checked'])) {
849  print_liste_field_titre("Company", $_SERVER['PHP_SELF'], "u.fk_soc", $param, "", "", $sortfield, $sortorder);
850  $totalarray['nbfield']++;
851 }
852 if (!empty($arrayfields['u.entity']['checked'])) {
853  print_liste_field_titre("Entity", $_SERVER['PHP_SELF'], "u.entity", $param, "", "", $sortfield, $sortorder);
854  $totalarray['nbfield']++;
855 }
856 if (!empty($arrayfields['u.salary']['checked'])) {
857  print_liste_field_titre("Salary", $_SERVER['PHP_SELF'], "u.salary", $param, "", "", $sortfield, $sortorder, 'right ');
858  $totalarray['nbfield']++;
859 }
860 if (!empty($arrayfields['u.datelastlogin']['checked'])) {
861  print_liste_field_titre("LastConnexion", $_SERVER['PHP_SELF'], "u.datelastlogin", $param, "", '', $sortfield, $sortorder, 'center ');
862  $totalarray['nbfield']++;
863 }
864 if (!empty($arrayfields['u.datepreviouslogin']['checked'])) {
865  print_liste_field_titre("PreviousConnexion", $_SERVER['PHP_SELF'], "u.datepreviouslogin", $param, "", '', $sortfield, $sortorder, 'center ');
866  $totalarray['nbfield']++;
867 }
868 // Extra fields
869 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php';
870 // Hook fields
871 $parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder, 'totalarray'=>&$totalarray);
872 $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook
873 print $hookmanager->resPrint;
874 if (!empty($arrayfields['u.datec']['checked'])) {
875  print_liste_field_titre("DateCreationShort", $_SERVER["PHP_SELF"], "u.datec", "", $param, '', $sortfield, $sortorder, 'center nowrap ');
876  $totalarray['nbfield']++;
877 }
878 if (!empty($arrayfields['u.tms']['checked'])) {
879  print_liste_field_titre("DateModificationShort", $_SERVER["PHP_SELF"], "u.tms", "", $param, '', $sortfield, $sortorder, 'center nowrap ');
880  $totalarray['nbfield']++;
881 }
882 if (!empty($arrayfields['u.statut']['checked'])) {
883  print_liste_field_titre("Status", $_SERVER["PHP_SELF"], "u.statut", "", $param, '', $sortfield, $sortorder, 'center ');
884  $totalarray['nbfield']++;
885 }
886 // Action column
887 if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) {
888  print getTitleFieldOfList(($mode != 'kanban' ? $selectedfields : ''), 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
889  $totalarray['nbfield']++;
890 }
891 print '</tr>'."\n";
892 
893 
894 // Detect if we need a fetch on each output line
895 $needToFetchEachLine = 0;
896 if (isset($extrafields->attributes[$object->table_element]['computed']) && is_array($extrafields->attributes[$object->table_element]['computed']) && count($extrafields->attributes[$object->table_element]['computed']) > 0) {
897  foreach ($extrafields->attributes[$object->table_element]['computed'] as $key => $val) {
898  if (preg_match('/\$object/', $val)) {
899  $needToFetchEachLine++; // There is at least one compute field that use $object
900  }
901  }
902 }
903 
904 
905 // Loop on record
906 // --------------------------------------------------------------------
907 $i = 0;
908 $savnbfield = $totalarray['nbfield'];
909 $totalarray['nbfield'] = 0;
910 $imaxinloop = ($limit ? min($num, $limit) : $num);
911 while ($i < $imaxinloop) {
912  $obj = $db->fetch_object($resql);
913  if (empty($obj)) {
914  break; // Should not happen
915  }
916 
917  if (empty($obj->country_code)) $obj->country_code = ''; // TODO Add join in select with country table to get country_code
918 
919  // Store properties in $object
920  $object->setVarsFromFetchObj($obj);
921 
922  $object->id = $obj->rowid;
923  $object->admin = $obj->admin;
924  $object->ref = $obj->rowid;
925  $object->login = $obj->login;
926  $object->statut = $obj->status;
927  $object->status = $obj->status;
928  $object->office_phone = $obj->office_phone;
929  $object->user_mobile = $obj->user_mobile;
930  $object->email = $obj->email;
931  $object->gender = $obj->gender;
932  $object->socid = $obj->fk_soc;
933  $object->firstname = $obj->firstname;
934  $object->lastname = $obj->lastname;
935  $object->employee = $obj->employee;
936  $object->photo = $obj->photo;
937 
938  $li = $object->getNomUrl(-1, '', 0, 0, 24, 1, 'login', '', 1);
939 
940  $canreadhrmdata = 0;
941  if ((!empty($conf->salaries->enabled) && !empty($user->rights->salaries->read) && in_array($obj->rowid, $childids))
942  || (!empty($conf->salaries->enabled) && !empty($user->rights->salaries->readall))
943  || (!empty($conf->hrm->enabled) && !empty($user->rights->hrm->employee->read))) {
944  $canreadhrmdata = 1;
945  }
946  $canreadsecretapi = 0;
947  if ($user->id == $obj->rowid || !empty($user->admin)) { // Current user or admin
948  $canreadsecretapi = 1;
949  }
950 
951  if ($mode == 'kanban') {
952  if ($i == 0) {
953  print '<tr><td colspan="'.$savnbfield.'">';
954  print '<div class="box-flex-container">';
955  }
956 
957  // Output Kanban
958  print $object->getKanbanView('');
959  if ($i == ($imaxinloop - 1)) {
960  print '</div>';
961  print '</td></tr>';
962  }
963  } else {
964  // Show here line of result
965  $j = 0;
966  print '<tr data-rowid="'.$object->id.'" class="oddeven">';
967  // Action column
968  if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) {
969  print '<td class="nowrap center">';
970  if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
971  $selected = 0;
972  if (in_array($object->id, $arrayofselected)) {
973  $selected = 1;
974  }
975  print '<input id="cb'.$object->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$object->id.'"'.($selected ? ' checked="checked"' : '').'>';
976  }
977  print '</td>';
978  }
979  // Login
980  if (!empty($arrayfields['u.login']['checked'])) {
981  print '<td class="nowraponall tdoverflowmax150">';
982  print $li;
983  if (!empty($conf->multicompany->enabled) && $obj->admin && !$obj->entity) {
984  print img_picto($langs->trans("SuperAdministrator"), 'redstar', 'class="valignmiddle paddingleft"');
985  } elseif ($obj->admin) {
986  print img_picto($langs->trans("Administrator"), 'star', 'class="valignmiddle paddingleft"');
987  }
988  print '</td>';
989  if (!$i) {
990  $totalarray['nbfield']++;
991  }
992  }
993  if (!empty($arrayfields['u.lastname']['checked'])) {
994  print '<td class="tdoverflowmax150" title="'.dol_escape_htmltag($obj->lastname).'">'.dol_escape_htmltag($obj->lastname).'</td>';
995  if (!$i) {
996  $totalarray['nbfield']++;
997  }
998  }
999  if (!empty($arrayfields['u.firstname']['checked'])) {
1000  print '<td class="tdoverflowmax150" title="'.dol_escape_htmltag($obj->lastname).'">'.dol_escape_htmltag($obj->firstname).'</td>';
1001  if (!$i) {
1002  $totalarray['nbfield']++;
1003  }
1004  }
1005  if (!empty($arrayfields['u.gender']['checked'])) {
1006  print '<td class="center">';
1007  if ($obj->gender) {
1008  // Preparing gender's display if there is one
1009  $addgendertxt = '';
1010  switch ($obj->gender) {
1011  case 'man':
1012  $addgendertxt .= '<i class="fas fa-mars" title="'.dol_escape_htmltag($langs->trans("Gender".$obj->gender)).'"></i>';
1013  break;
1014  case 'woman':
1015  $addgendertxt .= '<i class="fas fa-venus" title="'.dol_escape_htmltag($langs->trans("Gender".$obj->gender)).'"></i>';
1016  break;
1017  case 'other':
1018  $addgendertxt .= '<i class="fas fa-transgender" title="'.dol_escape_htmltag($langs->trans("Gender".$obj->gender)).'"></i>';
1019  break;
1020  }
1021  print $addgendertxt;
1022  //print $langs->trans("Gender".$obj->gender);
1023  }
1024  print '</td>';
1025  if (!$i) {
1026  $totalarray['nbfield']++;
1027  }
1028  }
1029  // Employee yes/no
1030  if (!empty($arrayfields['u.employee']['checked'])) {
1031  print '<td class="center">'.yn($obj->employee).'</td>';
1032  if (!$i) {
1033  $totalarray['nbfield']++;
1034  }
1035  }
1036 
1037  // Supervisor
1038  if (!empty($arrayfields['u.fk_user']['checked'])) {
1039  // Resp
1040  print '<td class="nowrap">';
1041  if ($obj->login2) {
1042  $user2->id = $obj->id2;
1043  $user2->login = $obj->login2;
1044  $user2->lastname = $obj->lastname2;
1045  $user2->firstname = $obj->firstname2;
1046  $user2->gender = $obj->gender2;
1047  $user2->photo = $obj->photo2;
1048  $user2->admin = $obj->admin2;
1049  $user2->office_phone = $obj->office_phone;
1050  $user2->user_mobile = $obj->user_mobile;
1051  $user2->email = $obj->email2;
1052  $user2->socid = $obj->fk_soc2;
1053  $user2->statut = $obj->status2;
1054  $user2->status = $obj->status2;
1055  print $user2->getNomUrl(-1, '', 0, 0, 24, 0, '', '', 1);
1056  if (!empty($conf->multicompany->enabled) && $obj->admin2 && !$obj->entity2) {
1057  print img_picto($langs->trans("SuperAdministrator"), 'redstar', 'class="valignmiddle paddingleft"');
1058  } elseif ($obj->admin2) {
1059  print img_picto($langs->trans("Administrator"), 'star', 'class="valignmiddle paddingleft"');
1060  }
1061  }
1062  print '</td>';
1063  if (!$i) {
1064  $totalarray['nbfield']++;
1065  }
1066  }
1067 
1068  if (!empty($arrayfields['u.accountancy_code']['checked'])) {
1069  print '<td>'.$obj->accountancy_code.'</td>';
1070  if (!$i) {
1071  $totalarray['nbfield']++;
1072  }
1073  }
1074 
1075  if (!empty($arrayfields['u.office_phone']['checked'])) {
1076  print '<td>'.dol_print_phone($obj->office_phone, $obj->country_code, 0, $obj->rowid, 'AC_TEL', ' ', 'phone')."</td>\n";
1077  if (!$i) {
1078  $totalarray['nbfield']++;
1079  }
1080  }
1081  if (!empty($arrayfields['u.user_mobile']['checked'])) {
1082  print '<td>'.dol_print_phone($obj->user_mobile, $obj->country_code, 0, $obj->rowid, 'AC_TEL', ' ', 'mobile')."</td>\n";
1083  if (!$i) {
1084  $totalarray['nbfield']++;
1085  }
1086  }
1087  if (!empty($arrayfields['u.email']['checked'])) {
1088  print '<td class="tdoverflowmax150">'.dol_print_email($obj->email, $obj->rowid, $obj->fk_soc, 'AC_EMAIL', 0, 0, 1)."</td>\n";
1089  if (!$i) {
1090  $totalarray['nbfield']++;
1091  }
1092  }
1093  if (!empty($arrayfields['u.api_key']['checked'])) {
1094  print '<td>';
1095  if ($obj->api_key) {
1096  if ($canreadsecretapi) {
1097  print $obj->api_key;
1098  } else {
1099  print '<span class="opacitymedium">'.$langs->trans("Hidden").'</span>';
1100  }
1101  }
1102  print '</td>';
1103  if (!$i) {
1104  $totalarray['nbfield']++;
1105  }
1106  }
1107  if (!empty($arrayfields['u.fk_soc']['checked'])) {
1108  print '<td class="tdoverflowmax150">';
1109  if ($obj->fk_soc > 0) {
1110  $companystatic->id = $obj->fk_soc;
1111  $companystatic->name = $obj->name;
1112  $companystatic->canvas = $obj->canvas;
1113  print $companystatic->getNomUrl(1);
1114  } elseif ($obj->ldap_sid) {
1115  print '<span class="opacitymedium">'.$langs->trans("DomainUser").'</span>';
1116  } else {
1117  print '<span class="opacitymedium">'.$langs->trans("InternalUser").'</span>';
1118  }
1119  print '</td>';
1120  if (!$i) {
1121  $totalarray['nbfield']++;
1122  }
1123  }
1124  // Multicompany enabled
1125  if (!empty($conf->multicompany->enabled) && is_object($mc) && empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
1126  if (!empty($arrayfields['u.entity']['checked'])) {
1127  print '<td>';
1128  if (!$obj->entity) {
1129  print $langs->trans("AllEntities");
1130  } else {
1131  $mc->getInfo($obj->entity);
1132  print $mc->label;
1133  }
1134  print '</td>';
1135  if (!$i) {
1136  $totalarray['nbfield']++;
1137  }
1138  }
1139  }
1140 
1141  // Salary
1142  if (!empty($arrayfields['u.salary']['checked'])) {
1143  print '<td class="nowraponall right amount">';
1144  if ($obj->salary) {
1145  if ($canreadhrmdata) {
1146  print price($obj->salary);
1147  } else {
1148  print '<span class="opacitymedium">'.$langs->trans("Hidden").'</span>';
1149  }
1150  }
1151  print '</td>';
1152  if (!$i) {
1153  $totalarray['nbfield']++;
1154  }
1155  }
1156 
1157  // Date last login
1158  if (!empty($arrayfields['u.datelastlogin']['checked'])) {
1159  print '<td class="nowrap center">'.dol_print_date($db->jdate($obj->datelastlogin), "dayhour").'</td>';
1160  if (!$i) {
1161  $totalarray['nbfield']++;
1162  }
1163  }
1164  // Date previous login
1165  if (!empty($arrayfields['u.datepreviouslogin']['checked'])) {
1166  print '<td class="nowrap center">'.dol_print_date($db->jdate($obj->datepreviouslogin), "dayhour").'</td>';
1167  if (!$i) {
1168  $totalarray['nbfield']++;
1169  }
1170  }
1171 
1172  // Extra fields
1173  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
1174  // Fields from hook
1175  $parameters = array('arrayfields'=>$arrayfields, 'object'=>$object, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray);
1176  $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object); // Note that $action and $object may have been modified by hook
1177  print $hookmanager->resPrint;
1178  // Date creation
1179  if (!empty($arrayfields['u.datec']['checked'])) {
1180  print '<td class="center">';
1181  print dol_print_date($db->jdate($obj->date_creation), 'dayhour', 'tzuser');
1182  print '</td>';
1183  if (!$i) {
1184  $totalarray['nbfield']++;
1185  }
1186  }
1187  // Date modification
1188  if (!empty($arrayfields['u.tms']['checked'])) {
1189  print '<td class="center">';
1190  print dol_print_date($db->jdate($obj->date_update), 'dayhour', 'tzuser');
1191  print '</td>';
1192  if (!$i) {
1193  $totalarray['nbfield']++;
1194  }
1195  }
1196  // Status
1197  if (!empty($arrayfields['u.statut']['checked'])) {
1198  print '<td class="center">'.$object->getLibStatut(5).'</td>';
1199  if (!$i) {
1200  $totalarray['nbfield']++;
1201  }
1202  }
1203  // Action column
1204  if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) {
1205  print '<td class="nowrap center">';
1206  if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
1207  $selected = 0;
1208  if (in_array($object->id, $arrayofselected)) {
1209  $selected = 1;
1210  }
1211  print '<input id="cb'.$object->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$object->id.'"'.($selected ? ' checked="checked"' : '').'>';
1212  }
1213  print '</td>';
1214  }
1215  if (!$i) {
1216  $totalarray['nbfield']++;
1217  }
1218 
1219  print '</tr>'."\n";
1220  }
1221 
1222  $i++;
1223 }
1224 
1225 // Show total line
1226 include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php';
1227 
1228 // If no record found
1229 if ($num == 0) {
1230  $colspan = 1;
1231  foreach ($arrayfields as $key => $val) {
1232  if (!empty($val['checked'])) {
1233  $colspan++;
1234  }
1235  }
1236  print '<tr><td colspan="'.$colspan.'"><span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span></td></tr>';
1237 }
1238 
1239 
1240 $db->free($resql);
1241 
1242 $parameters = array('arrayfields'=>$arrayfields, 'sql'=>$sql);
1243 $reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object); // Note that $action and $object may have been modified by hook
1244 print $hookmanager->resPrint;
1245 
1246 print '</table>'."\n";
1247 print '</div>'."\n";
1248 
1249 print '</form>'."\n";
1250 
1251 
1252 // End of page
1253 llxFooter();
1254 $db->close();
GETPOST($paramname, $check= 'alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
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...
dolGetButtonTitle($label, $helpText= '', $iconClass= 'fa fa-file', $url= '', $id= '', $status=1, $params=array())
Function dolGetButtonTitle : this kind of buttons are used in title in list.
dol_now($mode= 'auto')
Return date for now.
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
dolGetButtonTitleSeparator($moreClass="")
Add space between dolGetButtonTitle.
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...
if(GETPOST('button_removefilter_x', 'alpha')||GETPOST('button_removefilter.x', 'alpha')||GETPOST('button_removefilter', 'alpha')) if(GETPOST('button_search_x', 'alpha')||GETPOST('button_search.x', 'alpha')||GETPOST('button_search', 'alpha')) if($action=="save"&&empty($cancel)) $help_url
View.
Definition: agenda.php:116
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 with static methods for building HTML components related to products Only components common to ...
Class to manage standard extra fields.
setEventMessages($mesg, $mesgs, $style= 'mesgs', $messagekey= '')
Set event messages in dol_events session object.
print_barre_liste($titre, $page, $file, $options= '', $sortfield= '', $sortorder= '', $morehtmlcenter= '', $num=-1, $totalnboflines= '', $picto= 'generic', $pictoisfullpath=0, $morehtmlright= '', $morecss= '', $limit=-1, $hideselectlimit=0, $hidenavigation=0, $pagenavastextinput=0, $morehtmlrightbeforearrow= '')
Print a title with navigation controls for pagination.
Class to manage generation of HTML components Only common components must be here.
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...)
print_liste_field_titre($name, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $tooltip="", $forcenowrapcolumntitle=0)
Show title line of an array.
Class to manage categories.
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)
Classe permettant la generation de composants html autre Only common components are here...
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 ...
natural_search($fields, $value, $mode=0, $nofirstand=0)
Generate natural SQL search string for a criteria (this criteria can be tested on one or several fiel...
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_sort_array(&$array, $index, $order= 'asc', $natsort=0, $case_sensitive=0, $keepindex=0)
Advanced sort array by second index function, which produces ascending (default) or descending output...
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...
isModEnabled($module)
Is Dolibarr module enabled.
getTitleFieldOfList($name, $thead=0, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $disablesortlink=0, $tooltip= '', $forcenowrapcolumntitle=0)
Get title line of an array.
llxFooter()
Empty footer.
Definition: wrapper.php:73