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/Hooks/Handlers/Menu.php +64 -53 2.2.0 → 2.4.5 View file →
@@ -142,31 +142,27 @@
142 142 );
143 143 }
144 144 }
145 145
146 - public function renderApp()
146 + public function getMenuItems()
147 147 {
148 - $app = App::getInstance();
149 -
150 - $assets = $app['url.assets'];
151 -
152 148 $baseUrl = apply_filters('fluent_support/base_url', admin_url('admin.php?page=fluent-support#/'));
153 149
154 150 $menuItems = [
155 - [
151 + 'dashboard' => [
156 152 'key' => 'dashboard',
157 153 'label' => __('Dashboard', 'fluent-support'),
158 - 'permalink' => $baseUrl
154 + 'permalink' => $baseUrl,
159 155 ],
160 - [
156 + 'tickets' => [
161 157 'key' => 'tickets',
162 158 'label' => __('Tickets', 'fluent-support'),
163 159 'permalink' => $baseUrl . 'tickets',
164 160 ],
165 - [
161 + 'reports' => [
166 162 'key' => 'reports',
167 163 'label' => __('Reports', 'fluent-support'),
168 - 'permalink' => $baseUrl . 'reports'
164 + 'permalink' => $baseUrl . 'reports',
169 165 ],
170 166 ];
171 167
172 168 $canManageSettings = PermissionManager::currentUserCan('fst_manage_settings');
@@ -171,33 +167,31 @@
171 167
172 168 $canManageSettings = PermissionManager::currentUserCan('fst_manage_settings');
173 169
174 170 if ($canManageSettings) {
175 - $menuItems[] = [
171 + $menuItems['mailboxes'] = [
176 172 'key' => 'mailboxes',
177 173 'label' => __('Business Inboxes', 'fluent-support'),
178 - 'permalink' => $baseUrl . 'mailboxes'
174 + 'permalink' => $baseUrl . 'mailboxes',
179 175 ];
180 176 }
181 177
182 178 if (PermissionManager::currentUserCan('fst_view_activity_logs')) {
183 - $menuItems[] = [
179 + $menuItems['activity'] = [
184 180 'key' => 'activity',
185 181 'label' => __('Activities', 'fluent-support'),
186 - 'permalink' => $baseUrl . 'activity'
182 + 'permalink' => $baseUrl . 'activity',
187 183 ];
188 184 }
189 185
190 - $hasSensitiveAccess = PermissionManager::currentUserCan('fst_sensitive_data');
191 - if ($hasSensitiveAccess) {
192 - $menuItems[] = [
186 + if (PermissionManager::currentUserCan('fst_sensitive_data')) {
187 + $menuItems['customers'] = [
193 188 'key' => 'customers',
194 189 'label' => __('Customers', 'fluent-support'),
195 - 'permalink' => $baseUrl . 'customers'
190 + 'permalink' => $baseUrl . 'customers',
196 191 ];
197 192 }
198 193
199 - // Build the "More" dropdown children
200 194 $moreChildren = [];
201 195
202 196 if (PermissionManager::currentUserCan('fst_manage_saved_replies')) {
203 197 $moreChildren['saved_replies'] = [
@@ -202,9 +196,9 @@
202 196 if (PermissionManager::currentUserCan('fst_manage_saved_replies')) {
203 197 $moreChildren['saved_replies'] = [
204 198 'key' => 'saved_replies',
205 199 'label' => __('Saved Replies', 'fluent-support'),
206 - 'permalink' => $baseUrl . 'saved-replies'
200 + 'permalink' => $baseUrl . 'saved-replies',
207 201 ];
208 202 }
209 203
210 204 if (PermissionManager::currentUserCan('fst_manage_workflows')) {
@@ -210,61 +204,65 @@
210 204 if (PermissionManager::currentUserCan('fst_manage_workflows')) {
211 205 $moreChildren['workflows'] = [
212 206 'key' => 'workflows',
213 207 'label' => __('Workflows', 'fluent-support'),
214 - 'permalink' => $baseUrl . 'workflows'
208 + 'permalink' => $baseUrl . 'workflows',
215 209 ];
216 210 }
217 211
218 - // Add the "More" dropdown if there are children
219 212 if (!empty($moreChildren)) {
220 - $menuItems[] = [
221 - 'key' => 'more',
222 - 'label' => __('More', 'fluent-support'),
213 + $menuItems['more'] = [
214 + 'key' => 'more',
215 + 'label' => __('More', 'fluent-support'),
223 216 'permalink' => '#',
224 - 'children' => $moreChildren
217 + 'children' => $moreChildren,
225 218 ];
226 219 }
227 220
228 - $secondaryItems = [];
229 -
230 221 if ($canManageSettings) {
231 - $secondaryItems[] = [
222 + $menuItems['settings'] = [
232 223 'key' => 'settings',
233 224 'label' => __('Global Settings', 'fluent-support'),
234 - 'permalink' => $baseUrl . 'settings'
225 + 'permalink' => $baseUrl . 'settings',
235 226 ];
236 227 }
237 228
238 - /*
239 - * Filter Fluent Support dashboard top-left menu items
240 - *
241 - * @since v1.0.0
242 - *
243 - * @param array $menuItems
244 - */
245 - $menuItems = apply_filters('fluent_support/primary_menu_items', $menuItems);
229 + return apply_filters('fluent_support/menu_items', $menuItems);
230 + }
246 231
247 - /*
248 - * Filter Fluent Support dashboard top-right menu items
249 - *
250 - * @since v1.0.0
251 - *
252 - * @param array $secondaryItems
253 - */
254 - $secondaryItems = apply_filters('fluent_support/secondary_menu_items', $secondaryItems);
232 + public function renderApp()
233 + {
234 + $app = App::getInstance();
255 235
236 + $assets = $app['url.assets'];
256 237
238 + $allItems = $this->getMenuItems();
257 239
240 + $secondaryKeys = ['settings'];
241 + $menuItems = [];
242 + $secondaryItems = [];
243 +
244 + foreach ($allItems as $key => $item) {
245 + if (in_array($key, $secondaryKeys, true)) {
246 + $secondaryItems[] = $item;
247 + } else {
248 + $menuItems[] = $item;
249 + }
250 + }
251 +
252 + $menuItems = apply_filters('fluent_support/primary_menu_items', $menuItems);
253 + $secondaryItems = apply_filters('fluent_support/secondary_menu_items', $secondaryItems);
254 +
258 255 if (!defined('FLUENT_SUPPORT_PRO_DIR_FILE')) {
259 256 $secondaryItems[] = [
260 257 'key' => 'upgrade_to_pro',
261 - 'label' => 'Upgrade to Pro',
262 - 'permalink' => 'https://fluentsupport.com'
258 + 'label' => __('Upgrade to Pro', 'fluent-support'),
259 + 'permalink' => Helper::getUpgradeUrl('sidebar_cta')
263 260 ];
264 261 }
265 262
266 - $app = App::getInstance();
263 + $baseUrl = apply_filters('fluent_support/base_url', admin_url('admin.php?page=fluent-support#/'));
264 +
267 265 $this->enqueueAssets();
268 266
269 267 do_action('fluent_support/admin_app_loaded', $app);
270 268 $app->view->render('admin.menu', [
@@ -326,9 +324,9 @@
326 324 add_action('admin_head', function () {
327 325 Vite::injectViteClient();
328 326 }, 1);
329 327
330 - wp_enqueue_script('dompurify', $assets . 'libs/purify/purify.min.js', [], '2.4.3');
328 + wp_enqueue_script('dompurify', $assets . 'libs/purify/purify.min.js', [], '3.4.16');
331 329
332 330 if (is_rtl()) {
333 331 wp_enqueue_style('fluent_support_admin_app_rtl', $assets . 'admin/css/alpha-admin-rtl.css', [], FLUENT_SUPPORT_VERSION);
334 332 } else {
@@ -426,8 +424,10 @@
426 424 }, $tags);
427 425
428 426 $i18ns = TranslationStrings::getAdminStrings();
429 427 $i18ns['allowed_files_and_size'] = Helper::getFileUploadMessage();
428 + $i18ns['open'] = __('Open', 'fluent-support');
429 + $i18ns['all'] = __('All', 'fluent-support');
430 430
431 431 /*
432 432 * Filter agent portal localize javascript data
433 433 *
@@ -444,22 +444,30 @@
444 444 'lastEntry' => '',
445 445 'asset_url' => $assets,
446 446 'support_agents' => $agents,
447 447 'agent_groups' => $agentGroups,
448 - 'support_products' => Product::select(['id', 'title'])->get(),
448 + 'support_products' => Product::select(['id', 'title'])->orderedByTitle()->get(),
449 449 'client_priorities' => Helper::customerTicketPriorities(),
450 450 'ticket_statuses' => Helper::ticketStatuses(),
451 451 'ticket_statuses_group' => Helper::ticketStatusGroups(),
452 452 'changeable_ticket_statuses' => Helper::changeableTicketStatuses(),
453 453 'admin_priorities' => Helper::adminTicketPriorities(),
454 - 'mailboxes' => MailBox::select(['id', 'name', 'settings'])->get(),
454 + 'mailboxes' => MailBox::getAccessibleBoxes(),
455 + // Whether the site has any inbox at all, regardless of what this agent may see.
456 + // `mailboxes` is restriction-filtered and can legitimately be empty, so it cannot
457 + // double as the "is Fluent Support set up yet?" signal the setup wizard keys off.
458 + 'has_mailboxes' => MailBox::count() > 0,
455 459 'me' => $me,
460 + // Deleting a customer needs fst_sensitive_data plus administrator rights unless
461 + // the site turns the administrator part off.
462 + 'customer_delete_requires_admin' => (bool) apply_filters('fluent_support/customer_delete_requires_admin', true),
456 463 'pref' => [
457 464 'go_back_after_reply' => 'yes'
458 465 ],
459 466 'notification_integrations' => $integrationDrivers,
460 467 'internal_notification_settings' => (new NotificationSettings())->get(false),
461 - 'server_time' => gmdate('Y-m-d\TH:i:sP'),
468 + // Site time, like every date the API sends; relative times compare the two.
469 + 'server_time' => current_time('mysql'),
462 470 'has_email_parser' => defined('FLUENTSUPPORTPRO_PLUGIN_VERSION'),
463 471 'ticket_tags' => $tags,
464 472 'i18n' => $i18ns,
465 473 'custom_fields' => apply_filters('fluent_support/ticket_custom_fields', []),
@@ -484,8 +492,11 @@
484 492 $appVars['fluent_boards'] = true;
485 493 }
486 494
487 495 $appVars['has_pro'] = defined('FLUENTSUPPORTPRO_PLUGIN_VERSION');
496 + $appVars['version'] = FLUENT_SUPPORT_VERSION;
497 + // Single source of truth for upgrade CTAs; the SPA only re-points utm_content on this.
498 + $appVars['upgrade_url'] = Helper::getUpgradeUrl();
488 499 if ($appVars['has_pro']) {
489 500 $appVars['agent_feedback_rating'] = Helper::getBusinessSettings('agent_feedback_rating', 'no');
490 501 $appVars['open_ai_integration'] = Helper::openAIIntegrationStatus();
491 502 }