dolibarr  19.0.0-dev
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
26 require '../main.inc.php';
27 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
28 require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
29 require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
30 
31 // load bookcal libraries
32 require_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');
59 if (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)
80 if (!$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 }
84 if (!$sortorder) {
85  $sortorder = "ASC";
86 }
87 
88 // Initialize array of search criterias
89 $search_all = GETPOST('search_all', 'alphanohtml');
90 $search = array();
91 foreach ($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();
103 foreach ($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();
111 foreach ($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
125 include 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;
134 if ($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)
145 if ($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);
150 if (!isModEnabled('bookcal')) accessforbidden('Module not enabled');
151 if (!$permissiontoread) accessforbidden();
152 
153 
154 /*
155  * Actions
156  */
157 
158 if (GETPOST('cancel', 'alpha')) {
159  $action = 'list';
160  $massaction = '';
161 }
162 if (!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
168 if ($reshook < 0) {
169  setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
170 }
171 
172 if (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
222 if (!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";
235 if (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;
242 if ($object->ismultientitymanaged == 1) {
243  $sql .= " WHERE t.entity IN (".getEntity($object->element).")";
244 } else {
245  $sql .= " WHERE 1 = 1";
246 }
247 foreach ($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 }
276 if ($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
281 include 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 ";
289 foreach($object->fields as $key => $val) {
290  $sql .= "t.".$db->escape($key).", ";
291 }
292 // Add fields from extrafields
293 if (!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 = '';
314 if (!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);
347 if ($limit) {
348  $sql .= $db->plimit($limit + 1, $offset);
349 }
350 
351 $resql = $db->query($sql);
352 if (!$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
361 if ($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 
372 llxHeader('', $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 = '';
392 if (!empty($mode)) {
393  $param .= '&mode='.urlencode($mode);
394 }
395 if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
396  $param .= '&contextpage='.urlencode($contextpage);
397 }
398 if ($limit > 0 && $limit != $conf->liste_limit) {
399  $param .= '&limit='.((int) $limit);
400 }
401 foreach ($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 }
412 if ($optioncss != '') {
413  $param .= '&optioncss='.urlencode($optioncss);
414 }
415 // Add $param from extra fields
416 include 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 );
429 if (!empty($permissiontodelete)) {
430  $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
431 }
432 if (GETPOST('nomassaction', 'int') || in_array($massaction, array('presend', 'predelete'))) {
433  $arrayofmassactions = array();
434 }
435 $massactionbutton = $form->selectMassAction('', $arrayofmassactions);
436 
437 print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">'."\n";
438 if ($optioncss != '') {
439  print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
440 }
441 print '<input type="hidden" name="token" value="'.newToken().'">';
442 print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
443 print '<input type="hidden" name="action" value="list">';
444 print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
445 print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
446 print '<input type="hidden" name="page" value="'.$page.'">';
447 print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
448 print '<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 
457 print_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;
464 include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
465 
466 if ($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
483 if (empty($reshook)) {
484  $moreforfilter .= $hookmanager->resPrint;
485 } else {
486  $moreforfilter = $hookmanager->resPrint;
487 }
488 
489 if (!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 
499 print '<div class="div-table-responsive">'; // You can use div-table-responsive-no-min if you dont need reserved height for your table
500 print '<table class="tagtable nobottomiftotal liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n";
501 
502 
503 // Fields title search
504 // --------------------------------------------------------------------
505 print '<tr class="liste_titre">';
506 // Action column
507 if (!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 }
513 foreach ($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
549 include 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
554 print $hookmanager->resPrint;
555 /*if (!empty($arrayfields['anotherfield']['checked'])) {
556  print '<td class="liste_titre"></td>';
557 }*/
558 // Action column
559 if (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 }
565 print '</tr>'."\n";
566 
567 $totalarray = array();
568 $totalarray['nbfield'] = 0;
569 
570 // Fields title label
571 // --------------------------------------------------------------------
572 print '<tr class="liste_titre">';
573 if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) {
574  print getTitleFieldOfList(($mode != 'kanban' ? $selectedfields : ''), 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
575 }
576 foreach ($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
594 include 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
598 print $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
604 if (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']++;
608 print '</tr>'."\n";
609 
610 
611 // Detect if we need a fetch on each output line
612 $needToFetchEachLine = 0;
613 if (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);
629 while ($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
747 include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php';
748 
749 // If no record found
750 if ($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
765 print $hookmanager->resPrint;
766 
767 print '</table>'."\n";
768 print '</div>'."\n";
769 
770 print '</form>'."\n";
771 
772 if (in_array('builddoc', $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
793 llxFooter();
794 $db->close();
if(GETPOST('button_removefilter_x', 'alpha')||GETPOST('button_removefilter.x', 'alpha')||GETPOST('button_removefilter', 'alpha')) if(GETPOST('button_search_x', 'alpha')||GETPOST('button_search.x', 'alpha')||GETPOST('button_search', 'alpha')) if($action=="save" &&empty($cancel)) $help_url
View.
Definition: agenda.php:118
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.
if(isModEnabled('facture') && $user->hasRight('facture', 'lire')) if((isModEnabled('fournisseur') &&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') && $user->hasRight('don', 'lire')) if(isModEnabled('tax') &&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture') &&isModEnabled('commande') && $user->hasRight("commande", "lire") &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $sql
Social contributions to pay.
Definition: index.php:746
if($cancel &&! $id) if($action=='add' &&! $cancel) if($action=='delete') if($id) $form
Actions.
Definition: card.php:143
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.
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
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...
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.