dolibarr 25.0.0-alpha
evaluation_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-2026 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';
37
38// load module libraries
39require_once __DIR__.'/class/evaluation.class.php';
40
49// Load translation files required by the page
50$langs->loadLangs(array('hrm', 'other'));
51
52// Get Parameters
53$action = GETPOST('action', 'aZ09') ? GETPOST('action', 'aZ09') : 'view'; // The action 'add', 'create', 'edit', 'update', 'view', ...
54$massaction = GETPOST('massaction', 'alpha'); // The bulk action (combo box choice into lists)
55$show_files = GETPOSTINT('show_files'); // Show files area generated by bulk actions ?
56$confirm = GETPOST('confirm', 'alpha'); // Result of a confirmation
57$cancel = GETPOST('cancel', 'alpha'); // We click on a Cancel button
58$toselect = GETPOST('toselect', 'array:int'); // Array of ids of elements selected into a list
59$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'evaluationlist'; // To manage different context of search
60$backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page
61$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print')
62$mode = GETPOST('mode', 'alpha'); // for mode view result
63
64$id = GETPOSTINT('id');
65$ref = GETPOST('ref', 'alpha');
66
67// Load variable for pagination
68$limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
69$sortfield = GETPOST('sortfield', 'aZ09comma');
70$sortorder = GETPOST('sortorder', 'aZ09comma');
71$page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page");
72if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha')) {
73 // If $page is not defined, or '' or -1 or if we click on clear filters
74 $page = 0;
75}
76$offset = $limit * $page;
77$pageprev = $page - 1;
78$pagenext = $page + 1;
79
80// Initialize a technical objects
82$extrafields = new ExtraFields($db);
83$diroutputmassaction = $conf->hrm->dir_output.'/temp/massgeneration/'.$user->id;
84$hookmanager->initHooks(array('evaluationlist')); // 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 $sortfield = "t.ref"; // Set here default search field. By default 1st field in definition.
95}
96if (!$sortorder) {
97 $sortorder = "DESC";
98}
99
100// Initialize array of search criteria
101$search_all = GETPOST('search_all', 'alphanohtml');
102$search = array();
103foreach ($object->fields as $key => $val) {
104 if (GETPOST('search_'.$key, 'alpha') !== '') {
105 $search[$key] = GETPOST('search_'.$key, 'alpha');
106 }
107 if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
108 $search[$key.'_dtstart'] = dol_mktime(0, 0, 0, GETPOSTINT('search_'.$key.'_dtstartmonth'), GETPOSTINT('search_'.$key.'_dtstartday'), GETPOSTINT('search_'.$key.'_dtstartyear'));
109 $search[$key.'_dtend'] = dol_mktime(23, 59, 59, GETPOSTINT('search_'.$key.'_dtendmonth'), GETPOSTINT('search_'.$key.'_dtendday'), GETPOSTINT('search_'.$key.'_dtendyear'));
110 }
111}
112
113// List of fields to search into when doing a "search in all"
114$fieldstosearchall = array();
115foreach ($object->fields as $key => $val) {
116 if (!empty($val['searchall'])) {
117 $fieldstosearchall['t.'.$key] = $val['label'];
118 }
119}
120
121// Definition of array of fields for columns
122$arrayfields = array();
123foreach ($object->fields as $key => $val) {
124 // If $val['visible']==0, then we never show the field
125 if (!empty($val['visible'])) {
126 $visible = (int) dol_eval((string) $val['visible'], 1);
127 $arrayfields['t.'.$key] = array(
128 'label' => $val['label'],
129 'checked' => (($visible < 0) ? 0 : 1),
130 'enabled' => (abs($visible) != 3 && (bool) dol_eval((string) $val['enabled'], 1)),
131 'position' => $val['position'],
132 'help' => isset($val['help']) ? $val['help'] : ''
133 );
134 }
135}
136// Extra fields
137include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php';
138// Add hook to complete $arrayfield
139$parameters = array('arrayfields' => &$arrayfields);
140$reshook = $hookmanager->executeHooks('completeArrayFields', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
141
142$object->fields = dol_sort_array($object->fields, 'position');
143$arrayfields = dol_sort_array($arrayfields, 'position');
144
145// Permissions
146$permissiontoread = $user->hasRight('hrm', 'evaluation', 'read');
147$permissiontoreadall = $user->hasRight('hrm', 'evaluation', 'readall');
148$permissiontoadd = $user->hasRight('hrm', 'evaluation', 'write');
149$permissiontodelete = $user->hasRight('hrm', 'evaluation', 'delete');
150
151// Security check
152if (!isModEnabled('hrm')) {
153 accessforbidden('Module not enabled');
154}
155
156// Security check (enable the most restrictive one)
157if ($user->socid > 0) {
159}
160//if ($user->socid > 0) accessforbidden();
161//$socid = 0; if ($user->socid > 0) $socid = $user->socid;
162//$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0);
163//restrictedArea($user, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft);
164//if (empty($conf->hrm->enabled)) accessforbidden();
165if (!$permissiontoread) {
167}
168
169
170
171/*
172 * Actions
173 */
174
175if (GETPOST('cancel', 'alpha')) {
176 $action = 'list';
177 $massaction = '';
178}
179if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') {
180 $massaction = '';
181}
182
183$parameters = array();
184$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
185if ($reshook < 0) {
186 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
187}
188
189if (empty($reshook)) {
190 // Selection of new fields
191 include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
192
193 // Purge search criteria
194 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
195 foreach ($object->fields as $key => $val) {
196 $search[$key] = '';
197 if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
198 $search[$key.'_dtstart'] = '';
199 $search[$key.'_dtend'] = '';
200 }
201 }
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 = 'Evaluation';
212 $objectlabel = 'Evaluation';
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
225$now = dol_now();
226
227//$help_url="EN:Module_Evaluation|FR:Module_Evaluation_FR|ES:Módulo_Evaluation";
228$help_url = '';
229$title = $langs->trans('Evaluations');
230$morejs = array();
231$morecss = array();
232
233
234// Build and execute select
235// --------------------------------------------------------------------
236$sql = 'SELECT ';
237$sql .= $object->getFieldList('t');
238// Add fields from extrafields
239if (!empty($extrafields->attributes[$object->table_element]['label'])) {
240 foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
241 $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key." as options_".$key : '');
242 }
243}
244// Add fields from hooks
245$parameters = array();
246$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
247$sql .= $hookmanager->resPrint;
248$sql = preg_replace('/,\s*$/', '', $sql);
249//$sql .= ", COUNT(rc.rowid) as anotherfield";
250
251$sqlfields = $sql; // $sql fields to remove for count total
252
253$sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t";
254if (isset($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) {
255 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (t.rowid = ef.fk_object)";
256}
257// Add table from hooks
258$parameters = array();
259$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object); // Note that $action and $object may have been modified by hook
260$sql .= $hookmanager->resPrint;
261if ($object->ismultientitymanaged == 1) {
262 $sql .= " WHERE t.entity IN (".getEntity($object->element).")";
263} else {
264 $sql .= " WHERE 1 = 1";
265}
266foreach ($search as $key => $val) {
267 if (array_key_exists($key, $object->fields)) {
268 if ($key == 'status' && $search[$key] == -1) {
269 continue;
270 }
271 $mode_search = (($object->isInt($object->fields[$key]) || $object->isFloat($object->fields[$key])) ? 1 : 0);
272 if ((strpos($object->fields[$key]['type'], 'integer:') === 0) || (strpos($object->fields[$key]['type'], 'sellist:') === 0) || !empty($object->fields[$key]['arrayofkeyval'])) {
273 if ($search[$key] == '-1' || ($search[$key] === '0' && (empty($object->fields[$key]['arrayofkeyval']) || !array_key_exists('0', $object->fields[$key]['arrayofkeyval'])))) {
274 $search[$key] = '';
275 }
276 $mode_search = 2;
277 }
278 if ($search[$key] != '') {
279 $sql .= natural_search("t.".$db->escape($key), $search[$key], (($key == 'status') ? 2 : $mode_search));
280 }
281 } else {
282 if (preg_match('/(_dtstart|_dtend)$/', $key) && $search[$key] != '') {
283 $columnName = preg_replace('/(_dtstart|_dtend)$/', '', $key);
284 if (preg_match('/^(date|timestamp|datetime)/', $object->fields[$columnName]['type'])) {
285 if (preg_match('/_dtstart$/', $key)) {
286 $sql .= " AND t.".$db->sanitize($columnName)." >= '".$db->idate($search[$key])."'";
287 }
288 if (preg_match('/_dtend$/', $key)) {
289 $sql .= " AND t.".$db->sanitize($columnName)." <= '".$db->idate($search[$key])."'";
290 }
291 }
292 }
293 }
294}
295if ($search_all) {
296 $sql .= natural_search(array_keys($fieldstosearchall), $search_all);
297}
298
299if (empty($permissiontoreadall)) {
300 $sql .= " AND t.fk_user IN(".$db->sanitize(implode(", ", $user->getAllChildIds(1))).") ";
301}
302
303//$sql.= dolSqlDateFilter("t.field", $search_xxxday, $search_xxxmonth, $search_xxxyear);
304// Add where from extra fields
305include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
306// Add where from hooks
307$parameters = array();
308$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
309$sql .= $hookmanager->resPrint;
310
311/* If a group by is required
312$sql .= " GROUP BY ";
313foreach($object->fields as $key => $val) {
314 $sql .= "t.".$key.", ";
315}
316// Add fields from extrafields
317if (!empty($extrafields->attributes[$object->table_element]['label'])) {
318 foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
319 $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? "ef.".$key.', ' : '');
320 }
321}
322// Add where from hooks
323$parameters = array();
324$reshook = $hookmanager->executeHooks('printFieldListGroupBy', $parameters, $object); // Note that $action and $object may have been modified by hook
325$sql .= $hookmanager->resPrint;
326$sql = preg_replace('/,\s*$/', '', $sql);
327*/
328
329// Count total nb of records
330$nbtotalofrecords = '';
331if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
332 /* The fast and low memory method to get and count full list converts the sql into a sql count */
333 $sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql);
334 $sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount);
335 $resql = $db->query($sqlforcount);
336 if ($resql) {
337 $objforcount = $db->fetch_object($resql);
338 $nbtotalofrecords = $objforcount->nbtotalofrecords;
339 } else {
341 }
342
343 if (($page * $limit) > (int) $nbtotalofrecords) { // if total resultset is smaller than the paging size (filtering), goto and load page 0
344 $page = 0;
345 $offset = 0;
346 }
347 $db->free($resql);
348}
349
350// Complete request and execute it with limit
351$sql .= $db->order($sortfield, $sortorder);
352if ($limit) {
353 $sql .= $db->plimit($limit + 1, $offset);
354}
355
356$resql = $db->query($sql);
357if (!$resql) {
359 exit;
360}
361
362$num = $db->num_rows($resql);
363
364
365// Direct jump if only one record found
366if ($num == 1 && getDolGlobalString('MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE') && $search_all && !$page) {
367 $obj = $db->fetch_object($resql);
368 $id = $obj->rowid;
369 header("Location: ".dol_buildpath('/hrm/evaluation_card.php', 1).'?id='.$id);
370 exit;
371}
372
373
374// Output page
375// --------------------------------------------------------------------
376
377llxHeader('', $title, $help_url, '', 0, 0, $morejs, $morecss, '', '');
378
379// Example : Adding jquery code
380// print '<script type="text/javascript" language="javascript">
381// jQuery(document).ready(function() {
382// function init_myfunc()
383// {
384// jQuery("#myid").removeAttr(\'disabled\');
385// jQuery("#myid").attr(\'disabled\',\'disabled\');
386// }
387// init_myfunc();
388// jQuery("#mybutton").click(function() {
389// init_myfunc();
390// });
391// });
392// </script>';
393
394$arrayofselected = is_array($toselect) ? $toselect : array();
395
396$param = '';
397if (!empty($mode)) {
398 $param .= '&mode='.urlencode($mode);
399}
400if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
401 $param .= '&contextpage='.urlencode($contextpage);
402}
403if ($limit > 0 && $limit != $conf->liste_limit) {
404 $param .= '&limit='.((int) $limit);
405}
406foreach ($search as $key => $val) {
407 if (is_array($search[$key])) {
408 foreach ($search[$key] as $skey) {
409 if ($skey != '') {
410 $param .= '&search_'.$key.'[]='.urlencode($skey);
411 }
412 }
413 } elseif (preg_match('/(_dtstart|_dtend)$/', $key) && !empty($val)) {
414 $param .= '&search_'.$key.'month='.(GETPOSTINT('search_'.$key.'month'));
415 $param .= '&search_'.$key.'day='.(GETPOSTINT('search_'.$key.'day'));
416 $param .= '&search_'.$key.'year='.(GETPOSTINT('search_'.$key.'year'));
417 } elseif ($search[$key] != '') {
418 $param .= '&search_'.$key.'='.urlencode($search[$key]);
419 }
420}
421if ($optioncss != '') {
422 $param .= '&optioncss='.urlencode($optioncss);
423}
424// Add $param from extra fields
425include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
426// Add $param from hooks
427$parameters = array('param' => &$param);
428$reshook = $hookmanager->executeHooks('printFieldListSearchParam', $parameters, $object); // Note that $action and $object may have been modified by hook
429$param .= $hookmanager->resPrint;
430
431// List of mass actions available
432$arrayofmassactions = array(
433 //'validate'=>img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("Validate"),
434 //'generate_doc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("ReGeneratePDF"),
435 //'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"),
436 //'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"),
437);
438if (!empty($permissiontodelete)) {
439 $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
440}
441if (GETPOSTINT('nomassaction') || in_array($massaction, array('presend', 'predelete'))) {
442 $arrayofmassactions = array();
443}
444$massactionbutton = $form->selectMassAction('', $arrayofmassactions);
445
446print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">'."\n";
447if ($optioncss != '') {
448 print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
449}
450print '<input type="hidden" name="token" value="'.newToken().'">';
451print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
452print '<input type="hidden" name="action" value="list">';
453print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
454print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
455print '<input type="hidden" name="page" value="'.$page.'">';
456print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
457print '<input type="hidden" name="mode" value="'.$mode.'">';
458
459$newcardbutton = '';
460$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'));
461$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'));
462$newcardbutton .= dolGetButtonTitleSeparator();
463$newcardbutton .= dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', dol_buildpath('/hrm/evaluation_card.php', 1).'?action=create', '', $permissiontoadd);
464
465print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'object_'.$object->picto, 0, $newcardbutton, '', $limit, 0, 0, 1);
466
467// Add code for pre mass action (confirmation or email presend form)
468$topicmail = "SendEvaluationRef";
469$modelmail = "evaluation";
470$objecttmp = new Evaluation($db);
471$trackid = 'xxxx'.$object->id;
472include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
473
474if ($search_all) {
475 $setupstring = '';
476 foreach ($fieldstosearchall as $key => $val) {
477 $fieldstosearchall[$key] = $langs->trans($val);
478 $setupstring .= $key."=".$val.";";
479 }
480 print '<!-- Search done like if HRM_EVALUATION_QUICKSEARCH_ON_FIELDS = '.$setupstring.' -->'."\n";
481 print '<div class="divsearchfieldfilter">'.$langs->trans("FilterOnInto", $search_all).implode(', ', $fieldstosearchall).'</div>';
482}
483
484$moreforfilter = '';
485/*$moreforfilter.='<div class="divsearchfield">';
486$moreforfilter.= $langs->trans('MyFilter') . ': <input type="text" name="search_myfield" value="'.dol_escape_htmltag($search_myfield).'">';
487$moreforfilter.= '</div>';*/
488
489$parameters = array();
490$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
491if (empty($reshook)) {
492 $moreforfilter .= $hookmanager->resPrint;
493} else {
494 $moreforfilter = $hookmanager->resPrint;
495}
496
497if (!empty($moreforfilter)) {
498 print '<div class="liste_titre liste_titre_bydiv centpercent">';
499 print $moreforfilter;
500 print '</div>';
501}
502
503$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
504$htmlofselectarray = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, $conf->main_checkbox_left_column); // This also change content of $arrayfields with user setup
505$selectedfields = ($mode != 'kanban' ? $htmlofselectarray : '');
506$selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : '');
507
508print '<div class="div-table-responsive">'; // You can use div-table-responsive-no-min if you don't need reserved height for your table
509print '<table class="tagtable nobottomiftotal liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n";
510
511// Fields title search
512// --------------------------------------------------------------------
513print '<tr class="liste_titre_filter">';
514// Action column
515if ($conf->main_checkbox_left_column) {
516 print '<td class="liste_titre maxwidthsearch center">';
517 $searchpicto = $form->showFilterButtons('left');
518 print $searchpicto;
519 print '</td>';
520}
521foreach ($object->fields as $key => $val) {
522 $searchkey = empty($search[$key]) ? '' : $search[$key];
523 $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']);
524 if ($key == 'status') {
525 $cssforfield .= ($cssforfield ? ' ' : '').'center';
526 } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
527 $cssforfield .= ($cssforfield ? ' ' : '').'center';
528 } elseif (in_array($val['type'], array('timestamp'))) {
529 $cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
530 } 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'])) {
531 $cssforfield .= ($cssforfield ? ' ' : '').'right';
532 }
533 if (!empty($arrayfields['t.'.$key]['checked'])) {
534 print '<td class="liste_titre'.($cssforfield ? ' '.$cssforfield : '').($key == 'status' ? ' parentonrightofpage' : '').'">';
535 if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
536 print $form->selectarray('search_'.$key, $val['arrayofkeyval'], (isset($search[$key]) ? $search[$key] : ''), $val['notnull'], 0, 0, '', 1, 0, 0, '', 'maxwidth100'.($key == 'status' ? ' search_status width100 onrightofpage' : ''), 1);
537 } elseif ((strpos($val['type'], 'integer:') === 0) || (strpos($val['type'], 'sellist:') === 0)) {
538 print $object->showInputField($val, $key, (isset($search[$key]) ? $search[$key] : ''), '', '', 'search_', $cssforfield.' maxwidth250', 1);
539 } elseif (preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
540 print '<div class="nowrap">';
541 print $form->selectDate($search[$key.'_dtstart'] ? $search[$key.'_dtstart'] : '', "search_".$key."_dtstart", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From'));
542 print '</div>';
543 print '<div class="nowrap">';
544 print $form->selectDate($search[$key.'_dtend'] ? $search[$key.'_dtend'] : '', "search_".$key."_dtend", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to'));
545 print '</div>';
546 } elseif ($key == 'lang') {
547 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
548 $formadmin = new FormAdmin($db);
549 print $formadmin->select_language($search[$key], 'search_lang', 0, array(), 1, 0, 0, 'minwidth100imp maxwidth125', 2);
550 } else {
551 print '<input type="text" class="flat maxwidth'.($val['type'] == 'integer' ? '50' : '75').'" name="search_'.$key.'" value="'.dol_escape_htmltag(isset($search[$key]) ? $search[$key] : '').'">';
552 }
553 print '</td>';
554 }
555}
556// Extra fields
557include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php';
558
559// Fields from hook
560$parameters = array('arrayfields' => $arrayfields);
561$reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
562print $hookmanager->resPrint;
563// Action column
564if (!$conf->main_checkbox_left_column) {
565 print '<td class="liste_titre maxwidthsearch">';
566 $searchpicto = $form->showFilterButtons();
567 print $searchpicto;
568 print '</td>';
569}
570print '</tr>'."\n";
571
572$totalarray = array();
573$totalarray['nbfield'] = 0;
574
575// Fields title label
576// --------------------------------------------------------------------
577print '<tr class="liste_titre">';
578// Action column
579if ($conf->main_checkbox_left_column) {
580 print getTitleFieldOfList(($mode != 'kanban' ? $selectedfields : ''), 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
581 $totalarray['nbfield']++;
582}
583foreach ($object->fields as $key => $val) {
584 $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']);
585 if ($key == 'status') {
586 $cssforfield .= ($cssforfield ? ' ' : '').'center';
587 } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
588 $cssforfield .= ($cssforfield ? ' ' : '').'center';
589 } elseif (in_array($val['type'], array('timestamp'))) {
590 $cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
591 } 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'])) {
592 $cssforfield .= ($cssforfield ? ' ' : '').'right';
593 }
594 $cssforfield = preg_replace('/small\s*/', '', $cssforfield); // the 'small' css must not be used for the title label
595 if (!empty($arrayfields['t.'.$key]['checked'])) {
596 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";
597 $totalarray['nbfield']++;
598 }
599}
600// Extra fields
601include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php';
602// Hook fields
603$parameters = array('arrayfields' => $arrayfields, 'param' => $param, 'sortfield' => $sortfield, 'sortorder' => $sortorder, 'totalarray' => &$totalarray);
604$reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
605print $hookmanager->resPrint;
606// Action column
607if (!$conf->main_checkbox_left_column) {
608 print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
609 $totalarray['nbfield']++;
610}
611print '</tr>'."\n";
612
613
614// Detect if we need a fetch on each output line
615$needToFetchEachLine = 0;
616if (isset($extrafields->attributes[$object->table_element]['computed']) && is_array($extrafields->attributes[$object->table_element]['computed']) && count($extrafields->attributes[$object->table_element]['computed']) > 0) {
617 foreach ($extrafields->attributes[$object->table_element]['computed'] as $key => $val) {
618 if (!is_null($val) && preg_match('/\$object/', $val)) {
619 $needToFetchEachLine++; // There is at least one compute field that use $object
620 }
621 }
622}
623
624
625// Loop on record
626// --------------------------------------------------------------------
627$i = 0;
628$savnbfield = $totalarray['nbfield'];
629$totalarray = array();
630$totalarray['nbfield'] = 0;
631$imaxinloop = ($limit ? min($num, $limit) : $num);
632while ($i < $imaxinloop) {
633 $obj = $db->fetch_object($resql);
634 if (empty($obj)) {
635 break; // Should not happen
636 }
637
638 // Store properties in $object
639 $object->setVarsFromFetchObj($obj);
640
641 if ($mode == 'kanban') {
642 if ($i == 0) {
643 print '<tr class="trkanban"><td colspan="'.$savnbfield.'">';
644 print '<div class="box-flex-container kanban">';
645 }
646 // Output Kanban
647 $object->date_eval = $obj->date_eval;
648
649 // TODO Use a cache on job
650 $job = new Job($db);
651 $job->fetch($obj->fk_job);
652
653 // TODO Use a cache on user
654 $userstatic = new User($db);
655 $userstatic->fetch($obj->fk_user);
656
657 $selected = -1;
658 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
659 $selected = 0;
660 if (in_array($object->id, $arrayofselected)) {
661 $selected = 1;
662 }
663 }
664 print $object->getKanbanView('', array('user' => $userstatic->getNomUrl(-1), 'job' => $job->getNomUrl(1), 'selected' => $selected));
665 if ($i == ($imaxinloop - 1)) {
666 print '</div>';
667 print '</td></tr>';
668 }
669 } else {
670 // Show here line of result
671 print '<tr data-rowid="'.$object->id.'" class="oddeven">';
672 // Action column
673 if ($conf->main_checkbox_left_column) {
674 print '<td class="nowrap center">';
675 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
676 $selected = 0;
677 if (in_array($object->id, $arrayofselected)) {
678 $selected = 1;
679 }
680 print '<input id="cb'.$object->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$object->id.'"'.($selected ? ' checked="checked"' : '').'>';
681 }
682 print '</td>';
683 if (!$i) {
684 $totalarray['nbfield']++;
685 }
686 }
687 foreach ($object->fields as $key => $val) {
688 $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']);
689 if (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
690 $cssforfield .= ($cssforfield ? ' ' : '').'center';
691 } elseif ($key == 'status') {
692 $cssforfield .= ($cssforfield ? ' ' : '').'center';
693 }
694
695 if (in_array($val['type'], array('timestamp'))) {
696 $cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
697 } elseif ($key == 'ref') {
698 $cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
699 }
700
701 if (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && !in_array($key, array('rowid', 'status')) && empty($val['arrayofkeyval'])) {
702 $cssforfield .= ($cssforfield ? ' ' : '').'right';
703 }
704 //if (in_array($key, array('fk_soc', 'fk_user', 'fk_warehouse'))) $cssforfield = 'tdoverflowmax100';
705
706 if (!empty($arrayfields['t.'.$key]['checked'])) {
707 print '<td'.($cssforfield ? ' class="'.$cssforfield.(preg_match('/tdoverflow/', $cssforfield) ? ' classfortooltip' : '').'"' : '');
708 if (preg_match('/tdoverflow/', $cssforfield) && !is_numeric($object->$key)) {
709 print ' title="'.dol_escape_htmltag((string) $object->$key).'"';
710 }
711 print '>';
712 if ($key == 'status') {
713 print $object->getLibStatut(5);
714 } elseif ($key == 'rowid') {
715 print $object->showOutputField($val, $key, (string) $object->id, '');
716 } else {
717 print $object->showOutputField($val, $key, $object->$key, '');
718 }
719 print '</td>';
720 if (!$i) {
721 $totalarray['nbfield']++;
722 }
723 if (!empty($val['isameasure']) && $val['isameasure'] == 1) {
724 if (!$i) {
725 $totalarray['pos'][$totalarray['nbfield']] = 't.'.$key;
726 }
727 if (!isset($totalarray['val'])) {
728 $totalarray['val'] = array();
729 }
730 if (!isset($totalarray['val']['t.'.$key])) {
731 $totalarray['val']['t.'.$key] = 0;
732 }
733 $totalarray['val']['t.'.$key] += $object->$key;
734 }
735 }
736 }
737 // Extra fields
738 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
739 // Fields from hook
740 $parameters = array('arrayfields' => $arrayfields, 'object' => $object, 'obj' => $obj, 'i' => $i, 'totalarray' => &$totalarray);
741 $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
742 print $hookmanager->resPrint;
743 // Action column
744 if (!$conf->main_checkbox_left_column) {
745 print '<td class="nowrap center">';
746 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
747 $selected = 0;
748 if (in_array($object->id, $arrayofselected)) {
749 $selected = 1;
750 }
751 print '<input id="cb'.$object->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$object->id.'"'.($selected ? ' checked="checked"' : '').'>';
752 }
753 print '</td>';
754 if (!$i) {
755 $totalarray['nbfield']++;
756 }
757 }
758 print '</tr>'."\n";
759 }
760
761 $i++;
762}
763
764// Show total line
765include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php';
766
767// If no record found
768if ($num == 0) {
769 $colspan = 1;
770 foreach ($arrayfields as $key => $val) {
771 if (!empty($val['checked'])) {
772 $colspan++;
773 }
774 }
775 print '<tr><td colspan="'.$colspan.'"><span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span></td></tr>';
776}
777
778
779$db->free($resql);
780
781$parameters = array('arrayfields' => $arrayfields, 'sql' => $sql);
782$reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
783print $hookmanager->resPrint;
784
785print '</table>'."\n";
786print '</div>'."\n";
787
788print '</form>'."\n";
789
790if (in_array('builddoc', array_keys($arrayofmassactions)) && ($nbtotalofrecords === '' || $nbtotalofrecords)) {
791 $hidegeneratedfilelistifempty = 1;
792 if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) {
793 $hidegeneratedfilelistifempty = 0;
794 }
795
796 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
797 $formfile = new FormFile($db);
798
799 // Show list of available documents
800 $urlsource = $_SERVER['PHP_SELF'].'?sortfield='.$sortfield.'&sortorder='.$sortorder;
801 $urlsource .= str_replace('&amp;', '&', $param);
802
803 $filedir = $diroutputmassaction;
804 $genallowed = $permissiontoread;
805 $delallowed = $permissiontoadd;
806
807 print $formfile->showdocuments('massfilesarea_hrm', '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty);
808}
809
810// End of page
811llxFooter();
812$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 list.php:501
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 for Evaluation.
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 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:
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $db
API class for accounts.
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...
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...
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_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
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)
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_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...
Definition html.lib.php:172
print $langs trans("Show") . '< td style="' . $timeColor . '" align="center"> s</td > badge status0 badge status4 badge status3 Error badge status8< td align="center">< span class="badge ' . $badge . '"></span ></td >< td align="center">< a href="#" class="button button-small" onclick="openLogModal(this)" data-req="' . dol_escape_htmltag($reqSafe) . '" data-res="' . dol_escape_htmltag($resSafe) . '" data-err="' . dol_escape_htmltag($errSafe) . '">< span class="fa fa-search-plus"></span ></a ></td ></tr >< tr >< td colspan="' . $colspan . '" class="opacitymedium"></td ></tr ></table ></div ></form > logModal none logModal none s a JSON string
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.