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