dolibarr 21.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
27require '../main.inc.php';
28require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
29require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
30require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
31
32// load module libraries
33require_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");
57if (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 a 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)
78if (!$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}
82if (!$sortorder) {
83 $sortorder = "ASC";
84}
85
86// Initialize array of search criteria
87$search_all = GETPOST('search_all', 'alphanohtml');
88$search = array();
89foreach ($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.
115if (!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();
124foreach ($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 && (bool) dol_eval($val['enabled'], 1)),
132 'position' => $val['position'],
133 'help' => isset($val['help']) ? $val['help'] : ''
134 );
135 }
136}
137// Extra fields
138include 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;
147if ($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)
158if ($user->socid > 0) {
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);
165if (!isModEnabled("bookcal")) {
166 accessforbidden('Module bookcal not enabled');
167}
168if (!$permissiontoread) {
170}
171
172
173/*
174 * Actions
175 */
176
177if (GETPOST('cancel', 'alpha')) {
178 $action = 'list';
179 $massaction = '';
180}
181if (!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
187if ($reshook < 0) {
188 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
189}
190
191if (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
244if (!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";
260if (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;
267if ($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}
272foreach ($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}
301if ($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
306include 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 ";
314foreach($object->fields as $key => $val) {
315 $sql .= "t.".$db->escape($key).", ";
316}
317// Add fields from extrafields
318if (!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 = '';
339if (!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);
360if ($limit) {
361 $sql .= $db->plimit($limit + 1, $offset);
362}
363
364$resql = $db->query($sql);
365if (!$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
374if ($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
385llxHeader('', $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 = '';
390if (!empty($mode)) {
391 $param .= '&mode='.urlencode($mode);
392}
393if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
394 $param .= '&contextpage='.urlencode($contextpage);
395}
396if ($limit > 0 && $limit != $conf->liste_limit) {
397 $param .= '&limit='.((int) $limit);
398}
399if ($optioncss != '') {
400 $param .= '&optioncss='.urlencode($optioncss);
401}
402foreach ($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
418include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
419// Add $param from hooks
420$parameters = array('param' => &$param);
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);
431if (!empty($permissiontodelete)) {
432 $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
433}
434if (GETPOSTINT('nomassaction') || in_array($massaction, array('presend', 'predelete'))) {
435 $arrayofmassactions = array();
436}
437$massactionbutton = $form->selectMassAction('', $arrayofmassactions);
438
439print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">'."\n";
440if ($optioncss != '') {
441 print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
442}
443print '<input type="hidden" name="token" value="'.newToken().'">';
444print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
445print '<input type="hidden" name="action" value="list">';
446print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
447print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
448print '<input type="hidden" name="page" value="'.$page.'">';
449print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
450print '<input type="hidden" name="page_y" value="">';
451print '<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
460print_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;
467include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
468
469if ($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
486if (empty($reshook)) {
487 $moreforfilter .= $hookmanager->resPrint;
488} else {
489 $moreforfilter = $hookmanager->resPrint;
490}
491
492if (!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
506print '<div class="div-table-responsive">'; // You can use div-table-responsive-no-min if you don't need reserved height for your table
507print '<table class="tagtable nobottomiftotal liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n";
508
509// Fields title search
510// --------------------------------------------------------------------
511print '<tr class="liste_titre_filter">';
512// Action column
513if (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}
519foreach ($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, 'minwidth100imp maxwidth125', 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
555include 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
560print $hookmanager->resPrint;
561/*if (!empty($arrayfields['anotherfield']['checked'])) {
562 print '<td class="liste_titre"></td>';
563}*/
564// Action column
565if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
566 print '<td class="liste_titre center maxwidthsearch">';
567 $searchpicto = $form->showFilterButtons();
568 print $searchpicto;
569 print '</td>';
570}
571print '</tr>'."\n";
572
573$totalarray = array();
574$totalarray['nbfield'] = 0;
575
576// Fields title label
577// --------------------------------------------------------------------
578print '<tr class="liste_titre">';
579// Action column
580if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
581 print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
582 $totalarray['nbfield']++;
583}
584foreach ($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
602include 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
606print $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
612if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
613 print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
614 $totalarray['nbfield']++;
615}
616print '</tr>'."\n";
617
618// Detect if we need a fetch on each output line
619$needToFetchEachLine = 0;
620if (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);
636while ($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
765include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php';
766
767// If no record found
768if ($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
783print $hookmanager->resPrint;
784
785print '</table>'."\n";
786print '</div>'."\n";
787
788print '</form>'."\n";
789
790if (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
811llxFooter();
812$db->close();
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:58
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
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.
llxFooter()
Footer empty.
Definition document.php:107
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.
print_barre_liste($title, $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.
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.
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...
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.