* Copyright (C) 2016 Christophe Battarel * Copyright (C) 2018 Regis Houssin * Copyright (C) 2019-2021 Juanjo Menent * Copyright (C) 2019-2020 Laurent Destailleur * Copyright (C) 2023 Charlene Benke * Copyright (C) 2024 MDW * Copyright (C) 2024 Benjamin Falière * Copyright (C) 2024 Frédéric France * * 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 . */ /** * \file htdocs/ticket/list.php * \ingroup ticket * \brief List page for tickets */ // Load Dolibarr environment require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/ticket/class/actions_ticket.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formticket.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php'; include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; include_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; include_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php'; // Load translation files required by the page $langs->loadLangs(array("ticket", "companies", "other", "projects", "contracts")); // Get parameters $action = GETPOST('action', 'aZ09') ? GETPOST('action', 'aZ09') : 'view'; // The action 'add', 'create', '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'); // Array of ids of elements selected into a list $contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'ticketlist'; // 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', 'alpha'); $id = GETPOSTINT('id'); $msg_id = GETPOSTINT('msg_id'); $socid = GETPOSTINT('socid'); $contractid = GETPOSTINT('contractid'); $projectid = GETPOSTINT('projectid'); $project_ref = GETPOST('project_ref', 'alpha'); $search_societe = GETPOST('search_societe', 'alpha'); $search_fk_project = GETPOSTINT('search_fk_project') ? GETPOSTINT('search_fk_project') : GETPOSTINT('projectid'); $search_fk_contract = GETPOSTINT('search_fk_contract') ? GETPOSTINT('search_fk_contract') : GETPOSTINT('contractid'); $search_date_start = dol_mktime(0, 0, 0, GETPOSTINT('search_date_startmonth'), GETPOSTINT('search_date_startday'), GETPOSTINT('search_date_startyear')); $search_date_end = dol_mktime(23, 59, 59, GETPOSTINT('search_date_endmonth'), GETPOSTINT('search_date_endday'), GETPOSTINT('search_date_endyear')); $search_dateread_start = dol_mktime(0, 0, 0, GETPOSTINT('search_dateread_startmonth'), GETPOSTINT('search_dateread_startday'), GETPOSTINT('search_dateread_startyear')); $search_dateread_end = dol_mktime(23, 59, 59, GETPOSTINT('search_dateread_endmonth'), GETPOSTINT('search_dateread_endday'), GETPOSTINT('search_dateread_endyear')); $search_dateclose_start = dol_mktime(0, 0, 0, GETPOSTINT('search_dateclose_startmonth'), GETPOSTINT('search_dateclose_startday'), GETPOSTINT('search_dateclose_startyear')); $search_dateclose_end = dol_mktime(23, 59, 59, GETPOSTINT('search_dateclose_endmonth'), GETPOSTINT('search_dateclose_endday'), GETPOSTINT('search_dateclose_endyear')); // 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 Ticket($db); $extrafields = new ExtraFields($db); $diroutputmassaction = $conf->ticket->dir_output.'/temp/massgeneration/'.$user->id; if ($socid > 0) { $hookmanager->initHooks(array('thirdpartyticket', 'globalcard')); } elseif ($projectid > 0) { $hookmanager->initHooks(array('projectticket', 'globalcard')); } else { $hookmanager->initHooks(array('ticketlist')); } // 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.datec"; } if (!$sortorder) { $sortorder = "DESC"; } /*if (GETPOST('search_fk_status', 'alpha') == 'non_closed') { $_GET['search_fk_statut'][] = 'openall'; // For backward compatibility }*/ // Initialize array of search criteria $search_all = (GETPOSTISSET("search_all") ? GETPOST("search_all", 'alpha') : GETPOST('sall')); $search = array(); foreach ($object->fields as $key => $val) { if (GETPOST('search_'.$key, 'alpha') !== '') { $search[$key] = GETPOST('search_'.$key, 'alpha'); } else { $search[$key] = ""; } 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')); } } // List of fields to search into when doing a "search in all" $fieldstosearchall = array(); foreach ($object->fields as $key => $val) { if (!empty($val['searchall'])) { $fieldstosearchall['t.'.$key] = $val['label']; } } $fieldstosearchall['s.name_alias'] = "AliasNameShort"; $fieldstosearchall['s.zip'] = "Zip"; $fieldstosearchall['s.town'] = "Town"; // 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'] : '' ); } } // 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'); // Security check if (!$user->hasRight('ticket', 'read')) { accessforbidden(); } // restrict view to current user's company if ($user->socid > 0) { $socid = $user->socid; } // Store current page url $url_page_current = DOL_URL_ROOT.'/ticket/list.php'; if ($project_ref) { $tmpproject = new Project($db); $tmpproject->fetch(0, $project_ref); $projectid = $tmpproject->id; $search_fk_project = $projectid; } $permissiontoread = $user->hasRight('ticket', 'read'); $permissiontoadd = $user->hasRight('ticket', 'write'); $permissiontodelete = $user->hasRight('ticket', 'delete'); $error = 0; /* * Actions */ if (GETPOST('cancel', 'alpha')) { $action = 'list'; $massaction = ''; } if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend' && $massaction != 'presendonclose' && $massaction != 'close') { $massaction = ''; } $parameters = array('arrayfields' => &$arrayfields); if ($socid > 0) { $parameters['socid'] = $socid; } if ($projectid > 0) { $parameters['projectid'] = $projectid; } $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'] = ''; } } $toselect = array(); $search_array_options = array(); $search_date_start = ''; $search_date_end = ''; $search_dateread_start = ''; $search_dateread_end = ''; $search_dateclose_start = ''; $search_dateclose_end = ''; } 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 } // Mass actions $objectclass = 'Ticket'; $objectlabel = 'Ticket'; $uploaddir = $conf->ticket->dir_output; include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; // Close records if (!$error && $massaction == 'close' && $permissiontoadd) { $objecttmp = new $objectclass($db); if (!$error) { $db->begin(); $nbok = 0; foreach ($toselect as $toselectid) { $result = $objecttmp->fetch($toselectid); if ($result > 0) { $result = $objecttmp->close($user); if ($result < 0) { setEventMessages($objecttmp->error, $objecttmp->errors, 'errors'); $error++; break; } else { $nbok++; } } else { setEventMessages($objecttmp->error, $objecttmp->errors, 'errors'); $error++; break; } } if (!$error) { setEventMessages($langs->trans("RecordsModified", $nbok), null, 'mesgs'); $db->commit(); } else { $db->rollback(); } //var_dump($listofobjectthirdparties);exit; } } // Reopen records if (!$error && $massaction == 'reopen' && $permissiontoadd) { $objecttmp = new $objectclass($db); if (!$error) { $db->begin(); $nbok = 0; foreach ($toselect as $toselectid) { $result = $objecttmp->fetch($toselectid); if ($result > 0) { if ($objecttmp->status == Ticket::STATUS_CLOSED || $objecttmp->status == Ticket::STATUS_CANCELED) { $result = $objecttmp->setStatut(Ticket::STATUS_ASSIGNED); if ($result < 0) { setEventMessages($objecttmp->error, $objecttmp->errors, 'errors'); $error++; break; } else { $nbok++; } } else { $langs->load("errors"); setEventMessages($langs->trans("ErrorObjectMustHaveStatusClosedToBeReOpened", $objecttmp->ref), null, 'errors'); $error++; break; } } else { setEventMessages($objecttmp->error, $objecttmp->errors, 'errors'); $error++; break; } } if (!$error) { setEventMessages($langs->trans("RecordsModified", $nbok), null, 'mesgs'); $db->commit(); } else { $db->rollback(); } //var_dump($listofobjectthirdparties);exit; } } } /* * View */ $form = new Form($db); $formTicket = new FormTicket($db); $now = dol_now(); $user_temp = new User($db); $socstatic = new Societe($db); $help_url = ''; $moretitle = ''; if ($socid > 0) { $socstatic->fetch($socid); $moretitle = $langs->trans("ThirdParty") . ' - '; if (getDolGlobalString('MAIN_HTML_TITLE') && preg_match('/thirdpartynameonly/', $conf->global->MAIN_HTML_TITLE) && $socstatic->name) { $moretitle = $socstatic->name . ' - '; } } $title = $moretitle . $langs->trans('Tickets'); $morejs = array(); $morecss = array(); // Build and execute select // -------------------------------------------------------------------- $sql = 'SELECT '; $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)"; } // Add table from hooks $parameters = array(); $reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON (t.fk_soc = s.rowid)"; $sql .= " WHERE t.entity IN (".getEntity($object->element).")"; if ($socid > 0) { $sql .= " AND t.fk_soc = ".((int) $socid); } foreach ($search as $key => $val) { if ($key == 'fk_statut' && !empty($search['fk_statut'])) { $newarrayofstatus = array(); foreach ($search['fk_statut'] as $key2 => $val2) { if (in_array($val2, array('openall', 'closeall'))) { continue; } $newarrayofstatus[] = $val2; } if ($search['fk_statut'] == 'openall' || in_array('openall', $search['fk_statut'])) { $newarrayofstatus[] = Ticket::STATUS_NOT_READ; $newarrayofstatus[] = Ticket::STATUS_READ; $newarrayofstatus[] = Ticket::STATUS_ASSIGNED; $newarrayofstatus[] = Ticket::STATUS_IN_PROGRESS; $newarrayofstatus[] = Ticket::STATUS_NEED_MORE_INFO; $newarrayofstatus[] = Ticket::STATUS_WAITING; } if ($search['fk_statut'] == 'closeall' || in_array('closeall', $search['fk_statut'])) { $newarrayofstatus[] = Ticket::STATUS_CLOSED; $newarrayofstatus[] = Ticket::STATUS_CANCELED; } if (count($newarrayofstatus)) { $sql .= natural_search($key, implode(',', $newarrayofstatus), 2); } continue; } elseif ($key == 'fk_user_assign' || $key == 'fk_user_create' || $key == 'fk_project' || $key == 'fk_contract') { if ($search[$key] > 0) { $sql .= natural_search($key, $search[$key], 2); } continue; } elseif ($key == 'type_code') { $newarrayoftypecodes = is_array($search[$key]) ? $search[$key] : (!empty($search[$key]) ? explode(',', $search[$key]) : array()); if (count($newarrayoftypecodes)) { $sql .= natural_search($key, implode(',', $newarrayoftypecodes), 3); } continue; } $mode_search = ((!empty($object->fields[$key]) && ($object->isInt($object->fields[$key]) || $object->isFloat($object->fields[$key]))) ? 1 : 0); // $search[$key] can be an array of values, or a string. We add filter if array not empty or if it is a string. if ((is_array($search[$key]) && !empty($search[$key])) || (!is_array($search[$key]) && $search[$key] != '')) { $sql .= natural_search($key, $search[$key], $mode_search); } } if ($search_all) { $sql .= natural_search(array_keys($fieldstosearchall), $search_all); } if ($search_societe) { $sql .= natural_search('s.nom', $search_societe); } if ($search_fk_project > 0) { $sql .= natural_search('fk_project', (string) $search_fk_project, 2); } if ($search_fk_contract > 0) { $sql .= natural_search('fk_contract', (string) $search_fk_contract, 2); } if ($search_date_start) { $sql .= " AND t.datec >= '".$db->idate($search_date_start)."'"; } if ($search_date_end) { $sql .= " AND t.datec <= '".$db->idate($search_date_end)."'"; } if ($search_dateread_start) { $sql .= " AND t.date_read >= '".$db->idate($search_dateread_start)."'"; } if ($search_dateread_end) { $sql .= " AND t.date_read <= '".$db->idate($search_dateread_end)."'"; } if ($search_dateclose_start) { $sql .= " AND t.date_close >= '".$db->idate($search_dateclose_start)."'"; } if ($search_dateclose_end) { $sql .= " AND t.date_close <= '".$db->idate($search_dateclose_end)."'"; } if (!$user->socid && ($mode == "mine" || (!$user->admin && getDolGlobalString('TICKET_LIMIT_VIEW_ASSIGNED_ONLY')))) { $sql .= " AND (t.fk_user_assign = ".((int) $user->id); if (!getDolGlobalString('TICKET_LIMIT_VIEW_ASSIGNED_ONLY')) { $sql .= " OR t.fk_user_create = ".((int) $user->id); } $sql .= ")"; } // 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); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; // Count total nb of records $nbtotalofrecords = ''; if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) { /* 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) { $objforcount = $db->fetch_object($resql); $nbtotalofrecords = $objforcount->nbtotalofrecords; } else { dol_print_error($db); } 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 && getDolGlobalString('MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE') && $search_all && !$page) { $obj = $db->fetch_object($resql); $id = $obj->rowid; header("Location: ".DOL_URL_ROOT.'/ticket/card.php?id='.$id); exit; } // Output page // -------------------------------------------------------------------- llxHeader('', $title, $help_url, '', 0, 0, $morejs, $morecss, '', 'mod-ticket page-list bodyforlist'); if ($socid && !$projectid && !$project_ref && $user->hasRight('societe', 'lire')) { $socstat = new Societe($db); $res = $socstat->fetch($socid); if ($res > 0) { $tmpobject = $object; $object = $socstat; // $object must be of type Societe when calling societe_prepare_head $head = societe_prepare_head($socstat); $object = $tmpobject; print dol_get_fiche_head($head, 'ticket', $langs->trans("ThirdParty"), -1, 'company'); dol_banner_tab($socstat, 'socid', '', ($user->socid ? 0 : 1), 'rowid', 'nom'); print '
'; print '
'; print ''; // Type Prospect/Customer/Supplier print ''; // Customer code if ($socstat->client && !empty($socstat->code_client)) { print ''; print ''; } // Supplier code if ($socstat->fournisseur && !empty($socstat->code_fournisseur)) { print ''; print ''; } print '
'.$langs->trans('NatureOfThirdParty').''; print $socstat->getTypeUrl(1); print '
'; print $langs->trans('CustomerCode').''; print showValueWithClipboardCPButton(dol_escape_htmltag($socstat->code_client)); $tmpcheck = $socstat->check_codeclient(); if ($tmpcheck != 0 && $tmpcheck != -5) { print ' ('.$langs->trans("WrongCustomerCode").')'; } print '
'; print $langs->trans('SupplierCode').''; print showValueWithClipboardCPButton(dol_escape_htmltag($socstat->code_fournisseur)); $tmpcheck = $socstat->check_codefournisseur(); if ($tmpcheck != 0 && $tmpcheck != -5) { print ' ('.$langs->trans("WrongSupplierCode").')'; } print '
'; print '
'; print dol_get_fiche_end(); print '
'; } } if ($projectid > 0 || $project_ref) { $projectstat = new Project($db); if ($projectstat->fetch($projectid, $project_ref) > 0) { $projectid = $projectstat->id; $projectstat->fetch_thirdparty(); $savobject = $object; $object = $projectstat; // To verify role of users //$userAccess = $object->restrictedProjectArea($user,'read'); $userWrite = $projectstat->restrictedProjectArea($user, 'write'); //$userDelete = $object->restrictedProjectArea($user,'delete'); //print "userAccess=".$userAccess." userWrite=".$userWrite." userDelete=".$userDelete; $head = project_prepare_head($projectstat); print dol_get_fiche_head($head, 'ticket', $langs->trans("Project"), -1, ($projectstat->public ? 'projectpub' : 'project')); // Project card $linkback = ''.$langs->trans("BackToList").''; $morehtmlref = '
'; // Title $morehtmlref .= $object->title; // Thirdparty if (!empty($object->thirdparty->id) && $object->thirdparty->id > 0) { $morehtmlref .= '
'.$object->thirdparty->getNomUrl(1, 'project'); } $morehtmlref .= '
'; // Define a complementary filter for search of next/prev ref. if (!$user->hasRight('projet', 'all', 'lire')) { $objectsListId = $object->getProjectsAuthorizedForUser($user, 0, 0); $object->next_prev_filter = "rowid IN (".$db->sanitize(count($objectsListId) ? implode(',', array_keys($objectsListId)) : '0').")"; } dol_banner_tab($object, 'project_ref', $linkback, 1, 'ref', 'ref', $morehtmlref); print '
'; print '
'; print ''; // Visibility print ''; print "
'.$langs->trans("Visibility").''; if ($projectstat->public) { print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"'); print $langs->trans('SharedProject'); } else { print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"'); print $langs->trans('PrivateProject'); } print '
"; print '
'; print dol_get_fiche_end(); print '
'; $object = $savobject; } else { print "ErrorRecordNotFound"; } } $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); } 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]); } } if ($optioncss != '') { $param .= '&optioncss='.urlencode($optioncss); } // 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); // Note that $action and $object may have been modified by hook $param .= $hookmanager->resPrint; if ($socid > 0) { $param .= '&socid='.urlencode((string) ($socid)); } if ($search_societe) { $param .= '&search_societe='.urlencode($search_societe); } if ($projectid > 0) { $param .= '&projectid='.urlencode((string) ($projectid)); } if ($contractid > 0) { $param .= '&contractid='.urlencode((string) ($contractid)); } if ($search_date_start) { $tmparray = dol_getdate($search_date_start); $param .= '&search_date_startday='.((int) $tmparray['mday']); $param .= '&search_date_startmonth='.((int) $tmparray['mon']); $param .= '&search_date_startyear='.((int) $tmparray['year']); } if ($search_date_end) { $tmparray = dol_getdate($search_date_end); $param .= '&search_date_endday='.((int) $tmparray['mday']); $param .= '&search_date_endmonth='.((int) $tmparray['mon']); $param .= '&search_date_endyear='.((int) $tmparray['year']); } if ($search_dateread_start) { $tmparray = dol_getdate($search_dateread_start); $param .= '&search_dateread_startday='.((int) $tmparray['mday']); $param .= '&search_dateread_startmonth='.((int) $tmparray['mon']); $param .= '&search_dateread_startyear='.((int) $tmparray['year']); } if ($search_dateread_end) { $tmparray = dol_getdate($search_dateread_end); $param .= '&search_dateread_endday='.((int) $tmparray['mday']); $param .= '&search_dateread_endmonth='.((int) $tmparray['mon']); $param .= '&search_dateread_endyear='.((int) $tmparray['year']); } if ($search_dateclose_start) { $tmparray = dol_getdate($search_dateclose_start); $param .= '&search_dateclose_startday='.((int) $tmparray['mday']); $param .= '&search_dateclose_startmonth='.((int) $tmparray['mon']); $param .= '&search_dateclose_startyear='.((int) $tmparray['year']); } if ($search_dateclose_end) { $tmparray = dol_getdate($search_dateclose_end); $param .= '&search_date_endday='.((int) $tmparray['mday']); $param .= '&search_date_endmonth='.((int) $tmparray['mon']); $param .= '&search_date_endyear='.((int) $tmparray['year']); } // List of mass actions available $arrayofmassactions = array( //'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"), //'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"), ); if ($permissiontoadd) { $arrayofmassactions['presendonclose'] = img_picto('', 'close_title', 'class="pictofixedwidth"').$langs->trans("Close"); $arrayofmassactions['reopen'] = img_picto('', 'folder-open', 'class="pictofixedwidth"').$langs->trans("ReOpen"); } if ($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 '
'."\n"; if ($optioncss != '') { print ''; } print ''; print ''; print ''; print ''; print ''; print ''; print ''; if ($socid) { print ''; } if ($projectid) { print ''; } $url = DOL_URL_ROOT.'/ticket/card.php?action=create'.($socid ? '&socid='.$socid : '').($projectid ? '&origin=projet_project&originid='.$projectid : ''); if (!empty($socid)) { $url .= '&socid='.$socid; } $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('NewTicket'), '', 'fa fa-plus-circle', $url, '', $user->hasRight('ticket', 'write')); $picto = 'ticket'; if ($socid > 0) { $picto = ''; } print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, $picto, 0, $newcardbutton, '', $limit, 0, 0, 1); if ($mode == 'mine') { print '
'.$langs->trans('TicketAssignedToMeInfos').'

'; } // Add code for pre mass action (confirmation or email presend form) $topicmail = "SendTicketRef"; $modelmail = "ticket"; $objecttmp = new Ticket($db); $trackid = 'tic'.$object->id; include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php'; // confirm auto send on close if ($massaction == 'presendonclose') { $hidden_form = array([ "type" => "hidden", "name" => "massaction", "value" => "close" ]); $selectedchoice = getDolGlobalString('TICKET_NOTIFY_AT_CLOSING') ? "yes" : "no"; print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmMassTicketClosingSendEmail"), $langs->trans("ConfirmMassTicketClosingSendEmailQuestion"), 'confirm_send_close', $hidden_form, $selectedchoice, 0, 200, 500, 1); } if ($search_all) { $setupstring = ''; foreach ($fieldstosearchall as $key => $val) { $fieldstosearchall[$key] = $langs->trans($val); $setupstring .= $key."=".$val.";"; } print ''."\n"; print '
'.$langs->trans("FilterOnInto", $search_all).implode(', ', $fieldstosearchall).'
'."\n"; } $moreforfilter = ''; /*$moreforfilter.='
'; $moreforfilter.= $langs->trans('MyFilter') . ': '; $moreforfilter.= '
';*/ $parameters = array(); $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object); // 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 '
'; print $moreforfilter; print '
'; } $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage; $selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')); // This also change content of $arrayfields $selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : ''); print '
'; // You can use div-table-responsive-no-min if you don't need reserved height for your table print '
'; print ''."\n"; // Fields title search // -------------------------------------------------------------------- print ''; // Action column if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { print ''; } 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 == 'fk_statut') { $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'])) { if ($key == 'progress') { print ''; } elseif ($key == 'type_code') { print ''; } elseif ($key == 'category_code') { print ''; } elseif ($key == 'severity_code') { print ''; } elseif ($key == 'fk_user_assign' || $key == 'fk_user_create') { print ''; } elseif ($key == 'fk_statut') { $arrayofstatus = array(); $arrayofstatus['openall'] = '-- '.$langs->trans('OpenAll').' --'; foreach ($object->labelStatusShort as $key2 => $val2) { if ($key2 == Ticket::STATUS_CLOSED) { $arrayofstatus['closeall'] = '-- '.$langs->trans('ClosedAll').' --'; } $arrayofstatus[$key2] = $val2; } print ''; } elseif ($key == "fk_soc") { print ''; } elseif ($key == "datec" || $key == 'date_read' || $key == 'date_close') { print ''; } else { print ''; } } } // 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; // Action column if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { print ''; } print ''."\n"; $totalarray = array(); $totalarray['nbfield'] = 0; // Fields title label // -------------------------------------------------------------------- print ''; if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { print getTitleFieldOfList(($mode != 'kanban' ? $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 == 'fk_statut' || $key == 'severity_code') { $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; if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { print getTitleFieldOfList(($mode != 'kanban' ? $selectedfields : ''), 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n"; $totalarray['nbfield']++; } print ''."\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); $cacheofoutputfield = array(); while ($i < $imaxinloop) { $obj = $db->fetch_object($resql); if (empty($obj)) { break; // Should not happen } // Store properties in $object $object->setVarsFromFetchObj($obj); $object->type_code = $obj->type_code; $object->status = $object->fk_statut; // because field name is fk_statut if ($mode == 'kanban') { if ($i == 0) { print ''; } } else { // Show line of result $j = 0; print ''; // Action column if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { print ''; 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'; } if (in_array($val['type'], array('timestamp'))) { $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; } if (in_array($key, array('ref', 'fk_project'))) { $cssforfield .= ($cssforfield ? ' ' : '').'nowraponall'; } if ($key == 'fk_statut' || $key == 'severity_code') { $cssforfield .= ($cssforfield ? ' ' : '').'center'; } if (!empty($arrayfields['t.'.$key]['checked'])) { print '$key)) { print ' title="'.dol_escape_htmltag($object->$key).'"'; } print '>'; if ($key == 'fk_statut') { print $object->getLibStatut(5); } elseif ($key == 'subject') { $s = $obj->subject; print ''; print dol_escape_htmltag($s); print ''; } elseif ($key == 'type_code') { $s = $langs->getLabelFromKey($db, 'TicketTypeShort'.$object->type_code, 'c_ticket_type', 'code', 'label', $object->type_code); print ''; print $s; print ''; } elseif ($key == 'category_code') { $s = $langs->getLabelFromKey($db, 'TicketCategoryShort'.$object->category_code, 'c_ticket_category', 'code', 'label', $object->category_code); print ''; print $s; print ''; } elseif ($key == 'severity_code') { $s = $langs->getLabelFromKey($db, 'TicketSeverityShort'.$object->severity_code, 'c_ticket_severity', 'code', 'label', $object->severity_code); print ''; print $s; print ''; } elseif ($key == 'tms') { print dol_print_date($db->jdate($obj->$key), 'dayhour', 'tzuser'); } elseif ($key == 'fk_user_create') { if ($object->fk_user_create > 0) { if (isset($conf->cache['user'][$object->fk_user_create])) { $user_temp = $conf->cache['user'][$object->fk_user_create]; } else { $user_temp = new User($db); $user_temp->fetch($object->fk_user_create); $conf->cache['user'][$object->fk_user_create] = $user_temp; } print $user_temp->getNomUrl(-1); } } elseif ($key == 'fk_user_assign') { if ($object->fk_user_assign > 0) { if (isset($conf->cache['user'][$object->fk_user_assign])) { $user_temp = $conf->cache['user'][$object->fk_user_assign]; } else { $user_temp = new User($db); $user_temp->fetch($object->fk_user_assign); $conf->cache['user'][$object->fk_user_assign] = $user_temp; } print $user_temp->getNomUrl(-1); } } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) { print $object->showOutputField($val, $key, $db->jdate($obj->$key), ''); } elseif ($key == 'ref') { print $object->showOutputField($val, $key, $obj->$key, ''); // display a warning on untreated tickets $is_open = ($object->status != Ticket::STATUS_CLOSED && $object->status != Ticket::STATUS_CANCELED); $should_show_warning = (getDolGlobalString('TICKET_DELAY_SINCE_LAST_RESPONSE') || getDolGlobalString('TICKET_DELAY_BEFORE_FIRST_RESPONSE')); if ($is_open && $should_show_warning) { $date_last_msg_sent = (int) $object->date_last_msg_sent; $hour_diff = ($now - $date_last_msg_sent) / 3600 ; if (getDolGlobalString('TICKET_DELAY_BEFORE_FIRST_RESPONSE') && $date_last_msg_sent == 0) { $creation_date = $object->datec; $hour_diff_creation = ($now - $creation_date) / 3600 ; if ($hour_diff_creation > getDolGlobalInt('TICKET_DELAY_BEFORE_FIRST_RESPONSE')) { print " " . img_picto($langs->trans('Late') . ' : ' . $langs->trans('TicketsDelayForFirstResponseTooLong', getDolGlobalString('TICKET_DELAY_BEFORE_FIRST_RESPONSE')), 'warning', 'style="color: red;"', false, 0, 0, '', ''); } } elseif (getDolGlobalString('TICKET_DELAY_SINCE_LAST_RESPONSE') && $hour_diff > getDolGlobalInt('TICKET_DELAY_SINCE_LAST_RESPONSE')) { print " " . img_picto($langs->trans('Late') . ' : ' . $langs->trans('TicketsDelayFromLastResponseTooLong', getDolGlobalString('TICKET_DELAY_SINCE_LAST_RESPONSE')), 'warning'); } } } else { // Example: key=fk_soc, obj->key=123 val=array('type'=>'integer', ... $tmp = explode(':', $val['type']); if ($tmp[0] == 'integer' && !empty($tmp[1]) && class_exists($tmp[1])) { // It is a type of an foreign field. We will try to reduce the number of fetch that the showOutputField is making. //var_dump('eeee-'.$key.'-'.$obj->$key.'-'.$val['type']); if ($key && $obj->$key && $val['type'] && array_key_exists($key.'-'.$obj->$key.'-'.$val['type'], $cacheofoutputfield)) { $result = $cacheofoutputfield[$key.'-'.$obj->$key.'-'.$val['type']]; } else { $result = $object->showOutputField($val, $key, $obj->$key, ''); $cacheofoutputfield[$key.'-'.$obj->$key.'-'.$val['type']] = $result; } } else { $result = $object->showOutputField($val, $key, $obj->$key, ''); } print $result; } print ''; 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; // Action column if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { print ''; if (!$i) { $totalarray['nbfield']++; } } print ''."\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++; } } print ''; } $db->free($resql); $parameters = array('arrayfields' => $arrayfields, 'sql' => $sql); $reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; print '
'; $searchpicto = $form->showFilterButtons('left'); print $searchpicto; print ''; print ''; print ''; $formTicket->selectTypesTickets(empty($search[$key]) ? '' : $search[$key], 'search_'.$key, '', 2, 1, 1, 0, (!empty($val['css']) ? $val['css'] : 'maxwidth150'), 1); print ''; $formTicket->selectGroupTickets(dol_escape_htmltag(empty($search[$key]) ? '' : $search[$key]), 'search_'.$key, '', 2, 1, 1, 0, (!empty($val['css']) ? $val['css'] : 'maxwidth150')); print ''; $formTicket->selectSeveritiesTickets(dol_escape_htmltag(empty($search[$key]) ? '' : $search[$key]), 'search_'.$key, '', 2, 1, 1, 0, (!empty($val['css']) ? $val['css'] : 'maxwidth150')); print ''; print $form->select_dolusers((empty($search[$key]) ? '' : $search[$key]), 'search_'.$key, 1, null, 0, '', '', '0', 0, 0, '', 0, '', (!empty($val['css']) ? $val['css'] : 'maxwidth100')); print ''; //var_dump($arrayofstatus); //var_dump($search['fk_statut']); //var_dump(array_values($search[$key])); $selectedarray = null; if (!empty($search[$key])) { $selectedarray = array_values($search[$key]); } print Form::multiselectarray('search_fk_statut', $arrayofstatus, $selectedarray, 0, 0, 'search_status width150 onrightofpage', 1, 0, '', '', ''); print ''; print '
'; switch ($key) { case 'datec': print $form->selectDate($search_date_start ?: -1, 'search_date_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From")); break; case 'date_read': print $form->selectDate($search_dateread_start ?: -1, 'search_dateread_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From")); break; case 'date_close': print $form->selectDate($search_dateclose_start ?: -1, 'search_dateclose_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From")); } print '
'; print '
'; switch ($key) { case 'datec': print $form->selectDate($search_date_end ?: -1, 'search_date_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to")); break; case 'date_read': print $form->selectDate($search_dateread_end ?: -1, 'search_dateread_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to")); break; case 'date_close': print $form->selectDate($search_dateclose_end ?: -1, 'search_dateclose_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to")); } print '
'; print '
'; if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) { print $form->selectarray('search_'.$key, $val['arrayofkeyval'], $search[$key], $val['notnull'], 0, 0, '', 1, 0, 0, '', 'maxwidth100', 1); } elseif (strpos($val['type'], 'integer:') === 0) { print $object->showInputField($val, $key, !empty($search[$key]) ? $search[$key] : "", '', '', 'search_', 'maxwidth150', 1); } elseif (!preg_match('/^(date|timestamp)/', $val['type'])) { print ''; } print ''; $searchpicto = $form->showFilterButtons(); print $searchpicto; print '
'; print '
'; } // get infos needed from object // TODO Create a cache on users $arraydata = array(); if ($obj->fk_user_assign > 0) { $user_temp->fetch($obj->fk_user_assign); $arraydata['user_assignment'] = $user_temp->getNomUrl(-3); } $arraydata['selected'] = in_array($object->id, $arrayofselected); // Output Kanban print $object->getKanbanView('', $arraydata); if ($i == ($imaxinloop - 1)) { print '
'; print '
'; 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 ''; } print ''; 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 ''; } print '
'.$langs->trans("NoRecordFound").'
'."\n"; print '
'."\n"; print '
'."\n"; // end div-responsive-inside print '
'."\n"; 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_ticket', '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty); } // End of page llxFooter(); $db->close();