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