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