dolibarr 20.0.0
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 $parameters = array();
492 $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
493 print $hookmanager->resPrint;
494 print '</div>';
495}
496
497$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
498$htmlofselectarray = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')); // This also change content of $arrayfields with user setup
499$selectedfields = ($mode != 'kanban' ? $htmlofselectarray : '');
500$selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : '');
501
502print '<div class="div-table-responsive">'; // You can use div-table-responsive-no-min if you don't need reserved height for your table
503print '<table class="tagtable nobottomiftotal liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n";
504
505
506// Fields title search
507// --------------------------------------------------------------------
508
509print '<tr class="liste_titre_filter">';
510// Action column
511if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
512 print '<td class="liste_titre center maxwidthsearch">';
513 $searchpicto = $form->showFilterButtons('left');
514 print $searchpicto;
515 print '</td>';
516}
517foreach ($object->fields as $key => $val) {
518 $searchkey = empty($search[$key]) ? '' : $search[$key];
519 $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']);
520 if ($key == 'status') {
521 $cssforfield .= ($cssforfield ? ' ' : '').'center';
522 } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
523 $cssforfield .= ($cssforfield ? ' ' : '').'center';
524 } elseif (in_array($val['type'], array('timestamp'))) {
525 $cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
526 } 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'])) {
527 $cssforfield .= ($cssforfield ? ' ' : '').'right';
528 }
529 if (!empty($arrayfields['t.'.$key]['checked'])) {
530 print '<td class="liste_titre'.($cssforfield ? ' '.$cssforfield : '').($key == 'status' ? ' parentonrightofpage' : '').'">';
531 if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
532 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);
533 } elseif ((strpos($val['type'], 'integer:') === 0) || (strpos($val['type'], 'sellist:') === 0)) {
534 print $object->showInputField($val, $key, (isset($search[$key]) ? $search[$key] : ''), '', '', 'search_', $cssforfield.' maxwidth250', 1);
535 } elseif (preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
536 print '<div class="nowrap">';
537 print $form->selectDate($search[$key.'_dtstart'] ? $search[$key.'_dtstart'] : '', "search_".$key."_dtstart", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From'));
538 print '</div>';
539 print '<div class="nowrap">';
540 print $form->selectDate($search[$key.'_dtend'] ? $search[$key.'_dtend'] : '', "search_".$key."_dtend", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to'));
541 print '</div>';
542 } elseif ($key == 'lang') {
543 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
544 $formadmin = new FormAdmin($db);
545 print $formadmin->select_language($search[$key], 'search_lang', 0, null, 1, 0, 0, 'minwidth100imp maxwidth125', 2);
546 } else {
547 print '<input type="text" class="flat maxwidth75" name="search_'.$key.'" value="'.dol_escape_htmltag(isset($search[$key]) ? $search[$key] : '').'">';
548 }
549 print '</td>';
550 }
551}
552
553// usergroups
554if (!empty($arrayfields['wug.fk_usergroup']['checked'])) {
555 print '<td class="liste_titre minwidth100">';
556 print $form->select_dolgroups($groups, 'groups', 1, '', 0, '', '', $conf->entity, true);
557 print '</td>';
558}
559
560// resources
561if (!empty($arrayfields['wr.fk_resource']['checked'])) {
562 print '<td class="liste_titre">';
563 print $formresource->select_resource_list($resources, 'resources', [], '', 0, '', '', $conf->entity, true, 0, '', true);
564 print '</td>';
565}
566
567// Extra fields
568include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php';
569
570// Fields from hook
571$parameters = array('arrayfields' => $arrayfields);
572$reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
573print $hookmanager->resPrint;
574// Action column
575if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
576 print '<td class="liste_titre center maxwidthsearch">';
577 $searchpicto = $form->showFilterButtons();
578 print $searchpicto;
579 print '</td>';
580}
581print '</tr>'."\n";
582
583$totalarray = array();
584$totalarray['nbfield'] = 0;
585
586// Fields title label
587// --------------------------------------------------------------------
588print '<tr class="liste_titre">';
589// Action column
590if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
591 print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
592 $totalarray['nbfield']++;
593}
594foreach ($object->fields as $key => $val) {
595 $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']);
596 if ($key == 'status') {
597 $cssforfield .= ($cssforfield ? ' ' : '').'center';
598 } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
599 $cssforfield .= ($cssforfield ? ' ' : '').'center';
600 } elseif (in_array($val['type'], array('timestamp'))) {
601 $cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
602 } 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'])) {
603 $cssforfield .= ($cssforfield ? ' ' : '').'right';
604 }
605 $cssforfield = preg_replace('/small\s*/', '', $cssforfield); // the 'small' css must not be used for the title label
606 if (!empty($arrayfields['t.'.$key]['checked'])) {
607 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";
608 $totalarray['nbfield']++;
609 }
610}
611
612// usergroups
613if (!empty($arrayfields['wug.fk_usergroup']['checked'])) {
614 print getTitleFieldOfList($arrayfields['wug.fk_usergroup']['label'], 0, $_SERVER['PHP_SELF'], '', '', $param, '', $sortfield, $sortorder, '') . "\n";
615}
616
617// resources
618if (!empty($arrayfields['wr.fk_resource']['checked'])) {
619 print getTitleFieldOfList($arrayfields['wr.fk_resource']['label'], 0, $_SERVER['PHP_SELF'], '', '', $param, '', $sortfield, $sortorder, '') . "\n";
620}
621
622// Extra fields
623include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php';
624// Hook fields
625$parameters = array('arrayfields' => $arrayfields, 'param' => $param, 'sortfield' => $sortfield, 'sortorder' => $sortorder, 'totalarray' => &$totalarray);
626$reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
627print $hookmanager->resPrint;
628// Action column
629if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
630 print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
631 $totalarray['nbfield']++;
632}
633print '</tr>'."\n";
634
635
636// Detect if we need a fetch on each output line
637$needToFetchEachLine = 0;
638if (isset($extrafields->attributes[$object->table_element]['computed']) && is_array($extrafields->attributes[$object->table_element]['computed']) && count($extrafields->attributes[$object->table_element]['computed']) > 0) {
639 foreach ($extrafields->attributes[$object->table_element]['computed'] as $key => $val) {
640 if (!is_null($val) && preg_match('/\$object/', $val)) {
641 $needToFetchEachLine++; // There is at least one compute field that use $object
642 }
643 }
644}
645
646
647// Loop on record
648// --------------------------------------------------------------------
649$i = 0;
650$savnbfield = $totalarray['nbfield'];
651$totalarray = array();
652$totalarray['nbfield'] = 0;
653$imaxinloop = ($limit ? min($num, $limit) : $num);
654while ($i < $imaxinloop) {
655 $obj = $db->fetch_object($resql);
656 if (empty($obj)) {
657 break; // Should not happen
658 }
659
660 // Store properties in $object
661 $object->setVarsFromFetchObj($obj);
662
665
666 if ($mode == 'kanban') {
667 if ($i == 0) {
668 print '<tr class="trkanban"><td colspan="'.($savnbfield + 1).'">';
669 print '<div class="box-flex-container kanban">';
670 }
671 // Output Kanban
672 $selected = -1;
673 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
674 $selected = 0;
675 if (in_array($object->id, $arrayofselected)) {
676 $selected = 1;
677 }
678 }
679 print $object->getKanbanView('', array('selected' => $selected));
680 if ($i == ($imaxinloop - 1)) {
681 print '</div>';
682 print '</td></tr>';
683 }
684 } else {
685 // Show line of result
686 $j = 0;
687 print '<tr data-rowid="'.$object->id.'" class="oddeven">';
688 // Action column
689 if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
690 print '<td class="nowrap center">';
691 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
692 $selected = 0;
693 if (in_array($object->id, $arrayofselected)) {
694 $selected = 1;
695 }
696 print '<input id="cb'.$object->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$object->id.'"'.($selected ? ' checked="checked"' : '').'>';
697 }
698 print '</td>';
699 if (!$i) {
700 $totalarray['nbfield']++;
701 }
702 }
703 foreach ($object->fields as $key => $val) {
704 $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']);
705 if (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
706 $cssforfield .= ($cssforfield ? ' ' : '').'center';
707 } elseif ($key == 'status') {
708 $cssforfield .= ($cssforfield ? ' ' : '').'center';
709 }
710
711 if (in_array($val['type'], array('timestamp'))) {
712 $cssforfield .= ($cssforfield ? ' ' : '').'nowraponall';
713 } elseif ($key == 'ref') {
714 $cssforfield .= ($cssforfield ? ' ' : '').'nowraponall';
715 }
716
717 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'])) {
718 $cssforfield .= ($cssforfield ? ' ' : '').'right';
719 }
720 //if (in_array($key, array('fk_soc', 'fk_user', 'fk_warehouse'))) $cssforfield = 'tdoverflowmax100';
721
722 if (!empty($arrayfields['t.'.$key]['checked'])) {
723 print '<td'.($cssforfield ? ' class="'.$cssforfield.(preg_match('/tdoverflow/', $cssforfield) ? ' classfortooltip' : '').'"' : '');
724 if (preg_match('/tdoverflow/', $cssforfield) && !in_array($val['type'], array('ip', 'url')) && !is_numeric($object->$key)) {
725 print ' title="'.dol_escape_htmltag($object->$key).'"';
726 }
727 print '>';
728 if ($key == 'status') {
729 print $object->getLibStatut(5);
730 } elseif ($key == 'rowid') {
731 print $object->showOutputField($val, $key, $object->id, '');
732 } else {
733 print $object->showOutputField($val, $key, $object->$key, '');
734 }
735 print '</td>';
736 if (!$i) {
737 $totalarray['nbfield']++;
738 }
739 if (!empty($val['isameasure']) && $val['isameasure'] == 1) {
740 if (!$i) {
741 $totalarray['pos'][$totalarray['nbfield']] = 't.'.$key;
742 }
743 if (!isset($totalarray['val'])) {
744 $totalarray['val'] = array();
745 }
746 if (!isset($totalarray['val']['t.'.$key])) {
747 $totalarray['val']['t.'.$key] = 0;
748 }
749 $totalarray['val']['t.'.$key] += $object->$key;
750 }
751 }
752 }
753
754 if (!empty($arrayfields['wug.fk_usergroup']['checked'])) {
755 $toprint = array();
756 $cssforli = '';
757 if (count($object->usergroups) >= 4) {
758 $cssforli = 'tdoverflowmax60';
759 } elseif (count($object->usergroups) >= 2) {
760 $cssforli = 'tdoverflowmax80';
761 }
762 foreach ($object->usergroups as $id_group) {
763 $g = new UserGroup($db);
764 $g->fetch($id_group);
765 $toprint[] = '<li class="select2-search-choice-dolibarr noborderoncategories'.($cssforli ? ' '.$cssforli : '').'" style="background: #bbb">' . $g->getNomUrl(1, '', 0, 'categtextwhite') . '</li>';
766 }
767
768 print '<td class="minwidth300imp nowraponall">';
769 print '<div class="select2-container-multi-dolibarr"><ul class="select2-choices-dolibarr">' . implode(' ', $toprint) . '</ul></div>';
770 print '</td>';
771 }
772
773 if (!empty($arrayfields['wr.fk_resource']['checked'])) {
774 $toprint = array();
775 $cssforli = '';
776 if (count($object->resources) >= 4) {
777 $cssforli = 'tdoverflowmax60';
778 } elseif (count($object->resources) >= 2) {
779 $cssforli = 'tdoverflowmax80';
780 }
781 foreach ($object->resources as $id_resource) {
782 $r = new Dolresource($db);
783 $r->fetch($id_resource);
784 $toprint[] = '<li class="select2-search-choice-dolibarr noborderoncategories'.($cssforli ? ' '.$cssforli : '').'" style="background: #bbb">' . $r->getNomUrl(1, '', '', 0, 'categtextwhite') . '</li>';
785 }
786
787 print '<td class="minwidth300imp">';
788 print '<div class="select2-container-multi-dolibarr"><ul class="select2-choices-dolibarr">' . implode(' ', $toprint) . '</ul></div>';
789 print '</td>';
790 }
791
792 // Extra fields
793 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
794 // Fields from hook
795 $parameters = array('arrayfields' => $arrayfields, 'object' => $object, 'obj' => $obj, 'i' => $i, 'totalarray' => &$totalarray);
796 $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
797 print $hookmanager->resPrint;
798 // Action column
799 if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
800 print '<td class="nowrap center">';
801 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
802 $selected = 0;
803 if (in_array($object->id, $arrayofselected)) {
804 $selected = 1;
805 }
806 print '<input id="cb'.$object->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$object->id.'"'.($selected ? ' checked="checked"' : '').'>';
807 }
808 print '</td>';
809 if (!$i) {
810 $totalarray['nbfield']++;
811 }
812 }
813
814 print '</tr>'."\n";
815 }
816
817 $i++;
818}
819
820// Show total line
821include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php';
822
823// If no record found
824if ($num == 0) {
825 $colspan = 1;
826 foreach ($arrayfields as $key => $val) {
827 if (!empty($val['checked'])) {
828 $colspan++;
829 }
830 }
831 print '<tr><td colspan="'.$colspan.'"><span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span></td></tr>';
832}
833
834
835$db->free($resql);
836
837$parameters = array('arrayfields' => $arrayfields, 'sql' => $sql);
838$reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
839print $hookmanager->resPrint;
840
841print '</table>'."\n";
842print '</div>'."\n";
843
844print '</form>'."\n";
845
846if (in_array('builddoc', array_keys($arrayofmassactions)) && ($nbtotalofrecords === '' || $nbtotalofrecords)) {
847 $hidegeneratedfilelistifempty = 1;
848 if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) {
849 $hidegeneratedfilelistifempty = 0;
850 }
851
852 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
853 $formfile = new FormFile($db);
854
855 // Show list of available documents
856 $urlsource = $_SERVER['PHP_SELF'].'?sortfield='.$sortfield.'&sortorder='.$sortorder;
857 $urlsource .= str_replace('&amp;', '&', $param);
858
859 $filedir = $diroutputmassaction;
860 $genallowed = $permissiontoread;
861 $delallowed = $permissiontoadd;
862
863 print $formfile->showdocuments('massfilesarea_'.$object->module, '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty);
864}
865
866// End of page
867llxFooter();
868$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.