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