PluginProbe
Fluent Support – Helpdesk & Customer Support Ticket System / 2.4.0
Fluent Support – Helpdesk & Customer Support Ticket System v2.4.0
2.4.5 2.4.0 2.3.2 2.3.1 2.3.0 2.2.1 2.2.0 trunk 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.10.5 1.4.0 1.4.1 1.4.2 1.4.5 1.4.6 1.4.7 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 All 69 releases
← All changes | app/Services/TicketHelper.php +104 -12 1.10.5 → 2.4.0 View file →
@@ -60,20 +60,85 @@
60 60
61 61 return self::getAgentsInfoFromActivities($activities);
62 62 }
63 63
64 - public static function getAgentsInfoFromActivities($activities)
64 + private static function getAgentsInfoFromActivities($activities)
65 65 {
66 66 if (!$activities) {
67 67 return [];
68 68 }
69 69
70 - return Agent::select(['email', 'first_name', 'last_name'])
70 + return Agent::select(['id', 'email', 'first_name', 'last_name'])
71 71 ->whereIn('id', array_keys($activities))
72 72 ->get();
73 73 }
74 74
75 75 /**
76 + * Batch-load live activity for a collection of tickets.
77 + * Uses 2 queries total: one for activity metas, one for all agents.
78 + *
79 + * @param \Iterable $tickets Collection of Ticket models
80 + * @return void
81 + */
82 + public static function loadBatchLiveActivities($tickets)
83 + {
84 + $activeTicketIds = $tickets->where('status', '!=', 'closed')->pluck('id')->toArray();
85 +
86 + if (!$activeTicketIds) {
87 + foreach ($tickets as $ticket) {
88 + $ticket->live_activity = [];
89 + }
90 + return;
91 + }
92 +
93 + $activityMetas = Meta::where('object_type', 'ticket_meta')
94 + ->where('key', '_live_activity')
95 + ->whereIn('object_id', $activeTicketIds)
96 + ->get()
97 + ->keyBy('object_id');
98 +
99 + $allAgentIds = [];
100 + $ticketActivities = [];
101 +
102 + foreach ($activityMetas as $ticketId => $meta) {
103 + $activities = Helper::safeUnserialize($meta->value);
104 + if (!is_array($activities)) {
105 + continue;
106 + }
107 +
108 + $activities = array_filter($activities, function ($time) {
109 + return (time() - $time) <= 60;
110 + });
111 +
112 + $ticketActivities[$ticketId] = $activities;
113 + $allAgentIds = array_merge($allAgentIds, array_keys($activities));
114 + }
115 +
116 + $allAgentIds = array_unique(array_filter($allAgentIds));
117 + $agents = $allAgentIds
118 + ? Agent::select(['id', 'email', 'first_name', 'last_name'])
119 + ->whereIn('id', $allAgentIds)
120 + ->get()
121 + ->keyBy('id')
122 + : [];
123 +
124 + $activitiesByTicket = [];
125 + foreach ($ticketActivities as $ticketId => $activities) {
126 + $ticketAgents = [];
127 + foreach (array_keys($activities) as $agentId) {
128 + if (isset($agents[$agentId])) {
129 + $ticketAgents[] = $agents[$agentId];
130 + }
131 + }
132 + $activitiesByTicket[$ticketId] = $ticketAgents;
133 + }
134 +
135 + foreach ($tickets as $ticket) {
136 + $ticket->live_activity = $activitiesByTicket[$ticket->id] ?? [];
137 + }
138 + }
139 +
140 + /**
76 141 * removeFromActivities method will remove the old live activity by agent and ticket id
77 142 * @param $ticketId
78 143 * @param $agentId
79 144 * @return bool
@@ -115,13 +180,16 @@
115 180 * @return mixed
116 181 */
117 182 public static function getSuggestedTickets($agentId, $limit = 5)
118 183 {
119 - $restrictedBusinessBoxes = PermissionManager::currentUserRestrictedBusinessBoxes();
184 + $restrictedBusinessBoxes = PermissionManager::getRestrictedMailboxIds();
120 185
121 186 //Get lis of tickets which are waiting for reply
122 187 $tickets = Ticket::where('agent_id', $agentId)
123 - ->whereNotIn('mailbox_id', $restrictedBusinessBoxes)
188 + ->where(function ($q) use ($restrictedBusinessBoxes) {
189 + $q->whereNotIn('mailbox_id', $restrictedBusinessBoxes);
190 + $q->orWhereNull('mailbox_id');
191 + })
124 192 ->where('status', '!=', 'closed')
125 193 ->applyFilters([
126 194 'waiting_for_reply' => 'yes'
127 195 ])
@@ -126,9 +194,15 @@
126 194 'waiting_for_reply' => 'yes'
127 195 ])
128 196 ->oldest('last_customer_response')
129 197 ->limit($limit)
130 - ->with('customer')
198 + ->with(
199 + [
200 + 'customer',
201 + 'mailbox',
202 + 'tags',
203 + 'agent'
204 + ])
131 205 ->get();
132 206
133 207 //If no ticket is available for reply and logged-in user has permission to manage unassigned tickets
134 208 if($tickets->isEmpty() && PermissionManager::currentUserCan('fst_manage_unassigned_tickets')) {
@@ -134,14 +208,22 @@
134 208 if($tickets->isEmpty() && PermissionManager::currentUserCan('fst_manage_unassigned_tickets')) {
135 209 //Get the ticket list which status is not closed and agent id is null or 0
136 210 $tickets = Ticket::where('status', '!=', 'closed')
137 211 ->oldest('id')
138 - ->whereNotIn('mailbox_id', $restrictedBusinessBoxes)
212 + ->where(function ($q) use ($restrictedBusinessBoxes) {
213 + $q->whereNotIn('mailbox_id', $restrictedBusinessBoxes);
214 + $q->orWhereNull('mailbox_id');
215 + })
139 216 ->where(function ($q) {
140 217 $q->whereNull('agent_id');
141 218 $q->orWhere('agent_id', '0');
142 219 })
143 - ->with('customer')
220 + ->with(
221 + [
222 + 'customer',
223 + 'mailbox',
224 + 'tags',
225 + ])
144 226 ->limit($limit)
145 227 ->get();
146 228 }
147 229
@@ -165,13 +247,22 @@
165 247 // This method will return all tagged/mentioned/watcher tickets of logged in agent
166 248 public static function getTicketsToWatch()
167 249 {
168 250 $agent = Helper::getCurrentAgent();
169 - $restrictedBusinessBoxes = PermissionManager::currentUserRestrictedBusinessBoxes();
251 + $restrictedBusinessBoxes = PermissionManager::getRestrictedMailboxIds();
170 252
171 - $tickets = Ticket::with('customer')
253 + $tickets = Ticket::with(
254 + [
255 + 'customer',
256 + 'mailbox',
257 + 'tags',
258 + 'agent'
259 + ])
172 260 ->limit(5)
173 - ->whereNotIn('mailbox_id', $restrictedBusinessBoxes)
261 + ->where(function ($q) use ($restrictedBusinessBoxes) {
262 + $q->whereNotIn('mailbox_id', $restrictedBusinessBoxes);
263 + $q->orWhereNull('mailbox_id');
264 + })
174 265 ->join('fs_tag_pivot', 'fs_tag_pivot.source_id', '=', 'fs_tickets.id')
175 266 ->where('fs_tag_pivot.source_type', '=', 'ticket_watcher')
176 267 ->where('fs_tag_pivot.tag_id', '=', $agent->id)
177 268 ->select(['fs_tickets.*'])
@@ -191,8 +282,9 @@
191 282
192 283 return $watcherAgents;
193 284 }
194 285
286 + /** @internal Not called from core controllers — available for Pro/hook usage. */
195 287 public static function getCarbonCopyCustomerInfo($ticketId){
196 288 $existing = Meta::where('object_type', 'beginning_cc_info')->where('object_id', $ticketId)->first();
197 289 if($existing){
198 290 return Helper::safeUnserialize($existing->value, []);
@@ -242,11 +334,11 @@
242 334 'changeable_ticket_statuses' => Helper::changeableTicketStatuses(),
243 335 'admin_priorities' => Helper::adminTicketPriorities(),
244 336 'enable_draft_mode' => Helper::getBusinessSettings('enable_draft_mode', 'no'),
245 337 'max_file_upload' => Helper::getBusinessSettings('max_file_upload', 3),
246 - 'support_products' => Product::select(['id', 'title'])->get(),
338 + 'support_products' => Product::select(['id', 'title'])->orderedByTitle()->get(),
247 339 'ticket_tags' => TicketTag::select(['id', 'title'])->get()->toArray(),
248 - 'mailboxes' => MailBox::select(['id', 'name', 'settings'])->get(),
340 + 'mailboxes' => MailBox::getAccessibleBoxes(),
249 341 'ticket_statuses' => Helper::ticketStatuses(),
250 342 ];
251 343
252 344 return $type ? $data[$type] : $data;