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