Skip to content

Commit 4f075fc

Browse files
authored
Merge pull request #6691 from yverhenne/improve-search-and-export-ticket
improve search and export ticket
2 parents 9f14265 + 557bb4c commit 4f075fc

File tree

2 files changed

+154
-76
lines changed

2 files changed

+154
-76
lines changed

main/inc/lib/TicketManager.php

Lines changed: 103 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ public static function getUsersInCategory($categoryId)
242242
return Database::store_result($result);
243243
}
244244

245-
/**
245+
/**
246246
* Returns the list of category IDs assigned to a user.
247247
*
248248
* @param int $userId
@@ -355,14 +355,37 @@ public static function add(
355355
$course_id = (int) $course_id;
356356
$category_id = (int) $category_id;
357357
$project_id = (int) $project_id;
358-
$priority = empty($priority) ? self::PRIORITY_NORMAL : (int) $priority;
359358

360-
if ($status === '') {
361-
$status = self::STATUS_NEW;
359+
// Resolve priority to numeric ID (accepts ID or code like 'NRM')
360+
$priorityId = null;
361+
$priorityCodeOrId = $priority;
362+
if (empty($priorityCodeOrId)) {
363+
$priorityCodeOrId = self::PRIORITY_NORMAL;
364+
}
365+
if (is_numeric($priorityCodeOrId)) {
366+
$priorityId = (int) $priorityCodeOrId;
367+
} else {
368+
$priorityId = self::getPriorityIdFromCode((string) $priorityCodeOrId);
369+
}
370+
if (empty($priorityId)) {
371+
// Fallback to default priority if mapping failed
372+
$priorityId = self::getPriorityIdFromCode(self::PRIORITY_NORMAL);
373+
}
374+
375+
// Resolve status to numeric ID (accepts ID or code like 'NAT')
376+
$statusId = null;
377+
$statusCodeOrId = $status;
378+
if ($statusCodeOrId === '' || $statusCodeOrId === null) {
379+
$statusCodeOrId = self::STATUS_NEW;
362380
if ($other_area > 0) {
363-
$status = self::STATUS_FORWARDED;
381+
$statusCodeOrId = self::STATUS_FORWARDED;
364382
}
365383
}
384+
if (is_numeric($statusCodeOrId)) {
385+
$statusId = (int) $statusCodeOrId;
386+
} else {
387+
$statusId = self::getStatusIdFromCode((string) $statusCodeOrId);
388+
}
366389

367390
if (!empty($category_id)) {
368391
if (empty($assignedUserId)) {
@@ -388,9 +411,9 @@ public static function add(
388411
$params = [
389412
'project_id' => $project_id,
390413
'category_id' => $category_id,
391-
'priority_id' => $priority,
414+
'priority_id' => $priorityId,
392415
'personal_email' => $personalEmail,
393-
'status_id' => $status,
416+
'status_id' => $statusId,
394417
'start_date' => $now,
395418
'sys_insert_user_id' => $currentUserId,
396419
'sys_insert_datetime' => $now,
@@ -935,7 +958,7 @@ public static function getTicketsByCurrentUser(
935958

936959
// Check if a role was set to the project
937960
if ($userIsAllowInProject == false) {
938-
$categoryList = self::getCategoryIdsByUser($userId, $projectId);
961+
$categoryList = self::getCategoryIdsByUser($userId, $projectId);
939962
$categoryCondition = '';
940963
if (!empty($categoryList)) {
941964
$categoryIds = implode(',', array_map('intval', $categoryList));
@@ -945,6 +968,7 @@ public static function getTicketsByCurrentUser(
945968
$sql .= " AND (ticket.assigned_last_user = $userId OR ticket.sys_insert_user_id = $userId".$categoryCondition.")";
946969
}
947970

971+
948972
// Search simple
949973
if (isset($_GET['submit_simple']) && $_GET['keyword'] != '') {
950974
$keyword = Database::escape_string(trim($_GET['keyword']));
@@ -1112,65 +1136,54 @@ public static function getTotalTicketsCurrentUser()
11121136
if (empty($userInfo)) {
11131137
return 0;
11141138
}
1115-
$userId = $userInfo['id'];
1139+
$userId = (int) $userInfo['id'];
11161140

11171141
if (!isset($_GET['project_id'])) {
11181142
return 0;
11191143
}
11201144

1121-
$sql = "SELECT COUNT(ticket.id) AS total
1145+
$sql = "SELECT COUNT(DISTINCT ticket.id) AS total
11221146
FROM $table_support_tickets ticket
11231147
INNER JOIN $table_support_category cat
1124-
ON (cat.id = ticket.category_id)
1148+
ON (cat.id = ticket.category_id)
11251149
INNER JOIN $table_support_priority priority
1126-
ON (ticket.priority_id = priority.id)
1150+
ON (ticket.priority_id = priority.id)
11271151
INNER JOIN $table_support_status status
1128-
ON (ticket.status_id = status.id)
1129-
WHERE 1 = 1";
1152+
ON (ticket.status_id = status.id)
1153+
WHERE 1 = 1";
11301154

11311155
$projectId = (int) $_GET['project_id'];
1132-
$allowRoleList = self::getAllowedRolesFromProject($projectId);
1133-
1134-
// Check if a role was set to the project
1135-
if (!empty($allowRoleList) && is_array($allowRoleList)) {
1136-
if (!in_array($userInfo['status'], $allowRoleList)) {
1137-
$categoryList = self::getCategoryIdsByUser($userId, $projectId);
1138-
$categoryCondition = '';
1139-
if (!empty($categoryList)) {
1140-
$categoryIds = implode(',', array_map('intval', $categoryList));
1141-
$categoryCondition = " OR ticket.category_id IN ($categoryIds)";
1142-
}
1143-
1144-
$sql .= " AND (ticket.assigned_last_user = $userId OR ticket.sys_insert_user_id = $userId".$categoryCondition.")";
1145-
}
1146-
} else {
1147-
if (!api_is_platform_admin()) {
1148-
$categoryList = self::getCategoryIdsByUser($userId, $projectId);
1149-
$categoryCondition = '';
1150-
if (!empty($categoryList)) {
1151-
$categoryIds = implode(',', array_map('intval', $categoryList));
1152-
$categoryCondition = " OR ticket.category_id IN ($categoryIds)";
1153-
}
1156+
$userIsAllowInProject = self::userIsAllowInProject($userInfo, $projectId);
11541157

1155-
$sql .= " AND (ticket.assigned_last_user = $userId OR ticket.sys_insert_user_id = $userId".$categoryCondition.")";
1158+
// Apply same permission constraints as getTicketsByCurrentUser
1159+
if ($userIsAllowInProject == false) {
1160+
$categoryList = self::getCategoryIdsByUser($userId, $projectId);
1161+
$categoryCondition = '';
1162+
if (!empty($categoryList)) {
1163+
$categoryIds = implode(',', array_map('intval', $categoryList));
1164+
$categoryCondition = " OR ticket.category_id IN ($categoryIds)";
11561165
}
1166+
$sql .= " AND (ticket.assigned_last_user = $userId OR ticket.sys_insert_user_id = $userId".$categoryCondition.")";
11571167
}
11581168

1159-
// Search simple
1160-
if (isset($_GET['submit_simple'])) {
1161-
if ($_GET['keyword'] != '') {
1162-
$keyword = Database::escape_string(trim($_GET['keyword']));
1163-
$sql .= " AND (
1164-
ticket.code LIKE '%$keyword%' OR
1165-
ticket.subject LIKE '%$keyword%' OR
1166-
ticket.message LIKE '%$keyword%' OR
1167-
ticket.keyword LIKE '%$keyword%' OR
1168-
ticket.personal_email LIKE '%$keyword%' OR
1169-
ticket.source LIKE '%$keyword%'
1170-
)";
1171-
}
1169+
// Simple search (align with getTicketsByCurrentUser)
1170+
if (isset($_GET['submit_simple']) && $_GET['keyword'] !== '') {
1171+
$keyword = Database::escape_string(trim($_GET['keyword']));
1172+
$sql .= " AND (
1173+
ticket.id LIKE '%$keyword%' OR
1174+
ticket.code LIKE '%$keyword%' OR
1175+
ticket.subject LIKE '%$keyword%' OR
1176+
ticket.message LIKE '%$keyword%' OR
1177+
ticket.keyword LIKE '%$keyword%' OR
1178+
ticket.source LIKE '%$keyword%' OR
1179+
cat.name LIKE '%$keyword%' OR
1180+
status.name LIKE '%$keyword%' OR
1181+
priority.name LIKE '%$keyword%' OR
1182+
ticket.personal_email LIKE '%$keyword%'
1183+
)";
11721184
}
11731185

1186+
// Exact-match filters
11741187
$keywords = [
11751188
'project_id' => 'ticket.project_id',
11761189
'keyword_category' => 'ticket.category_id',
@@ -1182,42 +1195,41 @@ public static function getTotalTicketsCurrentUser()
11821195
];
11831196

11841197
foreach ($keywords as $keyword => $sqlLabel) {
1185-
if (!empty($_GET[$keyword])) {
1198+
if (isset($_GET[$keyword])) {
11861199
$data = Database::escape_string(trim($_GET[$keyword]));
1187-
$sql .= " AND $sqlLabel = '$data' ";
1200+
if ($data !== '') {
1201+
$sql .= " AND $sqlLabel = '$data' ";
1202+
}
11881203
}
11891204
}
11901205

1191-
// Search advanced
1206+
// Advanced search: date range and course
11921207
$keyword_start_date_start = isset($_GET['keyword_start_date_start']) ? Database::escape_string(trim($_GET['keyword_start_date_start'])) : '';
11931208
$keyword_start_date_end = isset($_GET['keyword_start_date_end']) ? Database::escape_string(trim($_GET['keyword_start_date_end'])) : '';
1194-
$keyword_range = isset($_GET['keyword_dates']) ? Database::escape_string(trim($_GET['keyword_dates'])) : '';
11951209
$keyword_course = isset($_GET['keyword_course']) ? Database::escape_string(trim($_GET['keyword_course'])) : '';
1210+
$keyword_range = !empty($keyword_start_date_start) && !empty($keyword_start_date_end);
11961211

1197-
if ($keyword_range == false && $keyword_start_date_start != '') {
1212+
if (!$keyword_range && $keyword_start_date_start !== '') {
11981213
$sql .= " AND ticket.start_date >= '$keyword_start_date_start' ";
11991214
}
1200-
if ($keyword_range && $keyword_start_date_start != '' && $keyword_start_date_end != '') {
1201-
$sql .= " AND ticket.start_date >= '$keyword_start_date_start'
1202-
AND ticket.start_date <= '$keyword_start_date_end'";
1215+
if ($keyword_range) {
1216+
$sql .= " AND ticket.start_date >= '$keyword_start_date_start' AND ticket.start_date <= '$keyword_start_date_end'";
12031217
}
1204-
if ($keyword_course != '') {
1218+
if ($keyword_course !== '') {
12051219
$course_table = Database::get_main_table(TABLE_MAIN_COURSE);
12061220
$sql .= " AND ticket.course_id IN (
1207-
SELECT id
1208-
FROM $course_table
1209-
WHERE (
1210-
title LIKE '%$keyword_course%' OR
1211-
code LIKE '%$keyword_course%' OR
1212-
visual_code LIKE '%$keyword_course%'
1213-
)
1214-
) ";
1221+
SELECT id FROM $course_table
1222+
WHERE (
1223+
title LIKE '%$keyword_course%' OR
1224+
code LIKE '%$keyword_course%' OR
1225+
visual_code LIKE '%$keyword_course%'
1226+
)
1227+
)";
12151228
}
12161229

12171230
$res = Database::query($sql);
12181231
$obj = Database::fetch_object($res);
1219-
1220-
return (int) $obj->total;
1232+
return $obj ? (int) $obj->total : 0;
12211233
}
12221234

12231235
/**
@@ -2018,6 +2030,27 @@ public static function getStatusIdFromCode($code)
20182030
return 0;
20192031
}
20202032

2033+
/**
2034+
* Returns the numeric priority ID from its code (e.g. 'NRM', 'HGH').
2035+
*
2036+
* @param string $code
2037+
*
2038+
* @return int
2039+
*/
2040+
public static function getPriorityIdFromCode($code)
2041+
{
2042+
$item = Database::getManager()
2043+
->getRepository('ChamiloTicketBundle:Priority')
2044+
->findOneBy(['code' => $code])
2045+
;
2046+
2047+
if ($item) {
2048+
return $item->getId();
2049+
}
2050+
2051+
return 0;
2052+
}
2053+
20212054
/**
20222055
* @return array
20232056
*/
@@ -2642,4 +2675,4 @@ public static function notifiyTicketUpdated(int $ticketId, int $categoryId, stri
26422675
}
26432676
}
26442677
}
2645-
}
2678+
}

