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