dolibarr 21.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 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'); // 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($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
165
166/*
167 * Actions
168 */
169
170if (GETPOST('cancel', 'alpha')) {
171 $action = 'list';
172 $massaction = '';
173}
174if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') {
175 $massaction = '';
176}
177
178$parameters = array('arrayfields' => &$arrayfields);
179$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
180if ($reshook < 0) {
181 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
182}
183
184if (empty($reshook)) {
185 // Selection of new fields
186 include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
187
188 // Purge search criteria
189 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
190 foreach ($object->fields as $key => $val) {
191 $search[$key] = '';
192 if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
193 $search[$key.'_dtstart'] = '';
194 $search[$key.'_dtend'] = '';
195 }
196 }
197 $search_all = '';
198 $toselect = array();
199 $search_array_options = array();
200 }
201 if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')
202 || GETPOST('button_search_x', 'alpha') || GETPOST('button_search.x', 'alpha') || GETPOST('button_search', 'alpha')) {
203 $massaction = ''; // Protection to avoid mass action if we force a new search during a mass action confirmation
204 }
205
206 // Mass actions
207 $objectclass = 'Position';
208 $objectlabel = 'Position';
209 $uploaddir = $conf->hrm->dir_output;
210 include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
211}
212
213
214
215/*
216 * View
217 */
218
219$form = new Form($db);
220$jobstatic = new Job($db);
221
222$now = dol_now();
223
224$title = $langs->trans('EmployeePositions');
225//$help_url="EN:Module_Position|FR:Module_Position_FR|ES:Módulo_Position";
226$help_url = '';
227$morejs = array();
228$morecss = array();
229
230
231// Build and execute select
232// --------------------------------------------------------------------
233$sql = 'SELECT ';
234$sql .= $object->getFieldList('t');
235$sql .= ',';
236$sql .= $userstatic->getFieldList('u', array('rowid'));
237$sql .= ', u.email, u.statut, u.photo, u.login'; // Add more field not yet into the user->fields
238$sql .= ', j.rowid as job_id, j.label as job_label';
239// Add fields from extrafields
240if (!empty($extrafields->attributes[$object->table_element]['label'])) {
241 foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
242 $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key." as options_".$key : "");
243 }
244}
245// Add fields from hooks
246$parameters = array();
247$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
248$sql .= $hookmanager->resPrint;
249$sql = preg_replace('/,\s*$/', '', $sql);
250
251$sqlfields = $sql; // $sql fields to remove for count total
252
253$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";
254
255//$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."anothertable as rc ON rc.parent = t.rowid";
256if (isset($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) {
257 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (t.rowid = ef.fk_object)";
258}
259// Add table from hooks
260$parameters = array();
261$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
262$sql .= $hookmanager->resPrint;
263if ($object->ismultientitymanaged == 1) {
264 $sql .= " WHERE t.entity IN (".getEntity($object->element, (GETPOSTINT('search_current_entity') ? 0 : 1)).")";
265} else {
266 $sql .= " WHERE 1 = 1";
267}
268$sql .= " AND t.fk_job = j.rowid";
269foreach ($search as $key => $val) {
270 if (array_key_exists($key, $object->fields)) {
271 if ($key == 'status' && $search[$key] == -1) {
272 continue;
273 }
274 $mode_search = (($object->isInt($object->fields[$key]) || $object->isFloat($object->fields[$key])) ? 1 : 0);
275 if ((strpos($object->fields[$key]['type'], 'integer:') === 0) || (strpos($object->fields[$key]['type'], 'sellist:') === 0) || !empty($object->fields[$key]['arrayofkeyval'])) {
276 if ($search[$key] == '-1' || ($search[$key] === '0' && (empty($object->fields[$key]['arrayofkeyval']) || !array_key_exists('0', $object->fields[$key]['arrayofkeyval'])))) {
277 $search[$key] = '';
278 }
279 $mode_search = 2;
280 }
281 if (empty($object->fields[$key]['searchmulti'])) {
282 if (!is_array($search[$key]) && $search[$key] != '') {
283 $sql .= natural_search("t.".$db->escape($key), $search[$key], (($key == 'status') ? 2 : $mode_search));
284 }
285 } else {
286 if (is_array($search[$key]) && !empty($search[$key])) {
287 $sql .= natural_search("t.".$db->escape($key), implode(',', $search[$key]), (($key == 'status') ? 2 : $mode_search));
288 }
289 }
290 } else {
291 if (preg_match('/(_dtstart|_dtend)$/', $key) && $search[$key] != '') {
292 $columnName = preg_replace('/(_dtstart|_dtend)$/', '', $key);
293 if (preg_match('/^(date|timestamp|datetime)/', $object->fields[$columnName]['type'])) {
294 if (preg_match('/_dtstart$/', $key)) {
295 $sql .= " AND t.".$db->sanitize($columnName)." >= '".$db->idate($search[$key])."'";
296 }
297 if (preg_match('/_dtend$/', $key)) {
298 $sql .= " AND t.".$db->sanitize($columnName)." <= '".$db->idate($search[$key])."'";
299 }
300 }
301 }
302 }
303}
304$vacant = GETPOST('search_fk_uservacant', 'alphanohtml') === 'on';
305if ($vacant) {
306 $sql .= ' AND t.fk_user = 0';
307}
308if ($search_all) {
309 $sql .= natural_search(array_keys($fieldstosearchall), $search_all);
310}
311//$sql.= dolSqlDateFilter("t.field", $search_xxxday, $search_xxxmonth, $search_xxxyear);
312// Add where from extra fields
313include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
314// Add where from hooks
315$parameters = array();
316$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
317$sql .= $hookmanager->resPrint;
318
319/* If a group by is required
320$sql .= " GROUP BY ";
321foreach($object->fields as $key => $val) {
322 $sql .= "t.".$db->sanitize($key).", ";
323}
324// Add fields from extrafields
325if (!empty($extrafields->attributes[$object->table_element]['label'])) {
326 foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
327 $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? "ef.".$key.', ' : '');
328 }
329}
330// Add groupby from hooks
331$parameters = array();
332$reshook = $hookmanager->executeHooks('printFieldListGroupBy', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
333$sql .= $hookmanager->resPrint;
334$sql = preg_replace('/,\s*$/', '', $sql);
335*/
336
337// Count total nb of records
338$nbtotalofrecords = '';
339if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
340 /* The fast and low memory method to get and count full list converts the sql into a sql count */
341 $sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql);
342 $sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount);
343
344 $resql = $db->query($sqlforcount);
345 if ($resql) {
346 $objforcount = $db->fetch_object($resql);
347 $nbtotalofrecords = $objforcount->nbtotalofrecords;
348 } else {
349 dol_print_error($db);
350 }
351
352 if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller than the paging size (filtering), goto and load page 0
353 $page = 0;
354 $offset = 0;
355 }
356 $db->free($resql);
357}
358
359// Complete request and execute it with limit
360$sql .= $db->order($sortfield, $sortorder);
361if ($limit) {
362 $sql .= $db->plimit($limit + 1, $offset);
363}
364
365$resql = $db->query($sql);
366if (!$resql) {
367 dol_print_error($db);
368 exit;
369}
370
371$num = $db->num_rows($resql);
372
373
374// Direct jump if only one record found
375if ($num == 1 && getDolGlobalInt('MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE') && $search_all && !$page) {
376 $obj = $db->fetch_object($resql);
377 $id = $obj->rowid;
378 header("Location: ".dol_buildpath('/hrm/position.php', 1).'?id='.$id);
379 exit;
380}
381
382
383// Output page
384// --------------------------------------------------------------------
385
386llxHeader('', $title, $help_url, '', 0, 0, $morejs, $morecss, '', 'bodyforlist');
387
388// Example : Adding jquery code
389// print '<script type="text/javascript">
390// jQuery(document).ready(function() {
391// function init_myfunc()
392// {
393// jQuery("#myid").removeAttr(\'disabled\');
394// jQuery("#myid").attr(\'disabled\',\'disabled\');
395// }
396// init_myfunc();
397// jQuery("#mybutton").click(function() {
398// init_myfunc();
399// });
400// });
401// </script>';
402
403$arrayofselected = is_array($toselect) ? $toselect : array();
404
405$param = '';
406if (!empty($mode)) {
407 $param .= '&mode='.urlencode($mode);
408}
409if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
410 $param .= '&contextpage='.urlencode($contextpage);
411}
412if ($limit > 0 && $limit != $conf->liste_limit) {
413 $param .= '&limit='.((int) $limit);
414}
415if ($optioncss != '') {
416 $param .= '&optioncss='.urlencode($optioncss);
417}
418
419foreach ($search as $key => $val) {
420 if (is_array($search[$key])) {
421 foreach ($search[$key] as $skey) {
422 if ($skey != '') {
423 $param .= '&search_'.$key.'[]='.urlencode($skey);
424 }
425 }
426 } elseif (preg_match('/(_dtstart|_dtend)$/', $key) && !empty($val)) {
427 $param .= '&search_'.$key.'month='.GETPOSTINT('search_'.$key.'month');
428 $param .= '&search_'.$key.'day='.GETPOSTINT('search_'.$key.'day');
429 $param .= '&search_'.$key.'year='.GETPOSTINT('search_'.$key.'year');
430 } elseif ($search[$key] != '') {
431 $param .= '&search_'.$key.'='.urlencode($search[$key]);
432 }
433}
434// Add $param from extra fields
435include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
436// Add $param from hooks
437$parameters = array('param' => &$param);
438$reshook = $hookmanager->executeHooks('printFieldListSearchParam', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
439$param .= $hookmanager->resPrint;
440
441// List of mass actions available
442$arrayofmassactions = array(
443 //'validate'=>img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("Validate"),
444 //'generate_doc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("ReGeneratePDF"),
445 //'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"),
446 //'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"),
447);
448if (!empty($permissiontodelete)) {
449 $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
450}
451if (GETPOSTINT('nomassaction') || in_array($massaction, array('presend', 'predelete'))) {
452 $arrayofmassactions = array();
453}
454$massactionbutton = $form->selectMassAction('', $arrayofmassactions);
455
456print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">'."\n";
457if ($optioncss != '') {
458 print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
459}
460print '<input type="hidden" name="token" value="'.newToken().'">';
461print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
462print '<input type="hidden" name="action" value="list">';
463print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
464print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
465print '<input type="hidden" name="page" value="'.$page.'">';
466print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
467print '<input type="hidden" name="page_y" value="">';
468print '<input type="hidden" name="mode" value="'.$mode.'">';
469
470$newcardbutton = '';
471$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'));
472$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'));
473$newcardbutton .= dolGetButtonTitleSeparator();
474$newcardbutton .= dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', dol_buildpath('/hrm/position.php', 1).'?action=create', '', $permissiontoadd);
475
476print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'object_'.$object->picto, 0, $newcardbutton, '', $limit, 0, 0, 1);
477
478// Add code for pre mass action (confirmation or email presend form)
479$topicmail = "SendPositionRef";
480$modelmail = "position";
481$objecttmp = new Position($db);
482$trackid = 'xxxx'.$object->id;
483include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
484
485if ($search_all) {
486 $setupstring = '';
487 // @phan-suppress-next-line PhanEmptyForeach
488 foreach ($fieldstosearchall as $key => $val) {
489 $fieldstosearchall[$key] = $langs->trans($val);
490 $setupstring .= $key."=".$val.";";
491 }
492 print '<!-- Search done like if JOBPOSITION_QUICKSEARCH_ON_FIELDS = '.$setupstring.' -->'."\n";
493 print '<div class="divsearchfieldfilter">'.$langs->trans("FilterOnInto", $search_all).implode(', ', $fieldstosearchall).'</div>';
494}
495
496$moreforfilter = '';
497/*$moreforfilter.='<div class="divsearchfield">';
498$moreforfilter.= $langs->trans('MyFilter') . ': <input type="text" name="search_myfield" value="'.dol_escape_htmltag($search_myfield).'">';
499$moreforfilter.= '</div>';*/
500
501$parameters = array();
502$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
503if (empty($reshook)) {
504 $moreforfilter .= $hookmanager->resPrint;
505} else {
506 $moreforfilter = $hookmanager->resPrint;
507}
508
509if (!empty($moreforfilter)) {
510 print '<div class="liste_titre liste_titre_bydiv centpercent">';
511 print $moreforfilter;
512 print '</div>';
513}
514
515$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
516$htmlofselectarray = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, $conf->main_checkbox_left_column); // This also change content of $arrayfields with user setup
517$selectedfields = ($mode != 'kanban' ? $htmlofselectarray : '');
518$selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : '');
519
520print '<div class="div-table-responsive">'; // You can use div-table-responsive-no-min if you don't need reserved height for your table
521print '<table class="tagtable nobottomiftotal noborder liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n";
522
523
524$totalarray = array();
525$totalarray['nbfield'] = 0;
526
527// Fields title search
528// --------------------------------------------------------------------
529print '<tr class="liste_titre_filter">';
530// Action column
531if ($conf->main_checkbox_left_column) {
532 print '<td class="liste_titre center maxwidthsearch">';
533 $searchpicto = $form->showFilterButtons('left');
534 print $searchpicto;
535 print '</td>';
536}
537foreach ($object->fields as $key => $val) {
538 //$searchkey = empty($search[$key]) ? '' : $search[$key];
539 $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']);
540 if ($key == 'status') {
541 $cssforfield .= ($cssforfield ? ' ' : '').'center';
542 } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
543 $cssforfield .= ($cssforfield ? ' ' : '').'center';
544 } elseif (in_array($val['type'], array('timestamp'))) {
545 $cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
546 } 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'])) {
547 $cssforfield .= ($cssforfield ? ' ' : '').'right';
548 }
549 if (!empty($arrayfields['t.'.$key]['checked'])) {
550 print '<td class="liste_titre'.($cssforfield ? ' '.$cssforfield : '').($key == 'status' ? ' parentonrightofpage' : '').'">';
551 if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
552 if (empty($val['searchmulti'])) {
553 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);
554 } else {
555 print $form->multiselectarray('search_'.$key, $val['arrayofkeyval'], (isset($search[$key]) ? $search[$key] : ''), 0, 0, 'maxwidth100'.($key == 'status' ? ' search_status width100 onrightofpage' : ''), 1);
556 }
557 } elseif ((strpos($val['type'], 'integer:') === 0) || (strpos($val['type'], 'sellist:') === 0)) {
558 print $object->showInputField($val, $key, (isset($search[$key]) ? $search[$key] : ''), '', '', 'search_', $cssforfield.' maxwidth250', 1);
559 } elseif (preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
560 print '<div class="nowrap">';
561 print $form->selectDate($search[$key.'_dtstart'] ? $search[$key.'_dtstart'] : '', "search_".$key."_dtstart", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From'));
562 print '</div>';
563 print '<div class="nowrap">';
564 print $form->selectDate($search[$key.'_dtend'] ? $search[$key.'_dtend'] : '', "search_".$key."_dtend", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to'));
565 print '</div>';
566 } elseif ($key == 'lang') {
567 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
568 $formadmin = new FormAdmin($db);
569 print $formadmin->select_language((isset($search[$key]) ? $search[$key] : ''), 'search_lang', 0, array(), 1, 0, 0, 'minwidth100imp maxwidth125', 2);
570 } else {
571 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] : '').'">';
572 }
573 print '</td>';
574 }
575}
576// Extra fields
577include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php';
578
579// Fields from hook
580$parameters = array('arrayfields' => $arrayfields);
581$reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
582print $hookmanager->resPrint;
583// Action column
584if (!$conf->main_checkbox_left_column) {
585 print '<td class="liste_titre center maxwidthsearch">';
586 $searchpicto = $form->showFilterButtons();
587 print $searchpicto;
588 print '</td>';
589}
590print '</tr>'."\n";
591
592$totalarray = array();
593$totalarray['nbfield'] = 0;
594
595// Fields title label
596// --------------------------------------------------------------------
597print '<tr class="liste_titre">';
598// Action column
599if ($conf->main_checkbox_left_column) {
600 print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
601 $totalarray['nbfield']++;
602}
603foreach ($object->fields as $key => $val) {
604 $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']);
605 if ($key == 'status') {
606 $cssforfield .= ($cssforfield ? ' ' : '').'center';
607 } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
608 $cssforfield .= ($cssforfield ? ' ' : '').'center';
609 } elseif (in_array($val['type'], array('timestamp'))) {
610 $cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
611 } 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'])) {
612 $cssforfield .= ($cssforfield ? ' ' : '').'right';
613 }
614 $cssforfield = preg_replace('/small\s*/', '', $cssforfield); // the 'small' css must not be used for the title label
615 if (!empty($arrayfields['t.'.$key]['checked'])) {
616 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";
617 $totalarray['nbfield']++;
618 }
619}
620// Extra fields
621include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php';
622// Hook fields
623$parameters = array('arrayfields' => $arrayfields, 'param' => $param, 'sortfield' => $sortfield, 'sortorder' => $sortorder, 'totalarray' => &$totalarray);
624$reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
625print $hookmanager->resPrint;
626/*if (!empty($arrayfields['anotherfield']['checked'])) {
627 print '<th class="liste_titre right">'.$langs->trans("AnotherField").'</th>';
628 $totalarray['nbfield']++;
629 }*/
630// Action column
631if (!$conf->main_checkbox_left_column) {
632 print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
633 $totalarray['nbfield']++;
634}
635print '</tr>'."\n";
636
637
638// Detect if we need a fetch on each output line
639$needToFetchEachLine = 0;
640if (isset($extrafields->attributes[$object->table_element]['computed']) && is_array($extrafields->attributes[$object->table_element]['computed']) && count($extrafields->attributes[$object->table_element]['computed']) > 0) {
641 foreach ($extrafields->attributes[$object->table_element]['computed'] as $key => $val) {
642 if (!is_null($val) && preg_match('/\$object/', $val)) {
643 $needToFetchEachLine++; // There is at least one compute field that use $object
644 }
645 }
646}
647
648
649// Loop on record
650// --------------------------------------------------------------------
651$i = 0;
652$savnbfield = $totalarray['nbfield'];
653$totalarray = array();
654$totalarray['nbfield'] = 0;
655$imaxinloop = ($limit ? min($num, $limit) : $num);
656while ($i < $imaxinloop) {
657 $obj = $db->fetch_object($resql);
658 if (empty($obj)) {
659 break; // Should not happen
660 }
661
662 // Store properties in $object
663 $object->setVarsFromFetchObj($obj);
664
665 if ($mode == 'kanban') {
666 if ($i == 0) {
667 print '<tr class="trkanban"><td colspan="'.$savnbfield.'">';
668 print '<div class="box-flex-container kanban">';
669 }
670 // get info needed
671 $object->date_start = $obj->date_start;
672 $object->date_end = $obj->date_end;
673 $object->fk_job = $obj->job_id;
674
675 $jobstatic->id = $obj->job_id;
676 $jobstatic->label = $obj->job_label;
677 $jobstatic->status = $obj->job_status;
678
679 $userstatic->id = $obj->fk_user;
680 $userstatic->ref = $obj->fk_user;
681 $userstatic->firstname = $obj->firstname;
682 $userstatic->lastname = $obj->lastname;
683 $userstatic->email = $obj->email;
684 $userstatic->statut = $obj->statut;
685 $userstatic->status = $obj->statut;
686 $userstatic->login = $obj->login;
687 $userstatic->photo = $obj->photo;
688
689 // Output Kanban
690 $selected = -1;
691 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
692 $selected = 0;
693 if (in_array($object->id, $arrayofselected)) {
694 $selected = 1;
695 }
696 }
697 print $object->getKanbanView('', array('user' => $userstatic->getNomUrl(-1), 'job' => $jobstatic->getNomUrl(1), 'selected' => $selected));
698 if ($i == ($imaxinloop - 1)) {
699 print '</div>';
700 print '</td></tr>';
701 }
702 } else {
703 // Show line of result
704 $j = 0;
705 print '<tr data-rowid="'.$object->id.'" class="oddeven">';
706 // Action column
707 if ($conf->main_checkbox_left_column) {
708 print '<td class="nowrap center">';
709 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
710 $selected = 0;
711 if (in_array($object->id, $arrayofselected)) {
712 $selected = 1;
713 }
714 print '<input id="cb'.$object->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$object->id.'"'.($selected ? ' checked="checked"' : '').'>';
715 }
716 print '</td>';
717 if (!$i) {
718 $totalarray['nbfield']++;
719 }
720 }
721 foreach ($object->fields as $key => $val) {
722 $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']);
723 if (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
724 $cssforfield .= ($cssforfield ? ' ' : '').'center';
725 } elseif ($key == 'status') {
726 $cssforfield .= ($cssforfield ? ' ' : '').'center';
727 }
728
729 if (in_array($val['type'], array('timestamp'))) {
730 $cssforfield .= ($cssforfield ? ' ' : '').'nowraponall';
731 } elseif ($key == 'ref') {
732 $cssforfield .= ($cssforfield ? ' ' : '').'nowraponall';
733 }
734
735 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'])) {
736 $cssforfield .= ($cssforfield ? ' ' : '').'right';
737 }
738 //if (in_array($key, array('fk_soc', 'fk_user', 'fk_warehouse'))) $cssforfield = 'tdoverflowmax100';
739
740 if (!empty($arrayfields['t.'.$key]['checked'])) {
741 print '<td'.($cssforfield ? ' class="'.$cssforfield.((preg_match('/tdoverflow/', $cssforfield) && !in_array($val['type'], array('ip', 'url')) && !is_numeric($object->$key)) ? ' classfortooltip' : '').'"' : '');
742 if (preg_match('/tdoverflow/', $cssforfield) && !in_array($val['type'], array('ip', 'url')) && !is_numeric($object->$key) && !in_array($key, array('ref'))) {
743 print ' title="'.dol_escape_htmltag($object->$key).'"';
744 }
745 print '>';
746 if ($key == 'status') {
747 print $object->getLibStatut(5);
748 } elseif ($key == 'rowid') {
749 print $object->showOutputField($val, $key, $object->id, '');
750 } else {
751 print $object->showOutputField($val, $key, $object->$key, '');
752 }
753 print '</td>';
754 if (!$i) {
755 $totalarray['nbfield']++;
756 }
757 if (!empty($val['isameasure']) && $val['isameasure'] == 1) {
758 if (!$i) {
759 $totalarray['pos'][$totalarray['nbfield']] = 't.'.$key;
760 }
761 if (!isset($totalarray['val'])) {
762 $totalarray['val'] = array();
763 }
764 if (!isset($totalarray['val']['t.'.$key])) {
765 $totalarray['val']['t.'.$key] = 0;
766 }
767 $totalarray['val']['t.'.$key] += $object->$key;
768 }
769 }
770 }
771 // Extra fields
772 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
773 // Fields from hook
774 $parameters = array('arrayfields' => $arrayfields, 'object' => $object, 'obj' => $obj, 'i' => $i, 'totalarray' => &$totalarray);
775 $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
776 print $hookmanager->resPrint;
777 // Action column
778 if (empty($conf->main_checkbox_left_column)) {
779 print '<td class="nowrap center">';
780 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
781 $selected = 0;
782 if (in_array($object->id, $arrayofselected)) {
783 $selected = 1;
784 }
785 print '<input id="cb'.$object->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$object->id.'"'.($selected ? ' checked="checked"' : '').'>';
786 }
787 print '</td>';
788 if (!$i) {
789 $totalarray['nbfield']++;
790 }
791 }
792
793 print '</tr>'."\n";
794 }
795
796 $i++;
797}
798
799// Show total line
800include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php';
801
802// If no record found
803if ($num == 0) {
804 $colspan = 1;
805 foreach ($arrayfields as $key => $val) {
806 if (!empty($val['checked'])) {
807 $colspan++;
808 }
809 }
810 print '<tr><td colspan="'.$colspan.'"><span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span></td></tr>';
811}
812
813
814$db->free($resql);
815
816$parameters = array('arrayfields' => $arrayfields, 'sql' => $sql);
817$reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
818print $hookmanager->resPrint;
819
820print '</table>'."\n";
821print '</div>'."\n";
822
823print '</form>'."\n";
824
825if (in_array('builddoc', array_keys($arrayofmassactions)) && ($nbtotalofrecords === '' || $nbtotalofrecords)) {
826 $hidegeneratedfilelistifempty = 1;
827 if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) {
828 $hidegeneratedfilelistifempty = 0;
829 }
830
831 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
832 $formfile = new FormFile($db);
833
834 // Show list of available documents
835 $urlsource = $_SERVER['PHP_SELF'].'?sortfield='.$sortfield.'&sortorder='.$sortorder;
836 $urlsource .= str_replace('&amp;', '&', $param);
837
838 $filedir = $diroutputmassaction;
839 $genallowed = $permissiontoread;
840 $delallowed = $permissiontoadd;
841
842 print $formfile->showdocuments('massfilesarea_hrm', '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty);
843}
844
845// End of page
846llxFooter();
847$db->close();
$id
Definition account.php:48
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:66
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
Definition wrapper.php:87
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:71
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_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)
Generate natural SQL search string for a criteria (this criteria can be tested on one or several fiel...
dol_now($mode='auto')
Return date for now.
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...
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...
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.