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