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