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