dolibarr 25.0.0-alpha
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-2024 Regis Houssin <regis.houssin@inodbox.com>
5 * Copyright (C) 2015-2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
6 * Copyright (C) 2016 Marcos García <marcosgdf@gmail.com>
7 * Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
8 * Copyright (C) 2024 Benjamin Falière <benjamin.faliere@altairis.fr>
9 * Copyright (C) 2024 William Mead <william.mead@manchenumerique.fr>
10 * Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 3 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program. If not, see <https://www.gnu.org/licenses/>.
24 */
25
32// Load Dolibarr environment
33require '../main.inc.php';
42require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
43require_once DOL_DOCUMENT_ROOT.'/core/lib/phone.lib.php';
44if (isModEnabled('category')) {
45 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
46}
47
48// Load translation files required by page
49$langs->loadLangs(array('users', 'companies', 'hrm', 'salaries'));
50
51$action = GETPOST('action', 'aZ09') ? GETPOST('action', 'aZ09') : 'view'; // The action 'add', 'create', 'edit', 'update', 'view', ...
52$massaction = GETPOST('massaction', 'alpha'); // The bulk action (combo box choice into lists)
53$show_files = GETPOSTINT('show_files'); // Show files area generated by bulk actions ?
54$confirm = GETPOST('confirm', 'alpha'); // Result of a confirmation
55$cancel = GETPOST('cancel', 'alpha'); // We click on a Cancel button
56$toselect = GETPOST('toselect', 'array:int'); // Array of ids of elements selected into a list
57$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : str_replace('_', '', basename(dirname(__FILE__)).basename(__FILE__, '.php')); // To manage different context of search
58$backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page
59$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print')
60$mode = GETPOST("mode", 'aZ');
61
62// Security check (for external users)
63$socid = 0;
64if ($user->socid > 0) {
65 $socid = $user->socid;
66}
67
68// Load variable for pagination
69$limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
70$sortfield = GETPOST('sortfield', 'aZ09comma');
71$sortorder = GETPOST('sortorder', 'aZ09comma');
72$page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page");
73if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha')) {
74 // If $page is not defined, or '' or -1 or if we click on clear filters
75 $page = 0;
76}
77$offset = $limit * $page;
78$pageprev = $page - 1;
79$pagenext = $page + 1;
80
81// Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context
82$object = new User($db);
83
84$diroutputmassaction = $conf->user->dir_output.'/temp/massgeneration/'.$user->id;
85$hookmanager->initHooks(array('userlist'));
86
87// Fetch optionals attributes and labels
88$extrafields->fetch_name_optionals_label($object->table_element);
89
90$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
91
92if (!$sortfield) {
93 $sortfield = "u.login";
94}
95if (!$sortorder) {
96 $sortorder = "ASC";
97}
98
99// Initialize array of search criteria
100$search_all = trim(GETPOST('search_all', 'alphanohtml'));
101$search = array();
102foreach ($object->fields as $key => $val) {
103 if (GETPOST('search_'.$key, 'alpha') !== '') {
104 $search[$key] = GETPOST('search_'.$key, 'alpha');
105 }
106 if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
107 $search[$key.'_dtstart'] = dol_mktime(0, 0, 0, GETPOSTINT('search_'.$key.'_dtstartmonth'), GETPOSTINT('search_'.$key.'_dtstartday'), GETPOSTINT('search_'.$key.'_dtstartyear'));
108 $search[$key.'_dtend'] = dol_mktime(23, 59, 59, GETPOSTINT('search_'.$key.'_dtendmonth'), GETPOSTINT('search_'.$key.'_dtendday'), GETPOSTINT('search_'.$key.'_dtendyear'));
109 }
110}
111
112$userstatic = new User($db);
113$companystatic = new Societe($db);
114$form = new Form($db);
115
116// List of fields to search into when doing a "search in all"
117$fieldstosearchall = array(
118 'u.login' => "Login",
119 'u.lastname' => "Lastname",
120 'u.firstname' => "Firstname",
121 'u.accountancy_code' => "AccountancyCode",
122 'u.office_phone' => "PhonePro",
123 'u.user_mobile' => "PhoneMobile",
124 'u.email' => "EMail",
125 'co.label' => "Country",
126 'u.note_public' => "NotePublic",
127 'u.note_private' => "NotePrivate"
128);
129if (isModEnabled('api')) {
130 $fieldstosearchall['u.api_key'] = "ApiKey";
131}
132
133$permissiontoreadhr = $user->hasRight('hrm', 'read_personal_information', 'read') || $user->hasRight('hrm', 'write_personal_information', 'write');
134$permissiontowritehr = $user->hasRight('hrm', 'write_personal_information', 'write');
135
136// Definition of fields for list
137$arrayfields = array(
138 'u.rowid' => array('label' => "TechnicalID", 'checked' => '-1', 'position' => 5),
139 'u.login' => array('label' => "Login", 'checked' => '1', 'position' => 10),
140 'u.lastname' => array('label' => "Lastname", 'checked' => '1', 'position' => 15),
141 'u.firstname' => array('label' => "Firstname", 'checked' => '1', 'position' => 20),
142 'u.entity' => array('label' => "Entity", 'checked' => '1', 'position' => 50, 'enabled' => (string) (int) (isModEnabled('multicompany') && !getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE'))),
143 'u.gender' => array('label' => "Gender", 'checked' => '0', 'position' => 22),
144 'u.employee' => array('label' => "Employee", 'checked' => ($contextpage == 'employeelist' ? '1' : '0'), 'position' => 25),
145 'u.fk_user' => array('label' => "HierarchicalResponsible", 'checked' => '1', 'position' => 27, 'csslist' => 'maxwidth150'),
146 'u.accountancy_code' => array('label' => "AccountancyCode", 'checked' => '0', 'position' => 30),
147 'u.office_phone' => array('label' => "PhonePro", 'checked' => '1', 'position' => 31),
148 'u.user_mobile' => array('label' => "PhoneMobile", 'checked' => '1', 'position' => 32),
149 'u.email' => array('label' => "EMail", 'checked' => '1', 'position' => 35),
150 'co.label' => array('label' => "Country", 'checked' => '0', 'position' => 37),
151 'u.api_key' => array('label' => "ApiKey", 'checked' => '0', 'position' => 40, "enabled" => (string) (int) (isModEnabled('api') && $user->admin)),
152 'u.fk_soc' => array('label' => "Company", 'checked' => ($contextpage == 'employeelist' ? '0' : '1'), 'position' => 45),
153 'u.ref_employee' => array('label' => "RefEmployee", 'checked' => '-1', 'position' => 50, 'enabled' => (string) (int) (isModEnabled('hrm') && $permissiontoreadhr)),
154 'u.national_registration_number' => array('label' => "NationalRegistrationNumber", 'checked' => '-1', 'position' => 51, 'enabled' => (string) (int) (isModEnabled('hrm') && $permissiontoreadhr)),
155 'u.job' => array('label' => "PostOrFunction", 'checked' => '-1', 'position' => 60),
156 'u.salary' => array('label' => "Salary", 'checked' => '-1', 'position' => 80, 'enabled' => (string) (int) (isModEnabled('salaries') && $user->hasRight("salaries", "readall")), 'isameasure' => 1),
157 'u.thm' => array('label' => "THM", 'langs' => 'salaries', 'checked' => '-1', 'position' => 82, 'enabled' => '1', 'isameasure' => 1),
158 'u.datec' => array('label' => "DateCreation", 'checked' => '0', 'position' => 500),
159 'date_modification' => array('label' => "DateModificationShort", 'checked' => '0', 'position' => 500),
160 'u.import_key' => array('label' => "ImportId", 'checked' => '-1', 'position' => 800, 'enabled' => '1'),
161 'u.statut' => array('label' => "Status", 'checked' => '1', 'position' => 1000),
162);
163// Add hook to complete $arrayfield
164$parameters = array('arrayfields' => &$arrayfields);
165$reshook = $hookmanager->executeHooks('completeArrayFields', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
166
167if (getDolGlobalInt('MAIN_ENABLE_LOGINS_PRIVACY') == 0) {
168 $arrayfields['u.datelastlogin'] = array('label' => "LastConnexion", 'checked' => '1', 'position' => 100);
169 $arrayfields['u.datepreviouslogin'] = array('label' => "PreviousConnexion", 'checked' => '0', 'position' => 110);
170}
171
172// Extra fields
173include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_list_array_fields.tpl.php';
174
175$object->fields = dol_sort_array($object->fields, 'position');
176$arrayfields = dol_sort_array($arrayfields, 'position');
177
178// Init search fields
179$search_all = trim(GETPOST('search_all', 'alphanohtml'));
180$search_user = GETPOST('search_user', 'alpha');
181$search_rowid = GETPOST('search_rowid', 'alpha');
182$search_login = GETPOST('search_login', 'alpha');
183$search_lastname = GETPOST('search_lastname', 'alpha');
184$search_firstname = GETPOST('search_firstname', 'alpha');
185$search_gender = GETPOST('search_gender', 'alpha');
186$search_employee = GETPOST('search_employee', 'alpha');
187$search_accountancy_code = GETPOST('search_accountancy_code', 'alpha');
188$search_phonepro = GETPOST('search_phonepro', 'alpha');
189$search_phonemobile = GETPOST('search_phonemobile', 'alpha');
190$search_email = GETPOST('search_email', 'alpha');
191$search_country = GETPOST('search_country', 'alpha');
192$search_api_key = GETPOST('search_api_key', 'alphanohtml');
193$search_status = GETPOST('search_status', 'intcomma');
194$search_thirdparty = GETPOST('search_thirdparty', 'alpha');
195$search_job = GETPOST('search_job', 'alpha');
196$search_warehouse = GETPOST('search_warehouse', 'alpha');
197$search_supervisor = GETPOST('search_supervisor', 'intcomma');
198$search_categ = GETPOST("search_categ", 'intcomma');
199$search_datelastlogin = GETPOSTDATE('search_datelastlogin', '', 'tzuserrel');
200$search_datepreviouslogin = GETPOSTDATE('search_datepreviouslogin', '', 'tzuserrel');
201
202$searchCategoryUserOperator = 0;
203if (GETPOSTISSET('formfilteraction')) {
204 $searchCategoryUserOperator = GETPOSTINT('search_category_user_operator');
205} elseif (getDolGlobalString('MAIN_SEARCH_CAT_OR_BY_DEFAULT')) {
206 $searchCategoryUserOperator = getDolGlobalString('MAIN_SEARCH_CAT_OR_BY_DEFAULT');
207}
208$searchCategoryUserList = GETPOST('search_category_user_list', 'array:int');
209$catid = GETPOSTINT('catid');
210if (!empty($catid) && empty($searchCategoryUserList)) {
211 $searchCategoryUserList = array($catid);
212}
213$catid = GETPOSTINT('catid');
214if (!empty($catid) && empty($search_categ)) {
215 $search_categ = $catid;
216}
217
218// Default search
219if ($search_status == '' && empty($search_all)) {
220 $search_status = '1';
221}
222if ($contextpage == 'employeelist' && !GETPOSTISSET('search_employee')) {
223 $search_employee = 1;
224}
225
226// Define value to know what current user can do on users
227$permissiontoadd = (isModEnabled('multicompany') && !empty($user->entity) && getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE') ? false : (!empty($user->admin) || $user->hasRight("user", "user", "write")));
228$canreaduser = (!empty($user->admin) || $user->hasRight("user", "user", "read"));
229$canedituser = $permissiontoadd;
230$candisableuser = (isModEnabled('multicompany') && !empty($user->entity) && getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE') ? false : (!empty($user->admin) || $user->hasRight("user", "user", "delete")));
231$canreadgroup = $canreaduser;
232$caneditgroup = $canedituser;
233if (getDolGlobalString('MAIN_USE_ADVANCED_PERMS')) {
234 $canreadgroup = (!empty($user->admin) || $user->hasRight("user", "group_advance", "read"));
235 $caneditgroup = (isModEnabled('multicompany') && !empty($user->entity) && getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE') ? false : (!empty($user->admin) || $user->hasRight("user", "group_advance", "write")));
236}
237
238$error = 0;
239
240// Permission to list
241if (isModEnabled('salaries') && $contextpage == 'employeelist' && $search_employee == 1) {
242 if (!$user->hasRight("salaries", "read")) {
244 }
245} else {
246 if (!$user->hasRight("user", "user", "read") && empty($user->admin)) {
248 }
249}
250
251$childids = $user->getAllChildIds(1);
252
253
254/*
255 * Actions
256 */
257
258if (GETPOST('cancel', 'alpha')) {
259 $action = 'list';
260 $massaction = '';
261}
262if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') {
263 $massaction = '';
264}
265
266$parameters = array('arrayfields' => &$arrayfields);
267$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
268if ($reshook < 0) {
269 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
270}
271
272if (empty($reshook)) {
273 // Selection of new fields
274 include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
275
276 // Purge search criteria
277 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
278 $search_user = "";
279 $search_rowid = "";
280 $search_login = "";
281 $search_lastname = "";
282 $search_firstname = "";
283 $search_gender = "";
284 $search_employee = "";
285 $search_accountancy_code = "";
286 $search_phonepro = "";
287 $search_phonemobile = "";
288 $search_email = "";
289 $search_country = "";
290 $search_status = "";
291 $search_thirdparty = "";
292 $search_job = "";
293 $search_warehouse = "";
294 $search_supervisor = "";
295 $search_api_key = "";
296 $search_categ = 0;
297 $search_all = '';
298 $toselect = array();
299 $search_array_options = array();
300 if (getDolGlobalInt('MAIN_ENABLE_LOGINS_PRIVACY') == 0) {
301 $search_datelastlogin = "";
302 $search_datepreviouslogin = "";
303 }
304 }
305 if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')
306 || GETPOST('button_search_x', 'alpha') || GETPOST('button_search.x', 'alpha') || GETPOST('button_search', 'alpha')) {
307 $massaction = ''; // Protection to avoid mass action if we force a new search during a mass action confirmation
308 }
309
310 // Mass actions
311 $objectclass = 'User';
312 $objectlabel = 'User';
313 $uploaddir = $conf->user->dir_output;
314
315 global $error;
316
317 // Disable or Enable records
318 if (!$error && ($massaction == 'disable' || $massaction == 'reactivate') && $permissiontoadd) {
319 $objecttmp = new User($db);
320
321 $db->begin();
322
323 $nbok = 0;
324 foreach ($toselect as $toselectid) {
325 if ($toselectid == $user->id) {
326 setEventMessages($langs->trans($massaction == 'disable' ? 'CantDisableYourself' : 'CanEnableYourself'), null, 'errors');
327 $error++;
328 break;
329 }
330
331 $result = $objecttmp->fetch($toselectid);
332 if ($result > 0) {
333 if ($objecttmp->admin) {
334 setEventMessages($langs->trans($massaction == 'disable' ? 'CantDisableAnAdminUserWithMassActions' : 'CantEnableAnAdminUserWithMassActions', $objecttmp->login), null, 'errors');
335 $error++;
336 break;
337 }
338
339 $result = $objecttmp->setstatus($massaction == 'disable' ? 0 : 1);
340 if ($result == 0) {
341 // Nothing is done
342 } elseif ($result < 0) {
343 setEventMessages($objecttmp->error, $objecttmp->errors, 'errors');
344 $error++;
345 break;
346 } else {
347 $nbok++;
348 }
349 } else {
350 setEventMessages($objecttmp->error, $objecttmp->errors, 'errors');
351 $error++;
352 break;
353 }
354 }
355
356 if (!$error && !empty($conf->file->main_limit_users)) {
357 $nb = $object->getNbOfUsers("active");
358 if ($nb >= $conf->file->main_limit_users) {
359 $error++;
360 setEventMessages($langs->trans("YourQuotaOfUsersIsReached"), null, 'errors');
361 }
362 }
363
364 if (!$error) {
365 setEventMessages($langs->trans("RecordsModified", $nbok), null, 'mesgs');
366 $db->commit();
367 } else {
368 $db->rollback();
369 }
370
371 $massaction = '';
372 }
373
374 // Generic mass actions
375 include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
376}
377
378
379/*
380 * View
381 */
382
383$formother = new FormOther($db);
384$user2 = new User($db);
385
386$help_url = 'EN:Module_Users|FR:Module_Utilisateurs|ES:M&oacute;dulo_Usuarios|DE:Modul_Benutzer';
387if ($contextpage == 'employeelist' && $search_employee == 1) {
388 $title = $langs->trans("Employees");
389} else {
390 $title = $langs->trans("Users");
391}
392$morejs = array();
393$morecss = array();
394$morehtmlright = "";
395
396// Build and execute select
397// --------------------------------------------------------------------
398$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,";
399$sql .= " u.fk_user,";
400$sql .= " u.ref_employee, u.national_registration_number, u.job, u.salary, u.thm, u.datelastlogin, u.datepreviouslogin,";
401$sql .= " u.datestartvalidity, u.dateendvalidity,";
402$sql .= " u.ldap_sid, u.statut as status, u.entity, u.import_key,";
403$sql .= " GREATEST(u.tms, ef.tms) as date_modification, u.datec as date_creation,";
404$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,";
405$sql .= " s.nom as name, s.canvas,";
406$sql .= " co.code as country_code, co.label as country_label";
407// Add fields from extrafields
408if (!empty($extrafields->attributes[$object->table_element]['label'])) {
409 foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
410 $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key." as options_".$key : '');
411 }
412}
413// Add fields from hooks
414$parameters = array();
415$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object); // Note that $action and $object may have been modified by hook
416$sql .= $hookmanager->resPrint;
417$sql = preg_replace('/,\s*$/', '', $sql);
418
419$sqlfields = $sql; // $sql fields to remove for count total
420
421$sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as u";
422$sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (u.rowid = ef.fk_object)";
423$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON u.fk_soc = s.rowid";
424$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u2 ON u.fk_user = u2.rowid";
425$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as co ON u.fk_country = co.rowid";
426// Add table from hooks
427$parameters = array();
428$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object); // Note that $action and $object may have been modified by hook
429$sql .= $hookmanager->resPrint;
430if ($reshook > 0) {
431 $sql .= $hookmanager->resPrint;
432}
433$sql .= " WHERE u.entity IN (".getEntity($object->element).")";
434if ($socid > 0) {
435 $sql .= " AND u.fk_soc = ".((int) $socid);
436}
437//if ($search_user != '') $sql.=natural_search(array('u.login', 'u.lastname', 'u.firstname'), $search_user);
438if ($search_supervisor > 0) {
439 $sql .= " AND u.fk_user IN (".$db->sanitize($search_supervisor).")";
440}
441if ($search_thirdparty != '') {
442 $sql .= natural_search(array('s.nom'), $search_thirdparty);
443}
444if ($search_warehouse > 0) {
445 $sql .= natural_search(array('u.fk_warehouse'), $search_warehouse);
446}
447if ($search_rowid != '') {
448 $sql .= natural_search("u.rowid", $search_rowid, 1);
449}
450if ($search_login != '') {
451 $sql .= natural_search("u.login", $search_login);
452}
453if ($search_lastname != '') {
454 $sql .= natural_search("u.lastname", $search_lastname);
455}
456if ($search_firstname != '') {
457 $sql .= natural_search("u.firstname", $search_firstname);
458}
459if ($search_gender != '' && $search_gender != '-1') {
460 $sql .= " AND u.gender = '".$db->escape($search_gender)."'"; // Cannot use natural_search as looking for %man% also includes woman
461}
462if (is_numeric($search_employee) && $search_employee >= 0) {
463 $sql .= ' AND u.employee = '.(int) $search_employee;
464}
465if ($search_accountancy_code != '') {
466 $sql .= natural_search("u.accountancy_code", $search_accountancy_code);
467}
468if ($search_phonepro != '') {
469 $sql .= dol_natural_search_phone($db, "u.office_phone", $search_phonepro);
470}
471if ($search_phonemobile != '') {
472 $sql .= dol_natural_search_phone($db, "u.user_mobile", $search_phonemobile);
473}
474if ($search_email != '') {
475 $sql .= natural_search("u.email", $search_email);
476}
477if ($search_country != '') {
478 $sql .= " AND u.fk_country IN (".$db->sanitize($search_country).')';
479}
480if ($search_api_key != '') {
481 $sql .= natural_search("u.api_key", $search_api_key);
482}
483if ($search_job != '') {
484 $sql .= natural_search(array('u.job'), $search_job);
485}
486if ($search_status != '' && $search_status >= 0) {
487 $sql .= " AND u.statut IN (".$db->sanitize($search_status).")";
488}
489if ($search_all) {
490 $sql .= natural_search(array_keys($fieldstosearchall), $search_all);
491}
492// Search for tag/category ($searchCategoryUserList is an array of ID)
493$searchCategoryUserList = array($search_categ);
494if (!empty($searchCategoryUserList)) {
495 $searchCategoryUserSqlList = array();
496 $listofcategoryid = '';
497 foreach ($searchCategoryUserList as $searchCategoryUser) {
498 if (intval($searchCategoryUser) == -2) {
499 $searchCategoryUserSqlList[] = "NOT EXISTS (SELECT ck.fk_user FROM ".MAIN_DB_PREFIX."categorie_user as ck WHERE u.rowid = ck.fk_user)";
500 } elseif (intval($searchCategoryUser) > 0) {
501 if ($searchCategoryUserOperator == 0) {
502 $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).")";
503 } else {
504 $listofcategoryid .= ($listofcategoryid ? ', ' : '') .((int) $searchCategoryUser);
505 }
506 }
507 }
508 if ($listofcategoryid) {
509 $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)."))";
510 }
511 if ($searchCategoryUserOperator == 1) {
512 if (!empty($searchCategoryUserSqlList)) {
513 $sql .= " AND (".implode(' OR ', $searchCategoryUserSqlList).")";
514 }
515 } else {
516 if (!empty($searchCategoryUserSqlList)) {
517 $sql .= " AND (".implode(' AND ', $searchCategoryUserSqlList).")";
518 }
519 }
520}
521if ($search_warehouse > 0) {
522 $sql .= " AND u.fk_warehouse = ".((int) $search_warehouse);
523}
524if (isModEnabled('salaries') && $contextpage == 'employeelist' && !$user->hasRight("salaries", "readall")) {
525 $sql .= " AND u.rowid IN (".$db->sanitize(implode(',', $childids)).")";
526}
527// Add where from extra fields
528include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
529// Add where from hooks
530$parameters = array();
531$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object); // Note that $action and $object may have been modified by hook
532$sql .= $hookmanager->resPrint;
533
534// Count total nb of records
535$nbtotalofrecords = '';
536if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
537 /* The fast and low memory method to get and count full list converts the sql into a sql count */
538 $sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql);
539 $sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount);
540 $resql = $db->query($sqlforcount);
541 if ($resql) {
542 $objforcount = $db->fetch_object($resql);
543 $nbtotalofrecords = $objforcount->nbtotalofrecords;
544 } else {
545 dol_print_error($db);
546 }
547
548 if (($page * $limit) > (int) $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0
549 $page = 0;
550 $offset = 0;
551 }
552 $db->free($resql);
553}
554
555// Complete request and execute it with limit
556$sql .= $db->order($sortfield, $sortorder);
557if ($limit) {
558 $sql .= $db->plimit($limit + 1, $offset);
559}
560
561$resql = $db->query($sql);
562if (!$resql) {
563 dol_print_error($db);
564 exit;
565}
566
567$num = $db->num_rows($resql);
568
569// Direct jump if only one record found
570if ($num == 1 && getDolGlobalString('MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE') && $search_all && !$page) {
571 $obj = $db->fetch_object($resql);
572 $id = $obj->rowid;
573 header("Location: ".DOL_URL_ROOT.'/user/card.php?id='.$id);
574 exit;
575}
576
577// Output page
578// --------------------------------------------------------------------
579
580llxHeader('', $title, $help_url, '', 0, 0, $morejs, $morecss, '', 'bodyforlist mod-user page-list');
581
582$arrayofselected = is_array($toselect) ? $toselect : array();
583
584$param = '';
585if (!empty($mode)) {
586 $param .= '&mode='.urlencode($mode);
587}
588if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
589 $param .= '&contextpage='.urlencode($contextpage);
590}
591if ($limit > 0 && $limit != $conf->liste_limit) {
592 $param .= '&limit='.((int) $limit);
593}
594if ($optioncss != '') {
595 $param .= '&optioncss='.urlencode($optioncss);
596}
597if ($search_all != '') {
598 $param .= '&search_all='.urlencode($search_all);
599}
600if ($search_user != '') {
601 $param .= "&search_user=".urlencode($search_user);
602}
603if ($search_rowid != '') {
604 $param .= "&search_rowid=".urlencode($search_rowid);
605}
606if ($search_login != '') {
607 $param .= "&search_login=".urlencode($search_login);
608}
609if ($search_lastname != '') {
610 $param .= "&search_lastname=".urlencode($search_lastname);
611}
612if ($search_firstname != '') {
613 $param .= "&search_firstname=".urlencode($search_firstname);
614}
615if ($search_gender != '' && $search_gender != '-1') {
616 $param .= "&search_gender=".urlencode($search_gender);
617}
618if ($search_employee != '' && $search_employee != '-1') {
619 $param .= "&search_employee=".urlencode($search_employee);
620}
621if ($search_accountancy_code != '') {
622 $param .= "&search_accountancy_code=".urlencode($search_accountancy_code);
623}
624if ($search_phonepro != '') {
625 $param .= "&search_phonepro=".urlencode($search_phonepro);
626}
627if ($search_phonemobile != '') {
628 $param .= "&search_phonemobile=".urlencode($search_phonemobile);
629}
630if ($search_email != '') {
631 $param .= "&search_email=".urlencode($search_email);
632}
633if ($search_country != '') {
634 $param .= "&search_country=".urlencode($search_country);
635}
636if ($search_api_key != '') {
637 $param .= "&search_api_key=".urlencode($search_api_key);
638}
639if ($search_supervisor > 0) {
640 $param .= "&search_supervisor=".urlencode($search_supervisor);
641}
642if ($search_status != '') {
643 $param .= "&search_status=".urlencode($search_status);
644}
645if ($search_categ > 0) {
646 $param .= '&search_categ='.urlencode((string) ($search_categ));
647}
648if ($search_warehouse > 0) {
649 $param .= '&search_warehouse='.urlencode($search_warehouse);
650}
651// Add $param from extra fields
652include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
653
654// List of mass actions available
655$arrayofmassactions = array();
656if ($permissiontoadd) {
657 $arrayofmassactions['disable'] = img_picto('', 'close_title', 'class="pictofixedwidth"').$langs->trans("DisableUser");
658}
659if ($permissiontoadd) {
660 $arrayofmassactions['reactivate'] = img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("Reactivate");
661}
662if (isModEnabled('category') && $permissiontoadd) {
663 $arrayofmassactions['preaffecttag'] = img_picto('', 'category', 'class="pictofixedwidth"').$langs->trans("AffectTag");
664}
665if ($permissiontoadd) {
666 $arrayofmassactions['presetsupervisor'] = img_picto('', 'user', 'class="pictofixedwidth"').$langs->trans("SetSupervisor");
667}
668//if ($permissiontodelete) $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
669
670if (GETPOSTINT('nomassaction') || in_array($massaction, array('presend', 'predelete', 'preaffecttag', 'presetsupervisor'))) {
671 $arrayofmassactions = array();
672}
673$massactionbutton = $form->selectMassAction('', $arrayofmassactions);
674
675print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">'."\n";
676if ($optioncss != '') {
677 print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
678}
679print '<input type="hidden" name="token" value="'.newToken().'">';
680print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
681print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
682print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
683print '<input type="hidden" name="page" value="'.$page.'">';
684print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
685print '<input type="hidden" name="page_y" value="">';
686print '<input type="hidden" name="mode" value="'.$mode.'">';
687
688$url = DOL_URL_ROOT.'/user/card.php?action=create'.($contextpage == 'employeelist' ? '&search_employee=1' : '').'&leftmenu=';
689if (!empty($socid)) {
690 $url .= '&socid='.urlencode((string) ($socid));
691}
692
693$newcardbutton = '';
694$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'));
695$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'));
696$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'));
697$newcardbutton .= dolGetButtonTitleSeparator();
698$newcardbutton .= dolGetButtonTitle($langs->trans('NewUser'), '', 'fa fa-plus-circle', $url, '', (int) $permissiontoadd);
699
700/*$moreparam = array('morecss'=>'btnTitleSelected');
701$morehtmlright = dolGetButtonTitle($langs->trans("List"), '', 'fa fa-list paddingleft imgforviewmode', DOL_URL_ROOT.'/user/list.php'.(($search_status != '' && $search_status >= 0) ? '?search_status='.$search_status : ''), '', 1, $moreparam);
702$moreparam = array('morecss'=>'marginleftonly');
703$morehtmlright .= dolGetButtonTitle($langs->trans("HierarchicView"), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT.'/user/hierarchy.php'.(($search_status != '' && $search_status >= 0) ? '?search_status='.$search_status : ''), '', 1, $moreparam);
704*/
705print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'user', 0, $morehtmlright.' '.$newcardbutton, '', $limit, 0, 0, 1);
706
707
708
709// Add code for pre mass action (confirmation or email presend form)
710$topicmail = "SendUserRef";
711$modelmail = "user";
712$objecttmp = new User($db);
713$trackid = 'use'.$object->id;
714include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
715
716if (!empty($catid)) {
717 print "<div id='ways'>";
718 $c = new Categorie($db);
719 $ways = $c->print_all_ways('auto', 'user/list.php');
720 print " &gt; ".$ways[0]."<br>\n";
721 print "</div><br>";
722}
723
724if ($search_all) {
725 $setupstring = '';
726 foreach ($fieldstosearchall as $key => $val) {
727 $fieldstosearchall[$key] = $langs->trans($val);
728 $setupstring .= $key."=".$val.";";
729 }
730 print '<!-- Search done like if USER_QUICKSEARCH_ON_FIELDS = '.$setupstring.' -->'."\n";
731 print '<div class="divsearchfieldfilter">'.$langs->trans("FilterOnInto", $search_all).implode(', ', $fieldstosearchall).'</div>';
732}
733
734$moreforfilter = '';
735/*$moreforfilter.='<div class="divsearchfield">';
736 $moreforfilter.= $langs->trans('MyFilter') . ': <input type="text" name="search_myfield" value="'.dol_escape_htmltag($search_myfield).'">';
737 $moreforfilter.= '</div>';*/
738
739// Filter on categories
740if (isModEnabled('category') && $user->hasRight("categorie", "read")) {
741 $moreforfilter .= '<div class="divsearchfield">';
742 $tmptitle = $langs->trans('Category');
743 $moreforfilter .= img_picto($langs->trans("Category"), 'category', 'class="pictofixedwidth"').$formother->select_categories(Categorie::TYPE_USER, $search_categ, 'search_categ', 1, $tmptitle);
744 $moreforfilter .= '</div>';
745}
746// Filter on warehouse
747if (isModEnabled('stock') && getDolGlobalString('MAIN_DEFAULT_WAREHOUSE_USER')) {
748 require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
749 $formproduct = new FormProduct($db);
750 $moreforfilter .= '<div class="divsearchfield">';
751 $tmptitle = $langs->trans('Warehouse');
752 $moreforfilter .= img_picto($tmptitle, 'stock', 'class="pictofixedwidth"').$formproduct->selectWarehouses($search_warehouse, 'search_warehouse', '', 1, 0, 0, $tmptitle);
753 $moreforfilter .= '</div>';
754}
755
756$parameters = array();
757$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
758if (empty($reshook)) {
759 $moreforfilter .= $hookmanager->resPrint;
760} else {
761 $moreforfilter = $hookmanager->resPrint;
762}
763
764if (!empty($moreforfilter)) {
765 print '<div class="liste_titre liste_titre_bydiv centpercent">';
766 print $moreforfilter;
767 print '</div>';
768}
769
770$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
771$htmlofselectarray = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, $conf->main_checkbox_left_column); // This also change content of $arrayfields
772$selectedfields = ($mode != 'kanban' ? $htmlofselectarray : '');
773$selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : '');
774
775print '<div class="div-table-responsive">'; // You can use div-table-responsive-no-min if you don't need reserved height for your table
776print '<table class="tagtable nobottomiftotal liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n";
777
778// Fields title search
779// --------------------------------------------------------------------
780print '<tr class="liste_titre_filter">';
781// Action column
782if ($conf->main_checkbox_left_column) {
783 print '<td class="liste_titre center maxwidthsearch">';
784 $searchpicto = $form->showFilterButtons('left');
785 print $searchpicto;
786 print '</td>';
787}
788if (!empty($arrayfields['u.rowid']['checked'])) {
789 print '<td class="liste_titre"><input type="text" name="search_rowid" class="maxwidth50" value="'.$search_rowid.'"></td>';
790}
791if (!empty($arrayfields['u.login']['checked'])) {
792 print '<td class="liste_titre"><input type="text" name="search_login" class="maxwidth50" value="'.$search_login.'"></td>';
793}
794if (!empty($arrayfields['u.lastname']['checked'])) {
795 print '<td class="liste_titre"><input type="text" name="search_lastname" class="maxwidth50" value="'.$search_lastname.'"></td>';
796}
797if (!empty($arrayfields['u.firstname']['checked'])) {
798 print '<td class="liste_titre"><input type="text" name="search_firstname" class="maxwidth50" value="'.$search_firstname.'"></td>';
799}
800if (!empty($arrayfields['u.gender']['checked'])) {
801 print '<td class="liste_titre center">';
802 $arraygender = array('man' => $langs->trans("Genderman"), 'woman' => $langs->trans("Genderwoman"), 'other' => $langs->trans("Genderother"));
803 print $form->selectarray('search_gender', $arraygender, $search_gender, 1);
804 print '</td>';
805}
806if (!empty($arrayfields['u.employee']['checked'])) {
807 print '<td class="liste_titre">';
808 print $form->selectyesno('search_employee', $search_employee, 1, false, 1);
809 print '</td>';
810}
811// Supervisor
812if (!empty($arrayfields['u.fk_user']['checked'])) {
813 print '<td class="liste_titre">';
814 print $form->select_dolusers($search_supervisor, 'search_supervisor', 1, array(), 0, '', '', '0', 0, 0, '', 0, '', 'maxwidth125');
815 print '</td>';
816}
817if (!empty($arrayfields['u.accountancy_code']['checked'])) {
818 print '<td class="liste_titre"><input type="text" name="search_accountancy_code" class="maxwidth50" value="'.$search_accountancy_code.'"></td>';
819}
820if (!empty($arrayfields['u.office_phone']['checked'])) {
821 print '<td class="liste_titre"><input type="text" name="search_phonepro" class="maxwidth50" value="'.$search_phonepro.'"></td>';
822}
823if (!empty($arrayfields['u.user_mobile']['checked'])) {
824 print '<td class="liste_titre"><input type="text" name="search_phonemobile" class="maxwidth50" value="'.$search_phonemobile.'"></td>';
825}
826if (!empty($arrayfields['u.email']['checked'])) {
827 print '<td class="liste_titre"><input type="text" name="search_email" class="maxwidth75" value="'.$search_email.'"></td>';
828}
829if (!empty($arrayfields['co.label']['checked'])) {
830 print '<td class="liste_titre">';
831 print $form->select_country($search_country, 'search_country', '', 0, 'minwidth100imp maxwidth100');
832 print '</td>';
833}
834if (!empty($arrayfields['u.api_key']['checked'])) {
835 print '<td class="liste_titre"><input type="text" name="search_api_key" class="maxwidth50" value="'.$search_api_key.'"></td>';
836}
837if (!empty($arrayfields['u.fk_soc']['checked'])) {
838 print '<td class="liste_titre"><input type="text" name="search_thirdparty" class="maxwidth75" value="'.$search_thirdparty.'"></td>';
839}
840if (!empty($arrayfields['u.entity']['checked'])) {
841 print '<td class="liste_titre"></td>';
842}
843if (!empty($arrayfields['u.ref_employee']['checked'])) {
844 print '<td class="liste_titre"></td>';
845}
846if (!empty($arrayfields['u.national_registration_number']['checked'])) {
847 print '<td class="liste_titre"></td>';
848}
849if (!empty($arrayfields['u.job']['checked'])) {
850 print '<td class="liste_titre"><input type="text" name="search_job" class="maxwidth75" value="'.$search_job.'"></td>';
851}
852if (!empty($arrayfields['u.salary']['checked'])) {
853 print '<td class="liste_titre"></td>';
854}
855if (!empty($arrayfields['u.thm']['checked'])) {
856 print '<td class="liste_titre"></td>';
857}
858if (!empty($arrayfields['u.datelastlogin']['checked']) && getDolGlobalInt('MAIN_ENABLE_LOGINS_PRIVACY') == 0) {
859 print '<td class="liste_titre"></td>';
860}
861if (!empty($arrayfields['u.datepreviouslogin']['checked']) && getDolGlobalInt('MAIN_ENABLE_LOGINS_PRIVACY') == 0) {
862 print '<td class="liste_titre"></td>';
863}
864// Extra fields
865include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php';
866// Fields from hook
867$parameters = array('arrayfields' => $arrayfields);
868$reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object); // Note that $action and $object may have been modified by hook
869print $hookmanager->resPrint;
870if (!empty($arrayfields['u.datec']['checked'])) {
871 // Date creation
872 print '<td class="liste_titre">';
873 print '</td>';
874}
875if (!empty($arrayfields['date_modification']['checked'])) {
876 // Date modification
877 print '<td class="liste_titre">';
878 print '</td>';
879}
880if (!empty($arrayfields['u.import_key']['checked'])) {
881 // Import ID
882 print '<td class="liste_titre">';
883 print '</td>';
884}
885if (!empty($arrayfields['u.statut']['checked'])) {
886 // Status
887 print '<td class="liste_titre center parentonrightofpage">';
888 print $form->selectarray('search_status', array('-1' => '', '0' => $langs->trans('Disabled'), '1' => $langs->trans('Enabled')), $search_status, 0, 0, 0, '', 0, 0, 0, '', 'search_status width100 onrightofpage');
889 print '</td>';
890}
891// Action column
892if (!$conf->main_checkbox_left_column) {
893 print '<td class="liste_titre maxwidthsearch">';
894 $searchpicto = $form->showFilterButtons();
895 print $searchpicto;
896 print '</td>';
897}
898print '</tr>'."\n";
899
900$totalarray = array();
901$totalarray['nbfield'] = 0;
902
903// Fields title label
904// --------------------------------------------------------------------
905print '<tr class="liste_titre">';
906if ($conf->main_checkbox_left_column) {
907 print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
908 $totalarray['nbfield']++;
909}
910if (!empty($arrayfields['u.rowid']['checked'])) {
911 // @phan-suppress-next-line PhanTypeInvalidDimOffset
912 print_liste_field_titre($arrayfields['u.rowid']['label'], $_SERVER['PHP_SELF'], "u.rowid", "", $param, "", $sortfield, $sortorder);
913 $totalarray['nbfield']++;
914}
915if (!empty($arrayfields['u.login']['checked'])) {
916 print_liste_field_titre($arrayfields['u.login']['label'], $_SERVER['PHP_SELF'], "u.login", "", $param, "", $sortfield, $sortorder);
917 $totalarray['nbfield']++;
918}
919if (!empty($arrayfields['u.lastname']['checked'])) {
920 print_liste_field_titre("Lastname", $_SERVER['PHP_SELF'], "u.lastname", "", $param, "", $sortfield, $sortorder);
921 $totalarray['nbfield']++;
922}
923if (!empty($arrayfields['u.firstname']['checked'])) {
924 print_liste_field_titre("FirstName", $_SERVER['PHP_SELF'], "u.firstname", "", $param, "", $sortfield, $sortorder);
925 $totalarray['nbfield']++;
926}
927if (!empty($arrayfields['u.gender']['checked'])) {
928 print_liste_field_titre("Gender", $_SERVER['PHP_SELF'], "u.gender", "", $param, "", $sortfield, $sortorder, 'center ');
929 $totalarray['nbfield']++;
930}
931if (!empty($arrayfields['u.employee']['checked'])) {
932 print_liste_field_titre("Employee", $_SERVER['PHP_SELF'], "u.employee", "", $param, "", $sortfield, $sortorder, 'center ');
933 $totalarray['nbfield']++;
934}
935if (!empty($arrayfields['u.fk_user']['checked'])) {
936 print_liste_field_titre("HierarchicalResponsible", $_SERVER['PHP_SELF'], "u.fk_user", "", $param, "", $sortfield, $sortorder);
937 $totalarray['nbfield']++;
938}
939if (!empty($arrayfields['u.accountancy_code']['checked'])) {
940 print_liste_field_titre("AccountancyCode", $_SERVER['PHP_SELF'], "u.accountancy_code", "", $param, "", $sortfield, $sortorder);
941 $totalarray['nbfield']++;
942}
943if (!empty($arrayfields['u.office_phone']['checked'])) {
944 print_liste_field_titre("PhonePro", $_SERVER['PHP_SELF'], "u.office_phone", "", $param, "", $sortfield, $sortorder);
945 $totalarray['nbfield']++;
946}
947if (!empty($arrayfields['u.user_mobile']['checked'])) {
948 print_liste_field_titre("PhoneMobile", $_SERVER['PHP_SELF'], "u.user_mobile", "", $param, "", $sortfield, $sortorder);
949 $totalarray['nbfield']++;
950}
951if (!empty($arrayfields['u.email']['checked'])) {
952 print_liste_field_titre("EMail", $_SERVER['PHP_SELF'], "u.email", "", $param, "", $sortfield, $sortorder);
953 $totalarray['nbfield']++;
954}
955if (!empty($arrayfields['co.label']['checked'])) {
956 print_liste_field_titre("Country", $_SERVER['PHP_SELF'], "co.label", "", $param, "", $sortfield, $sortorder);
957 $totalarray['nbfield']++;
958}
959if (!empty($arrayfields['u.api_key']['checked'])) {
960 print_liste_field_titre("ApiKey", $_SERVER['PHP_SELF'], "u.api_key", "", $param, "", $sortfield, $sortorder);
961 $totalarray['nbfield']++;
962}
963if (!empty($arrayfields['u.fk_soc']['checked'])) {
964 print_liste_field_titre("Company", $_SERVER['PHP_SELF'], "u.fk_soc", "", $param, "", $sortfield, $sortorder);
965 $totalarray['nbfield']++;
966}
967if (!empty($arrayfields['u.entity']['checked'])) {
968 print_liste_field_titre($arrayfields['u.entity']['label'], $_SERVER['PHP_SELF'], "u.entity", "", $param, "", $sortfield, $sortorder);
969 $totalarray['nbfield']++;
970}
971if (!empty($arrayfields['u.ref_employee']['checked'])) {
972 print_liste_field_titre("RefEmployee", $_SERVER['PHP_SELF'], "u.ref_employee", "", $param, "", $sortfield, $sortorder);
973 $totalarray['nbfield']++;
974}
975if (!empty($arrayfields['u.national_registration_number']['checked'])) {
976 print_liste_field_titre("NationalRegistrationNumber", $_SERVER['PHP_SELF'], "u.national_registration_number", "", $param, "", $sortfield, $sortorder);
977 $totalarray['nbfield']++;
978}
979if (!empty($arrayfields['u.job']['checked'])) {
980 print_liste_field_titre($arrayfields['u.job']['label'], $_SERVER['PHP_SELF'], "u.job", "", $param, "", $sortfield, $sortorder);
981 $totalarray['nbfield']++;
982}
983if (!empty($arrayfields['u.salary']['checked'])) {
984 print_liste_field_titre("Salary", $_SERVER['PHP_SELF'], "u.salary", "", $param, "", $sortfield, $sortorder, 'right ');
985 $totalarray['nbfield']++;
986}
987if (!empty($arrayfields['u.thm']['checked'])) {
988 print_liste_field_titre("THM", $_SERVER['PHP_SELF'], "u.thm", '', $param, "", $sortfield, $sortorder, 'right ');
989 $totalarray['nbfield']++;
990}
991if (!empty($arrayfields['u.datelastlogin']['checked']) && getDolGlobalInt('MAIN_ENABLE_LOGINS_PRIVACY') == 0) {
992 print_liste_field_titre("LastConnexion", $_SERVER['PHP_SELF'], "u.datelastlogin", "", $param, '', $sortfield, $sortorder, 'center ');
993 $totalarray['nbfield']++;
994}
995if (!empty($arrayfields['u.datepreviouslogin']['checked']) && getDolGlobalInt('MAIN_ENABLE_LOGINS_PRIVACY') == 0) {
996 print_liste_field_titre("PreviousConnexion", $_SERVER['PHP_SELF'], "u.datepreviouslogin", "", $param, '', $sortfield, $sortorder, 'center ');
997 $totalarray['nbfield']++;
998}
999// Extra fields
1000include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php';
1001// Hook fields
1002$parameters = array('arrayfields' => $arrayfields, 'param' => $param, 'sortfield' => $sortfield, 'sortorder' => $sortorder, 'totalarray' => &$totalarray);
1003$reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook
1004print $hookmanager->resPrint;
1005if (!empty($arrayfields['u.datec']['checked'])) {
1006 print_liste_field_titre("DateCreationShort", $_SERVER["PHP_SELF"], "u.datec", "", $param, '', $sortfield, $sortorder, 'center nowrap ');
1007 $totalarray['nbfield']++;
1008}
1009if (!empty($arrayfields['date_modification']['checked'])) {
1010 print_liste_field_titre("DateModificationShort", $_SERVER["PHP_SELF"], "date_modification", "", $param, '', $sortfield, $sortorder, 'center nowrap ');
1011 $totalarray['nbfield']++;
1012}
1013if (!empty($arrayfields['import_key']['checked'])) {
1014 print_liste_field_titre("ImportId", $_SERVER["PHP_SELF"], "u.import_key", "", $param, '', $sortfield, $sortorder, 'center ');
1015 $totalarray['nbfield']++;
1016}
1017if (!empty($arrayfields['u.import_key']['checked'])) {
1018 print_liste_field_titre("ImportId", $_SERVER["PHP_SELF"], "u.import_key", "", $param, '', $sortfield, $sortorder, 'center ');
1019 $totalarray['nbfield']++;
1020}
1021if (!empty($arrayfields['u.statut']['checked'])) {
1022 print_liste_field_titre("Status", $_SERVER["PHP_SELF"], "u.statut", "", $param, '', $sortfield, $sortorder, 'center ');
1023 $totalarray['nbfield']++;
1024}
1025// Action column
1026if (!$conf->main_checkbox_left_column) {
1027 print getTitleFieldOfList(($mode != 'kanban' ? $selectedfields : ''), 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
1028 $totalarray['nbfield']++;
1029}
1030print '</tr>'."\n";
1031
1032
1033// Detect if we need a fetch on each output line
1034$needToFetchEachLine = 0;
1035if (isset($extrafields->attributes[$object->table_element]['computed']) && is_array($extrafields->attributes[$object->table_element]['computed']) && count($extrafields->attributes[$object->table_element]['computed']) > 0) {
1036 foreach ($extrafields->attributes[$object->table_element]['computed'] as $key => $val) {
1037 if (!is_null($val) && preg_match('/\$object/', $val)) {
1038 $needToFetchEachLine++; // There is at least one compute field that use $object
1039 }
1040 }
1041}
1042
1043
1044// Loop on record
1045// --------------------------------------------------------------------
1046$i = 0;
1047$savnbfield = $totalarray['nbfield'];
1048$totalarray = array('val' => array('u.salary' => 0));
1049$totalarray['nbfield'] = 0;
1050$imaxinloop = ($limit ? min($num, $limit) : $num);
1051while ($i < $imaxinloop) {
1052 $obj = $db->fetch_object($resql);
1053 if (empty($obj)) {
1054 break; // Should not happen
1055 }
1056
1057 // Store properties in $object
1058 $object->setVarsFromFetchObj($obj);
1059
1060 $object->id = $obj->rowid;
1061 $object->admin = $obj->admin;
1062 $object->ref = (string) $obj->rowid;
1063 $object->login = $obj->login;
1064 $object->status = (int) $obj->status;
1065 $object->office_phone = $obj->office_phone;
1066 $object->user_mobile = $obj->user_mobile;
1067 $object->job = $obj->job;
1068 $object->email = $obj->email;
1069 $object->gender = $obj->gender;
1070 $object->socid = $obj->fk_soc;
1071 $object->firstname = $obj->firstname;
1072 $object->lastname = $obj->lastname;
1073 $object->employee = $obj->employee;
1074 $object->photo = $obj->photo;
1075 $object->datestartvalidity = $db->jdate($obj->datestartvalidity);
1076 $object->dateendvalidity = $db->jdate($obj->dateendvalidity);
1077 $object->country_code = $obj->country_code;
1078 $object->country = $obj->country_label;
1079
1080 $li = $object->getNomUrl(-1, '', 0, 0, 24, 1, 'login', '', 1);
1081
1082 $canreadhrmdata = 0;
1083 if ((isModEnabled('salaries') && $user->hasRight("salaries", "read") && in_array($obj->rowid, $childids))
1084 || (isModEnabled('salaries') && $user->hasRight("salaries", "readall"))
1085 || (isModEnabled('hrm') && $user->hasRight("hrm", "employee", "read"))) {
1086 $canreadhrmdata = 1;
1087 }
1088 $canreadsecretapi = 0;
1089 if ($user->id == $obj->rowid || !empty($user->admin)) { // Current user or admin
1090 $canreadsecretapi = 1;
1091 }
1092
1093 if ($mode == 'kanban') {
1094 if ($i == 0) {
1095 print '<tr class="trkanban"><td colspan="'.$savnbfield.'">';
1096 print '<div class="box-flex-container kanban">';
1097 }
1098
1099 // Output Kanban
1100 $selected = -1;
1101 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
1102 $selected = 0;
1103 if (in_array($object->id, $arrayofselected)) {
1104 $selected = 1;
1105 }
1106 }
1107 print $object->getKanbanView('', array('selected' => $selected));
1108 if ($i == ($imaxinloop - 1)) {
1109 print '</div>';
1110 print '</td></tr>';
1111 }
1112 } else {
1113 // Show here line of result
1114 $j = 0;
1115 print '<tr data-rowid="'.$object->id.'" class="oddeven row-with-select">';
1116 // Action column
1117 if ($conf->main_checkbox_left_column) {
1118 print '<td class="nowrap center">';
1119 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
1120 $selected = 0;
1121 if (in_array($object->id, $arrayofselected)) {
1122 $selected = 1;
1123 }
1124 print '<input id="cb'.$object->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$object->id.'"'.($selected ? ' checked="checked"' : '').'>';
1125 }
1126 print '</td>';
1127 if (!$i) {
1128 $totalarray['nbfield']++;
1129 }
1130 }
1131 // TechnicalID
1132 if (!empty($arrayfields['u.rowid']['checked'])) {
1133 print '<td class="nowraponall">'.dolPrintHTML((string) $obj->rowid).'</td>';
1134 if (!$i) {
1135 $totalarray['nbfield']++;
1136 }
1137 }
1138 // Login
1139 if (!empty($arrayfields['u.login']['checked'])) {
1140 print '<td class="nowraponall tdoverflowmax150">';
1141 print $li;
1142 if (isModEnabled('multicompany') && $obj->admin && !$obj->entity) {
1143 print img_picto($langs->trans("SuperAdministratorDesc"), 'superadmin', 'class="valignmiddle paddingright paddingleft"');
1144 } elseif ($obj->admin) {
1145 print img_picto($langs->trans("AdministratorDesc"), 'admin', 'class="valignmiddle paddingright paddingleft"');
1146 }
1147 print '</td>';
1148 if (!$i) {
1149 $totalarray['nbfield']++;
1150 }
1151 }
1152 // Lastname
1153 if (!empty($arrayfields['u.lastname']['checked'])) {
1154 print '<td class="tdoverflowmax150" title="'.dol_escape_htmltag($obj->lastname).'">'.dol_escape_htmltag($obj->lastname).'</td>';
1155 if (!$i) {
1156 $totalarray['nbfield']++;
1157 }
1158 }
1159 // Fistname
1160 if (!empty($arrayfields['u.firstname']['checked'])) {
1161 print '<td class="tdoverflowmax150" title="'.dol_escape_htmltag($obj->lastname).'">'.dol_escape_htmltag($obj->firstname).'</td>';
1162 if (!$i) {
1163 $totalarray['nbfield']++;
1164 }
1165 }
1166 // Gender
1167 if (!empty($arrayfields['u.gender']['checked'])) {
1168 print '<td class="center">';
1169 if ($obj->gender) {
1170 // Preparing gender's display if there is one
1171 $addgendertxt = '';
1172 switch ($obj->gender) {
1173 case 'man':
1174 $addgendertxt .= '<i class="fas fa-mars" title="'.dol_escape_htmltag($langs->trans("Gender".$obj->gender)).'"></i>';
1175 break;
1176 case 'woman':
1177 $addgendertxt .= '<i class="fas fa-venus" title="'.dol_escape_htmltag($langs->trans("Gender".$obj->gender)).'"></i>';
1178 break;
1179 case 'other':
1180 $addgendertxt .= '<i class="fas fa-transgender" title="'.dol_escape_htmltag($langs->trans("Gender".$obj->gender)).'"></i>';
1181 break;
1182 }
1183 print $addgendertxt;
1184 //print $langs->trans("Gender".$obj->gender);
1185 }
1186 print '</td>';
1187 if (!$i) {
1188 $totalarray['nbfield']++;
1189 }
1190 }
1191 // Employee yes/no
1192 if (!empty($arrayfields['u.employee']['checked'])) {
1193 print '<td class="center">'.yn($obj->employee).'</td>';
1194 if (!$i) {
1195 $totalarray['nbfield']++;
1196 }
1197 }
1198
1199 // Supervisor
1200 if (!empty($arrayfields['u.fk_user']['checked'])) {
1201 print '<td class="tdoverflowmax125">';
1202 if ($obj->login2) {
1203 $user2->id = $obj->id2;
1204 $user2->login = $obj->login2;
1205 $user2->lastname = $obj->lastname2;
1206 $user2->firstname = $obj->firstname2;
1207 $user2->gender = $obj->gender2;
1208 $user2->photo = $obj->photo2;
1209 $user2->admin = $obj->admin2;
1210 $user2->office_phone = $obj->office_phone;
1211 $user2->user_mobile = $obj->user_mobile;
1212 $user2->email = $obj->email2;
1213 $user2->socid = $obj->fk_soc2;
1214 $user2->status = $obj->status2;
1215 if (isModEnabled('multicompany') && $obj->admin2 && !$obj->entity2) {
1216 print img_picto($langs->trans("SuperAdministratorDesc"), 'superadmin', 'class="valignmiddle paddingright"');
1217 } elseif ($obj->admin2) {
1218 print img_picto($langs->trans("AdministratorDesc"), 'admin', 'class="valignmiddle paddingright"');
1219 }
1220 print $user2->getNomUrl(-1, '', 0, 0, 24, 0, '', '', 1);
1221 }
1222 print '</td>';
1223 if (!$i) {
1224 $totalarray['nbfield']++;
1225 }
1226 }
1227
1228 // Accountancy code
1229 if (!empty($arrayfields['u.accountancy_code']['checked'])) {
1230 print '<td>'.$obj->accountancy_code.'</td>';
1231 if (!$i) {
1232 $totalarray['nbfield']++;
1233 }
1234 }
1235
1236 // Phone
1237 if (!empty($arrayfields['u.office_phone']['checked'])) {
1238 print '<td class="tdoverflowmax125">'.dol_print_phone($obj->office_phone, $obj->country_code, 0, $obj->rowid, 'AC_TEL', ' ', 'phone')."</td>\n";
1239 if (!$i) {
1240 $totalarray['nbfield']++;
1241 }
1242 }
1243 // Phone mobile
1244 if (!empty($arrayfields['u.user_mobile']['checked'])) {
1245 print '<td class="tdoverflowmax125">'.dol_print_phone($obj->user_mobile, $obj->country_code, 0, $obj->rowid, 'AC_TEL', ' ', 'mobile')."</td>\n";
1246 if (!$i) {
1247 $totalarray['nbfield']++;
1248 }
1249 }
1250 // Email
1251 if (!empty($arrayfields['u.email']['checked'])) {
1252 $showinvalidemail = (int) !getDolGlobalInt('MAIN_SHOW_INVALID_EMAIL_IN_LIST'); // to avoid slow display
1253 print '<td class="tdoverflowmax150" title="'.dolPrintHTMLForAttribute((string) $obj->email).'">'.dol_print_email((string) $obj->email, $obj->rowid, $obj->fk_soc, 1, 0, $showinvalidemail, 1)."</td>\n";
1254 if (!$i) {
1255 $totalarray['nbfield']++;
1256 }
1257 }
1258 // Country
1259 if (!empty($arrayfields['co.label']['checked'])) {
1260 print '<td class="tdoverflowmax150">'.$obj->country_label."</td>\n";
1261 if (!$i) {
1262 $totalarray['nbfield']++;
1263 }
1264 }
1265 // Api key
1266 if (!empty($arrayfields['u.api_key']['checked'])) {
1267 $api_key = dolDecrypt($obj->api_key);
1268 print '<td class="tdoverflowmax125" title="'.dol_escape_htmltag($api_key).'">';
1269 if ($api_key) {
1270 if ($canreadsecretapi) {
1271 print '<span class="opacitymedium">';
1272 print showValueWithClipboardCPButton($object->api_key, 1, dol_trunc($api_key, 3)); // TODO Add an option to also reveal the hash, not only copy paste
1273 print '</span>';
1274 } else {
1275 print '<span class="opacitymedium">'.$langs->trans("Hidden").'</span>';
1276 }
1277 }
1278 print '</td>';
1279 if (!$i) {
1280 $totalarray['nbfield']++;
1281 }
1282 }
1283 // User
1284 if (!empty($arrayfields['u.fk_soc']['checked'])) {
1285 print '<td class="tdoverflowmax150">';
1286 if ($obj->fk_soc > 0) {
1287 $companystatic->id = $obj->fk_soc;
1288 $companystatic->name = $obj->name;
1289 $companystatic->canvas = $obj->canvas;
1290 print $companystatic->getNomUrl(1);
1291 } elseif ($obj->ldap_sid) {
1292 print '<span class="opacitymedium">'.$langs->trans("DomainUser").'</span>';
1293 } else {
1294 print '<span class="opacitymedium">'.$langs->trans("InternalUser").'</span>';
1295 }
1296 print '</td>';
1297 if (!$i) {
1298 $totalarray['nbfield']++;
1299 }
1300 }
1301 // Multicompany enabled
1302 if (isModEnabled('multicompany') && isset($mc) && is_object($mc) && !getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE')) {
1303 if (!empty($arrayfields['u.entity']['checked'])) {
1304 if (!$obj->entity) {
1305 $labeltouse = $langs->trans("AllEntities");
1306 } else {
1307 $mc->getInfo($obj->entity);
1308 $labeltouse = $mc->label;
1309 }
1310 print '<td class="tdoverflowmax100" title="'.dol_escape_htmltag($labeltouse).'">';
1311 print $labeltouse;
1312 print '</td>';
1313 if (!$i) {
1314 $totalarray['nbfield']++;
1315 }
1316 }
1317 }
1318
1319 // Ref employee
1320 if (!empty($arrayfields['u.ref_employee']['checked'])) {
1321 print '<td class="tdoverflowmax100" title="'.dol_escape_htmltag($obj->ref_employee).'">';
1322 print dol_escape_htmltag($obj->ref_employee);
1323 print '</td>';
1324 if (!$i) {
1325 $totalarray['nbfield']++;
1326 }
1327 }
1328 // National number
1329 if (!empty($arrayfields['u.national_registration_number']['checked'])) {
1330 print '<td class="tdoverflowmax100" title="'.dol_escape_htmltag($obj->national_registration_number).'">';
1331 print dol_escape_htmltag($obj->national_registration_number);
1332 print '</td>';
1333 if (!$i) {
1334 $totalarray['nbfield']++;
1335 }
1336 }
1337 // Job position
1338 if (!empty($arrayfields['u.job']['checked'])) {
1339 print '<td class="tdoverflowmax100" title="'.dol_escape_htmltag($obj->job).'">';
1340 print dol_escape_htmltag($obj->job);
1341 print '</td>';
1342 if (!$i) {
1343 $totalarray['nbfield']++;
1344 }
1345 }
1346
1347 // Salary
1348 if (!empty($arrayfields['u.salary']['checked'])) {
1349 print '<td class="nowraponall right amount">';
1350 if ($obj->salary) {
1351 if ($canreadhrmdata) {
1352 print price($obj->salary);
1353 } else {
1354 print '<span class="opacitymedium">'.$langs->trans("Hidden").'</span>';
1355 }
1356 }
1357 print '</td>';
1358 if (!$i) {
1359 $totalarray['nbfield']++;
1360 }
1361 if (!$i) {
1362 $totalarray['pos'][$totalarray['nbfield']] = 'u.salary';
1363 }
1364 if (!isset($totalarray['val'])) {
1365 $totalarray['val'] = array();
1366 }
1367 if (!isset($totalarray['val']['u.salary'])) {
1368 $totalarray['val']['u.salary'] = 0;
1369 }
1370 $totalarray['val']['u.salary'] += $obj->salary;
1371 }
1372
1373 // Hourly rate
1374 if (!empty($arrayfields['u.thm']['checked'])) {
1375 print '<td class="nowraponall right amount">';
1376 if (!is_null($obj->thm)) {
1377 print price($obj->thm);
1378 }
1379 print '</td>';
1380 if (!$i) {
1381 $totalarray['nbfield']++;
1382 }
1383 }
1384
1385 // Date last login
1386 if (!empty($arrayfields['u.datelastlogin']['checked']) && getDolGlobalInt('MAIN_ENABLE_LOGINS_PRIVACY') == 0) {
1387 print '<td class="nowraponall center">'.dol_print_date($db->jdate($obj->datelastlogin), "dayhour").'</td>';
1388 if (!$i) {
1389 $totalarray['nbfield']++;
1390 }
1391 }
1392 // Date previous login
1393 if (!empty($arrayfields['u.datepreviouslogin']['checked']) && getDolGlobalInt('MAIN_ENABLE_LOGINS_PRIVACY') == 0) {
1394 print '<td class="nowraponall center">'.dol_print_date($db->jdate($obj->datepreviouslogin), "dayhour").'</td>';
1395 if (!$i) {
1396 $totalarray['nbfield']++;
1397 }
1398 }
1399
1400 // Extra fields
1401 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
1402 // Fields from hook
1403 $parameters = array('arrayfields' => $arrayfields, 'object' => $object, 'obj' => $obj, 'i' => $i, 'totalarray' => &$totalarray);
1404 $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object); // Note that $action and $object may have been modified by hook
1405 print $hookmanager->resPrint;
1406 // Date creation
1407 if (!empty($arrayfields['u.datec']['checked'])) {
1408 print '<td class="center nowraponall">';
1409 print dol_print_date($db->jdate($obj->date_creation), 'dayhour', 'tzuser');
1410 print '</td>';
1411 if (!$i) {
1412 $totalarray['nbfield']++;
1413 }
1414 }
1415 // Date modification
1416 if (!empty($arrayfields['date_modification']['checked'])) {
1417 print '<td class="center nowraponall">';
1418 print dol_print_date($db->jdate($obj->date_modification), 'dayhour', 'tzuser');
1419 print '</td>';
1420 if (!$i) {
1421 $totalarray['nbfield']++;
1422 }
1423 }
1424 // Import
1425 if (!empty($arrayfields['u.import_key']['checked'])) {
1426 print '<td class="center">'.dolPrintHTML($obj->import_key).'</td>';
1427 if (!$i) {
1428 $totalarray['nbfield']++;
1429 }
1430 }
1431 // Status
1432 if (!empty($arrayfields['u.statut']['checked'])) {
1433 print '<td class="center">'.$object->getLibStatut(5).'</td>';
1434 if (!$i) {
1435 $totalarray['nbfield']++;
1436 }
1437 }
1438 // Action column
1439 if (!$conf->main_checkbox_left_column) {
1440 print '<td class="nowrap center">';
1441 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
1442 $selected = 0;
1443 if (in_array($object->id, $arrayofselected)) {
1444 $selected = 1;
1445 }
1446 print '<input id="cb'.$object->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$object->id.'"'.($selected ? ' checked="checked"' : '').'>';
1447 }
1448 print '</td>';
1449 if (!$i) {
1450 $totalarray['nbfield']++;
1451 }
1452 }
1453
1454 print '</tr>'."\n";
1455 }
1456
1457 $i++;
1458}
1459
1460// Show total line
1461include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php';
1462
1463// If no record found
1464if ($num == 0) {
1465 $colspan = 1;
1466 foreach ($arrayfields as $key => $val) {
1467 if (!empty($val['checked'])) {
1468 $colspan++;
1469 }
1470 }
1471 print '<tr><td colspan="'.$colspan.'"><span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span></td></tr>';
1472}
1473
1474
1475$db->free($resql);
1476
1477$parameters = array('arrayfields' => $arrayfields, 'sql' => $sql);
1478$reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1479print $hookmanager->resPrint;
1480
1481print '</table>'."\n";
1482print '</div>'."\n";
1483
1484print '</form>'."\n";
1485
1486
1487// End of page
1488llxFooter();
1489$db->close();
$id
Support class for third parties, contacts, members, users or resources.
Definition account.php:47
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
Definition wrapper.php:91
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Definition wrapper.php:73
$c
Definition line.php:346
Class to manage categories.
Class to manage generation of HTML components Only common components must be here.
Class to help generate other html components Only common components are here.
Class with static methods for building HTML components related to products Only components common to ...
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage Dolibarr users.
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
dol_print_email($email, $contactid=0, $socid=0, $addlink=0, $max=0, $showinvalid=2, $withpicto=0, $morecss='paddingrightonly')
Show EMail link formatted for HTML output.
GETPOSTDATE($prefix, $hourTime='', $gm='auto', $saverestore='')
Helper function that combines values of a dolibarr DatePicker (such as Form\selectDate) for year,...
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.
natural_search($fields, $value, $mode=0, $nofirstand=0, $sqltoadd='')
Generate natural SQL search string for a criteria (this criteria can be tested on one or several fiel...
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_sort_array(&$array, $index, $order='asc', $natsort=0, $case_sensitive=0, $keepindex=0)
Advanced sort array by the value of a given key, which produces ascending (default) or descending out...
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0, $nodefault=0)
Return value of a param into GET or POST supervariable.
GETPOSTINT($paramname, $method=0, $nodefault=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
dol_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.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
print_liste_field_titre($name, $file="", $field="", $begin="", $param="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $tooltip="", $forcenowrapcolumntitle=0)
Show title line of an array.
showValueWithClipboardCPButton($valuetocopy, $showonlyonhover=1, $texttoshow='')
Create a button to copy $valuetocopy in the clipboard (for copy and paste feature).
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.
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.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Definition html.lib.php:181
dol_natural_search_phone($db, $fields, $value, $nofirstand=0)
Build a natural_search() SQL fragment for a phone/fax field, tolerant of the international storage fo...
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.
dolDecrypt($chain, $key='', $patterntotest='')
Decode a string with a symmetric encryption.