dolibarr 24.0.2
list.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2016 Marcos García <marcosgdf@gmail.com>
3 * Copyright (C) 2022 Open-Dsi <support@open-dsi.fr>
4 * Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
5 * Copyright (C) 2024 Benjamin Falière <benjamin.faliere@altairis.fr>
6 * Copyright (C) 2024-2026 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';
38require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
39require_once DOL_DOCUMENT_ROOT.'/variants/class/ProductAttribute.class.php';
40
41// Load translation files required by the page
42$langs->loadLangs(array("products", "other"));
43
44$action = GETPOST('action', 'aZ09') ? GETPOST('action', 'aZ09') : 'view'; // The action 'create'/'add', 'edit'/'update', 'view', ...
45$massaction = GETPOST('massaction', 'alpha'); // The bulk action (combo box choice into lists)
46$show_files = GETPOSTINT('show_files'); // Show files area generated by bulk actions
47$confirm = GETPOST('confirm', 'alpha'); // Result of a confirmation
48$cancel = GETPOST('cancel', 'alpha'); // We click on a Cancel button
49$toselect = GETPOST('toselect', 'array:int'); // Array of ids of elements selected into a list
50$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : str_replace('_', '', basename(dirname(__FILE__)).basename(__FILE__, '.php')); // To manage different context of search
51$backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page
52$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print')
53$mode = GETPOST('mode', 'aZ'); // The display mode ('list', 'kanban', 'hierarchy', 'calendar', 'gantt', ...)
54
55$id = GETPOSTINT('id');
56$rowid = GETPOSTINT('rowid'); // for line reordering in not ajax mode
57
58// Load variable for pagination
59$limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
60$sortfield = GETPOST('sortfield', 'aZ09comma');
61$sortorder = GETPOST('sortorder', 'aZ09comma');
62$page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT('page');
63if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha')) {
64 // If $page is not defined, or '' or -1 or if we click on clear filters
65 $page = 0;
66}
67$offset = $limit * $page;
68$pageprev = $page - 1;
69$pagenext = $page + 1;
70
71// Initialize a technical objects
73
74$diroutputmassaction = $conf->variants->dir_output.'/temp/massgeneration/'.$user->id;
75$hookmanager->initHooks(array('productattributelist')); // Note that conf->hooks_modules contains array
76
77// Fetch optionals attributes and labels
78$extrafields->fetch_name_optionals_label($object->table_element);
79
80$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
81
82// Default sort order (if not yet defined by previous GETPOST)
83if (!$sortfield) {
84 $sortfield = "t.position"; // Set here default search field. By default 1st field in definition.
85}
86if (!$sortorder) {
87 $sortorder = "ASC";
88}
89
90// Initialize array of search criteria
91$search_all = trim(GETPOST('search_all', 'alphanohtml'));
92$search = array();
93foreach ($object->fields as $key => $val) {
94 if (GETPOST('search_'.$key, 'alpha') !== '') {
95 $search[$key] = GETPOST('search_'.$key, 'alpha');
96 }
97 if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
98 $search[$key.'_dtstart'] = dol_mktime(0, 0, 0, GETPOSTINT('search_'.$key.'_dtstartmonth'), GETPOSTINT('search_'.$key.'_dtstartday'), GETPOSTINT('search_'.$key.'_dtstartyear'));
99 $search[$key.'_dtend'] = dol_mktime(23, 59, 59, GETPOSTINT('search_'.$key.'_dtendmonth'), GETPOSTINT('search_'.$key.'_dtendday'), GETPOSTINT('search_'.$key.'_dtendyear'));
100 }
101}
102$search['nb_of_values'] = GETPOST('search_nb_of_values', 'alpha');
103$search['nb_products'] = GETPOST('search_nb_products', 'alpha');
104
105$fieldstosearchall = array();
106// List of fields to search into when doing a "search in all"
107foreach ($object->fields as $key => $val) {
108 if (!empty($val['searchall'])) {
109 $fieldstosearchall['t.'.$key] = $val['label'];
110 }
111}
112$parameters = array('fieldstosearchall' => $fieldstosearchall);
113$reshook = $hookmanager->executeHooks('completeFieldsToSearchAll', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
114if ($reshook > 0) {
115 $fieldstosearchall = empty($hookmanager->resArray['fieldstosearchall']) ? array() : $hookmanager->resArray['fieldstosearchall'];
116} elseif ($reshook == 0) {
117 $fieldstosearchall = array_merge($fieldstosearchall, empty($hookmanager->resArray['fieldstosearchall']) ? array() : $hookmanager->resArray['fieldstosearchall']);
118}
119
120// Definition of array of fields for columns
121$arrayfields = array();
122foreach ($object->fields as $key => $val) {
123 // If $val['visible']==0, then we never show the field
124 if (!empty($val['visible'])) {
125 $visible = (int) dol_eval((string) $val['visible'], 1);
126 $arrayfields['t.'.$key] = array(
127 'label' => $val['label'],
128 'checked' => (($visible < 0) ? '0' : '1'),
129 'enabled' => (string) (int) (abs($visible) != 3 && (bool) dol_eval((string) $val['enabled'], 1)),
130 'position' => $val['position'],
131 'help' => isset($val['help']) ? $val['help'] : ''
132 );
133 }
134}
135$arrayfields['nb_of_values'] = array(
136 'label' => $langs->trans('NbOfDifferentValues'),
137 'checked' => '1',
138 'enabled' => '1',
139 'position' => 40,
140 'help' => ''
141);
142$arrayfields['nb_products'] = array(
143 'label' => $langs->trans('NbProducts'),
144 'checked' => '1',
145 'enabled' => '1',
146 'position' => 50,
147 'help' => ''
148);
149// Extra fields
150include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php';
151// Add hook to complete $arrayfield
152$parameters = array('arrayfields' => &$arrayfields);
153$reshook = $hookmanager->executeHooks('completeArrayFields', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
154
155$object->fields = dol_sort_array($object->fields, 'position');
156$arrayfields = dol_sort_array($arrayfields, 'position');
157
158$permissiontoread = $user->hasRight('variants', 'read');
159$permissiontoadd = $user->hasRight('variants', 'write');
160$permissiontodelete = $user->hasRight('variants', 'delete');
161
162// Security check
163if (!isModEnabled('variants')) {
164 accessforbidden('Module not enabled');
165}
166$socid = 0;
167if ($user->socid > 0) { // Protection if external user
168 //$socid = $user->socid;
170}
171if (!$permissiontoread) {
173}
174
175
176/*
177 * Actions
178 */
179
180if (GETPOST('cancel', 'alpha')) {
181 $action = 'list';
182 $massaction = '';
183}
184if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') {
185 $massaction = '';
186}
187
188$parameters = array('arrayfields' => &$arrayfields);
189$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
190if ($reshook < 0) {
191 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
192}
193
194if (empty($reshook)) {
195 // Selection of new fields
196 include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
197
198 // Purge search criteria
199 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
200 foreach ($object->fields as $key => $val) {
201 $search[$key] = '';
202 if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
203 $search[$key.'_dtstart'] = '';
204 $search[$key.'_dtend'] = '';
205 }
206 }
207 $search['nb_of_values'] = '';
208 $search['nb_products'] = '';
209 $toselect = array();
210 $search_array_options = array();
211 }
212 if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')
213 || GETPOST('button_search_x', 'alpha') || GETPOST('button_search.x', 'alpha') || GETPOST('button_search', 'alpha')) {
214 $massaction = ''; // Protection to avoid mass action if we force a new search during a mass action confirmation
215 }
216
217 if ($action == 'up' && $permissiontoadd) {
218 $object->attributeMoveUp($rowid);
219
220 header('Location: '.$_SERVER['PHP_SELF']);
221 exit();
222 } elseif ($action == 'down' && $permissiontoadd) {
223 $object->attributeMoveDown($rowid);
224
225 header('Location: '.$_SERVER['PHP_SELF']);
226 exit();
227 }
228
229 // Mass actions
230 $objectclass = 'ProductAttribute';
231 $objectlabel = 'ProductAttribute';
232 $uploaddir = $conf->variants->dir_output;
233 include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
234}
235
236
237
238/*
239 * View
240 */
241
242$form = new Form($db);
243
244$now = dol_now();
245
246$title = $langs->trans("ProductAttributes");
247$help_url = '';
248$morejs = array();
249$morecss = array();
250
251
252// Build and execute select
253// --------------------------------------------------------------------
254$sql = "SELECT COUNT(DISTINCT pav.rowid) AS nb_of_values, COUNT(DISTINCT pac2v.fk_prod_combination) AS nb_products, ";
255$sql .= $object->getFieldList("t");
256// Add fields from extrafields
257if (!empty($extrafields->attributes[$object->table_element]['label'])) {
258 foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
259 $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key." as options_".$key : "");
260 }
261}
262// Add fields from hooks
263$parameters = array();
264$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
265$sql .= $hookmanager->resPrint;
266$sql = preg_replace('/,\s*$/', '', $sql);
267
268$sqlfields = $sql; // $sql fields to remove for count total
269
270$sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t";
271if (isset($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) {
272 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (t.rowid = ef.fk_object)";
273}
274$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_attribute_combination2val AS pac2v ON pac2v.fk_prod_attr = t.rowid";
275$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_attribute_value AS pav ON pav.fk_product_attribute = t.rowid";
276// Add table from hooks
277$parameters = array();
278$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
279$sql .= $hookmanager->resPrint;
280if ($object->ismultientitymanaged == 1) {
281 $sql .= " WHERE t.entity IN (".getEntity($object->element, (GETPOSTINT('search_current_entity') ? 0 : 1)).")";
282} else {
283 $sql .= " WHERE 1 = 1";
284}
285foreach ($search as $key => $val) {
286 if (array_key_exists($key, $object->fields)) {
287 if ($key == 'status' && $search[$key] == -1) {
288 continue;
289 }
290 $mode_search = (($object->isInt($object->fields[$key]) || $object->isFloat($object->fields[$key])) ? 1 : 0);
291 if ((strpos($object->fields[$key]['type'], 'integer:') === 0) || (strpos($object->fields[$key]['type'], 'sellist:') === 0) || !empty($object->fields[$key]['arrayofkeyval'])) {
292 if ($search[$key] == '-1' || ($search[$key] === '0' && (empty($object->fields[$key]['arrayofkeyval']) || !array_key_exists('0', $object->fields[$key]['arrayofkeyval'])))) {
293 $search[$key] = '';
294 }
295 $mode_search = 2;
296 }
297 if ($search[$key] != '') {
298 $sql .= natural_search("t.".$db->sanitize($key), $search[$key], (($key == 'status') ? 2 : $mode_search));
299 }
300 } else {
301 if (preg_match('/(_dtstart|_dtend)$/', $key) && $search[$key] != '') {
302 $columnName = preg_replace('/(_dtstart|_dtend)$/', '', $key);
303 if (preg_match('/^(date|timestamp|datetime)/', $object->fields[$columnName]['type'])) {
304 if (preg_match('/_dtstart$/', $key)) {
305 $sql .= " AND t.".$db->sanitize($columnName)." >= '".$db->idate($search[$key])."'";
306 }
307 if (preg_match('/_dtend$/', $key)) {
308 $sql .= " AND t.".$db->sanitize($columnName)." <= '".$db->idate($search[$key])."'";
309 }
310 }
311 }
312 }
313}
314if ($search_all) {
315 $sql .= natural_search(array_keys($fieldstosearchall), $search_all);
316}
317//$sql.= dolSqlDateFilter("t.field", $search_xxxday, $search_xxxmonth, $search_xxxyear);
318// Add where from extra fields
319include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
320// Add where from hooks
321$parameters = array();
322$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
323$sql .= $hookmanager->resPrint;
324
325$hasgroupby = true;
326$sql .= " GROUP BY ";
327foreach ($object->fields as $key => $val) {
328 $sql .= "t.".$db->sanitize($key).", ";
329}
330// Add fields from extrafields
331if (!empty($extrafields->attributes[$object->table_element]['label'])) {
332 foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
333 $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? "ef.".$key.', ' : '');
334 }
335}
336// Add where from hooks
337$parameters = array();
338$reshook = $hookmanager->executeHooks('printFieldListGroupBy', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
339$sql .= $hookmanager->resPrint;
340$sql = preg_replace("/,\s*$/", "", $sql);
341
342$sql .= " HAVING 1=1";
343if ($search['nb_of_values'] != '') {
344 $sql .= natural_search("nb_of_values", $search['nb_of_values'], 1);
345}
346if ($search['nb_products'] != '') {
347 $sql .= natural_search("nb_products", $search['nb_products'], 1);
348}
349// Add HAVING from hooks
350$parameters = array();
351$reshook = $hookmanager->executeHooks('printFieldListHaving', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
352if (empty($reshook)) {
353 $sql .= empty($hookmanager->resPrint) ? "" : " HAVING 1=1 ".$hookmanager->resPrint;
354} else {
355 $sql = $hookmanager->resPrint;
356}
357
358// Count total nb of records
359$nbtotalofrecords = '';
360if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
361 /* This old and fast method to get and count full list returns all record so use a high amount of memory.
362 $resql = $db->query($sql);
363 $nbtotalofrecords = $db->num_rows($resql);
364 */
365 /* The slow method does not consume memory on mysql (not tested on pgsql) */
366 /*$resql = $db->query($sql, 0, 'auto', 1);
367 while ($db->fetch_object($resql)) {
368 $nbtotalofrecords++;
369 }*/
370 /* The fast and low memory method to get and count full list converts the sql into a sql count */
371 if ($hasgroupby) {
372 // The GROUP BY and the HAVING must be kept, so the grouped query is counted as a subquery
373 $sqlforcount = "SELECT COUNT(*) as nbtotalofrecords FROM (".$sql.") as tmpcount";
374 } else {
375 $sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql);
376 $sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount);
377 }
378
379 $resql = $db->query($sqlforcount);
380 if ($resql) {
381 if ($hasgroupby) {
382 $nbtotalofrecords = $db->num_rows($resql);
383 } else {
384 $objforcount = $db->fetch_object($resql);
385 $nbtotalofrecords = $objforcount->nbtotalofrecords;
386 }
387 if (($page * $limit) > (int) $nbtotalofrecords) { // if total resultset is smaller than the paging size (filtering), goto and load page 0
388 $page = 0;
389 $offset = 0;
390 }
391 $db->free($resql);
392 }
393}
394
395// Complete request and execute it with limit
396$sql .= $db->order($sortfield, $sortorder);
397if ($limit) {
398 $sql .= $db->plimit($limit + 1, $offset);
399}
400
401$resql = $db->query($sql);
402if (!$resql) {
404 exit;
405}
406
407$num = $db->num_rows($resql);
408
409
410// Direct jump if only one record found
411if ($num == 1 && getDolGlobalInt('MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE') && $search_all && !$page) {
412 $obj = $db->fetch_object($resql);
413 $id = $obj->rowid;
414 header("Location: " . dol_buildpath('/variants/card.php', 2) . '?id='.((int) $id));
415 exit;
416}
417
418
419// Output page
420// --------------------------------------------------------------------
421
422llxHeader('', $title, $help_url, '', 0, 0, $morejs, $morecss, '', 'bodyforlist');
423
424$arrayofselected = is_array($toselect) ? $toselect : array();
425
426$param = '';
427if (!empty($mode)) {
428 $param .= '&mode='.urlencode($mode);
429}
430if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
431 $param .= '&contextpage='.urlencode($contextpage);
432}
433if ($limit > 0 && $limit != $conf->liste_limit) {
434 $param .= '&limit='.((int) $limit);
435}
436if ($optioncss != '') {
437 $param .= '&optioncss='.urlencode($optioncss);
438}
439/*
440if ($groupby != '') {
441 $param .= '&groupby='.urlencode($groupby);
442}
443*/
444foreach ($search as $key => $val) {
445 if (is_array($search[$key])) {
446 foreach ($search[$key] as $skey) {
447 if ($skey != '') {
448 $param .= '&search_'.$key.'[]='.urlencode($skey);
449 }
450 }
451 } elseif (preg_match('/(_dtstart|_dtend)$/', $key) && !empty($val)) {
452 $param .= '&search_'.$key.'month='.(GETPOSTINT('search_'.$key.'month'));
453 $param .= '&search_'.$key.'day='.(GETPOSTINT('search_'.$key.'day'));
454 $param .= '&search_'.$key.'year='.(GETPOSTINT('search_'.$key.'year'));
455 } elseif ($search[$key] != '') {
456 $param .= '&search_'.$key.'='.urlencode($search[$key]);
457 }
458}
459// Add $param from extra fields
460include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
461// Add $param from hooks
462$parameters = array('param' => &$param);
463$reshook = $hookmanager->executeHooks('printFieldListSearchParam', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
464$param .= $hookmanager->resPrint;
465
466// List of mass actions available
467$arrayofmassactions = array(
468 //'validate'=>img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("Validate"),
469 //'generate_doc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("ReGeneratePDF"),
470 //'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"),
471 //'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"),
472);
473if (!empty($permissiontodelete)) {
474 $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
475}
476if (GETPOSTINT('nomassaction') || in_array($massaction, array('presend', 'predelete'))) {
477 $arrayofmassactions = array();
478}
479$massactionbutton = $form->selectMassAction('', $arrayofmassactions);
480
481print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">'."\n";
482if ($optioncss != '') {
483 print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
484}
485print '<input type="hidden" name="token" value="'.newToken().'">';
486print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
487print '<input type="hidden" name="action" value="list">';
488print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
489print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
490print '<input type="hidden" name="page" value="'.$page.'">';
491print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
492print '<input type="hidden" name="page_y" value="">';
493print '<input type="hidden" name="mode" value="'.$mode.'">';
494
495$newcardbutton = '';
496$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'));
497$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'));
498$newcardbutton .= dolGetButtonTitleSeparator();
499$newcardbutton .= dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/variants/card.php?action=create&backtopage='.urlencode($_SERVER['PHP_SELF']), '', $permissiontoadd);
500
501print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'object_'.$object->picto, 0, $newcardbutton, '', $limit, 0, 0, 1);
502
503// Add code for pre mass action (confirmation or email presend form)
504$topicmail = "SendProductAttributeRef";
505$modelmail = "productattribute";
506$objecttmp = new ProductAttribute($db);
507$trackid = 'pa'.$object->id;
508include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
509
510if ($search_all) {
511 $setupstring = '';
512 foreach ($fieldstosearchall as $key => $val) {
513 $fieldstosearchall[$key] = $langs->trans($val);
514 $setupstring .= $key."=".$val.";";
515 }
516 print '<!-- Search done like if MYOBJECT_QUICKSEARCH_ON_FIELDS = '.$setupstring.' -->'."\n";
517 print '<div class="divsearchfieldfilter">'.$langs->trans("FilterOnInto", $search_all).implode(', ', $fieldstosearchall).'</div>'."\n";
518}
519
520$moreforfilter = '';
521/*$moreforfilter.='<div class="divsearchfield">';
522$moreforfilter.= $langs->trans('MyFilter') . ': <input type="text" name="search_myfield" value="'.dol_escape_htmltag($search_myfield).'">';
523$moreforfilter.= '</div>';*/
524
525$parameters = array();
526$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
527if (empty($reshook)) {
528 $moreforfilter .= $hookmanager->resPrint;
529} else {
530 $moreforfilter = $hookmanager->resPrint;
531}
532
533if (!empty($moreforfilter)) {
534 print '<div class="liste_titre liste_titre_bydiv centpercent">';
535 print $moreforfilter;
536 print '</div>';
537}
538
539$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
540$htmlofselectarray = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, $conf->main_checkbox_left_column); // This also change content of $arrayfields with user setup
541$selectedfields = ($mode != 'kanban' ? $htmlofselectarray : '');
542$selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : '');
543
544print '<div class="div-table-responsive">'; // You can use div-table-responsive-no-min if you don't need reserved height for your table
545print '<table id="tableattributes" class="tagtable nobottomiftotal liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n";
546
547
548// Fields title search
549// --------------------------------------------------------------------
550print '<tr class="liste_titre_filter nodrag nodrop">';
551// Action column
552if ($conf->main_checkbox_left_column) {
553 print '<td class="liste_titre center maxwidthsearch">';
554 $searchpicto = $form->showFilterButtons('left');
555 print $searchpicto;
556 print '</td>';
557}
558foreach ($object->fields as $key => $val) {
559 //$searchkey = empty($search[$key]) ? '' : $search[$key];
560 $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']);
561 if ($key == 'status') {
562 $cssforfield .= ($cssforfield ? ' ' : '').'center';
563 } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
564 $cssforfield .= ($cssforfield ? ' ' : '').'center';
565 } elseif (in_array($val['type'], array('timestamp'))) {
566 $cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
567 } 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'])) {
568 $cssforfield .= ($cssforfield ? ' ' : '').'right';
569 }
570 if (!empty($arrayfields['t.'.$key]['checked'])) {
571 print '<td class="liste_titre'.($cssforfield ? ' '.$cssforfield : '').($key == 'status' ? ' parentonrightofpage' : '').'">';
572 if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
573 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);
574 } elseif ((strpos($val['type'], 'integer:') === 0) || (strpos($val['type'], 'sellist:') === 0)) {
575 print $object->showInputField($val, $key, (isset($search[$key]) ? $search[$key] : ''), '', '', 'search_', $cssforfield.' maxwidth250', 1);
576 } elseif (preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
577 print '<div class="nowrap">';
578 print $form->selectDate($search[$key.'_dtstart'] ? $search[$key.'_dtstart'] : '', "search_".$key."_dtstart", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From'));
579 print '</div>';
580 print '<div class="nowrap">';
581 print $form->selectDate($search[$key.'_dtend'] ? $search[$key.'_dtend'] : '', "search_".$key."_dtend", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to'));
582 print '</div>';
583 } elseif ($key == 'lang') {
584 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
585 $formadmin = new FormAdmin($db);
586 print $formadmin->select_language((isset($search[$key]) ? $search[$key] : ''), 'search_lang', 0, array(), 1, 0, 0, 'minwidth100imp maxwidth125', 2);
587 } else {
588 print '<input type="text" class="flat maxwidth'.($val['type'] == 'integer' ? '50' : '75').'" name="search_'.$key.'" value="'.dol_escape_htmltag(isset($search[$key]) ? $search[$key] : '').'">';
589 }
590 print '</td>';
591 }
592}
593// Extra fields
594include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php';
595// Fields from hook
596$parameters = array('arrayfields' => $arrayfields);
597$reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
598print $hookmanager->resPrint;
599
600$key = 'nb_of_values';
601if (!empty($arrayfields[$key]['checked'])) {
602 print '<td class="liste_titre center">';
603 print '<input type="text" class="flat maxwidth50" name="search_'.$key.'" value="'.dol_escape_htmltag(isset($search[$key]) ? $search[$key] : '').'">';
604 print '</td>';
605}
606$key = 'nb_products';
607if (!empty($arrayfields[$key]['checked'])) {
608 print '<td class="liste_titre center">';
609 print '<input type="text" class="flat maxwidth50" name="search_'.$key.'" value="'.dol_escape_htmltag(isset($search[$key]) ? $search[$key] : '').'">';
610 print '</td>';
611}
612// Action column
613if (!$conf->main_checkbox_left_column) {
614 print '<td class="liste_titre center maxwidthsearch">';
615 $searchpicto = $form->showFilterButtons();
616 print $searchpicto;
617 print '</td>';
618}
619// Move
620print '<td class="liste_titre linecolmove width25"></td>';
621print '</tr>'."\n";
622
623$totalarray = array();
624$totalarray['nbfield'] = 0;
625
626// Fields title label
627// --------------------------------------------------------------------
628print '<tr class="liste_titre nodrag nodrop">';
629// Action column
630if ($conf->main_checkbox_left_column) {
631 print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
632 $totalarray['nbfield']++;
633}
634foreach ($object->fields as $key => $val) {
635 $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']);
636 if ($key == 'status') {
637 $cssforfield .= ($cssforfield ? ' ' : '').'center';
638 } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
639 $cssforfield .= ($cssforfield ? ' ' : '').'center';
640 } elseif (in_array($val['type'], array('timestamp'))) {
641 $cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
642 } 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'])) {
643 $cssforfield .= ($cssforfield ? ' ' : '').'right';
644 }
645 $cssforfield = preg_replace('/small\s*/', '', $cssforfield); // the 'small' css must not be used for the title label
646 if (!empty($arrayfields['t.'.$key]['checked'])) {
647 print getTitleFieldOfList($arrayfields['t.'.$key]['label'], 0, $_SERVER['PHP_SELF'], 't.'.$key, '', $param, '', $sortfield, $sortorder, ($cssforfield ? $cssforfield.' ' : ''), 0, (empty($val['helplist']) ? '' : $val['helplist']))."\n";
648 $totalarray['nbfield']++;
649 }
650}
651// Extra fields
652include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php';
653// Hook fields
654$parameters = array('arrayfields' => $arrayfields, 'param' => $param, 'sortfield' => $sortfield, 'sortorder' => $sortorder, 'totalarray' => &$totalarray);
655$reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
656print $hookmanager->resPrint;
657
658$key = 'nb_of_values';
659if (!empty($arrayfields[$key]['checked'])) {
660 // @phan-suppress-next-line PhanTypeInvalidDimOffset
661 print getTitleFieldOfList($arrayfields[$key]['label'], 0, $_SERVER['PHP_SELF'], $key, '', $param, 'class="center"', $sortfield, $sortorder, 'center ')."\n";
662 $totalarray['nbfield']++;
663}
664$key = 'nb_products';
665if (!empty($arrayfields[$key]['checked'])) {
666 print getTitleFieldOfList($arrayfields[$key]['label'], 0, $_SERVER['PHP_SELF'], $key, '', $param, 'class="center"', $sortfield, $sortorder, 'center ')."\n";
667 $totalarray['nbfield']++;
668}
669// Action column
670if (!$conf->main_checkbox_left_column) {
671 print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
672 $totalarray['nbfield']++;
673}
674// Move
675print getTitleFieldOfList('', 0, '', '', '', '', '', '', '', 'linecolmove ')."\n";
676$totalarray['nbfield']++;
677print '</tr>'."\n";
678
679
680// Detect if we need a fetch on each output line
681$needToFetchEachLine = 0;
682//if (isset($extrafields->attributes[$object->table_element]['computed']) && is_array($extrafields->attributes[$object->table_element]['computed']) && count($extrafields->attributes[$object->table_element]['computed']) > 0) {
683// foreach ($extrafields->attributes[$object->table_element]['computed'] as $key => $val) {
684// if (!is_null($val) && preg_match('/\$object/', $val)) {
685// $needToFetchEachLine++; // There is at least one compute field that use $object
686// }
687// }
688//}
689
690
691// Loop on record
692// --------------------------------------------------------------------
693$i = 0;
694$savnbfield = $totalarray['nbfield'];
695$totalarray = array();
696$totalarray['nbfield'] = 0;
697$imaxinloop = ($limit ? min($num, $limit) : $num);
698while ($i < $imaxinloop) {
699 $obj = $db->fetch_object($resql);
700 if (empty($obj)) {
701 break; // Should not happen
702 }
703
704 // Store properties in $object
705 $object->setVarsFromFetchObj($obj);
706 $object->fetch_optionals();
707
708 if ($mode == 'kanban') {
709 if ($i == 0) {
710 print '<tr class="trkanban"><td colspan="'.$savnbfield.'">';
711 print '<div class="box-flex-container kanban">';
712 }
713 // Output Kanban
714 $selected = -1;
715 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
716 $selected = 0;
717 if (in_array($object->id, $arrayofselected)) {
718 $selected = 1;
719 }
720 }
721 print $object->getKanbanView('', array('selected' => $selected));
722 if ($i == ($imaxinloop - 1)) {
723 print '</div>';
724 print '</td></tr>';
725 }
726 } else {
727 // Show line of result
728 $j = 0;
729 print '<tr data-rowid="'.$object->id.'" class="oddeven row-with-select">';
730 // Action column
731 if ($conf->main_checkbox_left_column) {
732 print '<td class="nowrap center">';
733 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
734 $selected = 0;
735 if (in_array($object->id, $arrayofselected)) {
736 $selected = 1;
737 }
738 print '<input id="cb'.$object->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$object->id.'"'.($selected ? ' checked="checked"' : '').'>';
739 }
740 print '</td>';
741 if (!$i) {
742 $totalarray['nbfield']++;
743 }
744 }
745 // Fields
746 foreach ($object->fields as $key => $val) {
747 $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']);
748 if (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
749 $cssforfield .= ($cssforfield ? ' ' : '') . 'center';
750 } elseif ($key == 'status') {
751 $cssforfield .= ($cssforfield ? ' ' : '') . 'center';
752 }
753
754 if (in_array($val['type'], array('timestamp'))) {
755 $cssforfield .= ($cssforfield ? ' ' : '') . 'nowraponall';
756 } elseif ($key == 'ref') {
757 $cssforfield .= ($cssforfield ? ' ' : '') . 'nowraponall';
758 }
759
760 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'])) {
761 $cssforfield .= ($cssforfield ? ' ' : '') . 'right';
762 }
763 //if (in_array($key, array('fk_soc', 'fk_user', 'fk_warehouse'))) $cssforfield = 'tdoverflowmax100';
764
765 if (!empty($arrayfields['t.' . $key]['checked'])) {
766 print '<td'.($cssforfield ? ' class="'.$cssforfield.((preg_match('/tdoverflow/', $cssforfield) && !in_array($val['type'], array('ip', 'url')) && !is_numeric($object->$key)) ? ' classfortooltip' : '').'"' : '');
767 if (preg_match('/tdoverflow/', $cssforfield) && !in_array($val['type'], array('ip', 'url')) && !is_numeric($object->$key)) {
768 print ' title="'.dol_escape_htmltag((string) $object->$key).'"';
769 }
770 print '>';
771 if ($key == 'status') {
772 print $object->getLibStatut(5);
773 } elseif ($key == 'rowid') {
774 print $object->showOutputField($val, $key, (string) $object->id, '');
775 } else {
776 print $object->showOutputField($val, $key, $object->$key, '');
777 }
778 print '</td>';
779 if (!$i) {
780 $totalarray['nbfield']++;
781 }
782 if (!empty($val['isameasure']) && $val['isameasure'] == 1) {
783 if (!$i) {
784 $totalarray['pos'][$totalarray['nbfield']] = 't.' . $key;
785 }
786 if (!isset($totalarray['val'])) {
787 $totalarray['val'] = array();
788 }
789 if (!isset($totalarray['val']['t.' . $key])) {
790 $totalarray['val']['t.' . $key] = 0;
791 }
792 $totalarray['val']['t.' . $key] += $object->$key;
793 }
794 }
795 }
796 // Extra fields
797 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
798 // Fields from hook
799 $parameters = array('arrayfields' => $arrayfields, 'object' => $object, 'obj' => $obj, 'i' => $i, 'totalarray' => &$totalarray);
800 $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
801 print $hookmanager->resPrint;
802 // Other
803 $key = 'nb_of_values';
804 if (!empty($arrayfields[$key]['checked'])) {
805 print '<td class="center">';
806 print $obj->$key;
807 print '</td>';
808 if (!$i) {
809 $totalarray['nbfield']++;
810 }
811 }
812 $key = 'nb_products';
813 if (!empty($arrayfields[$key]['checked'])) {
814 print '<td class="center">';
815 print $obj->$key;
816 print '</td>';
817 if (!$i) {
818 $totalarray['nbfield']++;
819 }
820 }
821 // Action column
822 if (!$conf->main_checkbox_left_column) {
823 print '<td class="nowrap center">';
824 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
825 $selected = 0;
826 if (in_array($object->id, $arrayofselected)) {
827 $selected = 1;
828 }
829 print '<input id="cb'.$object->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$object->id.'"'.($selected ? ' checked="checked"' : '').'>';
830 }
831 print '</td>';
832 if (!$i) {
833 $totalarray['nbfield']++;
834 }
835 }
836 // Move
837 print '<td class="center linecolmove tdlineupdown">';
838 if ($i > 0) {
839 print '<a class="lineupdown" href="' . $_SERVER['PHP_SELF'] . '?action=up&amp;token='.newToken().'&amp;rowid=' . $obj->rowid . '">' . img_up('default', 0, 'imgupforline') . '</a>';
840 }
841 if ($i < $num - 1) {
842 print '<a class="lineupdown" href="' . $_SERVER['PHP_SELF'] . '?action=down&amp;token='.newToken().'&amp;rowid=' . $obj->rowid . '">' . img_down('default', 0, 'imgdownforline') . '</a>';
843 }
844 print '</td>';
845 if (!$i) {
846 $totalarray['nbfield']++;
847 }
848
849 print '</tr>' . "\n";
850 }
851
852 $i++;
853}
854
855// Show total line
856include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php';
857
858// If no record found
859if ($num == 0) {
860 $colspan = 1;
861 foreach ($arrayfields as $key => $val) {
862 if (!empty($val['checked'])) {
863 $colspan++;
864 }
865 }
866 $colspan++; // For the move column
867 print '<tr><td colspan="'.$colspan.'"><span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span></td></tr>';
868}
869
870$db->free($resql);
871
872$parameters = array('arrayfields' => $arrayfields, 'sql' => $sql);
873$reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
874print $hookmanager->resPrint;
875
876print '</table>'."\n";
877print '</div>'."\n";
878
879print '</form>'."\n";
880
881$forcereloadpage = getDolGlobalInt('MAIN_FORCE_RELOAD_PAGE');
882$tagidfortablednd = (empty($tagidfortablednd) ? 'tableattributes' : $tagidfortablednd);
883?>
884 <script>
885 $(document).ready(function(){
886 $(".imgupforline, .imgdownforline").hide();
887 $(".lineupdown").removeAttr('href');
888 $(".tdlineupdown")
889 .css("background-image", 'url(<?php echo DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/grip.png'; ?>)')
890 .css("background-repeat", "no-repeat")
891 .css("background-position", "center center")
892 .hover(
893 function () {
894 $(this).addClass('showDragHandle');
895 }, function () {
896 $(this).removeClass('showDragHandle');
897 }
898 );
899
900 $("#<?php echo $tagidfortablednd; ?>").tableDnD({
901 onDrop: function(table, row) {
902 console.log('onDrop variant .tableDnD');
903 $('#<?php echo $tagidfortablednd; ?> tr[data-element=extrafield]').attr('id', ''); // Set extrafields id to empty value in order to ignore them in tableDnDSerialize function
904 $('#<?php echo $tagidfortablednd; ?> tr[data-ignoreidfordnd=1]').attr('id', ''); // Set id to empty value in order to ignore them in tableDnDSerialize function
905 var reloadpage = "<?php echo $forcereloadpage; ?>";
906 var roworder = cleanSerialize(decodeURI($("#<?php echo $tagidfortablednd; ?>").tableDnDSerialize()));
907 $.post("<?php echo DOL_URL_ROOT; ?>/variants/ajax/orderAttribute.php",
908 {
909 roworder: roworder,
910 token: "<?php echo currentToken(); ?>"
911 },
912 function() {
913 if (reloadpage == 1) {
914 location.href = '<?php echo dol_escape_htmltag($_SERVER['PHP_SELF']).'?'.dol_escape_htmltag($_SERVER['QUERY_STRING']); ?>';
915 }
916 });
917 },
918 onDragClass: "dragClass",
919 dragHandle: "td.tdlineupdown"
920 });
921 });
922 </script>
923<?php
924
925if (in_array('builddoc', array_keys($arrayofmassactions)) && ($nbtotalofrecords === '' || $nbtotalofrecords)) {
926 $hidegeneratedfilelistifempty = 1;
927 if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) {
928 $hidegeneratedfilelistifempty = 0;
929 }
930
931 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
932 $formfile = new FormFile($db);
933
934 // Show list of available documents
935 $urlsource = $_SERVER['PHP_SELF'].'?sortfield='.$sortfield.'&sortorder='.$sortorder;
936 $urlsource .= str_replace('&amp;', '&', $param);
937
938 $filedir = $diroutputmassaction;
939 $genallowed = $permissiontoread;
940 $delallowed = $permissiontoadd;
941
942 print $formfile->showdocuments('massfilesarea_productattribute', '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty);
943}
944
945// End of page
946llxFooter();
947$db->close();
$id
Support class for third parties, contacts, members, users or resources.
Definition account.php:47
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
$totalarray
Definition list.php:501
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
Definition wrapper.php:91
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:73
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 ProductAttribute Used to represent a Product attribute Examples:
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $db
API class for accounts.
dol_now($mode='gmt')
Return date for now.
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, $allowothertags=array())
Show picto whatever it's its name (generic function)
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.
img_down($titlealt='default', $selected=0, $moreclass='')
Show down arrow logo.
natural_search($fields, $value, $mode=0, $nofirstand=0, $sqltoadd='')
Generate natural SQL search string for a criteria (this criteria can be tested on one or several fiel...
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...
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0, $nodefault=0)
Return value of a param into GET or POST supervariable.
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.
GETPOSTINT($paramname, $method=0, $nodefault=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
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...
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
isModEnabled($module)
Is Dolibarr module enabled.
img_up($titlealt='default', $selected=0, $moreclass='')
Show top arrow logo.
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...
treeview li table
No Email.
print $langs trans("Show") . '< td style="' . $timeColor . '" align="center"> s</td > badge status0 badge status4 badge status3 Error badge status8< td align="center">< span class="badge ' . $badge . '"></span ></td >< td align="center">< a href="#" class="button button-small" onclick="openLogModal(this)" data-req="' . dol_escape_htmltag($reqSafe) . '" data-res="' . dol_escape_htmltag($resSafe) . '" data-err="' . dol_escape_htmltag($errSafe) . '">< span class="fa fa-search-plus"></span ></a ></td ></tr >< tr >< td colspan="' . $colspan . '" class="opacitymedium"></td ></tr ></table ></div ></form > logModal none logModal none s a JSON string
buildzip.php
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.