PluginProbe
Fluent Support – Helpdesk & Customer Support Ticket System / 2.4.5
Fluent Support – Helpdesk & Customer Support Ticket System v2.4.5
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/Models/Traits/AgentTrait.php +108 -34 1.10.1 → 2.4.5 View file →
@@ -3,15 +3,20 @@
3 3 namespace FluentSupport\App\Models\Traits;
4 4
5 5 use FluentSupport\App\Models\Attachment;
6 6 use FluentSupport\App\Models\Conversation;
7 +use FluentSupport\App\Models\Meta;
7 8 use FluentSupport\App\Models\Product;
9 +use FluentSupport\App\Models\AgentGroup;
10 +use FluentSupport\App\Models\TagPivot;
8 11 use FluentSupport\App\Models\Ticket;
9 12 use FluentSupport\App\Modules\PermissionManager;
10 13 use FluentSupport\App\Models\Person;
11 14 use FluentSupport\App\Modules\Reporting\Reporting;
12 15 use FluentSupport\App\Modules\StatModule;
16 +use FluentSupport\App\Services\Helper;
13 17 use FluentSupport\App\Services\TicketHelper;
18 +use FluentSupport\App\Services\Tickets\AgentTicketAccess;
14 19 use FluentSupport\Framework\Support\Arr;
15 20 use Exception;
16 21
17 22 trait AgentTrait
@@ -19,10 +24,64 @@
19 24 public function getAgents($search)
20 25 {
21 26 $agents = static::latest()
22 27 ->searchBy($search)
28 + ->with(['groups' => function ($query) {
29 + $query->select(['fs_taggables.id', 'title']);
30 + }])
23 31 ->paginate();
24 32
33 + $agentIds = $agents->pluck('id')->map('intval')->all();
34 +
35 + if (!$agentIds) {
36 + return $agents;
37 + }
38 +
39 + // One query per kind of data for the whole page, not per agent.
40 + $repliesCount = Conversation::whereIn('person_id', $agentIds)
41 + ->groupBy('person_id')
42 + ->selectRaw('person_id, COUNT(*) AS total')
43 + ->pluck('total', 'person_id')
44 + ->all();
45 +
46 + $interactionsCount = Conversation::whereIn('person_id', $agentIds)
47 + ->groupBy('person_id')
48 + ->selectRaw('person_id, COUNT(DISTINCT ticket_id) AS total')
49 + ->pluck('total', 'person_id')
50 + ->all();
51 +
52 + $metaDefaults = [
53 + 'telegram_chat_id' => '',
54 + 'slack_user_id' => '',
55 + 'whatsapp_number' => '',
56 + 'agent_restrictions' => [
57 + 'restrictedBusinessBoxes' => [],
58 + 'businessBoxRestrictions' => false
59 + ],
60 + 'agent_signature' => '',
61 + 'agent_signature_enabled' => 'no',
62 + ];
63 +
64 + $metaRows = Meta::where('object_type', 'person_meta')
65 + ->whereIn('object_id', $agentIds)
66 + ->whereIn('key', array_keys($metaDefaults))
67 + ->orderBy('id', 'ASC')
68 + ->get(['object_id', 'key', 'value']);
69 +
70 + // First row per agent and key wins, as getMeta()'s first() did.
71 + $metaValues = [];
72 + foreach ($metaRows as $row) {
73 + if (!isset($metaValues[$row->object_id][$row->key])) {
74 + $metaValues[$row->object_id][$row->key] = Helper::safeUnserialize($row->value);
75 + }
76 + }
77 +
78 + // Prime WordPress's user and user meta caches for the permission lookups.
79 + $userIds = array_filter(array_map('intval', $agents->pluck('user_id')->all()));
80 + if ($userIds) {
81 + cache_users($userIds);
82 + }
83 +
25 84 foreach ($agents as $agent) {
26 85 $agent->permissions = PermissionManager::getUserPermissions($agent->user_id);
27 86
28 87 if ($agent->user_id) {
@@ -28,19 +87,23 @@
28 87 if ($agent->user_id) {
29 88 $agent->user_profile = admin_url('user-edit.php?user_id=' . $agent->user_id);
30 89 }
31 90
32 - $agent->replies_count = Conversation::where('person_id', $agent->id)->count();
33 - $agent->interactions_count = Conversation::where('person_id', $agent->id)->groupBy('ticket_id')->get()->count();
91 + $agent->replies_count = (int) Arr::get($repliesCount, $agent->id, 0);
92 + $agent->interactions_count = (int) Arr::get($interactionsCount, $agent->id, 0);
34 93
35 - $agent->telegram_chat_id = $agent->getMeta('telegram_chat_id');
36 - $agent->slack_user_id = $agent->getMeta('slack_user_id');
37 - $agent->whatsapp_number = $agent->getMeta('whatsapp_number');
38 - $agent->restrictions = $agent->getMeta('agent_restrictions', [
39 - 'restrictedBusinessBoxes' => [],
40 - 'businessBoxRestrictions' => false
41 - ]);
94 + // Same rule as getMeta(): a missing or empty value falls back to the default.
95 + $meta = function ($key) use ($metaValues, $metaDefaults, $agent) {
96 + $value = $metaValues[$agent->id][$key] ?? null;
97 + return $value ? $value : $metaDefaults[$key];
98 + };
42 99
100 + $agent->telegram_chat_id = $meta('telegram_chat_id');
101 + $agent->slack_user_id = $meta('slack_user_id');
102 + $agent->whatsapp_number = $meta('whatsapp_number');
103 + $agent->restrictions = $meta('agent_restrictions');
104 + $agent->agent_signature = $meta('agent_signature');
105 + $agent->agent_signature_enabled = $meta('agent_signature_enabled');
43 106 }
44 107
45 108 return $agents;
46 109 }
@@ -52,9 +115,8 @@
52 115 }
53 116
54 117 $data = $this->setAgentInfo($data, $user);
55 118
56 - // check if another agent has same email address
57 119 $person = Person::where('email', $data['email'])->first();
58 120
59 121 if ($person) {
60 122 throw new \Exception('Sorry, Another agent/person exist with the same email address. Please use a different email address');
@@ -60,20 +122,28 @@
60 122 throw new \Exception('Sorry, Another agent/person exist with the same email address. Please use a different email address');
61 123 }
62 124
63 125
64 - return $this->setAgentMeta(
65 - $user,
66 - $data,
67 - static::create($data)
68 - );
126 + $agent = $this->setAgentMeta($user, $data, static::create($data));
69 127
128 + $defaultGroup = AgentGroup::whereNotNull('settings')->get()->first(function ($group) {
129 + return !empty($group->settings['is_default']);
130 + });
131 +
132 + if ($defaultGroup) {
133 + TagPivot::create([
134 + 'tag_id' => $defaultGroup->id,
135 + 'source_id' => $agent->id,
136 + 'source_type' => 'agent_group',
137 + ]);
138 + }
139 +
140 + return $agent;
70 141 }
71 142
72 143 /**
73 - * Method to update agent info
74 144 * @param array $data
75 - * @param $agent
145 + * @param object $agent
76 146 * @return object
77 147 * @throws Exception
78 148 */
79 149 public function updateAgent(array $data, object $agent)
@@ -97,9 +167,10 @@
97 167 }
98 168
99 169
100 170 /**
101 - * This method will delete an agent by agent id
171 + * Delete an agent and move their records to the fallback agent.
172 + *
102 173 * @param int $fallBackAgentId
103 174 * @param int $agentId
104 175 * @return void
105 176 * @throws Exception
@@ -111,10 +182,8 @@
111 182 }
112 183
113 184 $agent = static::findOrFail($agentId);
114 185
115 - PermissionManager::attachPermissions($agent->user_id, []);
116 -
117 186 try {
118 187 $newAgent = static::findOrFail($fallBackAgentId);
119 188 } catch (\Exception $e) {
120 189 throw new \Exception('Fallback agent could not be found');
@@ -119,10 +188,16 @@
119 188 } catch (\Exception $e) {
120 189 throw new \Exception('Fallback agent could not be found');
121 190 }
122 191
192 + PermissionManager::detachPermissions($agent->user_id);
193 +
123 194 $this->assignDataToFallbackAgent($agent->id, $newAgent);
124 195
196 + TagPivot::where('source_id', $agent->id)
197 + ->where('source_type', 'agent_group')
198 + ->delete();
199 +
125 200 $agent->deleteAllMeta();
126 201
127 202 static::where('id', $agentId)->delete();
128 203 }
@@ -127,9 +202,8 @@
127 202 static::where('id', $agentId)->delete();
128 203 }
129 204
130 205 /**
131 - * This method will assign data to fallback agent
132 206 * @param int $agentId
133 207 * @param object $newAgent
134 208 * @return void
135 209 */
@@ -169,39 +243,28 @@
169 243 }
170 244
171 245 private function agentDashboardWidgets($data, $with, $agentId)
172 246 {
173 - //If the request come with suggested_tickets
174 247 if (in_array('suggested_tickets', $with)) {
175 - //Get suggested tickets from ticketHelper
176 248 $data['suggested_tickets'] = TicketHelper::getSuggestedTickets($agentId);
177 249 }
178 250
179 - //If the request come with mentioned_tickets
180 251 if (defined('FLUENTSUPPORTPRO') && in_array('ticket_to_watch', $with)) {
181 - //Get the overall statistics by the agent
182 252 $data['ticket_to_watch'] = TicketHelper::getTicketsToWatch();
183 253 }
184 254
185 - //If the request come with overall_stats
186 255 if (in_array('overall_stats', $with)) {
187 - //Get overall status
188 256 $data['overall_stats'] = (new Reporting())->getActiveStats();
189 257 }
190 258
191 - //If the request come with individual_stat
192 259 if (in_array('individual_stat', $with)) {
193 - //get overall statistics by agent id
194 260 $data['individual_stat'] = (new Reporting())->getActiveStatByAgent($agentId);
195 261 }
196 - //If the request come with my_overall_stats
197 262 if (in_array('my_overall_stats', $with)) {
198 - //Get the overall statistics by the agent
199 263 $data['my_overall_stats'] = StatModule::getAgentOverallStats($agentId);
200 264 }
201 265
202 266 if (in_array('tickets_by_products', $with)) {
203 - //Get tickets by product which are waiting for agent reply
204 267 $data['tickets_by_product'] = StatModule::getActiveTicketsByProductStats();
205 268 }
206 269
207 270 return $data;
@@ -207,9 +270,8 @@
207 270 return $data;
208 271 }
209 272
210 273 /**
211 - * Method to set agent info
212 274 * @param array $data
213 275 * @param $user
214 276 * @return array
215 277 */
@@ -228,9 +290,10 @@
228 290 return $data;
229 291 }
230 292
231 293 /**
232 - * Method to set agent meta data
294 + * Save permissions and agent settings meta.
295 + *
233 296 * @param $user
234 297 * @param array $data
235 298 * @param object $agent
236 299 * @return object
@@ -266,9 +329,20 @@
266 329 'businessBoxRestrictions' => $businessBoxRestrictions
267 330 ];
268 331
269 332 $agent->updateMeta('agent_restrictions', $restrictions);
333 + AgentTicketAccess::resetCache();
270 334 $agent->restrictions = $restrictions;
335 + }
336 +
337 + if (isset($data['agent_signature'])) {
338 + $agent->updateMeta('agent_signature', $data['agent_signature']);
339 + $agent->agent_signature = $data['agent_signature'];
340 + }
341 +
342 + if (isset($data['agent_signature_enabled'])) {
343 + $agent->updateMeta('agent_signature_enabled', $data['agent_signature_enabled']);
344 + $agent->agent_signature_enabled = $data['agent_signature_enabled'];
271 345 }
272 346
273 347 return $agent;
274 348 }