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
fluent-support / app / Http / Controllers / AgentController.php

AgentController.php in Fluent Support – Helpdesk & Customer Support Ticket System 2.4.5, at app/Http/Controllers/AgentController.php

258 lines 8.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentSupport\App\Http\Controllers;
4
5 use FluentSupport\App\Models\Agent;
6 use FluentSupport\App\Modules\StatModule;
7 use FluentSupport\App\Services\AvatarUploder;
8 use FluentSupport\App\Services\Helper;
9 use FluentSupport\Framework\Http\Request\Request;
10 use FluentSupport\App\Modules\PermissionManager;
11 use FluentSupport\App\Http\Requests\AgentCreateRequest;
12
13 /**
14 * Support staff (agent) endpoints.
15 */
16 class AgentController extends Controller
17 {
18 public function index(Request $request, Agent $agent)
19 {
20 return [
21 'agents' => $agent->getAgents($request->getSafe('search', 'sanitize_text_field')),
22 'permissions' => PermissionManager::getReadablePermissionGroups(),
23 'businessBoxes' => PermissionManager::getMailboxesForRestriction(),
24 ];
25 }
26
27 /**
28 * @param AgentCreateRequest $request
29 * @return \WP_REST_Response | array
30 * @throws \FluentSupport\Framework\Validator\ValidationException
31 */
32 public function addAgent(AgentCreateRequest $request, Agent $agent)
33 {
34 $data = $this->sanitizeAgentPayload($request, true);
35
36 try {
37 return [
38 'message' => __('Support Staff has been added', 'fluent-support'),
39 'agent' => $agent->createAgent($data)
40 ];
41 } catch (\Exception $e) {
42 return $this->sendError([
43 'message' => Helper::getSafeErrorMessage($e)
44 ]);
45 }
46 }
47
48 /**
49 * @param AgentCreateRequest $request
50 * @param Agent $agent
51 * @param int $agent_id
52 * @return \WP_REST_Response | array
53 * @throws \FluentSupport\Framework\Validator\ValidationException
54 */
55 public function updateAgent(AgentCreateRequest $request, Agent $agent, $agent_id)
56 {
57 $agent = $agent::findOrFail($agent_id);
58 $data = $this->sanitizeAgentPayload($request);
59
60 if (!$agent->user_id && ($user = get_user_by('email', $agent->email))) {
61 $agent->user_id = $user->ID;
62 }
63
64 try {
65 return [
66 'message' => __('Support Staff has been updated', 'fluent-support'),
67 'agent' => $agent->updateAgent($data, $agent)
68 ];
69 } catch (\Exception $e) {
70 return $this->sendError([
71 'message' => Helper::getSafeErrorMessage($e)
72 ]);
73 }
74 }
75
76 /**
77 * The agent's tickets and data move to fallback_agent_id.
78 *
79 * @param Request $request
80 * @param Agent $agent
81 * @param int $agent_id
82 * @return \WP_REST_Response | array
83 * @throws \FluentSupport\Framework\Validator\ValidationException
84 */
85 public function deleteAgent(Request $request, Agent $agent, $agent_id)
86 {
87 try {
88 $agent->deleteAgent($request->getSafe('fallback_agent_id', 'intval'), $agent_id);
89
90 return [
91 'message' => __('Support Staff has been deleted', 'fluent-support')
92 ];
93 } catch (\Exception $e) {
94 return $this->sendError([
95 'message' => Helper::getSafeErrorMessage($e)
96 ]);
97 }
98 }
99
100 /**
101 * @param Request $request
102 * @return \WP_REST_Response | array
103 */
104 public function myStats(Request $request)
105 {
106 $agent = Helper::getAgentByUserId();
107
108 try {
109 $stats = StatModule::getAgentStat($agent->id);
110 $with = $request->get('with', []);
111 $with = is_array($with) ? map_deep($with, 'sanitize_text_field') : [];
112
113 $response = (new Agent())->getAgentStat($stats, $with, $agent->id);
114
115 if (defined('FLUENTSUPPORTPRO')) {
116 $response['dashboard_notice'] = apply_filters('fluent_support/dashboard_notice', '', $agent);
117 }
118
119 return $response;
120 } catch (\Exception $e) {
121 return $this->sendError([
122 'message' => Helper::getSafeErrorMessage($e)
123 ]);
124 }
125 }
126
127 public function agentPerformance()
128 {
129 try {
130 if (PermissionManager::currentUserCan('fst_agent_today_performance')) {
131 $agentTodayStats = StatModule::getAgentTodayStats();
132
133 return ['agent_today_stats' => $agentTodayStats];
134 }
135 } catch (\Exception $e) {
136 return $this->sendError([
137 'message' => Helper::getSafeErrorMessage($e)
138 ]);
139 }
140
141 return [];
142 }
143
144 /**
145 * @param Request $request
146 * @param AvatarUploder $avatarUploder
147 * @return \WP_REST_Response | array
148 */
149 public function addOrUpdateProfileImage(Request $request, AvatarUploder $avatarUploder)
150 {
151 try {
152 return $avatarUploder->addOrUpdateProfileImage($request->files(), $request->getSafe('agent_id', 'intval'), 'agent');
153 } catch (\Exception $e) {
154 return $this->sendError([
155 'message' => Helper::getSafeErrorMessage($e)
156 ]);
157 }
158 }
159
160 /**
161 * No Agent type-hint: route-model binding runs before the policy, which would
162 * let unauthenticated callers probe agent IDs. Resolve after auth.
163 *
164 * @param int|string $agent
165 * @return array
166 */
167 public function resetAvatar($agent)
168 {
169 try {
170 $agent = Agent::findOrFail((int) $agent);
171 $agent->restoreAvatar();
172
173 return [
174 'message' => __('Support Staff avatar reset to gravatar default', 'fluent-support')
175 ];
176 } catch (\Exception $e) {
177 return $this->sendError([
178 'message' => Helper::getSafeErrorMessage($e)
179 ]);
180 }
181 }
182
183 public function getAgentInsights(Request $request, Agent $agent)
184 {
185 return [
186 'agents' => $agent->agentInsights($request->getSafe('search', 'sanitize_text_field')),
187 ];
188 }
189
190 public function ping(Request $request)
191 {
192 return [
193 'ping' => 'pong',
194 ];
195 }
196
197 /**
198 * @param AgentCreateRequest $request
199 * @param bool $includeEmail
200 * @return array
201 */
202 private function sanitizeAgentPayload(AgentCreateRequest $request, $includeEmail = false)
203 {
204 $data = [
205 'first_name' => $request->getSafe('first_name', 'sanitize_text_field'),
206 'last_name' => $request->getSafe('last_name', 'sanitize_text_field'),
207 'title' => $request->getSafe('title', 'sanitize_text_field'),
208 'permissions' => is_array($request->get('permissions')) ? array_map('sanitize_key', $request->get('permissions')) : [],
209 'telegram_chat_id' => $request->getSafe('telegram_chat_id', 'sanitize_text_field'),
210 'slack_user_id' => $request->getSafe('slack_user_id', 'sanitize_text_field'),
211 'whatsapp_number' => $request->getSafe('whatsapp_number', 'sanitize_text_field'),
212 'restrictions' => $this->sanitizeRestrictions($request->get('restrictions')),
213 ];
214
215 if ($request->has('agent_signature')) {
216 // Already unslashed by the request. Don't unslash again or literal backslashes are lost.
217 $data['agent_signature'] = wp_kses_post($request->get('agent_signature', ''));
218 }
219
220 if ($request->has('agent_signature_enabled')) {
221 $data['agent_signature_enabled'] = $request->get('agent_signature_enabled') === 'yes' ? 'yes' : 'no';
222 }
223
224 if ($includeEmail) {
225 $data['email'] = $request->getSafe('email', 'sanitize_email');
226 }
227
228 return $data;
229 }
230
231 /**
232 * @param mixed $restrictions
233 * @return array
234 */
235 private function sanitizeRestrictions($restrictions)
236 {
237 if (!is_array($restrictions)) {
238 return [
239 'restrictedBusinessBoxes' => [],
240 'businessBoxRestrictions' => false,
241 ];
242 }
243
244 $restrictedBusinessBoxes = isset($restrictions['restrictedBusinessBoxes']) && is_array($restrictions['restrictedBusinessBoxes'])
245 ? array_map('absint', $restrictions['restrictedBusinessBoxes'])
246 : [];
247
248 $businessBoxRestrictions = isset($restrictions['businessBoxRestrictions'])
249 ? rest_sanitize_boolean($restrictions['businessBoxRestrictions'])
250 : false;
251
252 return [
253 'restrictedBusinessBoxes' => $restrictedBusinessBoxes,
254 'businessBoxRestrictions' => $businessBoxRestrictions,
255 ];
256 }
257 }
258