dolibarr  16.0.5
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.fk_user,";
348 $sql .= " u.salary, u.datelastlogin, u.datepreviouslogin,";
349 $sql .= " u.ldap_sid, u.statut as status, u.entity,";
350 $sql .= " u.tms as date_update, u.datec as date_creation,";
351 $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,";
352 $sql .= " s.nom as name, s.canvas";
353 // Add fields from extrafields
354 if (!empty($extrafields->attributes[$object->table_element]['label'])) {
355  foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
356  $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key." as options_".$key : '');
357  }
358 }
359 // Add fields from hooks
360 $parameters = array();
361 $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object); // Note that $action and $object may have been modified by hook
362 $sql .= preg_replace('/^,/', '', $hookmanager->resPrint);
363 $sql = preg_replace('/,\s*$/', '', $sql);
364 $sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as u";
365 if (isset($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) {
366  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (u.rowid = ef.fk_object)";
367 }
368 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON u.fk_soc = s.rowid";
369 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u2 ON u.fk_user = u2.rowid";
370 if (!empty($search_categ) || !empty($catid)) {
371  $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
372 }
373 // Add table from hooks
374 $parameters = array();
375 $reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object); // Note that $action and $object may have been modified by hook
376 $sql .= $hookmanager->resPrint;
377 if ($reshook > 0) {
378  $sql .= $hookmanager->resPrint;
379 }
380 $sql .= " WHERE u.entity IN (".getEntity($object->element).")";
381 if ($socid > 0) {
382  $sql .= " AND u.fk_soc = ".((int) $socid);
383 }
384 //if ($search_user != '') $sql.=natural_search(array('u.login', 'u.lastname', 'u.firstname'), $search_user);
385 if ($search_supervisor > 0) {
386  $sql .= " AND u.fk_user IN (".$db->sanitize($search_supervisor).")";
387 }
388 if ($search_thirdparty != '') {
389  $sql .= natural_search(array('s.nom'), $search_thirdparty);
390 }
391 if ($search_warehouse > 0) {
392  $sql .= natural_search(array('u.fk_warehouse'), $search_warehouse);
393 }
394 if ($search_login != '') {
395  $sql .= natural_search("u.login", $search_login);
396 }
397 if ($search_lastname != '') {
398  $sql .= natural_search("u.lastname", $search_lastname);
399 }
400 if ($search_firstname != '') {
401  $sql .= natural_search("u.firstname", $search_firstname);
402 }
403 if ($search_gender != '' && $search_gender != '-1') {
404  $sql .= " AND u.gender = '".$db->escape($search_gender)."'"; // Cannot use natural_search as looking for %man% also includes woman
405 }
406 if (is_numeric($search_employee) && $search_employee >= 0) {
407  $sql .= ' AND u.employee = '.(int) $search_employee;
408 }
409 if ($search_accountancy_code != '') {
410  $sql .= natural_search("u.accountancy_code", $search_accountancy_code);
411 }
412 if ($search_phonepro != '') {
413  $sql .= natural_search("u.office_phone", $search_phonepro);
414 }
415 if ($search_phonemobile != '') {
416  $sql .= natural_search("u.user_mobile", $search_phonemobile);
417 }
418 if ($search_email != '') {
419  $sql .= natural_search("u.email", $search_email);
420 }
421 if ($search_api_key != '') {
422  $sql .= natural_search("u.api_key", $search_api_key);
423 }
424 if ($search_statut != '' && $search_statut >= 0) {
425  $sql .= " AND u.statut IN (".$db->sanitize($search_statut).")";
426 }
427 if ($sall) {
428  $sql .= natural_search(array_keys($fieldstosearchall), $sall);
429 }
430 if ($catid > 0) {
431  $sql .= " AND cu.fk_categorie = ".((int) $catid);
432 }
433 if ($catid == -2) {
434  $sql .= " AND cu.fk_categorie IS NULL";
435 }
436 if ($search_categ > 0) {
437  $sql .= " AND cu.fk_categorie = ".((int) $search_categ);
438 }
439 if ($search_categ == -2) {
440  $sql .= " AND cu.fk_categorie IS NULL";
441 }
442 if ($search_warehouse > 0) {
443  $sql .= " AND u.fk_warehouse = ".((int) $search_warehouse);
444 }
445 if ($mode == 'employee' && empty($user->rights->salaries->readall)) {
446  $sql .= " AND u.rowid IN (".$db->sanitize(join(',', $childids)).")";
447 }
448 // Add where from extra fields
449 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
450 // Add where from hooks
451 $parameters = array();
452 $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object); // Note that $action and $object may have been modified by hook
453 $sql .= $hookmanager->resPrint;
454 
455 // Count total nb of records
456 $nbtotalofrecords = '';
457 if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
458  /* This old and fast method to get and count full list returns all record so use a high amount of memory.
459  $resql = $db->query($sql);
460  $nbtotalofrecords = $db->num_rows($resql);
461  */
462  /* The slow method does not consume memory on mysql (not tested on pgsql) */
463  /*$resql = $db->query($sql, 0, 'auto', 1);
464  while ($db->fetch_object($resql)) {
465  if (empty($nbtotalofrecords)) {
466  $nbtotalofrecords = 1; // We can't make +1 because init value is ''
467  } else {
468  $nbtotalofrecords++;
469  }
470  }*/
471  /* The fast and low memory method to get and count full list converts the sql into a sql count */
472  $sqlforcount = preg_replace('/^SELECT[a-zA-Z0-9\._\s\(\),=<>\:\-\']+\sFROM/', 'SELECT COUNT(*) as nbtotalofrecords FROM', $sql);
473  $resql = $db->query($sqlforcount);
474  if ($resql) {
475  $objforcount = $db->fetch_object($resql);
476  $nbtotalofrecords = $objforcount->nbtotalofrecords;
477  } else {
478  dol_print_error($db);
479  }
480 
481  if (($page * $limit) > $nbtotalofrecords) { // if total of record found is smaller than page * limit, goto and load page 0
482  $page = 0;
483  $offset = 0;
484  }
485  $db->free($resql);
486 }
487 
488 // Complete request and execute it with limit
489 $sql .= $db->order($sortfield, $sortorder);
490 if ($limit) {
491  $sql .= $db->plimit($limit + 1, $offset);
492 }
493 
494 $resql = $db->query($sql);
495 if (!$resql) {
496  dol_print_error($db);
497  exit;
498 }
499 
500 $num = $db->num_rows($resql);
501 
502 // Direct jump if only one record found
503 if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $search_all && !$page) {
504  $obj = $db->fetch_object($resql);
505  $id = $obj->rowid;
506  header("Location: ".DOL_URL_ROOT.'/user/card.php?id='.$id);
507  exit;
508 }
509 
510 // Output page
511 // --------------------------------------------------------------------
512 
513 llxHeader('', $title, $help_url, '', 0, 0, $morejs, $morecss, '', 'bodyforlist');
514 
515 $arrayofselected = is_array($toselect) ? $toselect : array();
516 
517 $param = '';
518 if (!empty($mode)) {
519  $param .= '&amp;mode='.urlencode($mode);
520 }
521 if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
522  $param .= '&amp;contextpage='.urlencode($contextpage);
523 }
524 if ($limit > 0 && $limit != $conf->liste_limit) {
525  $param .= '&amp;limit='.urlencode($limit);
526 }
527 if ($sall != '') {
528  $param .= '&amp;sall='.urlencode($sall);
529 }
530 if ($search_user != '') {
531  $param .= "&amp;search_user=".urlencode($search_user);
532 }
533 if ($search_login != '') {
534  $param .= "&amp;search_login=".urlencode($search_login);
535 }
536 if ($search_lastname != '') {
537  $param .= "&amp;search_lastname=".urlencode($search_lastname);
538 }
539 if ($search_firstname != '') {
540  $param .= "&amp;search_firstname=".urlencode($search_firstname);
541 }
542 if ($search_gender != '' && $search_gender != '-1') {
543  $param .= "&amp;search_gender=".urlencode($search_gender);
544 }
545 if ($search_employee != '' && $search_employee != '-1') {
546  $param .= "&amp;search_employee=".urlencode($search_employee);
547 }
548 if ($search_accountancy_code != '') {
549  $param .= "&amp;search_accountancy_code=".urlencode($search_accountancy_code);
550 }
551 if ($search_phonepro != '') {
552  $param .= "&amp;search_phonepro=".urlencode($search_phonepro);
553 }
554 if ($search_phonemobile != '') {
555  $param .= "&amp;search_phonemobile=".urlencode($search_phonemobile);
556 }
557 if ($search_email != '') {
558  $param .= "&amp;search_email=".urlencode($search_email);
559 }
560 if ($search_api_key != '') {
561  $param .= "&amp;search_api_key=".urlencode($search_api_key);
562 }
563 if ($search_supervisor > 0) {
564  $param .= "&amp;search_supervisor=".urlencode($search_supervisor);
565 }
566 if ($search_statut != '') {
567  $param .= "&amp;search_statut=".urlencode($search_statut);
568 }
569 if ($optioncss != '') {
570  $param .= '&amp;optioncss='.urlencode($optioncss);
571 }
572 if ($search_categ > 0) {
573  $param .= '&amp;search_categ='.urlencode($search_categ);
574 }
575 if ($search_warehouse > 0) {
576  $param .= '&amp;search_warehouse='.urlencode($search_warehouse);
577 }
578 // Add $param from extra fields
579 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
580 
581 // List of mass actions available
582 $arrayofmassactions = array();
583 if ($permissiontoadd) {
584  $arrayofmassactions['disable'] = img_picto('', 'close_title', 'class="pictofixedwidth"').$langs->trans("DisableUser");
585 }
586 if ($permissiontoadd) {
587  $arrayofmassactions['reactivate'] = img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("Reactivate");
588 }
589 if (isModEnabled('category') && $permissiontoadd) {
590  $arrayofmassactions['preaffecttag'] = img_picto('', 'category', 'class="pictofixedwidth"').$langs->trans("AffectTag");
591 }
592 //if ($permissiontodelete) $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
593 
594 if (GETPOST('nomassaction', 'int') || in_array($massaction, array('presend', 'predelete', 'preaffecttag'))) {
595  $arrayofmassactions = array();
596 }
597 $massactionbutton = $form->selectMassAction('', $arrayofmassactions);
598 
599 print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">'."\n";
600 if ($optioncss != '') {
601  print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
602 }
603 print '<input type="hidden" name="token" value="'.newToken().'">';
604 print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
605 print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
606 print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
607 print '<input type="hidden" name="page" value="'.$page.'">';
608 print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
609 print '<input type="hidden" name="mode" value="'.$mode.'">';
610 
611 $url = DOL_URL_ROOT.'/user/card.php?action=create'.($mode == 'employee' ? '&employee=1' : '').'&leftmenu=';
612 if (!empty($socid)) {
613  $url .= '&socid='.urlencode($socid);
614 }
615 
616 $newcardbutton = '';
617 $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'));
618 $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'));
619 $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'));
620 $newcardbutton .= dolGetButtonTitleSeparator();
621 $newcardbutton .= dolGetButtonTitle($langs->trans('NewUser'), '', 'fa fa-plus-circle', $url, '', $permissiontoadd);
622 
623 /*$moreparam = array('morecss'=>'btnTitleSelected');
624 $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);
625 $moreparam = array('morecss'=>'marginleftonly');
626 $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);
627 */
628 print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'user', 0, $morehtmlright.' '.$newcardbutton, '', $limit, 0, 0, 1);
629 
630 
631 
632 // Add code for pre mass action (confirmation or email presend form)
633 $topicmail = "SendUserRef";
634 $modelmail = "user";
635 $objecttmp = new User($db);
636 $trackid = 'use'.$object->id;
637 include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
638 
639 if (!empty($catid)) {
640  print "<div id='ways'>";
641  $c = new Categorie($db);
642  $ways = $c->print_all_ways(' &gt; ', 'user/list.php');
643  print " &gt; ".$ways[0]."<br>\n";
644  print "</div><br>";
645 }
646 
647 if ($search_all) {
648  foreach ($fieldstosearchall as $key => $val) {
649  $fieldstosearchall[$key] = $langs->trans($val);
650  }
651  print '<!-- Search done like if USER_QUICKSEARCH_ON_FIELDS = '.$setupstring.' -->'."\n";
652  print '<div class="divsearchfieldfilter">'.$langs->trans("FilterOnInto", $search_all).join(', ', $fieldstosearchall).'</div>';
653 }
654 
655 $moreforfilter = '';
656 /*$moreforfilter.='<div class="divsearchfield">';
657  $moreforfilter.= $langs->trans('MyFilter') . ': <input type="text" name="search_myfield" value="'.dol_escape_htmltag($search_myfield).'">';
658  $moreforfilter.= '</div>';*/
659 
660 // Filter on categories
661 if (!empty($conf->categorie->enabled) && $user->rights->categorie->lire) {
662  $moreforfilter .= '<div class="divsearchfield">';
663  $tmptitle = $langs->trans('Category');
664  $moreforfilter .= img_picto($langs->trans("Category"), 'category', 'class="pictofixedwidth"').$formother->select_categories(Categorie::TYPE_USER, $search_categ, 'search_categ', 1, $tmptitle);
665  $moreforfilter .= '</div>';
666 }
667 // Filter on warehouse
668 if (!empty($conf->stock->enabled) && !empty($conf->global->MAIN_DEFAULT_WAREHOUSE_USER)) {
669  require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
670  $formproduct = new FormProduct($db);
671  $moreforfilter .= '<div class="divsearchfield">';
672  $tmptitle = $langs->trans('Warehouse');
673  $moreforfilter .= img_picto($tmptitle, 'stock', 'class="pictofixedwidth"').$formproduct->selectWarehouses($search_warehouse, 'search_warehouse', '', $tmptitle, 0, 0, $tmptitle);
674  $moreforfilter .= '</div>';
675 }
676 
677 $parameters = array();
678 $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook
679 if (empty($reshook)) {
680  $moreforfilter .= $hookmanager->resPrint;
681 } else {
682  $moreforfilter = $hookmanager->resPrint;
683 }
684 
685 if (!empty($moreforfilter)) {
686  print '<div class="liste_titre liste_titre_bydiv centpercent">';
687  print $moreforfilter;
688  print '</div>';
689 }
690 
691 $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
692 $selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN', '')); // This also change content of $arrayfields
693 $selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : '');
694 
695 print '<div class="div-table-responsive">'; // You can use div-table-responsive-no-min if you dont need reserved height for your table
696 print '<table class="tagtable nobottomiftotal liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n";
697 
698 // Fields title search
699 // --------------------------------------------------------------------
700 print '<tr class="liste_titre">';
701 // Action column
702 if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) {
703  print '<td class="liste_titre maxwidthsearch">';
704  $searchpicto = $form->showFilterButtons('left');
705  print $searchpicto;
706  print '</td>';
707 }
708 if (!empty($arrayfields['u.login']['checked'])) {
709  print '<td class="liste_titre"><input type="text" name="search_login" class="maxwidth50" value="'.$search_login.'"></td>';
710 }
711 if (!empty($arrayfields['u.lastname']['checked'])) {
712  print '<td class="liste_titre"><input type="text" name="search_lastname" class="maxwidth50" value="'.$search_lastname.'"></td>';
713 }
714 if (!empty($arrayfields['u.firstname']['checked'])) {
715  print '<td class="liste_titre"><input type="text" name="search_firstname" class="maxwidth50" value="'.$search_firstname.'"></td>';
716 }
717 if (!empty($arrayfields['u.gender']['checked'])) {
718  print '<td class="liste_titre center">';
719  $arraygender = array('man'=>$langs->trans("Genderman"), 'woman'=>$langs->trans("Genderwoman"), 'other'=>$langs->trans("Genderother"));
720  print $form->selectarray('search_gender', $arraygender, $search_gender, 1);
721  print '</td>';
722 }
723 if (!empty($arrayfields['u.employee']['checked'])) {
724  print '<td class="liste_titre">';
725  print $form->selectyesno('search_employee', $search_employee, 1, false, 1);
726  print '</td>';
727 }
728 // Supervisor
729 if (!empty($arrayfields['u.fk_user']['checked'])) {
730  print '<td class="liste_titre">';
731  print $form->select_dolusers($search_supervisor, 'search_supervisor', 1, array(), 0, '', 0, 0, 0, 0, '', 0, '', 'maxwidth150');
732  print '</td>';
733 }
734 if (!empty($arrayfields['u.accountancy_code']['checked'])) {
735  print '<td class="liste_titre"><input type="text" name="search_accountancy_code" class="maxwidth50" value="'.$search_accountancy_code.'"></td>';
736 }
737 if (!empty($arrayfields['u.office_phone']['checked'])) {
738  print '<td class="liste_titre"><input type="text" name="search_phonepro" class="maxwidth50" value="'.$search_phonepro.'"></td>';
739 }
740 if (!empty($arrayfields['u.user_mobile']['checked'])) {
741  print '<td class="liste_titre"><input type="text" name="search_phonemobile" class="maxwidth50" value="'.$search_phonemobile.'"></td>';
742 }
743 if (!empty($arrayfields['u.email']['checked'])) {
744  print '<td class="liste_titre"><input type="text" name="search_email" class="maxwidth75" value="'.$search_email.'"></td>';
745 }
746 if (!empty($arrayfields['u.api_key']['checked'])) {
747  print '<td class="liste_titre"><input type="text" name="search_api_key" class="maxwidth50" value="'.$search_api_key.'"></td>';
748 }
749 if (!empty($arrayfields['u.fk_soc']['checked'])) {
750  print '<td class="liste_titre"><input type="text" name="search_thirdparty" class="maxwidth75" value="'.$search_thirdparty.'"></td>';
751 }
752 if (!empty($arrayfields['u.entity']['checked'])) {
753  print '<td class="liste_titre"></td>';
754 }
755 if (!empty($arrayfields['u.salary']['checked'])) {
756  print '<td class="liste_titre"></td>';
757 }
758 if (!empty($arrayfields['u.datelastlogin']['checked'])) {
759  print '<td class="liste_titre"></td>';
760 }
761 if (!empty($arrayfields['u.datepreviouslogin']['checked'])) {
762  print '<td class="liste_titre"></td>';
763 }
764 // Extra fields
765 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php';
766 // Fields from hook
767 $parameters = array('arrayfields'=>$arrayfields);
768 $reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object); // Note that $action and $object may have been modified by hook
769 print $hookmanager->resPrint;
770 if (!empty($arrayfields['u.datec']['checked'])) {
771  // Date creation
772  print '<td class="liste_titre">';
773  print '</td>';
774 }
775 if (!empty($arrayfields['u.tms']['checked'])) {
776  // Date modification
777  print '<td class="liste_titre">';
778  print '</td>';
779 }
780 if (!empty($arrayfields['u.statut']['checked'])) {
781  // Status
782  print '<td class="liste_titre center">';
783  print $form->selectarray('search_statut', array('-1'=>'', '0'=>$langs->trans('Disabled'), '1'=>$langs->trans('Enabled')), $search_statut, 0, 0, 0, '', 0, 0, 0, '', 'minwidth75imp');
784  print '</td>';
785 }
786 // Action column
787 if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) {
788  print '<td class="liste_titre maxwidthsearch">';
789  $searchpicto = $form->showFilterButtons();
790  print $searchpicto;
791  print '</td>';
792 }
793 print '</tr>'."\n";
794 
795 $totalarray = array();
796 $totalarray['nbfield'] = 0;
797 
798 // Fields title label
799 // --------------------------------------------------------------------
800 print '<tr class="liste_titre">';
801 if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) {
802  print getTitleFieldOfList(($mode != 'kanban' ? $selectedfields : ''), 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
803  $totalarray['nbfield']++;
804 }
805 if (!empty($arrayfields['u.login']['checked'])) {
806  print_liste_field_titre("Login", $_SERVER['PHP_SELF'], "u.login", $param, "", "", $sortfield, $sortorder);
807  $totalarray['nbfield']++;
808 }
809 if (!empty($arrayfields['u.lastname']['checked'])) {
810  print_liste_field_titre("Lastname", $_SERVER['PHP_SELF'], "u.lastname", $param, "", "", $sortfield, $sortorder);
811  $totalarray['nbfield']++;
812 }
813 if (!empty($arrayfields['u.firstname']['checked'])) {
814  print_liste_field_titre("FirstName", $_SERVER['PHP_SELF'], "u.firstname", $param, "", "", $sortfield, $sortorder);
815  $totalarray['nbfield']++;
816 }
817 if (!empty($arrayfields['u.gender']['checked'])) {
818  print_liste_field_titre("Gender", $_SERVER['PHP_SELF'], "u.gender", $param, "", "", $sortfield, $sortorder, 'center ');
819  $totalarray['nbfield']++;
820 }
821 if (!empty($arrayfields['u.employee']['checked'])) {
822  print_liste_field_titre("Employee", $_SERVER['PHP_SELF'], "u.employee", $param, "", "", $sortfield, $sortorder, 'center ');
823  $totalarray['nbfield']++;
824 }
825 if (!empty($arrayfields['u.fk_user']['checked'])) {
826  print_liste_field_titre("HierarchicalResponsible", $_SERVER['PHP_SELF'], "u.fk_user", $param, "", "", $sortfield, $sortorder);
827  $totalarray['nbfield']++;
828 }
829 if (!empty($arrayfields['u.accountancy_code']['checked'])) {
830  print_liste_field_titre("AccountancyCode", $_SERVER['PHP_SELF'], "u.accountancy_code", $param, "", "", $sortfield, $sortorder);
831  $totalarray['nbfield']++;
832 }
833 if (!empty($arrayfields['u.office_phone']['checked'])) {
834  print_liste_field_titre("PhonePro", $_SERVER['PHP_SELF'], "u.office_phone", $param, "", "", $sortfield, $sortorder);
835  $totalarray['nbfield']++;
836 }
837 if (!empty($arrayfields['u.user_mobile']['checked'])) {
838  print_liste_field_titre("PhoneMobile", $_SERVER['PHP_SELF'], "u.user_mobile", $param, "", "", $sortfield, $sortorder);
839  $totalarray['nbfield']++;
840 }
841 if (!empty($arrayfields['u.email']['checked'])) {
842  print_liste_field_titre("EMail", $_SERVER['PHP_SELF'], "u.email", $param, "", "", $sortfield, $sortorder);
843  $totalarray['nbfield']++;
844 }
845 if (!empty($arrayfields['u.api_key']['checked'])) {
846  print_liste_field_titre("ApiKey", $_SERVER['PHP_SELF'], "u.api_key", $param, "", "", $sortfield, $sortorder);
847  $totalarray['nbfield']++;
848 }
849 if (!empty($arrayfields['u.fk_soc']['checked'])) {
850  print_liste_field_titre("Company", $_SERVER['PHP_SELF'], "u.fk_soc", $param, "", "", $sortfield, $sortorder);
851  $totalarray['nbfield']++;
852 }
853 if (!empty($arrayfields['u.entity']['checked'])) {
854  print_liste_field_titre("Entity", $_SERVER['PHP_SELF'], "u.entity", $param, "", "", $sortfield, $sortorder);
855  $totalarray['nbfield']++;
856 }
857 if (!empty($arrayfields['u.salary']['checked'])) {
858  print_liste_field_titre("Salary", $_SERVER['PHP_SELF'], "u.salary", $param, "", "", $sortfield, $sortorder, 'right ');
859  $totalarray['nbfield']++;
860 }
861 if (!empty($arrayfields['u.datelastlogin']['checked'])) {
862  print_liste_field_titre("LastConnexion", $_SERVER['PHP_SELF'], "u.datelastlogin", $param, "", '', $sortfield, $sortorder, 'center ');
863  $totalarray['nbfield']++;
864 }
865 if (!empty($arrayfields['u.datepreviouslogin']['checked'])) {
866  print_liste_field_titre("PreviousConnexion", $_SERVER['PHP_SELF'], "u.datepreviouslogin", $param, "", '', $sortfield, $sortorder, 'center ');
867  $totalarray['nbfield']++;
868 }
869 // Extra fields
870 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php';
871 // Hook fields
872 $parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder, 'totalarray'=>&$totalarray);
873 $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook
874 print $hookmanager->resPrint;
875 if (!empty($arrayfields['u.datec']['checked'])) {
876  print_liste_field_titre("DateCreationShort", $_SERVER["PHP_SELF"], "u.datec", "", $param, '', $sortfield, $sortorder, 'center nowrap ');
877  $totalarray['nbfield']++;
878 }
879 if (!empty($arrayfields['u.tms']['checked'])) {
880  print_liste_field_titre("DateModificationShort", $_SERVER["PHP_SELF"], "u.tms", "", $param, '', $sortfield, $sortorder, 'center nowrap ');
881  $totalarray['nbfield']++;
882 }
883 if (!empty($arrayfields['u.statut']['checked'])) {
884  print_liste_field_titre("Status", $_SERVER["PHP_SELF"], "u.statut", "", $param, '', $sortfield, $sortorder, 'center ');
885  $totalarray['nbfield']++;
886 }
887 // Action column
888 if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) {
889  print getTitleFieldOfList(($mode != 'kanban' ? $selectedfields : ''), 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
890  $totalarray['nbfield']++;
891 }
892 print '</tr>'."\n";
893 
894 
895 // Detect if we need a fetch on each output line
896 $needToFetchEachLine = 0;
897 if (isset($extrafields->attributes[$object->table_element]['computed']) && is_array($extrafields->attributes[$object->table_element]['computed']) && count($extrafields->attributes[$object->table_element]['computed']) > 0) {
898  foreach ($extrafields->attributes[$object->table_element]['computed'] as $key => $val) {
899  if (preg_match('/\$object/', $val)) {
900  $needToFetchEachLine++; // There is at least one compute field that use $object
901  }
902  }
903 }
904 
905 
906 // Loop on record
907 // --------------------------------------------------------------------
908 $i = 0;
909 $savnbfield = $totalarray['nbfield'];
910 $totalarray['nbfield'] = 0;
911 $imaxinloop = ($limit ? min($num, $limit) : $num);
912 while ($i < $imaxinloop) {
913  $obj = $db->fetch_object($resql);
914  if (empty($obj)) {
915  break; // Should not happen
916  }
917 
918  if (empty($obj->country_code)) $obj->country_code = ''; // TODO Add join in select with country table to get country_code
919 
920  // Store properties in $object
921  $object->setVarsFromFetchObj($obj);
922 
923  $object->id = $obj->rowid;
924  $object->admin = $obj->admin;
925  $object->ref = $obj->rowid;
926  $object->login = $obj->login;
927  $object->statut = $obj->status;
928  $object->status = $obj->status;
929  $object->office_phone = $obj->office_phone;
930  $object->user_mobile = $obj->user_mobile;
931  $object->email = $obj->email;
932  $object->gender = $obj->gender;
933  $object->socid = $obj->fk_soc;
934  $object->firstname = $obj->firstname;
935  $object->lastname = $obj->lastname;
936  $object->employee = $obj->employee;
937  $object->photo = $obj->photo;
938 
939  $li = $object->getNomUrl(-1, '', 0, 0, 24, 1, 'login', '', 1);
940 
941  $canreadhrmdata = 0;
942  if ((!empty($conf->salaries->enabled) && !empty($user->rights->salaries->read) && in_array($obj->rowid, $childids))
943  || (!empty($conf->salaries->enabled) && !empty($user->rights->salaries->readall))
944  || (!empty($conf->hrm->enabled) && !empty($user->rights->hrm->employee->read))) {
945  $canreadhrmdata = 1;
946  }
947  $canreadsecretapi = 0;
948  if ($user->id == $obj->rowid || !empty($user->admin)) { // Current user or admin
949  $canreadsecretapi = 1;
950  }
951 
952  if ($mode == 'kanban') {
953  if ($i == 0) {
954  print '<tr><td colspan="'.$savnbfield.'">';
955  print '<div class="box-flex-container">';
956  }
957 
958  // Output Kanban
959  print $object->getKanbanView('');
960  if ($i == ($imaxinloop - 1)) {
961  print '</div>';
962  print '</td></tr>';
963  }
964  } else {
965  // Show here line of result
966  $j = 0;
967  print '<tr data-rowid="'.$object->id.'" class="oddeven">';
968  // Action column
969  if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) {
970  print '<td class="nowrap center">';
971  if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
972  $selected = 0;
973  if (in_array($object->id, $arrayofselected)) {
974  $selected = 1;
975  }
976  print '<input id="cb'.$object->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$object->id.'"'.($selected ? ' checked="checked"' : '').'>';
977  }
978  print '</td>';
979  }
980  // Login
981  if (!empty($arrayfields['u.login']['checked'])) {
982  print '<td class="nowraponall tdoverflowmax150">';
983  print $li;
984  if (!empty($conf->multicompany->enabled) && $obj->admin && !$obj->entity) {
985  print img_picto($langs->trans("SuperAdministrator"), 'redstar', 'class="valignmiddle paddingleft"');
986  } elseif ($obj->admin) {
987  print img_picto($langs->trans("Administrator"), 'star', 'class="valignmiddle paddingleft"');
988  }
989  print '</td>';
990  if (!$i) {
991  $totalarray['nbfield']++;
992  }
993  }
994  if (!empty($arrayfields['u.lastname']['checked'])) {
995  print '<td class="tdoverflowmax150" title="'.dol_escape_htmltag($obj->lastname).'">'.dol_escape_htmltag($obj->lastname).'</td>';
996  if (!$i) {
997  $totalarray['nbfield']++;
998  }
999  }
1000  if (!empty($arrayfields['u.firstname']['checked'])) {
1001  print '<td class="tdoverflowmax150" title="'.dol_escape_htmltag($obj->lastname).'">'.dol_escape_htmltag($obj->firstname).'</td>';
1002  if (!$i) {
1003  $totalarray['nbfield']++;
1004  }
1005  }
1006  if (!empty($arrayfields['u.gender']['checked'])) {
1007  print '<td class="center">';
1008  if ($obj->gender) {
1009  // Preparing gender's display if there is one
1010  $addgendertxt = '';
1011  switch ($obj->gender) {
1012  case 'man':
1013  $addgendertxt .= '<i class="fas fa-mars" title="'.dol_escape_htmltag($langs->trans("Gender".$obj->gender)).'"></i>';
1014  break;
1015  case 'woman':
1016  $addgendertxt .= '<i class="fas fa-venus" title="'.dol_escape_htmltag($langs->trans("Gender".$obj->gender)).'"></i>';
1017  break;
1018  case 'other':
1019  $addgendertxt .= '<i class="fas fa-transgender" title="'.dol_escape_htmltag($langs->trans("Gender".$obj->gender)).'"></i>';
1020  break;
1021  }
1022  print $addgendertxt;
1023  //print $langs->trans("Gender".$obj->gender);
1024  }
1025  print '</td>';
1026  if (!$i) {
1027  $totalarray['nbfield']++;
1028  }
1029  }
1030  // Employee yes/no
1031  if (!empty($arrayfields['u.employee']['checked'])) {
1032  print '<td class="center">'.yn($obj->employee).'</td>';
1033  if (!$i) {
1034  $totalarray['nbfield']++;
1035  }
1036  }
1037 
1038  // Supervisor
1039  if (!empty($arrayfields['u.fk_user']['checked'])) {
1040  // Resp
1041  print '<td class="nowrap">';
1042  if ($obj->login2) {
1043  $user2->id = $obj->id2;
1044  $user2->login = $obj->login2;
1045  $user2->lastname = $obj->lastname2;
1046  $user2->firstname = $obj->firstname2;
1047  $user2->gender = $obj->gender2;
1048  $user2->photo = $obj->photo2;
1049  $user2->admin = $obj->admin2;
1050  $user2->office_phone = $obj->office_phone;
1051  $user2->user_mobile = $obj->user_mobile;
1052  $user2->email = $obj->email2;
1053  $user2->socid = $obj->fk_soc2;
1054  $user2->statut = $obj->status2;
1055  $user2->status = $obj->status2;
1056  print $user2->getNomUrl(-1, '', 0, 0, 24, 0, '', '', 1);
1057  if (!empty($conf->multicompany->enabled) && $obj->admin2 && !$obj->entity2) {
1058  print img_picto($langs->trans("SuperAdministrator"), 'redstar', 'class="valignmiddle paddingleft"');
1059  } elseif ($obj->admin2) {
1060  print img_picto($langs->trans("Administrator"), 'star', 'class="valignmiddle paddingleft"');
1061  }
1062  }
1063  print '</td>';
1064  if (!$i) {
1065  $totalarray['nbfield']++;
1066  }
1067  }
1068 
1069  if (!empty($arrayfields['u.accountancy_code']['checked'])) {
1070  print '<td>'.$obj->accountancy_code.'</td>';
1071  if (!$i) {
1072  $totalarray['nbfield']++;
1073  }
1074  }
1075 
1076  // Phone
1077  if (!empty($arrayfields['u.office_phone']['checked'])) {
1078  print '<td class="tdoverflowmax125">'.dol_print_phone($obj->office_phone, $obj->country_code, 0, $obj->rowid, 'AC_TEL', ' ', 'phone')."</td>\n";
1079  if (!$i) {
1080  $totalarray['nbfield']++;
1081  }
1082  }
1083  if (!empty($arrayfields['u.user_mobile']['checked'])) {
1084  print '<td class="tdoverflowmax125">'.dol_print_phone($obj->user_mobile, $obj->country_code, 0, $obj->rowid, 'AC_TEL', ' ', 'mobile')."</td>\n";
1085  if (!$i) {
1086  $totalarray['nbfield']++;
1087  }
1088  }
1089  if (!empty($arrayfields['u.email']['checked'])) {
1090  print '<td class="tdoverflowmax150">'.dol_print_email($obj->email, $obj->rowid, $obj->fk_soc, 'AC_EMAIL', 0, 0, 1)."</td>\n";
1091  if (!$i) {
1092  $totalarray['nbfield']++;
1093  }
1094  }
1095  if (!empty($arrayfields['u.api_key']['checked'])) {
1096  print '<td class="tdoverflowmax125" title="'.dol_escape_htmltag($obj->api_key).'">';
1097  if ($obj->api_key) {
1098  if ($canreadsecretapi) {
1099  print dol_escape_htmltag($obj->api_key);
1100  } else {
1101  print '<span class="opacitymedium">'.$langs->trans("Hidden").'</span>';
1102  }
1103  }
1104  print '</td>';
1105  if (!$i) {
1106  $totalarray['nbfield']++;
1107  }
1108  }
1109  if (!empty($arrayfields['u.fk_soc']['checked'])) {
1110  print '<td class="tdoverflowmax150">';
1111  if ($obj->fk_soc > 0) {
1112  $companystatic->id = $obj->fk_soc;
1113  $companystatic->name = $obj->name;
1114  $companystatic->canvas = $obj->canvas;
1115  print $companystatic->getNomUrl(1);
1116  } elseif ($obj->ldap_sid) {
1117  print '<span class="opacitymedium">'.$langs->trans("DomainUser").'</span>';
1118  } else {
1119  print '<span class="opacitymedium">'.$langs->trans("InternalUser").'</span>';
1120  }
1121  print '</td>';
1122  if (!$i) {
1123  $totalarray['nbfield']++;
1124  }
1125  }
1126  // Multicompany enabled
1127  if (!empty($conf->multicompany->enabled) && is_object($mc) && empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
1128  if (!empty($arrayfields['u.entity']['checked'])) {
1129  print '<td>';
1130  if (!$obj->entity) {
1131  print $langs->trans("AllEntities");
1132  } else {
1133  $mc->getInfo($obj->entity);
1134  print $mc->label;
1135  }
1136  print '</td>';
1137  if (!$i) {
1138  $totalarray['nbfield']++;
1139  }
1140  }
1141  }
1142 
1143  // Salary
1144  if (!empty($arrayfields['u.salary']['checked'])) {
1145  print '<td class="nowraponall right amount">';
1146  if ($obj->salary) {
1147  if ($canreadhrmdata) {
1148  print price($obj->salary);
1149  } else {
1150  print '<span class="opacitymedium">'.$langs->trans("Hidden").'</span>';
1151  }
1152  }
1153  print '</td>';
1154  if (!$i) {
1155  $totalarray['nbfield']++;
1156  }
1157  }
1158 
1159  // Date last login
1160  if (!empty($arrayfields['u.datelastlogin']['checked'])) {
1161  print '<td class="nowrap center">'.dol_print_date($db->jdate($obj->datelastlogin), "dayhour").'</td>';
1162  if (!$i) {
1163  $totalarray['nbfield']++;
1164  }
1165  }
1166  // Date previous login
1167  if (!empty($arrayfields['u.datepreviouslogin']['checked'])) {
1168  print '<td class="nowrap center">'.dol_print_date($db->jdate($obj->datepreviouslogin), "dayhour").'</td>';
1169  if (!$i) {
1170  $totalarray['nbfield']++;
1171  }
1172  }
1173 
1174  // Extra fields
1175  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
1176  // Fields from hook
1177  $parameters = array('arrayfields'=>$arrayfields, 'object'=>$object, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray);
1178  $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object); // Note that $action and $object may have been modified by hook
1179  print $hookmanager->resPrint;
1180  // Date creation
1181  if (!empty($arrayfields['u.datec']['checked'])) {
1182  print '<td class="center">';
1183  print dol_print_date($db->jdate($obj->date_creation), 'dayhour', 'tzuser');
1184  print '</td>';
1185  if (!$i) {
1186  $totalarray['nbfield']++;
1187  }
1188  }
1189  // Date modification
1190  if (!empty($arrayfields['u.tms']['checked'])) {
1191  print '<td class="center">';
1192  print dol_print_date($db->jdate($obj->date_update), 'dayhour', 'tzuser');
1193  print '</td>';
1194  if (!$i) {
1195  $totalarray['nbfield']++;
1196  }
1197  }
1198  // Status
1199  if (!empty($arrayfields['u.statut']['checked'])) {
1200  print '<td class="center">'.$object->getLibStatut(5).'</td>';
1201  if (!$i) {
1202  $totalarray['nbfield']++;
1203  }
1204  }
1205  // Action column
1206  if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) {
1207  print '<td class="nowrap center">';
1208  if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
1209  $selected = 0;
1210  if (in_array($object->id, $arrayofselected)) {
1211  $selected = 1;
1212  }
1213  print '<input id="cb'.$object->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$object->id.'"'.($selected ? ' checked="checked"' : '').'>';
1214  }
1215  print '</td>';
1216  }
1217  if (!$i) {
1218  $totalarray['nbfield']++;
1219  }
1220 
1221  print '</tr>'."\n";
1222  }
1223 
1224  $i++;
1225 }
1226 
1227 // Show total line
1228 include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php';
1229 
1230 // If no record found
1231 if ($num == 0) {
1232  $colspan = 1;
1233  foreach ($arrayfields as $key => $val) {
1234  if (!empty($val['checked'])) {
1235  $colspan++;
1236  }
1237  }
1238  print '<tr><td colspan="'.$colspan.'"><span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span></td></tr>';
1239 }
1240 
1241 
1242 $db->free($resql);
1243 
1244 $parameters = array('arrayfields'=>$arrayfields, 'sql'=>$sql);
1245 $reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object); // Note that $action and $object may have been modified by hook
1246 print $hookmanager->resPrint;
1247 
1248 print '</table>'."\n";
1249 print '</div>'."\n";
1250 
1251 print '</form>'."\n";
1252 
1253 
1254 // End of page
1255 llxFooter();
1256 $db->close();
Societe
Class to manage third parties objects (customers, suppliers, prospects...)
Definition: societe.class.php:48
dol_escape_htmltag
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.
Definition: functions.lib.php:1468
llxFooter
llxFooter()
Empty footer.
Definition: wrapper.php:73
getTitleFieldOfList
getTitleFieldOfList($name, $thead=0, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $disablesortlink=0, $tooltip='', $forcenowrapcolumntitle=0)
Get title line of an array.
Definition: functions.lib.php:5049
GETPOST
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
Definition: functions.lib.php:484
dol_print_error
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
Definition: functions.lib.php:4844
dol_sort_array
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...
Definition: functions.lib.php:8385
dolGetButtonTitleSeparator
dolGetButtonTitleSeparator($moreClass="")
Add space between dolGetButtonTitle.
Definition: functions.lib.php:10570
$form
if($cancel &&! $id) if($action=='add' &&! $cancel) if($action=='delete') if($id) $form
Actions.
Definition: card.php:142
FormOther
Classe permettant la generation de composants html autre Only common components are here.
Definition: html.formother.class.php:39
Categorie
Class to manage categories.
Definition: categorie.class.php:47
$help_url
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
dol_print_date
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
Definition: functions.lib.php:2514
img_picto
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
Definition: functions.lib.php:3880
dolGetButtonTitle
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.
Definition: functions.lib.php:10605
print_barre_liste
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.
Definition: functions.lib.php:5257
getDolGlobalString
if(!function_exists('utf8_encode')) if(!function_exists('utf8_decode')) getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
Definition: functions.lib.php:80
FormProduct
Class with static methods for building HTML components related to products Only components common to ...
Definition: html.formproduct.class.php:30
isModEnabled
isModEnabled($module)
Is Dolibarr module enabled.
Definition: functions.lib.php:105
User
Class to manage Dolibarr users.
Definition: user.class.php:44
GETPOSTISSET
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
Definition: functions.lib.php:386
print_liste_field_titre
print_liste_field_titre($name, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $tooltip="", $forcenowrapcolumntitle=0)
Show title line of an array.
Definition: functions.lib.php:5026
natural_search
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...
Definition: functions.lib.php:9420
ExtraFields
Class to manage standard extra fields.
Definition: extrafields.class.php:39
Form
Class to manage generation of HTML components Only common components must be here.
Definition: html.form.class.php:52
dol_now
dol_now($mode='auto')
Return date for now.
Definition: functions.lib.php:2845
$resql
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
price
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.
Definition: functions.lib.php:5541
setEventMessages
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='')
Set event messages in dol_events session object.
Definition: functions.lib.php:8137
accessforbidden
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 ...
Definition: security.lib.php:933
dol_mktime
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...
Definition: functions.lib.php:2757
llxHeader
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