dolibarr 23.0.3
position_list.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2007-2017 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2021 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
4 * Copyright (C) 2021 Greg Rastklan <greg.rastklan@atm-consulting.fr>
5 * Copyright (C) 2021 Jean-Pascal BOUDET <jean-pascal.boudet@atm-consulting.fr>
6 * Copyright (C) 2021 Grégory BLEMAND <gregory.blemand@atm-consulting.fr>
7 * Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
8 * Copyright (C) 2025 MDW <mdeweerd@users.noreply.github.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22 */
23
31// Load Dolibarr environment
32require '../main.inc.php';
33
34require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
35require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
36require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
37require_once DOL_DOCUMENT_ROOT.'/hrm/class/job.class.php';
38require_once DOL_DOCUMENT_ROOT.'/hrm/class/position.class.php';
39
48// Load translation files required by the page
49$langs->loadLangs(array('hrm', 'other'));
50
51// Get parameters
52$action = GETPOST('action', 'aZ09') ? GETPOST('action', 'aZ09') : 'view'; // The action 'add', 'create', 'edit', 'update', 'view', ...
53$massaction = GETPOST('massaction', 'alpha'); // The bulk action (combo box choice into lists)
54$show_files = GETPOSTINT('show_files'); // Show files area generated by bulk actions ?
55$confirm = GETPOST('confirm', 'alpha'); // Result of a confirmation
56$cancel = GETPOST('cancel', 'alpha'); // We click on a Cancel button
57$toselect = GETPOST('toselect', 'array:int'); // Array of ids of elements selected into a list
58$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'positionlist'; // To manage different context of search
59$backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page
60$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print')
61$mode = GETPOST('mode', 'aZ');
62
63$id = GETPOSTINT('id');
64$ref = GETPOST('ref', 'alpha');
65
66// Load variable for pagination
67$limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
68$sortfield = GETPOST('sortfield', 'aZ09comma');
69$sortorder = GETPOST('sortorder', 'aZ09comma');
70$page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT('page');
71if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha')) {
72 // If $page is not defined, or '' or -1 or if we click on clear filters
73 $page = 0;
74}
75$offset = $limit * $page;
76$pageprev = $page - 1;
77$pagenext = $page + 1;
78
79// Initialize a technical objects
80$object = new Position($db);
81$extrafields = new ExtraFields($db);
82$userstatic = new User($db);
83$diroutputmassaction = $conf->hrm->dir_output.'/temp/massgeneration/'.$user->id;
84$hookmanager->initHooks(array($contextpage)); // Note that conf->hooks_modules contains array
85
86// Fetch optionals attributes and labels
87$extrafields->fetch_name_optionals_label($object->table_element);
88//$extrafields->fetch_name_optionals_label($object->table_element_line);
89
90$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
91
92// Default sort order (if not yet defined by previous GETPOST)
93if (!$sortfield) {
94 reset($object->fields); // Reset is required to avoid key() to return null.
95 $sortfield = "t.".key($object->fields); // Set here default search field. By default 1st field in definition.
96}
97if (!$sortorder) {
98 $sortorder = "ASC";
99}
100
101// Initialize array of search criteria
102$search_all = trim(GETPOST('search_all', 'alphanohtml'));
103$search = array();
104foreach ($object->fields as $key => $val) {
105 if (GETPOST('search_'.$key, 'alpha') !== '') {
106 $search[$key] = GETPOST('search_'.$key, 'alpha');
107 }
108 if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
109 $search[$key.'_dtstart'] = dol_mktime(0, 0, 0, GETPOSTINT('search_'.$key.'_dtstartmonth'), GETPOSTINT('search_'.$key.'_dtstartday'), GETPOSTINT('search_'.$key.'_dtstartyear'));
110 $search[$key.'_dtend'] = dol_mktime(23, 59, 59, GETPOSTINT('search_'.$key.'_dtendmonth'), GETPOSTINT('search_'.$key.'_dtendday'), GETPOSTINT('search_'.$key.'_dtendyear'));
111 }
112}
113
114// List of fields to search into when doing a "search in all"
115$fieldstosearchall = array();
116foreach ($object->fields as $key => $val) {
117 if (!empty($val['searchall'])) {
118 $fieldstosearchall['t.'.$key] = $val['label'];
119 }
120}
121
122// Definition of array of fields for columns
123$tableprefix = 't';
124$arrayfields = array();
125foreach ($object->fields as $key => $val) {
126 // If $val['visible']==0, then we never show the field
127 if (!empty($val['visible'])) {
128 $visible = (int) dol_eval((string) $val['visible'], 1);
129 $arrayfields[$tableprefix.'.'.$key] = array(
130 'label' => $val['label'],
131 'checked' => (($visible < 0) ? 0 : 1),
132 'enabled' => (abs($visible) != 3 && (bool) dol_eval((string) $val['enabled'], 1)),
133 'position' => $val['position'],
134 'help' => isset($val['help']) ? $val['help'] : ''
135 );
136 }
137}
138// Extra fields
139include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php';
140
141$object->fields = dol_sort_array($object->fields, 'position');
142$arrayfields = dol_sort_array($arrayfields, 'position');
143
144// Permissions
145$permissiontoread = $user->hasRight('hrm', 'all', 'read');
146$permissiontoadd = $user->hasRight('hrm', 'all', 'write');
147$permissiontodelete = $user->hasRight('hrm', 'all', 'delete');
148
149// Security check (enable the most restrictive one)
150if ($user->socid > 0) {
152}
153//if ($user->socid > 0) accessforbidden();
154//$socid = 0; if ($user->socid > 0) $socid = $user->socid;
155//$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0);
156//restrictedArea($user, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft);
157if (!isModEnabled('hrm')) {
158 accessforbidden('Module hrm not enabled');
159}
160if (!$permissiontoread) {
162}
163
164// Force the type of field fk_user to remove the filter on active user.
165// Note: Another fix would be to be able to filter on a freetet on firstname/lastname.
166//var_dump($object->fields['fk_user']);
167$object->fields['fk_user']['type'] = 'integer:User:user/class/user.class.php:0';
168
169
170/*
171 * Actions
172 */
173
174if (GETPOST('cancel', 'alpha')) {
175 $action = 'list';
176 $massaction = '';
177}
178if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') {
179 $massaction = '';
180}
181
182$parameters = array('arrayfields' => &$arrayfields);
183$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
184if ($reshook < 0) {
185 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
186}
187
188if (empty($reshook)) {
189 // Selection of new fields
190 include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
191
192 // Purge search criteria
193 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
194 foreach ($object->fields as $key => $val) {
195 $search[$key] = '';
196 if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
197 $search[$key.'_dtstart'] = '';
198 $search[$key.'_dtend'] = '';
199 }
200 }
201 $search_all = '';
202 $toselect = array();
203 $search_array_options = array();
204 }
205 if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')
206 || GETPOST('button_search_x', 'alpha') || GETPOST('button_search.x', 'alpha') || GETPOST('button_search', 'alpha')) {
207 $massaction = ''; // Protection to avoid mass action if we force a new search during a mass action confirmation
208 }
209
210 // Mass actions
211 $objectclass = 'Position';
212 $objectlabel = 'Position';
213 $uploaddir = $conf->hrm->dir_output;
214 include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
215}
216
217
218
219/*
220 * View
221 */
222
223$form = new Form($db);
224$jobstatic = new Job($db);
225
226$now = dol_now();
227
228$title = $langs->trans('EmployeePositions');
229//$help_url="EN:Module_Position|FR:Module_Position_FR|ES:Módulo_Position";
230$help_url = '';
231$morejs = array();
232$morecss = array();
233
234
235// Build and execute select
236// --------------------------------------------------------------------
237$sql = 'SELECT ';
238$sql .= $object->getFieldList('t');
239$sql .= ',';
240$sql .= $userstatic->getFieldList('u', array('rowid'));
241$sql .= ', u.email, u.statut, u.photo, u.login'; // Add more field not yet into the user->fields
242$sql .= ', j.rowid as job_id, j.label as job_label';
243// Add fields from extrafields
244if (!empty($extrafields->attributes[$object->table_element]['label'])) {
245 foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
246 $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key." as options_".$key : "");
247 }
248}
249// Add fields from hooks
250$parameters = array();
251$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
252$sql .= $hookmanager->resPrint;
253$sql = preg_replace('/,\s*$/', '', $sql);
254
255$sqlfields = $sql; // $sql fields to remove for count total
256
257$sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t LEFT JOIN ".MAIN_DB_PREFIX.$userstatic->table_element." as u on t.fk_user = u.rowid, ".MAIN_DB_PREFIX."hrm_job as j";
258
259//$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."anothertable as rc ON rc.parent = t.rowid";
260if (isset($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) {
261 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (t.rowid = ef.fk_object)";
262}
263// Add table from hooks
264$parameters = array();
265$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
266$sql .= $hookmanager->resPrint;
267if ($object->ismultientitymanaged == 1) {
268 $sql .= " WHERE t.entity IN (".getEntity($object->element, (GETPOSTINT('search_current_entity') ? 0 : 1)).")";
269} else {
270 $sql .= " WHERE 1 = 1";
271}
272$sql .= " AND t.fk_job = j.rowid";
273foreach ($search as $key => $val) {
274 if (array_key_exists($key, $object->fields)) {
275 if ($key == 'status' && $search[$key] == -1) {
276 continue;
277 }
278 $mode_search = (($object->isInt($object->fields[$key]) || $object->isFloat($object->fields[$key])) ? 1 : 0);
279 if ((strpos($object->fields[$key]['type'], 'integer:') === 0) || (strpos($object->fields[$key]['type'], 'sellist:') === 0) || !empty($object->fields[$key]['arrayofkeyval'])) {
280 if ($search[$key] == '-1' || ($search[$key] === '0' && (empty($object->fields[$key]['arrayofkeyval']) || !array_key_exists('0', $object->fields[$key]['arrayofkeyval'])))) {
281 $search[$key] = '';
282 }
283 $mode_search = 2;
284 }
285 if (empty($object->fields[$key]['searchmulti'])) {
286 if (!is_array($search[$key]) && $search[$key] != '') {
287 $sql .= natural_search("t.".$db->escape($key), $search[$key], (($key == 'status') ? 2 : $mode_search));
288 }
289 } else {
290 if (is_array($search[$key]) && !empty($search[$key])) {
291 $sql .= natural_search("t.".$db->escape($key), implode(',', $search[$key]), (($key == 'status') ? 2 : $mode_search));
292 }
293 }
294 } else {
295 if (preg_match('/(_dtstart|_dtend)$/', $key) && $search[$key] != '') {
296 $columnName = preg_replace('/(_dtstart|_dtend)$/', '', $key);
297 if (preg_match('/^(date|timestamp|datetime)/', $object->fields[$columnName]['type'])) {
298 if (preg_match('/_dtstart$/', $key)) {
299 $sql .= " AND t.".$db->sanitize($columnName)." >= '".$db->idate($search[$key])."'";
300 }
301 if (preg_match('/_dtend$/', $key)) {
302 $sql .= " AND t.".$db->sanitize($columnName)." <= '".$db->idate($search[$key])."'";
303 }
304 }
305 }
306 }
307}
308$vacant = GETPOST('search_fk_uservacant', 'alphanohtml') === 'on';
309if ($vacant) {
310 $sql .= ' AND t.fk_user = 0';
311}
312if ($search_all) {
313 $sql .= natural_search(array_keys($fieldstosearchall), $search_all);
314}
315//$sql.= dolSqlDateFilter("t.field", $search_xxxday, $search_xxxmonth, $search_xxxyear);
316// Add where from extra fields
317include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
318// Add where from hooks
319$parameters = array();
320$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
321$sql .= $hookmanager->resPrint;
322
323/* If a group by is required
324$sql .= " GROUP BY ";
325foreach($object->fields as $key => $val) {
326 $sql .= "t.".$db->sanitize($key).", ";
327}
328// Add fields from extrafields
329if (!empty($extrafields->attributes[$object->table_element]['label'])) {
330 foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
331 $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? "ef.".$key.', ' : '');
332 }
333}
334// Add groupby from hooks
335$parameters = array();
336$reshook = $hookmanager->executeHooks('printFieldListGroupBy', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
337$sql .= $hookmanager->resPrint;
338$sql = preg_replace('/,\s*$/', '', $sql);
339*/
340
341// Count total nb of records
342$nbtotalofrecords = '';
343if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
344 /* The fast and low memory method to get and count full list converts the sql into a sql count */
345 $sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql);
346 $sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount);
347
348 $resql = $db->query($sqlforcount);
349 if ($resql) {
350 $objforcount = $db->fetch_object($resql);
351 $nbtotalofrecords = $objforcount->nbtotalofrecords;
352 } else {
353 dol_print_error($db);
354 }
355
356 if (($page * $limit) > (int) $nbtotalofrecords) { // if total resultset is smaller than the paging size (filtering), goto and load page 0
357 $page = 0;
358 $offset = 0;
359 }
360 $db->free($resql);
361}
362
363// Complete request and execute it with limit
364$sql .= $db->order($sortfield, $sortorder);
365if ($limit) {
366 $sql .= $db->plimit($limit + 1, $offset);
367}
368
369$resql = $db->query($sql);
370if (!$resql) {
371 dol_print_error($db);
372 exit;
373}
374
375$num = $db->num_rows($resql);
376
377
378// Direct jump if only one record found
379if ($num == 1 && getDolGlobalInt('MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE') && $search_all && !$page) {
380 $obj = $db->fetch_object($resql);
381 $id = $obj->rowid;
382 header("Location: ".dol_buildpath('/hrm/position.php', 1).'?id='.$id);
383 exit;
384}
385
386
387// Output page
388// --------------------------------------------------------------------
389
390llxHeader('', $title, $help_url, '', 0, 0, $morejs, $morecss, '', 'bodyforlist');
391
392// Example : Adding jquery code
393// print '<script type="text/javascript">
394// jQuery(document).ready(function() {
395// function init_myfunc()
396// {
397// jQuery("#myid").removeAttr(\'disabled\');
398// jQuery("#myid").attr(\'disabled\',\'disabled\');
399// }
400// init_myfunc();
401// jQuery("#mybutton").click(function() {
402// init_myfunc();
403// });
404// });
405// </script>';
406
407$arrayofselected = is_array($toselect) ? $toselect : array();
408
409$param = '';
410if (!empty($mode)) {
411 $param .= '&mode='.urlencode($mode);
412}
413if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
414 $param .= '&contextpage='.urlencode($contextpage);
415}
416if ($limit > 0 && $limit != $conf->liste_limit) {
417 $param .= '&limit='.((int) $limit);
418}
419if ($optioncss != '') {
420 $param .= '&optioncss='.urlencode($optioncss);
421}
422
423foreach ($search as $key => $val) {
424 if (is_array($search[$key])) {
425 foreach ($search[$key] as $skey) {
426 if ($skey != '') {
427 $param .= '&search_'.$key.'[]='.urlencode($skey);
428 }
429 }
430 } elseif (preg_match('/(_dtstart|_dtend)$/', $key) && !empty($val)) {
431 $param .= '&search_'.$key.'month='.GETPOSTINT('search_'.$key.'month');
432 $param .= '&search_'.$key.'day='.GETPOSTINT('search_'.$key.'day');
433 $param .= '&search_'.$key.'year='.GETPOSTINT('search_'.$key.'year');
434 } elseif ($search[$key] != '') {
435 $param .= '&search_'.$key.'='.urlencode($search[$key]);
436 }
437}
438// Add $param from extra fields
439include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
440// Add $param from hooks
441$parameters = array('param' => &$param);
442$reshook = $hookmanager->executeHooks('printFieldListSearchParam', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
443$param .= $hookmanager->resPrint;
444
445// List of mass actions available
446$arrayofmassactions = array(
447 //'validate'=>img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("Validate"),
448 //'generate_doc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("ReGeneratePDF"),
449 //'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"),
450 //'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"),
451);
452if (!empty($permissiontodelete)) {
453 $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
454}
455if (GETPOSTINT('nomassaction') || in_array($massaction, array('presend', 'predelete'))) {
456 $arrayofmassactions = array();
457}
458$massactionbutton = $form->selectMassAction('', $arrayofmassactions);
459
460print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">'."\n";
461if ($optioncss != '') {
462 print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
463}
464print '<input type="hidden" name="token" value="'.newToken().'">';
465print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
466print '<input type="hidden" name="action" value="list">';
467print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
468print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
469print '<input type="hidden" name="page" value="'.$page.'">';
470print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
471print '<input type="hidden" name="page_y" value="">';
472print '<input type="hidden" name="mode" value="'.$mode.'">';
473
474$newcardbutton = '';
475$newcardbutton .= dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-bars imgforviewmode', $_SERVER["PHP_SELF"].'?mode=common'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ((empty($mode) || $mode == 'common') ? 2 : 1), array('morecss' => 'reposition'));
476$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'));
477$newcardbutton .= dolGetButtonTitleSeparator();
478$newcardbutton .= dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', dol_buildpath('/hrm/position.php', 1).'?action=create', '', $permissiontoadd);
479
480print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'object_'.$object->picto, 0, $newcardbutton, '', $limit, 0, 0, 1);
481
482// Add code for pre mass action (confirmation or email presend form)
483$topicmail = "SendPositionRef";
484$modelmail = "position";
485$objecttmp = new Position($db);
486$trackid = 'xxxx'.$object->id;
487include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
488
489if ($search_all) {
490 $setupstring = '';
491 // @phan-suppress-next-line PhanEmptyForeach
492 foreach ($fieldstosearchall as $key => $val) {
493 $fieldstosearchall[$key] = $langs->trans($val);
494 $setupstring .= $key."=".$val.";";
495 }
496 print '<!-- Search done like if JOBPOSITION_QUICKSEARCH_ON_FIELDS = '.$setupstring.' -->'."\n";
497 print '<div class="divsearchfieldfilter">'.$langs->trans("FilterOnInto", $search_all).implode(', ', $fieldstosearchall).'</div>';
498}
499
500$moreforfilter = '';
501/*$moreforfilter.='<div class="divsearchfield">';
502$moreforfilter.= $langs->trans('MyFilter') . ': <input type="text" name="search_myfield" value="'.dol_escape_htmltag($search_myfield).'">';
503$moreforfilter.= '</div>';*/
504
505$parameters = array();
506$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
507if (empty($reshook)) {
508 $moreforfilter .= $hookmanager->resPrint;
509} else {
510 $moreforfilter = $hookmanager->resPrint;
511}
512
513if (!empty($moreforfilter)) {
514 print '<div class="liste_titre liste_titre_bydiv centpercent">';
515 print $moreforfilter;
516 print '</div>';
517}
518
519$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
520$htmlofselectarray = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, $conf->main_checkbox_left_column ? 'left' : ''); // This also change content of $arrayfields with user setup
521$selectedfields = ($mode != 'kanban' ? $htmlofselectarray : '');
522$selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : '');
523
524print '<div class="div-table-responsive">'; // You can use div-table-responsive-no-min if you don't need reserved height for your table
525print '<table class="tagtable nobottomiftotal noborder liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n";
526
527
528$totalarray = array();
529$totalarray['nbfield'] = 0;
530
531// Fields title search
532// --------------------------------------------------------------------
533print '<tr class="liste_titre_filter">';
534// Action column
535if ($conf->main_checkbox_left_column) {
536 print '<td class="liste_titre center maxwidthsearch">';
537 $searchpicto = $form->showFilterButtons('left');
538 print $searchpicto;
539 print '</td>';
540}
541foreach ($object->fields as $key => $val) {
542 //$searchkey = empty($search[$key]) ? '' : $search[$key];
543 $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']);
544 if ($key == 'status') {
545 $cssforfield .= ($cssforfield ? ' ' : '').'center';
546 } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
547 $cssforfield .= ($cssforfield ? ' ' : '').'center';
548 } elseif (in_array($val['type'], array('timestamp'))) {
549 $cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
550 } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && !in_array($key, array('id', 'rowid', 'ref', 'status')) && $val['label'] != 'TechnicalID' && empty($val['arrayofkeyval'])) {
551 $cssforfield .= ($cssforfield ? ' ' : '').'right';
552 }
553 if (!empty($arrayfields['t.'.$key]['checked'])) {
554 print '<td class="liste_titre'.($cssforfield ? ' '.$cssforfield : '').($key == 'status' ? ' parentonrightofpage' : '').'">';
555 if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
556 if (empty($val['searchmulti'])) {
557 print $form->selectarray('search_'.$key, $val['arrayofkeyval'], (isset($search[$key]) ? $search[$key] : ''), 1, 0, 0, '', 1, 0, 0, '', 'maxwidth100'.($key == 'status' ? ' search_status width100 onrightofpage' : ''), 1);
558 } else {
559 print $form->multiselectarray('search_'.$key, $val['arrayofkeyval'], (isset($search[$key]) ? $search[$key] : ''), 0, 0, 'maxwidth100'.($key == 'status' ? ' search_status width100 onrightofpage' : ''), 1);
560 }
561 } elseif ((strpos($val['type'], 'integer:') === 0) || (strpos($val['type'], 'sellist:') === 0)) {
562 print $object->showInputField($val, $key, (isset($search[$key]) ? $search[$key] : ''), '', '', 'search_', $cssforfield.' maxwidth250', 1);
563 } elseif (preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
564 print '<div class="nowrap">';
565 print $form->selectDate($search[$key.'_dtstart'] ? $search[$key.'_dtstart'] : '', "search_".$key."_dtstart", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From'));
566 print '</div>';
567 print '<div class="nowrap">';
568 print $form->selectDate($search[$key.'_dtend'] ? $search[$key.'_dtend'] : '', "search_".$key."_dtend", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to'));
569 print '</div>';
570 } elseif ($key == 'lang') {
571 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
572 $formadmin = new FormAdmin($db);
573 print $formadmin->select_language((isset($search[$key]) ? $search[$key] : ''), 'search_lang', 0, array(), 1, 0, 0, 'minwidth100imp maxwidth125', 2);
574 } else {
575 print '<input type="text" class="flat maxwidth'.(in_array($val['type'], array('integer', 'price')) ? '50' : '75').'" name="search_'.$key.'" value="'.dol_escape_htmltag(isset($search[$key]) ? $search[$key] : '').'">';
576 }
577 print '</td>';
578 }
579}
580// Extra fields
581include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php';
582
583// Fields from hook
584$parameters = array('arrayfields' => $arrayfields);
585$reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
586print $hookmanager->resPrint;
587// Action column
588if (!$conf->main_checkbox_left_column) {
589 print '<td class="liste_titre center maxwidthsearch">';
590 $searchpicto = $form->showFilterButtons();
591 print $searchpicto;
592 print '</td>';
593}
594print '</tr>'."\n";
595
596$totalarray = array();
597$totalarray['nbfield'] = 0;
598
599// Fields title label
600// --------------------------------------------------------------------
601print '<tr class="liste_titre">';
602// Action column
603if ($conf->main_checkbox_left_column) {
604 print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
605 $totalarray['nbfield']++;
606}
607foreach ($object->fields as $key => $val) {
608 $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']);
609 if ($key == 'status') {
610 $cssforfield .= ($cssforfield ? ' ' : '').'center';
611 } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
612 $cssforfield .= ($cssforfield ? ' ' : '').'center';
613 } elseif (in_array($val['type'], array('timestamp'))) {
614 $cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
615 } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && !in_array($key, array('id', 'rowid', 'ref', 'status')) && $val['label'] != 'TechnicalID' && empty($val['arrayofkeyval'])) {
616 $cssforfield .= ($cssforfield ? ' ' : '').'right';
617 }
618 $cssforfield = preg_replace('/small\s*/', '', $cssforfield); // the 'small' css must not be used for the title label
619 if (!empty($arrayfields['t.'.$key]['checked'])) {
620 print getTitleFieldOfList($arrayfields['t.'.$key]['label'], 0, $_SERVER['PHP_SELF'], 't.'.$key, '', $param, ($cssforfield ? 'class="'.$cssforfield.'"' : ''), $sortfield, $sortorder, ($cssforfield ? $cssforfield.' ' : ''), 0, (empty($val['helplist']) ? '' : $val['helplist']))."\n";
621 $totalarray['nbfield']++;
622 }
623}
624// Extra fields
625include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php';
626// Hook fields
627$parameters = array('arrayfields' => $arrayfields, 'param' => $param, 'sortfield' => $sortfield, 'sortorder' => $sortorder, 'totalarray' => &$totalarray);
628$reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
629print $hookmanager->resPrint;
630/*if (!empty($arrayfields['anotherfield']['checked'])) {
631 print '<th class="liste_titre right">'.$langs->trans("AnotherField").'</th>';
632 $totalarray['nbfield']++;
633 }*/
634// Action column
635if (!$conf->main_checkbox_left_column) {
636 print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
637 $totalarray['nbfield']++;
638}
639print '</tr>'."\n";
640
641
642// Detect if we need a fetch on each output line
643$needToFetchEachLine = 0;
644if (isset($extrafields->attributes[$object->table_element]['computed']) && is_array($extrafields->attributes[$object->table_element]['computed']) && count($extrafields->attributes[$object->table_element]['computed']) > 0) {
645 foreach ($extrafields->attributes[$object->table_element]['computed'] as $key => $val) {
646 if (!is_null($val) && preg_match('/\$object/', $val)) {
647 $needToFetchEachLine++; // There is at least one compute field that use $object
648 }
649 }
650}
651
652
653// Loop on record
654// --------------------------------------------------------------------
655$i = 0;
656$savnbfield = $totalarray['nbfield'];
657$totalarray = array();
658$totalarray['nbfield'] = 0;
659$imaxinloop = ($limit ? min($num, $limit) : $num);
660while ($i < $imaxinloop) {
661 $obj = $db->fetch_object($resql);
662 if (empty($obj)) {
663 break; // Should not happen
664 }
665
666 // Store properties in $object
667 $object->setVarsFromFetchObj($obj);
668
669 if ($mode == 'kanban') {
670 if ($i == 0) {
671 print '<tr class="trkanban"><td colspan="'.$savnbfield.'">';
672 print '<div class="box-flex-container kanban">';
673 }
674 // get info needed
675 $object->date_start = $obj->date_start;
676 $object->date_end = $obj->date_end;
677 $object->fk_job = $obj->job_id;
678
679 $jobstatic->id = $obj->job_id;
680 $jobstatic->label = $obj->job_label;
681 $jobstatic->status = $obj->job_status;
682
683 $userstatic->id = $obj->fk_user;
684 $userstatic->ref = (string) $obj->fk_user;
685 $userstatic->firstname = $obj->firstname;
686 $userstatic->lastname = $obj->lastname;
687 $userstatic->email = $obj->email;
688 $userstatic->statut = $obj->statut; // deprecated
689 $userstatic->status = $obj->statut;
690 $userstatic->login = $obj->login;
691 $userstatic->photo = $obj->photo;
692
693 // Output Kanban
694 $selected = -1;
695 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
696 $selected = 0;
697 if (in_array($object->id, $arrayofselected)) {
698 $selected = 1;
699 }
700 }
701 print $object->getKanbanView('', array('user' => $userstatic->getNomUrl(-1), 'job' => $jobstatic->getNomUrl(1), 'selected' => $selected));
702 if ($i == ($imaxinloop - 1)) {
703 print '</div>';
704 print '</td></tr>';
705 }
706 } else {
707 // Show line of result
708 $j = 0;
709 print '<tr data-rowid="'.$object->id.'" class="oddeven">';
710 // Action column
711 if ($conf->main_checkbox_left_column) {
712 print '<td class="nowrap center">';
713 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
714 $selected = 0;
715 if (in_array($object->id, $arrayofselected)) {
716 $selected = 1;
717 }
718 print '<input id="cb'.$object->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$object->id.'"'.($selected ? ' checked="checked"' : '').'>';
719 }
720 print '</td>';
721 if (!$i) {
722 $totalarray['nbfield']++;
723 }
724 }
725 foreach ($object->fields as $key => $val) {
726 $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']);
727 if (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
728 $cssforfield .= ($cssforfield ? ' ' : '').'center';
729 } elseif ($key == 'status') {
730 $cssforfield .= ($cssforfield ? ' ' : '').'center';
731 }
732
733 if (in_array($val['type'], array('timestamp'))) {
734 $cssforfield .= ($cssforfield ? ' ' : '').'nowraponall';
735 } elseif ($key == 'ref') {
736 $cssforfield .= ($cssforfield ? ' ' : '').'nowraponall';
737 }
738
739 if (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && !in_array($key, array('id', 'rowid', 'ref', 'status')) && empty($val['arrayofkeyval'])) {
740 $cssforfield .= ($cssforfield ? ' ' : '').'right';
741 }
742 //if (in_array($key, array('fk_soc', 'fk_user', 'fk_warehouse'))) $cssforfield = 'tdoverflowmax100';
743
744 if (!empty($arrayfields['t.'.$key]['checked'])) {
745 print '<td'.($cssforfield ? ' class="'.$cssforfield.((preg_match('/tdoverflow/', $cssforfield) && !in_array($val['type'], array('ip', 'url')) && !is_numeric($object->$key)) ? ' classfortooltip' : '').'"' : '');
746 if (preg_match('/tdoverflow/', $cssforfield) && !in_array($val['type'], array('ip', 'url')) && !is_numeric($object->$key) && !in_array($key, array('ref'))) {
747 print ' title="'.dolPrintHTMLForAttribute((string) $object->$key).'"';
748 }
749 print '>';
750 if ($key == 'status') {
751 print $object->getLibStatut(5);
752 } elseif ($key == 'rowid') {
753 print $object->showOutputField($val, $key, (string) $object->id, '');
754 } else {
755 print $object->showOutputField($val, $key, $object->$key, '');
756 }
757 print '</td>';
758 if (!$i) {
759 $totalarray['nbfield']++;
760 }
761 if (!empty($val['isameasure']) && $val['isameasure'] == 1) {
762 if (!$i) {
763 $totalarray['pos'][$totalarray['nbfield']] = 't.'.$key;
764 }
765 if (!isset($totalarray['val'])) {
766 $totalarray['val'] = array();
767 }
768 if (!isset($totalarray['val']['t.'.$key])) {
769 $totalarray['val']['t.'.$key] = 0;
770 }
771 $totalarray['val']['t.'.$key] += $object->$key;
772 }
773 }
774 }
775 // Extra fields
776 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
777 // Fields from hook
778 $parameters = array('arrayfields' => $arrayfields, 'object' => $object, 'obj' => $obj, 'i' => $i, 'totalarray' => &$totalarray);
779 $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
780 print $hookmanager->resPrint;
781 // Action column
782 if (empty($conf->main_checkbox_left_column)) {
783 print '<td class="nowrap center">';
784 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
785 $selected = 0;
786 if (in_array($object->id, $arrayofselected)) {
787 $selected = 1;
788 }
789 print '<input id="cb'.$object->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$object->id.'"'.($selected ? ' checked="checked"' : '').'>';
790 }
791 print '</td>';
792 if (!$i) {
793 $totalarray['nbfield']++;
794 }
795 }
796
797 print '</tr>'."\n";
798 }
799
800 $i++;
801}
802
803// Show total line
804include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php';
805
806// If no record found
807if ($num == 0) {
808 $colspan = 1;
809 foreach ($arrayfields as $key => $val) {
810 if (!empty($val['checked'])) {
811 $colspan++;
812 }
813 }
814 print '<tr><td colspan="'.$colspan.'"><span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span></td></tr>';
815}
816
817
818$db->free($resql);
819
820$parameters = array('arrayfields' => $arrayfields, 'sql' => $sql);
821$reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
822print $hookmanager->resPrint;
823
824print '</table>'."\n";
825print '</div>'."\n";
826
827print '</form>'."\n";
828
829if (in_array('builddoc', array_keys($arrayofmassactions)) && ($nbtotalofrecords === '' || $nbtotalofrecords)) {
830 $hidegeneratedfilelistifempty = 1;
831 if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) {
832 $hidegeneratedfilelistifempty = 0;
833 }
834
835 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
836 $formfile = new FormFile($db);
837
838 // Show list of available documents
839 $urlsource = $_SERVER['PHP_SELF'].'?sortfield='.$sortfield.'&sortorder='.$sortorder;
840 $urlsource .= str_replace('&amp;', '&', $param);
841
842 $filedir = $diroutputmassaction;
843 $genallowed = $permissiontoread;
844 $delallowed = $permissiontoadd;
845
846 print $formfile->showdocuments('massfilesarea_hrm', '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty);
847}
848
849// End of page
850llxFooter();
851$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
$totalarray
Definition export.php:1216
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
Class to manage standard extra fields.
Class to generate html code for admin pages.
Class to offer components to list and upload files.
Class to manage generation of HTML components Only common components must be here.
Class for Job.
Definition job.class.php:38
Class for Position.
Class to manage Dolibarr users.
dol_now($mode='gmt')
Return date for now.
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...
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
print_barre_liste($title, $page, $file, $options='', $sortfield='', $sortorder='', $morehtmlcenter='', $num=-1, $totalnboflines='', $picto='generic', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limit=-1, $selectlimitsuffix=0, $hidenavigation=0, $pagenavastextinput=0, $morehtmlrightbeforearrow='')
Print a title with navigation controls for pagination.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dolGetButtonTitle($label, $helpText='', $iconClass='fa fa-file', $url='', $id='', $status=1, $params=array())
Function dolGetButtonTitle : this kind of buttons are used in title in list.
dol_eval($s, $returnvalue=1, $hideerrors=1, $onlysimplestring='1')
Replace eval function to add more security.
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...
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.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
isModEnabled($module)
Is Dolibarr module enabled.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.