mirror of
https://github.com/Dolibarr/dolibarr.git
synced 2025-02-20 13:46:52 +01:00
* Qual: Enable & fix or ignore Invalid DimOffset # Qual: Enable & fix or ignore Invalid DimOffset The Invalid DimOffset notices occur when array keys are defined and the index used is not amongst the known array keys. This PR enables these notices and fixes array definitions when needed, or ignores the notices locally if it's a false positive, or in the baseline.txt when it does not seem to be a false positive so that it can be fixed later * Nullable object typing in function signature not ok for 7.0/8.4 Can't user '?User' as argument type for PHP7.0 which is required by PHP8.4. Therefore, removing the typing specification in the function definition --------- Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
927 lines
38 KiB
PHP
927 lines
38 KiB
PHP
<?php
|
|
/* Copyright (C) 2016 Marcos García <marcosgdf@gmail.com>
|
|
* Copyright (C) 2022 Open-Dsi <support@open-dsi.fr>
|
|
* Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
|
|
* Copyright (C) 2024 Benjamin Falière <benjamin.faliere@altairis.fr>
|
|
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/**
|
|
* \file htdocs/variants/list.php
|
|
* \ingroup variants
|
|
* \brief List page for product attribute
|
|
*/
|
|
|
|
// Load Dolibarr environment
|
|
require '../main.inc.php';
|
|
require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
|
|
require_once DOL_DOCUMENT_ROOT.'/variants/class/ProductAttribute.class.php';
|
|
|
|
// Load translation files required by the page
|
|
$langs->loadLangs(array("products", "other"));
|
|
|
|
$action = GETPOST('action', 'aZ09') ? GETPOST('action', 'aZ09') : 'view'; // The action 'create'/'add', 'edit'/'update', 'view', ...
|
|
$massaction = GETPOST('massaction', 'alpha'); // The bulk action (combo box choice into lists)
|
|
$show_files = GETPOSTINT('show_files'); // Show files area generated by bulk actions
|
|
$confirm = GETPOST('confirm', 'alpha'); // Result of a confirmation
|
|
$cancel = GETPOST('cancel', 'alpha'); // We click on a Cancel button
|
|
$toselect = GETPOST('toselect', 'array:int'); // Array of ids of elements selected into a list
|
|
$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : str_replace('_', '', basename(dirname(__FILE__)).basename(__FILE__, '.php')); // To manage different context of search
|
|
$backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page
|
|
$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print')
|
|
$mode = GETPOST('mode', 'aZ'); // The display mode ('list', 'kanban', 'hierarchy', 'calendar', 'gantt', ...)
|
|
|
|
$id = GETPOSTINT('id');
|
|
|
|
// Load variable for pagination
|
|
$limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
|
|
$sortfield = GETPOST('sortfield', 'aZ09comma');
|
|
$sortorder = GETPOST('sortorder', 'aZ09comma');
|
|
$page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT('page');
|
|
if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha')) {
|
|
// If $page is not defined, or '' or -1 or if we click on clear filters
|
|
$page = 0;
|
|
}
|
|
$offset = $limit * $page;
|
|
$pageprev = $page - 1;
|
|
$pagenext = $page + 1;
|
|
|
|
// Initialize a technical objects
|
|
$object = new ProductAttribute($db);
|
|
//$extrafields = new ExtraFields($db);
|
|
$diroutputmassaction = $conf->variants->dir_output.'/temp/massgeneration/'.$user->id;
|
|
$hookmanager->initHooks(array('productattributelist')); // Note that conf->hooks_modules contains array
|
|
|
|
// Fetch optionals attributes and labels
|
|
//$extrafields->fetch_name_optionals_label($object->table_element);
|
|
|
|
//$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
|
|
|
|
// Default sort order (if not yet defined by previous GETPOST)
|
|
if (!$sortfield) {
|
|
$sortfield = "t.position"; // Set here default search field. By default 1st field in definition.
|
|
}
|
|
if (!$sortorder) {
|
|
$sortorder = "ASC";
|
|
}
|
|
|
|
// Initialize array of search criteria
|
|
$search_all = trim(GETPOST('search_all', 'alphanohtml'));
|
|
$search = array();
|
|
foreach ($object->fields as $key => $val) {
|
|
if (GETPOST('search_'.$key, 'alpha') !== '') {
|
|
$search[$key] = GETPOST('search_'.$key, 'alpha');
|
|
}
|
|
if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
|
|
$search[$key.'_dtstart'] = dol_mktime(0, 0, 0, GETPOSTINT('search_'.$key.'_dtstartmonth'), GETPOSTINT('search_'.$key.'_dtstartday'), GETPOSTINT('search_'.$key.'_dtstartyear'));
|
|
$search[$key.'_dtend'] = dol_mktime(23, 59, 59, GETPOSTINT('search_'.$key.'_dtendmonth'), GETPOSTINT('search_'.$key.'_dtendday'), GETPOSTINT('search_'.$key.'_dtendyear'));
|
|
}
|
|
}
|
|
$search['nb_of_values'] = GETPOST('search_nb_of_values', 'alpha');
|
|
$search['nb_products'] = GETPOST('search_nb_products', 'alpha');
|
|
|
|
$fieldstosearchall = array();
|
|
// List of fields to search into when doing a "search in all"
|
|
foreach ($object->fields as $key => $val) {
|
|
if (!empty($val['searchall'])) {
|
|
$fieldstosearchall['t.'.$key] = $val['label'];
|
|
}
|
|
}
|
|
$parameters = array('fieldstosearchall' => $fieldstosearchall);
|
|
$reshook = $hookmanager->executeHooks('completeFieldsToSearchAll', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
|
|
if ($reshook > 0) {
|
|
$fieldstosearchall = empty($hookmanager->resArray['fieldstosearchall']) ? array() : $hookmanager->resArray['fieldstosearchall'];
|
|
} elseif ($reshook == 0) {
|
|
$fieldstosearchall = array_merge($fieldstosearchall, empty($hookmanager->resArray['fieldstosearchall']) ? array() : $hookmanager->resArray['fieldstosearchall']);
|
|
}
|
|
|
|
// Definition of array of fields for columns
|
|
$arrayfields = array();
|
|
foreach ($object->fields as $key => $val) {
|
|
// If $val['visible']==0, then we never show the field
|
|
if (!empty($val['visible'])) {
|
|
$visible = (int) dol_eval((string) $val['visible'], 1);
|
|
$arrayfields['t.'.$key] = array(
|
|
'label' => $val['label'],
|
|
'checked' => (($visible < 0) ? 0 : 1),
|
|
'enabled' => (abs($visible) != 3 && (bool) dol_eval($val['enabled'], 1)),
|
|
'position' => $val['position'],
|
|
'help' => isset($val['help']) ? $val['help'] : ''
|
|
);
|
|
}
|
|
}
|
|
$arrayfields['nb_of_values'] = array(
|
|
'label' => $langs->trans('NbOfDifferentValues'),
|
|
'checked' => 1,
|
|
'enabled' => 1,
|
|
'position' => 40,
|
|
'help' => ''
|
|
);
|
|
$arrayfields['nb_products'] = array(
|
|
'label' => $langs->trans('NbProducts'),
|
|
'checked' => 1,
|
|
'enabled' => 1,
|
|
'position' => 50,
|
|
'help' => ''
|
|
);
|
|
// Extra fields
|
|
//include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php';
|
|
|
|
$object->fields = dol_sort_array($object->fields, 'position');
|
|
$arrayfields = dol_sort_array($arrayfields, 'position');
|
|
'@phan-var-force array<string,array{label:string,checked?:int<0,1>,position?:int,help?:string}> $arrayfields'; // dol_sort_array looses type for Phan
|
|
|
|
$permissiontoread = $user->hasRight('variants', 'read');
|
|
$permissiontoadd = $user->hasRight('variants', 'write');
|
|
$permissiontodelete = $user->hasRight('variants', 'delete');
|
|
|
|
// Security check
|
|
if (!isModEnabled('variants')) {
|
|
accessforbidden('Module not enabled');
|
|
}
|
|
$socid = 0;
|
|
if ($user->socid > 0) { // Protection if external user
|
|
//$socid = $user->socid;
|
|
accessforbidden();
|
|
}
|
|
if (!$permissiontoread) {
|
|
accessforbidden();
|
|
}
|
|
|
|
|
|
/*
|
|
* Actions
|
|
*/
|
|
|
|
if (GETPOST('cancel', 'alpha')) {
|
|
$action = 'list';
|
|
$massaction = '';
|
|
}
|
|
if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') {
|
|
$massaction = '';
|
|
}
|
|
|
|
$parameters = array('arrayfields' => &$arrayfields);
|
|
$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
|
|
if ($reshook < 0) {
|
|
setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
|
|
}
|
|
|
|
if (empty($reshook)) {
|
|
// Selection of new fields
|
|
include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
|
|
|
|
// Purge search criteria
|
|
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
|
|
foreach ($object->fields as $key => $val) {
|
|
$search[$key] = '';
|
|
if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
|
|
$search[$key.'_dtstart'] = '';
|
|
$search[$key.'_dtend'] = '';
|
|
}
|
|
}
|
|
$search['nb_of_values'] = '';
|
|
$search['nb_products'] = '';
|
|
$toselect = array();
|
|
$search_array_options = array();
|
|
}
|
|
if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')
|
|
|| GETPOST('button_search_x', 'alpha') || GETPOST('button_search.x', 'alpha') || GETPOST('button_search', 'alpha')) {
|
|
$massaction = ''; // Protection to avoid mass action if we force a new search during a mass action confirmation
|
|
}
|
|
|
|
if ($action == 'up' && $permissiontoadd) {
|
|
$object->attributeMoveUp($rowid);
|
|
|
|
header('Location: '.$_SERVER['PHP_SELF']);
|
|
exit();
|
|
} elseif ($action == 'down' && $permissiontoadd) {
|
|
$object->attributeMoveDown($rowid);
|
|
|
|
header('Location: '.$_SERVER['PHP_SELF']);
|
|
exit();
|
|
}
|
|
|
|
// Mass actions
|
|
$objectclass = 'ProductAttribute';
|
|
$objectlabel = 'ProductAttribute';
|
|
$uploaddir = $conf->variants->dir_output;
|
|
include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
* View
|
|
*/
|
|
|
|
$form = new Form($db);
|
|
|
|
$now = dol_now();
|
|
|
|
$title = $langs->trans("ProductAttributes");
|
|
$help_url = '';
|
|
$morejs = array();
|
|
$morecss = array();
|
|
|
|
|
|
// Build and execute select
|
|
// --------------------------------------------------------------------
|
|
$sql = "SELECT COUNT(DISTINCT pav.rowid) AS nb_of_values, COUNT(DISTINCT pac2v.fk_prod_combination) AS nb_products, ";
|
|
$sql .= $object->getFieldList("t");
|
|
// Add fields from extrafields
|
|
//if (!empty($extrafields->attributes[$object->table_element]['label'])) {
|
|
// foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
|
|
// $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? "ef.".$key." as options_".$key.", " : "");
|
|
// }
|
|
//}
|
|
// Add fields from hooks
|
|
$parameters = array();
|
|
$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
|
|
$sql .= $hookmanager->resPrint;
|
|
$sql = preg_replace('/,\s*$/', '', $sql);
|
|
|
|
$sqlfields = $sql; // $sql fields to remove for count total
|
|
|
|
$sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t";
|
|
//if (isset($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) {
|
|
// $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (t.rowid = ef.fk_object)";
|
|
//}
|
|
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_attribute_combination2val AS pac2v ON pac2v.fk_prod_attr = t.rowid";
|
|
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_attribute_value AS pav ON pav.fk_product_attribute = t.rowid";
|
|
// Add table from hooks
|
|
$parameters = array();
|
|
$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
|
|
$sql .= $hookmanager->resPrint;
|
|
if ($object->ismultientitymanaged == 1) {
|
|
$sql .= " WHERE t.entity IN (".getEntity($object->element, (GETPOST('search_current_entity', 'int') ? 0 : 1)).")";
|
|
} else {
|
|
$sql .= " WHERE 1 = 1";
|
|
}
|
|
foreach ($search as $key => $val) {
|
|
if (array_key_exists($key, $object->fields)) {
|
|
if ($key == 'status' && $search[$key] == -1) {
|
|
continue;
|
|
}
|
|
$mode_search = (($object->isInt($object->fields[$key]) || $object->isFloat($object->fields[$key])) ? 1 : 0);
|
|
if ((strpos($object->fields[$key]['type'], 'integer:') === 0) || (strpos($object->fields[$key]['type'], 'sellist:') === 0) || !empty($object->fields[$key]['arrayofkeyval'])) {
|
|
if ($search[$key] == '-1' || ($search[$key] === '0' && (empty($object->fields[$key]['arrayofkeyval']) || !array_key_exists('0', $object->fields[$key]['arrayofkeyval'])))) {
|
|
$search[$key] = '';
|
|
}
|
|
$mode_search = 2;
|
|
}
|
|
if ($search[$key] != '') {
|
|
$sql .= natural_search("t.".$db->sanitize($key), $search[$key], (($key == 'status') ? 2 : $mode_search));
|
|
}
|
|
} else {
|
|
if (preg_match('/(_dtstart|_dtend)$/', $key) && $search[$key] != '') {
|
|
$columnName = preg_replace('/(_dtstart|_dtend)$/', '', $key);
|
|
if (preg_match('/^(date|timestamp|datetime)/', $object->fields[$columnName]['type'])) {
|
|
if (preg_match('/_dtstart$/', $key)) {
|
|
$sql .= " AND t.".$db->sanitize($columnName)." >= '".$db->idate($search[$key])."'";
|
|
}
|
|
if (preg_match('/_dtend$/', $key)) {
|
|
$sql .= " AND t.".$db->sanitize($columnName)." <= '".$db->idate($search[$key])."'";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if ($search_all) {
|
|
$sql .= natural_search(array_keys($fieldstosearchall), $search_all);
|
|
}
|
|
//$sql.= dolSqlDateFilter("t.field", $search_xxxday, $search_xxxmonth, $search_xxxyear);
|
|
// Add where from extra fields
|
|
//include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
|
|
// Add where from hooks
|
|
$parameters = array();
|
|
$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
|
|
$sql .= $hookmanager->resPrint;
|
|
|
|
$hasgroupby = true;
|
|
$sql .= " GROUP BY ";
|
|
foreach ($object->fields as $key => $val) {
|
|
$sql .= "t.".$db->sanitize($key).", ";
|
|
}
|
|
// Add fields from extrafields
|
|
//if (!empty($extrafields->attributes[$object->table_element]['label'])) {
|
|
// foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
|
|
// $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? "ef.".$key.', ' : '');
|
|
// }
|
|
//}
|
|
// Add where from hooks
|
|
$parameters = array();
|
|
$reshook = $hookmanager->executeHooks('printFieldListGroupBy', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
|
|
$sql .= $hookmanager->resPrint;
|
|
$sql = preg_replace("/,\s*$/", "", $sql);
|
|
|
|
$sql .= " HAVING 1=1";
|
|
if ($search['nb_of_values'] != '') {
|
|
$sql .= natural_search("nb_of_values", $search['nb_of_values'], 1);
|
|
}
|
|
if ($search['nb_products'] != '') {
|
|
$sql .= natural_search("nb_products", $search['nb_products'], 1);
|
|
}
|
|
// Add HAVING from hooks
|
|
$parameters = array();
|
|
$reshook = $hookmanager->executeHooks('printFieldListHaving', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
|
|
$sql .= empty($hookmanager->resPrint) ? "" : " ".$hookmanager->resPrint;
|
|
|
|
// Count total nb of records
|
|
$nbtotalofrecords = '';
|
|
if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
|
|
/* This old and fast method to get and count full list returns all record so use a high amount of memory.
|
|
$resql = $db->query($sql);
|
|
$nbtotalofrecords = $db->num_rows($resql);
|
|
*/
|
|
/* The slow method does not consume memory on mysql (not tested on pgsql) */
|
|
/*$resql = $db->query($sql, 0, 'auto', 1);
|
|
while ($db->fetch_object($resql)) {
|
|
$nbtotalofrecords++;
|
|
}*/
|
|
/* The fast and low memory method to get and count full list converts the sql into a sql count */
|
|
$sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql);
|
|
$sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount);
|
|
|
|
$resql = $db->query($sqlforcount);
|
|
if ($resql) {
|
|
if ($hasgroupby) {
|
|
$nbtotalofrecords = $db->num_rows($resql);
|
|
} else {
|
|
$objforcount = $db->fetch_object($resql);
|
|
$nbtotalofrecords = $objforcount->nbtotalofrecords;
|
|
}
|
|
if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller than the paging size (filtering), goto and load page 0
|
|
$page = 0;
|
|
$offset = 0;
|
|
}
|
|
$db->free($resql);
|
|
}
|
|
}
|
|
|
|
// Complete request and execute it with limit
|
|
$sql .= $db->order($sortfield, $sortorder);
|
|
if ($limit) {
|
|
$sql .= $db->plimit($limit + 1, $offset);
|
|
}
|
|
|
|
$resql = $db->query($sql);
|
|
if (!$resql) {
|
|
dol_print_error($db);
|
|
exit;
|
|
}
|
|
|
|
$num = $db->num_rows($resql);
|
|
|
|
|
|
// Direct jump if only one record found
|
|
if ($num == 1 && getDolGlobalInt('MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE') && $search_all && !$page) {
|
|
$obj = $db->fetch_object($resql);
|
|
$id = $obj->rowid;
|
|
header("Location: " . dol_buildpath('/variants/card.php', 2) . '?id='.((int) $id));
|
|
exit;
|
|
}
|
|
|
|
|
|
// Output page
|
|
// --------------------------------------------------------------------
|
|
|
|
llxHeader('', $title, $help_url, '', 0, 0, $morejs, $morecss, '', 'bodyforlist');
|
|
|
|
$arrayofselected = is_array($toselect) ? $toselect : array();
|
|
|
|
$param = '';
|
|
if (!empty($mode)) {
|
|
$param .= '&mode='.urlencode($mode);
|
|
}
|
|
if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
|
|
$param .= '&contextpage='.urlencode($contextpage);
|
|
}
|
|
if ($limit > 0 && $limit != $conf->liste_limit) {
|
|
$param .= '&limit='.((int) $limit);
|
|
}
|
|
if ($optioncss != '') {
|
|
$param .= '&optioncss='.urlencode($optioncss);
|
|
}
|
|
/*
|
|
if ($groupby != '') {
|
|
$param .= '&groupby='.urlencode($groupby);
|
|
}
|
|
*/
|
|
foreach ($search as $key => $val) {
|
|
if (is_array($search[$key])) {
|
|
foreach ($search[$key] as $skey) {
|
|
if ($skey != '') {
|
|
$param .= '&search_'.$key.'[]='.urlencode($skey);
|
|
}
|
|
}
|
|
} elseif (preg_match('/(_dtstart|_dtend)$/', $key) && !empty($val)) {
|
|
$param .= '&search_'.$key.'month='.(GETPOSTINT('search_'.$key.'month'));
|
|
$param .= '&search_'.$key.'day='.(GETPOSTINT('search_'.$key.'day'));
|
|
$param .= '&search_'.$key.'year='.(GETPOSTINT('search_'.$key.'year'));
|
|
} elseif ($search[$key] != '') {
|
|
$param .= '&search_'.$key.'='.urlencode($search[$key]);
|
|
}
|
|
}
|
|
// Add $param from extra fields
|
|
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
|
|
// Add $param from hooks
|
|
$parameters = array('param' => &$param);
|
|
$reshook = $hookmanager->executeHooks('printFieldListSearchParam', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
|
|
$param .= $hookmanager->resPrint;
|
|
|
|
// List of mass actions available
|
|
$arrayofmassactions = array(
|
|
//'validate'=>img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("Validate"),
|
|
//'generate_doc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("ReGeneratePDF"),
|
|
//'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"),
|
|
//'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"),
|
|
);
|
|
if (!empty($permissiontodelete)) {
|
|
$arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
|
|
}
|
|
if (GETPOSTINT('nomassaction') || in_array($massaction, array('presend', 'predelete'))) {
|
|
$arrayofmassactions = array();
|
|
}
|
|
$massactionbutton = $form->selectMassAction('', $arrayofmassactions);
|
|
|
|
print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">'."\n";
|
|
if ($optioncss != '') {
|
|
print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
|
|
}
|
|
print '<input type="hidden" name="token" value="'.newToken().'">';
|
|
print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
|
|
print '<input type="hidden" name="action" value="list">';
|
|
print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
|
|
print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
|
|
print '<input type="hidden" name="page" value="'.$page.'">';
|
|
print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
|
|
print '<input type="hidden" name="page_y" value="">';
|
|
print '<input type="hidden" name="mode" value="'.$mode.'">';
|
|
|
|
$newcardbutton = '';
|
|
$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'));
|
|
$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'));
|
|
$newcardbutton .= dolGetButtonTitleSeparator();
|
|
$newcardbutton .= dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/variants/card.php?action=create&backtopage='.urlencode($_SERVER['PHP_SELF']), '', $permissiontoadd);
|
|
|
|
print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'object_'.$object->picto, 0, $newcardbutton, '', $limit, 0, 0, 1);
|
|
|
|
// Add code for pre mass action (confirmation or email presend form)
|
|
$topicmail = "SendProductAttributeRef";
|
|
$modelmail = "productattribute";
|
|
$objecttmp = new ProductAttribute($db);
|
|
$trackid = 'pa'.$object->id;
|
|
include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
|
|
|
|
if ($search_all) {
|
|
$setupstring = '';
|
|
foreach ($fieldstosearchall as $key => $val) {
|
|
$fieldstosearchall[$key] = $langs->trans($val);
|
|
$setupstring .= $key."=".$val.";";
|
|
}
|
|
print '<!-- Search done like if MYOBJECT_QUICKSEARCH_ON_FIELDS = '.$setupstring.' -->'."\n";
|
|
print '<div class="divsearchfieldfilter">'.$langs->trans("FilterOnInto", $search_all).implode(', ', $fieldstosearchall).'</div>'."\n";
|
|
}
|
|
|
|
$moreforfilter = '';
|
|
/*$moreforfilter.='<div class="divsearchfield">';
|
|
$moreforfilter.= $langs->trans('MyFilter') . ': <input type="text" name="search_myfield" value="'.dol_escape_htmltag($search_myfield).'">';
|
|
$moreforfilter.= '</div>';*/
|
|
|
|
$parameters = array();
|
|
$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
|
|
if (empty($reshook)) {
|
|
$moreforfilter .= $hookmanager->resPrint;
|
|
} else {
|
|
$moreforfilter = $hookmanager->resPrint;
|
|
}
|
|
|
|
if (!empty($moreforfilter)) {
|
|
print '<div class="liste_titre liste_titre_bydiv centpercent">';
|
|
print $moreforfilter;
|
|
print '</div>';
|
|
}
|
|
|
|
$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
|
|
$htmlofselectarray = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')); // This also change content of $arrayfields with user setup
|
|
$selectedfields = ($mode != 'kanban' ? $htmlofselectarray : '');
|
|
$selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : '');
|
|
|
|
print '<div class="div-table-responsive">'; // You can use div-table-responsive-no-min if you don't need reserved height for your table
|
|
print '<table id="tableattributes" class="tagtable nobottomiftotal liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n";
|
|
|
|
|
|
// Fields title search
|
|
// --------------------------------------------------------------------
|
|
print '<tr class="liste_titre_filter">';
|
|
// Action column
|
|
if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
|
|
print '<td class="liste_titre center maxwidthsearch">';
|
|
$searchpicto = $form->showFilterButtons('left');
|
|
print $searchpicto;
|
|
print '</td>';
|
|
}
|
|
foreach ($object->fields as $key => $val) {
|
|
//$searchkey = empty($search[$key]) ? '' : $search[$key];
|
|
$cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']);
|
|
if ($key == 'status') {
|
|
$cssforfield .= ($cssforfield ? ' ' : '').'center';
|
|
} elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
|
|
$cssforfield .= ($cssforfield ? ' ' : '').'center';
|
|
} elseif (in_array($val['type'], array('timestamp'))) {
|
|
$cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
|
|
} 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'])) {
|
|
$cssforfield .= ($cssforfield ? ' ' : '').'right';
|
|
}
|
|
if (!empty($arrayfields['t.'.$key]['checked'])) {
|
|
print '<td class="liste_titre'.($cssforfield ? ' '.$cssforfield : '').($key == 'status' ? ' parentonrightofpage' : '').'">';
|
|
if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
|
|
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);
|
|
} elseif ((strpos($val['type'], 'integer:') === 0) || (strpos($val['type'], 'sellist:') === 0)) {
|
|
print $object->showInputField($val, $key, (isset($search[$key]) ? $search[$key] : ''), '', '', 'search_', $cssforfield.' maxwidth250', 1);
|
|
} elseif (preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
|
|
print '<div class="nowrap">';
|
|
print $form->selectDate($search[$key.'_dtstart'] ? $search[$key.'_dtstart'] : '', "search_".$key."_dtstart", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From'));
|
|
print '</div>';
|
|
print '<div class="nowrap">';
|
|
print $form->selectDate($search[$key.'_dtend'] ? $search[$key.'_dtend'] : '', "search_".$key."_dtend", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to'));
|
|
print '</div>';
|
|
} elseif ($key == 'lang') {
|
|
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
|
|
$formadmin = new FormAdmin($db);
|
|
print $formadmin->select_language((isset($search[$key]) ? $search[$key] : ''), 'search_lang', 0, array(), 1, 0, 0, 'minwidth100imp maxwidth125', 2);
|
|
} else {
|
|
print '<input type="text" class="flat maxwidth75" name="search_'.$key.'" value="'.dol_escape_htmltag(isset($search[$key]) ? $search[$key] : '').'">';
|
|
}
|
|
print '</td>';
|
|
}
|
|
}
|
|
// Extra fields
|
|
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php';
|
|
// Fields from hook
|
|
$parameters = array('arrayfields' => $arrayfields);
|
|
$reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
|
|
print $hookmanager->resPrint;
|
|
|
|
$key = 'nb_of_values';
|
|
if (!empty($arrayfields[$key]['checked'])) {
|
|
print '<td class="liste_titre center">';
|
|
print '<input type="text" class="flat maxwidth75" name="search_'.$key.'" value="'.dol_escape_htmltag(isset($search[$key]) ? $search[$key] : '').'">';
|
|
print '</td>';
|
|
}
|
|
$key = 'nb_products';
|
|
if (!empty($arrayfields[$key]['checked'])) {
|
|
print '<td class="liste_titre center">';
|
|
print '<input type="text" class="flat maxwidth75" name="search_'.$key.'" value="'.dol_escape_htmltag(isset($search[$key]) ? $search[$key] : '').'">';
|
|
print '</td>';
|
|
}
|
|
// Action column
|
|
if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
|
|
print '<td class="liste_titre center maxwidthsearch">';
|
|
$searchpicto = $form->showFilterButtons();
|
|
print $searchpicto;
|
|
print '</td>';
|
|
}
|
|
// Move
|
|
print '<td class="liste_titre linecolmove width25"></td>';
|
|
print '</tr>'."\n";
|
|
|
|
$totalarray = array();
|
|
$totalarray['nbfield'] = 0;
|
|
|
|
// Fields title label
|
|
// --------------------------------------------------------------------
|
|
print '<tr class="liste_titre">';
|
|
// Action column
|
|
if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
|
|
print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
|
|
$totalarray['nbfield']++;
|
|
}
|
|
foreach ($object->fields as $key => $val) {
|
|
$cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']);
|
|
if ($key == 'status') {
|
|
$cssforfield .= ($cssforfield ? ' ' : '').'center';
|
|
} elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
|
|
$cssforfield .= ($cssforfield ? ' ' : '').'center';
|
|
} elseif (in_array($val['type'], array('timestamp'))) {
|
|
$cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
|
|
} 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'])) {
|
|
$cssforfield .= ($cssforfield ? ' ' : '').'right';
|
|
}
|
|
$cssforfield = preg_replace('/small\s*/', '', $cssforfield); // the 'small' css must not be used for the title label
|
|
if (!empty($arrayfields['t.'.$key]['checked'])) {
|
|
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";
|
|
$totalarray['nbfield']++;
|
|
}
|
|
}
|
|
// Extra fields
|
|
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php';
|
|
// Hook fields
|
|
$parameters = array('arrayfields' => $arrayfields, 'param' => $param, 'sortfield' => $sortfield, 'sortorder' => $sortorder, 'totalarray' => &$totalarray);
|
|
$reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
|
|
print $hookmanager->resPrint;
|
|
|
|
$key = 'nb_of_values';
|
|
if (!empty($arrayfields[$key]['checked'])) {
|
|
// @phan-suppress-next-line PhanTypeInvalidDimOffset
|
|
print getTitleFieldOfList($arrayfields[$key]['label'], 0, $_SERVER['PHP_SELF'], $key, '', $param, 'class="center"', $sortfield, $sortorder, 'center ')."\n";
|
|
$totalarray['nbfield']++;
|
|
}
|
|
$key = 'nb_products';
|
|
if (!empty($arrayfields[$key]['checked'])) {
|
|
print getTitleFieldOfList($arrayfields[$key]['label'], 0, $_SERVER['PHP_SELF'], $key, '', $param, 'class="center"', $sortfield, $sortorder, 'center ')."\n";
|
|
$totalarray['nbfield']++;
|
|
}
|
|
// Action column
|
|
if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
|
|
print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
|
|
$totalarray['nbfield']++;
|
|
}
|
|
// Move
|
|
print getTitleFieldOfList('', 0, '', '', '', '', '', '', '', 'linecolmove ')."\n";
|
|
$totalarray['nbfield']++;
|
|
print '</tr>'."\n";
|
|
|
|
|
|
// Detect if we need a fetch on each output line
|
|
$needToFetchEachLine = 0;
|
|
//if (isset($extrafields->attributes[$object->table_element]['computed']) && is_array($extrafields->attributes[$object->table_element]['computed']) && count($extrafields->attributes[$object->table_element]['computed']) > 0) {
|
|
// foreach ($extrafields->attributes[$object->table_element]['computed'] as $key => $val) {
|
|
// if (!is_null($val) && preg_match('/\$object/', $val)) {
|
|
// $needToFetchEachLine++; // There is at least one compute field that use $object
|
|
// }
|
|
// }
|
|
//}
|
|
|
|
|
|
// Loop on record
|
|
// --------------------------------------------------------------------
|
|
$i = 0;
|
|
$savnbfield = $totalarray['nbfield'];
|
|
$totalarray = array();
|
|
$totalarray['nbfield'] = 0;
|
|
$imaxinloop = ($limit ? min($num, $limit) : $num);
|
|
while ($i < $imaxinloop) {
|
|
$obj = $db->fetch_object($resql);
|
|
if (empty($obj)) {
|
|
break; // Should not happen
|
|
}
|
|
|
|
// Store properties in $object
|
|
$object->setVarsFromFetchObj($obj);
|
|
|
|
if ($mode == 'kanban') {
|
|
if ($i == 0) {
|
|
print '<tr class="trkanban"><td colspan="'.$savnbfield.'">';
|
|
print '<div class="box-flex-container kanban">';
|
|
}
|
|
// Output Kanban
|
|
$selected = -1;
|
|
if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
|
|
$selected = 0;
|
|
if (in_array($object->id, $arrayofselected)) {
|
|
$selected = 1;
|
|
}
|
|
}
|
|
print $object->getKanbanView('', array('selected' => $selected));
|
|
if ($i == ($imaxinloop - 1)) {
|
|
print '</div>';
|
|
print '</td></tr>';
|
|
}
|
|
} else {
|
|
// Show line of result
|
|
$j = 0;
|
|
print '<tr data-rowid="'.$object->id.'" class="oddeven">';
|
|
// Action column
|
|
if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
|
|
print '<td class="nowrap center">';
|
|
if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
|
|
$selected = 0;
|
|
if (in_array($object->id, $arrayofselected)) {
|
|
$selected = 1;
|
|
}
|
|
print '<input id="cb'.$object->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$object->id.'"'.($selected ? ' checked="checked"' : '').'>';
|
|
}
|
|
print '</td>';
|
|
if (!$i) {
|
|
$totalarray['nbfield']++;
|
|
}
|
|
}
|
|
// Fields
|
|
foreach ($object->fields as $key => $val) {
|
|
$cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']);
|
|
if (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
|
|
$cssforfield .= ($cssforfield ? ' ' : '') . 'center';
|
|
} elseif ($key == 'status') {
|
|
$cssforfield .= ($cssforfield ? ' ' : '') . 'center';
|
|
}
|
|
|
|
if (in_array($val['type'], array('timestamp'))) {
|
|
$cssforfield .= ($cssforfield ? ' ' : '') . 'nowraponall';
|
|
} elseif ($key == 'ref') {
|
|
$cssforfield .= ($cssforfield ? ' ' : '') . 'nowraponall';
|
|
}
|
|
|
|
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'])) {
|
|
$cssforfield .= ($cssforfield ? ' ' : '') . 'right';
|
|
}
|
|
//if (in_array($key, array('fk_soc', 'fk_user', 'fk_warehouse'))) $cssforfield = 'tdoverflowmax100';
|
|
|
|
if (!empty($arrayfields['t.' . $key]['checked'])) {
|
|
print '<td'.($cssforfield ? ' class="'.$cssforfield.((preg_match('/tdoverflow/', $cssforfield) && !in_array($val['type'], array('ip', 'url')) && !is_numeric($object->$key)) ? ' classfortooltip' : '').'"' : '');
|
|
if (preg_match('/tdoverflow/', $cssforfield) && !in_array($val['type'], array('ip', 'url')) && !is_numeric($object->$key)) {
|
|
print ' title="'.dol_escape_htmltag($object->$key).'"';
|
|
}
|
|
print '>';
|
|
if ($key == 'status') {
|
|
print $object->getLibStatut(5);
|
|
} elseif ($key == 'rowid') {
|
|
print $object->showOutputField($val, $key, $object->id, '');
|
|
} else {
|
|
print $object->showOutputField($val, $key, $object->$key, '');
|
|
}
|
|
print '</td>';
|
|
if (!$i) {
|
|
$totalarray['nbfield']++;
|
|
}
|
|
if (!empty($val['isameasure']) && $val['isameasure'] == 1) {
|
|
if (!$i) {
|
|
$totalarray['pos'][$totalarray['nbfield']] = 't.' . $key;
|
|
}
|
|
if (!isset($totalarray['val'])) {
|
|
$totalarray['val'] = array();
|
|
}
|
|
if (!isset($totalarray['val']['t.' . $key])) {
|
|
$totalarray['val']['t.' . $key] = 0;
|
|
}
|
|
$totalarray['val']['t.' . $key] += $object->$key;
|
|
}
|
|
}
|
|
}
|
|
// Extra fields
|
|
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
|
|
// Fields from hook
|
|
$parameters = array('arrayfields' => $arrayfields, 'object' => $object, 'obj' => $obj, 'i' => $i, 'totalarray' => &$totalarray);
|
|
$reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
|
|
print $hookmanager->resPrint;
|
|
// Other
|
|
$key = 'nb_of_values';
|
|
if (!empty($arrayfields[$key]['checked'])) {
|
|
print '<td class="center">';
|
|
print $obj->$key;
|
|
print '</td>';
|
|
if (!$i) {
|
|
$totalarray['nbfield']++;
|
|
}
|
|
}
|
|
$key = 'nb_products';
|
|
if (!empty($arrayfields[$key]['checked'])) {
|
|
print '<td class="center">';
|
|
print $obj->$key;
|
|
print '</td>';
|
|
if (!$i) {
|
|
$totalarray['nbfield']++;
|
|
}
|
|
}
|
|
// Action column
|
|
if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
|
|
print '<td class="nowrap center">';
|
|
if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
|
|
$selected = 0;
|
|
if (in_array($object->id, $arrayofselected)) {
|
|
$selected = 1;
|
|
}
|
|
print '<input id="cb'.$object->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$object->id.'"'.($selected ? ' checked="checked"' : '').'>';
|
|
}
|
|
print '</td>';
|
|
if (!$i) {
|
|
$totalarray['nbfield']++;
|
|
}
|
|
}
|
|
// Move
|
|
print '<td class="center linecolmove tdlineupdown">';
|
|
if ($i > 0) {
|
|
print '<a class="lineupdown" href="' . $_SERVER['PHP_SELF'] . '?action=up&rowid=' . $obj->rowid . '">' . img_up('default', 0, 'imgupforline') . '</a>';
|
|
}
|
|
if ($i < $num - 1) {
|
|
print '<a class="lineupdown" href="' . $_SERVER['PHP_SELF'] . '?action=down&rowid=' . $obj->rowid . '">' . img_down('default', 0, 'imgdownforline') . '</a>';
|
|
}
|
|
print '</td>';
|
|
if (!$i) {
|
|
$totalarray['nbfield']++;
|
|
}
|
|
|
|
print '</tr>' . "\n";
|
|
}
|
|
|
|
$i++;
|
|
}
|
|
|
|
// Show total line
|
|
include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php';
|
|
|
|
// If no record found
|
|
if ($num == 0) {
|
|
$colspan = 1;
|
|
foreach ($arrayfields as $key => $val) {
|
|
if (!empty($val['checked'])) {
|
|
$colspan++;
|
|
}
|
|
}
|
|
$colspan++; // For the move column
|
|
print '<tr><td colspan="'.$colspan.'"><span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span></td></tr>';
|
|
}
|
|
|
|
$db->free($resql);
|
|
|
|
$parameters = array('arrayfields' => $arrayfields, 'sql' => $sql);
|
|
$reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
|
|
print $hookmanager->resPrint;
|
|
|
|
print '</table>'."\n";
|
|
print '</div>'."\n";
|
|
|
|
print '</form>'."\n";
|
|
|
|
$forcereloadpage = !getDolGlobalString('MAIN_FORCE_RELOAD_PAGE') ? 0 : 1;
|
|
$tagidfortablednd = (empty($tagidfortablednd) ? 'tableattributes' : $tagidfortablednd);
|
|
?>
|
|
<script>
|
|
$(document).ready(function(){
|
|
$(".imgupforline, .imgdownforline").hide();
|
|
$(".lineupdown").removeAttr('href');
|
|
$(".tdlineupdown")
|
|
.css("background-image", 'url(<?php echo DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/grip.png'; ?>)')
|
|
.css("background-repeat", "no-repeat")
|
|
.css("background-position", "center center")
|
|
.hover(
|
|
function () {
|
|
$(this).addClass('showDragHandle');
|
|
}, function () {
|
|
$(this).removeClass('showDragHandle');
|
|
}
|
|
);
|
|
|
|
$("#<?php echo $tagidfortablednd; ?>").tableDnD({
|
|
onDrop: function(table, row) {
|
|
console.log('drop');
|
|
$('#<?php echo $tagidfortablednd; ?> tr[data-element=extrafield]').attr('id', ''); // Set extrafields id to empty value in order to ignore them in tableDnDSerialize function
|
|
$('#<?php echo $tagidfortablednd; ?> tr[data-ignoreidfordnd=1]').attr('id', ''); // Set id to empty value in order to ignore them in tableDnDSerialize function
|
|
var reloadpage = "<?php echo $forcereloadpage; ?>";
|
|
var roworder = cleanSerialize(decodeURI($("#<?php echo $tagidfortablednd; ?>").tableDnDSerialize()));
|
|
$.post("<?php echo DOL_URL_ROOT; ?>/variants/ajax/orderAttribute.php",
|
|
{
|
|
roworder: roworder,
|
|
token: "<?php echo currentToken(); ?>"
|
|
},
|
|
function() {
|
|
if (reloadpage == 1) {
|
|
location.href = '<?php echo dol_escape_htmltag($_SERVER['PHP_SELF']).'?'.dol_escape_htmltag($_SERVER['QUERY_STRING']); ?>';
|
|
}
|
|
});
|
|
},
|
|
onDragClass: "dragClass",
|
|
dragHandle: "td.tdlineupdown"
|
|
});
|
|
});
|
|
</script>
|
|
<?php
|
|
|
|
if (in_array('builddoc', array_keys($arrayofmassactions)) && ($nbtotalofrecords === '' || $nbtotalofrecords)) {
|
|
$hidegeneratedfilelistifempty = 1;
|
|
if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) {
|
|
$hidegeneratedfilelistifempty = 0;
|
|
}
|
|
|
|
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
|
|
$formfile = new FormFile($db);
|
|
|
|
// Show list of available documents
|
|
$urlsource = $_SERVER['PHP_SELF'].'?sortfield='.$sortfield.'&sortorder='.$sortorder;
|
|
$urlsource .= str_replace('&', '&', $param);
|
|
|
|
$filedir = $diroutputmassaction;
|
|
$genallowed = $permissiontoread;
|
|
$delallowed = $permissiontoadd;
|
|
|
|
print $formfile->showdocuments('massfilesarea_productattribute', '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty);
|
|
}
|
|
|
|
// End of page
|
|
llxFooter();
|
|
$db->close();
|