PluginProbe
Fluent Support – Helpdesk & Customer Support Ticket System / 1.10.0
Fluent Support – Helpdesk & Customer Support Ticket System v1.10.0
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 1.5.5 All 68 releases
fluent-support / app / Hooks / Handlers / CustomerPortalHandler.php

CustomerPortalHandler.php in Fluent Support – Helpdesk & Customer Support Ticket System 1.10.0, at app/Hooks/Handlers/CustomerPortalHandler.php

320 lines 14.0 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\Hooks\Handlers;
4
5 use FluentSupport\App\App;
6 use FluentSupport\App\Models\Customer;
7 use FluentSupport\App\Models\Product;
8 use FluentSupport\App\Modules\PermissionManager;
9 use FluentSupport\App\Services\Blocks\BlockHelper;
10 use FluentSupport\App\Services\Helper;
11 use FluentSupport\Framework\Support\Arr;
12 use FluentSupportPro\App\Services\ProHelper;
13
14 class CustomerPortalHandler
15 {
16 public function renderPortal($args = [])
17 {
18 /**
19 * This hook filter customer portal access permission error message.
20 * If a customer has no access to the portal, then the message will be displayed.
21 * @param string $invalidPermissionMessage
22 * @return string
23 * @since 1.6.0
24 */
25 $invalidPermissionMessage = apply_filters(
26 'fluent_support/customer_portal_invalid_permission_message',
27 esc_html__('You don\'t have permission to access customer support portal', 'fluent-support')
28 );
29
30 $person = Helper::getCurrentPerson();
31
32 if (PermissionManager::currentUserPermissions()) {
33 $adminPortalUrl = Helper::getPortalAdminBaseUrl();
34
35 /**
36 * This hook filter is responsible for generating error message
37 * when a support staff try to access customer portal
38 * @param string $agentPermissionErrMessage
39 * @return string
40 * @since 1.6.0
41 */
42 $msg = __('Customer Portal is only accessible by Customers. Looks like you are a support staff', 'fluent-support');
43 $agentPermissionErrMessage = apply_filters(
44 'fluent_support/customer_portal_agent_permission_error_message',
45 $msg
46 );
47 return '<div style="text-align: center;"><h3>' . $agentPermissionErrMessage . '</h3><a href="' . $adminPortalUrl . '">' . esc_html__('Go to Support Admin Page', 'fluent-support') . '</a></div>';
48 } else if ($this->hasCustomerPortalAccess()) {
49
50 /*
51 * Filter customer portal access settings
52 *
53 * @since v1.0.0
54 *
55 * @param array $canAccess
56 */
57 $canAccess = apply_filters('fluent_support/user_portal_access_config', [
58 'status' => true,
59 'message' => $invalidPermissionMessage
60 ]);
61
62 if (empty($canAccess['status'])) {
63 $invalidPermissionMessage = Arr::get($canAccess, 'message', $invalidPermissionMessage);
64 return '<div id="fluent_support_client_app" style="text-align: center;"><h3 class="fs_customer_restriction">' . $invalidPermissionMessage . '</h3></div>';
65 }
66
67 if (!$person) {
68 $this->maybeCreateCustomer();
69 }
70
71 if (isset($args['attributes']) && !empty($args['attributes'])) {
72 BlockHelper::processAttributesAndPrepareStyle($args['attributes']);
73 }
74
75 $this->enqueueScripts();
76 return '<div id="fluent_support_client_app"><h3 class="fs_loading_text">' . __('Loading Customer Portal. Please wait...', 'fluent-support') . '</h3></div>';
77 } else {
78
79 $businessSettings = Helper::getBusinessSettings();
80 $loggedInMessage = Arr::get($businessSettings, 'login_message', '');
81
82 $loggedInMessage = str_replace('[fluent_support_portal]', '', $loggedInMessage);
83
84 return do_shortcode($loggedInMessage);
85 }
86 }
87
88 public function hasCustomerPortalAccess()
89 {
90 $userId = get_current_user_id();
91
92 if ($userId) {
93 return true;
94 }
95
96 return $this->isSignedTicketView();
97 }
98
99 protected function isSignedTicketView()
100 {
101 if (!Helper::isPublicSignedTicketEnabled()) {
102 return false;
103 }
104
105 return isset($_REQUEST['fs_view']) && $_REQUEST['fs_view'] == 'ticket' && isset($_REQUEST['support_hash']) && isset($_REQUEST['ticket_id']);
106 }
107
108 private function maybeCreateCustomer()
109 {
110 $userId = get_current_user_id();
111 if (!$userId) {
112 return false;
113 }
114
115 $person = Helper::getCurrentPerson();
116 if ($person) {
117 return $person;
118 }
119
120 $user = get_user_by('ID', $userId);
121
122 $request = App::request();
123
124 $onBehalf = [
125 'user_id' => $user->ID,
126 'email' => $user->user_email,
127 'last_ip_address' => $request->getIp()
128 ];
129
130 $customFields = Helper::getBusinessSettings('custom_registration_form_field');
131
132 if (!empty($customFields)) {
133 $onBehalf = $this->processCustomFields($customFields, $onBehalf);
134 }
135
136 return Customer::maybeCreateCustomer($onBehalf);
137 }
138
139 private function processCustomFields($customFields, $onBehalf)
140 {
141 $userMeta = get_user_meta(get_current_user_id());
142 $customData = [];
143
144 foreach ($customFields as $field) {
145 if (isset($userMeta[$field])) {
146 $customData[$field] = is_array($userMeta[$field]) ? $userMeta[$field][0] : $userMeta[$field];
147 }
148 }
149
150 if ($customData) {
151 $onBehalf = array_merge($onBehalf, $customData);
152 }
153
154 return $onBehalf;
155 }
156
157 public function enqueueScripts()
158 {
159 $app = App::getInstance();
160
161 $ns = $app->config->get('app.rest_namespace');
162 $v = $app->config->get('app.rest_version');
163 $slug = $app->config->get('app.slug');
164
165 $restInfo = [
166 'base_url' => esc_url_raw(rest_url()),
167 'url' => rest_url($ns . '/' . $v . '/customer-portal'),
168 'nonce' => wp_create_nonce('wp_rest'),
169 'namespace' => $ns,
170 'version' => $v,
171 ];
172
173 $assets = $app['url.assets'];
174
175
176 $i18ns = [
177 'Conversation' => __('Conversation', 'fluent-support'),
178 'Back to All Tickets' => __('Back to All Tickets', 'fluent-support'),
179 'Click Here to Write a reply' => __('Click Here to Write a reply', 'fluent-support'),
180 'All' => __('All', 'fluent-support'),
181 'All Tickets' => __('All Tickets', 'fluent-support'),
182 'Open' => __('Open', 'fluent-support'),
183 'open' => __('open', 'fluent-support'),
184 'Closed' => __('Closed', 'fluent-support'),
185 'new' => __('new', 'fluent-support'),
186 'Logout' => __('Logout', 'fluent-support'),
187 'active' => __('active', 'fluent-support'),
188 'on-hold' => __('on-hold', 'fluent-support'),
189 'closed' => __('closed', 'fluent-support'),
190 'Date' => __('Date', 'fluent-support'),
191 'Status' => __('Status', 'fluent-support'),
192 'Next' => __('Next', 'fluent-support'),
193 'Prev' => __('Prev', 'fluent-support'),
194 'Reply and Close' => __('Reply and Close', 'fluent-support'),
195 'Refresh' => __('Refresh', 'fluent-support'),
196 'agent_and_officials_can_see' => __('Only you and official support agents can view this conversation', 'fluent-support'),
197 'reopen_ticket_instruction' => __('If you still have related issues. Please reopen this ticket and reply', 'fluent-support'),
198 'ticket_closed' => __('This ticket was closed on', 'fluent-support'),
199 'Close Ticket' => __('Close Ticket', 'fluent-support'),
200 'not_to_share_private_info' => __('Please do not share any private information.', 'fluent-support'),
201 'replied' => __('replied', 'fluent-support'),
202 'conversation_started' => __('started the conversation', 'fluent-support'),
203 'Click to upload' => __('Click to upload', 'fluent-support'),
204 'This ticket is' => __('This ticket is', 'fluent-support'),
205 'Private' => __('Private', 'fluent-support'),
206 'Write a reply' => __('Write a reply', 'fluent-support'),
207 'Additional info' => __('Additional info', 'fluent-support'),
208 'Reply' => __('Reply', 'fluent-support'),
209 'You' => __('You', 'fluent-support'),
210 'no_open_support_tickets' => __('Looks like you did not open any support tickets yet', 'fluent-support'),
211 'no_support_ticket_found' => __('No support tickets found for this filter', 'fluent-support'),
212 'Delete Customer' => __('Delete Customer', 'fluent-support'),
213 'Update Customer' => __('Update Customer', 'fluent-support'),
214 'Create Customer' => __('Create Customer', 'fluent-support'),
215 'Browse Files' => __('Browse Files', 'fluent-support'),
216 'Add Attachment' => __('Add Attachment', 'fluent-support'),
217 'btn_text' => __('Create Ticket', 'fluent-support'),
218
219 'subject_placeholder' => __('What\'s this support ticket about?', 'fluent-support'),
220 'service_placeholder' => __('Select related Product/Service', 'fluent-support'),
221 'suggestion_loading' => __('Looking for similar articles...', 'fluent-support'),
222 'articles_heading' => __('Suggested articles', 'fluent-support'),
223 'priority_placeholder' => __('Select Priority', 'fluent-support'),
224 'Page' => __('Page', 'fluent-support'),
225 'page' => __('page', 'fluent-support'),
226 'of' => __('of', 'fluent-support'),
227
228 'subject' => __('Subject', 'fluent-support'),
229 'ticket_details' => __('Ticket Details', 'fluent-support'),
230 'details_help' => __('Please provide details about your problem', 'fluent-support'),
231 'product_services' => __('Related Product/Service', 'fluent-support'),
232 'priority' => __('Priority', 'fluent-support'),
233 'Create Ticket' => __('Create Ticket', 'fluent-support'),
234 'submit_heading' => __('Submit a Support Ticket', 'fluent-support'),
235 'All Products' => __('All Products', 'fluent-support'),
236 'Please input' => __('Please input', 'fluent-support'),
237 'Search' => __('Search', 'fluent-support'),
238 'No tickets found' => __('No tickets found', 'fluent-support'),
239 'create_ticket_cta' => __('Create Ticket', 'fluent-support'),
240 'Reopen This ticket' => __('Reopen This ticket', 'fluent-support'),
241 'by' => __('by', 'fluent-support'),
242 'Unknown error. Please reload this page' => __('Unknown error. Please reload this page', 'fluent-support'),
243 'View Your Tickets' => __('View Your Tickets', 'fluent-support'),
244 'View All' => __('View All', 'fluent-support'),
245 'Support Staff' => __('Support Staff', 'fluent-support'),
246 'Thread Starter' => __('Thread Starter', 'fluent-support'),
247 'Thread Follower' => __('Thread Follower', 'fluent-support'),
248 'Sort By' => __('Sort By', 'fluent-support'),
249 'Ascending' => __('Ascending', 'fluent-support'),
250 'Descending' => __('Descending', 'fluent-support'),
251 'Apply' => __('Apply', 'fluent-support'),
252 'Ticket ID' => __('Ticket ID', 'fluent-support'),
253 'Title' => __('Title', 'fluent-support'),
254 'Created at' => __('Created at', 'fluent-support'),
255 'Subject' => __('Subject', 'fluent-support'),
256 'Suggested Articles' => __('Suggested Articles', 'fluent-support'),
257 'Log Out' => __('Log Out', 'fluent-support'),
258 'Completed' => __('Completed', 'fluent-support'),
259 'Processing' => __('Processing', 'fluent-support'),
260 'Failed' => __('Failed', 'fluent-support'),
261 'customer_inactive_message' => __('Your account is currently inactive. You cannot create new tickets or reply to existing ones. Please contact the site administrator for assistance.', 'fluent-support'),
262 ];
263
264 $i18ns['allowed_files_and_size'] = Helper::getFileUploadMessage();
265
266 $data = [
267 'rest' => $restInfo,
268 'nonce' => wp_create_nonce($slug),
269 'support_products' => Product::select(['id', 'title'])->get(),
270 'product_field_required' => Helper::isProductRequired(),
271 'customer_ticket_priorities' => Helper::customerTicketPriorities(),
272 'view_tickets_url' => '#/',
273 'i18n' => $i18ns,
274 'fallback_image' => $assets . 'images/icons/file.svg',
275 'has_file_upload' => !!Helper::ticketAcceptedFileMiles(),
276 'has_rich_text_editor' => true,
277 'customer_status' => static::customerStatus()->status ?? static::customerStatus(),
278 'max_file_upload' => Helper::getBusinessSettings('max_file_upload', 3),
279 'agent_feedback_rating' => Helper::getBusinessSettings('agent_feedback_rating', 'no'),
280 ];
281
282 if ($this->isSignedTicketView()) {
283 $data['intended_ticket_hash'] = sanitize_text_field($_REQUEST['support_hash']);
284 $data['view_tickets_url'] = Helper::getPortalBaseUrl() . '/#';
285 } else {
286 add_filter('user_can_richedit', '__return_true');
287 }
288 /*
289 * Filter customer portal localize javascript data
290 *
291 * @since v1.0.0
292 *
293 * @param array $data
294 */
295 $data = apply_filters('fluent_support/customer_portal_vars', $data);
296
297 if (!empty($data['has_rich_text_editor'])) {
298 wp_tinymce_inline_scripts();
299 wp_enqueue_editor();
300 }
301
302 wp_enqueue_script('dompurify', $assets . 'libs/purify/purify.min.js', [], '2.4.3');
303 wp_enqueue_script('fs_tk_customer_portal', $assets . 'portal/js/app.js', ['jquery'], FLUENT_SUPPORT_VERSION, true);
304 wp_enqueue_style('fs_tk_customer_portal', $assets . 'portal/css/app.css', [], FLUENT_SUPPORT_VERSION);
305
306 wp_localize_script('fs_tk_customer_portal', 'fs_customer_portal', $data);
307 }
308
309 protected static function customerStatus()
310 {
311 $user = get_current_user_id();
312
313 if (!$user && isset($_REQUEST['support_hash']) && isset($_REQUEST['ticket_id']) && isset($_REQUEST['fs_view']) && $_REQUEST['fs_view'] == 'ticket') {
314 return true;
315 }
316
317 return Customer::where('user_id', $user)->select(['status'])->first();
318 }
319 }
320