main/ticket/tickets.php

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,37 @@ function display_advanced_search_form () {
6565
'DESC'
6666
);
6767

68-
$table->set_additional_parameters(['project_id' => $projectId]);
68+
// Preserve current search parameters across pagination and page size changes
69+
$additionalParameters = [
70+
'project_id' => $projectId,
71+
];
72+
73+
$searchParams = [
74+
// Simple search
75+
'keyword',
76+
'submit_simple',
77+
// Advanced search
78+
'submit_advanced',
79+
'keyword_status',
80+
'keyword_category',
81+
'keyword_assigned_to',
82+
'keyword_created_by',
83+
'keyword_priority',
84+
'keyword_course',
85+
'keyword_unread',
86+
'keyword_start_date_start',
87+
'keyword_start_date_end',
88+
// Extra supported keys used by TicketManager
89+
'keyword_source',
90+
];
91+
92+
foreach ($searchParams as $paramName) {
93+
if (isset($_GET[$paramName]) && $_GET[$paramName] !== '') {
94+
$additionalParameters[$paramName] = Security::remove_XSS($_GET[$paramName]);
95+
}
96+
}
97+
98+
$table->set_additional_parameters($additionalParameters);
6999

70100
if ($table->per_page == 0) {
71101
$table->per_page = 20;
@@ -109,27 +139,42 @@ function display_advanced_search_form () {
109139
$datos = $table->get_clean_html();
110140
$ticketTable = Database::get_main_table(TABLE_TICKET_TICKET);
111141
foreach ($datos as $ticket) {
112-
$ticketId = 0;
142+
$ticketId = 0;
113143
if (preg_match('/ticket_id=(\d+)/', $ticket[0], $matches)) {
114144
$ticketId = (int) $matches[1];
115145
}
116146
$ticketCode = '';
117147
$ticketTitle = '';
148+
$ticketDate = '';
149+
$ticketLastUpdate = '';
118150
if ($ticketId > 0) {
119-
$sql = "SELECT code, subject FROM $ticketTable WHERE id = $ticketId";
151+
$sql = "SELECT code, subject, start_date, sys_lastedit_datetime FROM $ticketTable WHERE id = $ticketId";
120152
$rs = Database::query($sql);
121153
if ($row = Database::fetch_array($rs)) {
122154
$ticketCode = $row['code'];
123155
$ticketTitle = $row['subject'];
156+
// Format dates for export as dd/mm/yy
157+
if (!empty($row['start_date'])) {
158+
$ts = strtotime($row['start_date']);
159+
if ($ts !== false) {
160+
$ticketDate = date('d/m/y', $ts);
161+
}
162+
}
163+
if (!empty($row['sys_lastedit_datetime'])) {
164+
$ts2 = strtotime($row['sys_lastedit_datetime']);
165+
if ($ts2 !== false) {
166+
$ticketLastUpdate = date('d/m/y', $ts2);
167+
}
168+
}
124169
}
125170
}
126171

127172
$ticket_rem = [
128173
utf8_decode($ticketCode),
129174
utf8_decode($ticketTitle),
130175
utf8_decode(api_html_entity_decode($ticket[1])),
131-
utf8_decode(strip_tags($ticket[2])),
132-
utf8_decode(strip_tags($ticket[3])),
176+
utf8_decode(!empty($ticketDate) ? $ticketDate : strip_tags($ticket[2])),
177+
utf8_decode(!empty($ticketLastUpdate) ? $ticketLastUpdate : strip_tags($ticket[3])),
133178
utf8_decode(strip_tags($ticket[4])),
134179
utf8_decode(strip_tags($ticket[5])),
135180
utf8_decode(strip_tags($ticket[6])),
@@ -456,4 +501,4 @@ function display_advanced_search_form () {
456501
}
457502

458503
$table->display();
459-
Display::display_footer();
504+
Display::display_footer();

0 commit comments

Comments
 (0)