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