getMenuIcon(),
$menuPosition
);
add_submenu_page(
'fluent-support',
__('Dashboard', 'fluent-support'),
__('Dashboard', 'fluent-support'),
$capability,
'fluent-support',
array($this, 'renderApp')
);
add_submenu_page(
'fluent-support',
__('Tickets', 'fluent-support'),
__('Tickets', 'fluent-support'),
$capability,
'fluent-support#/tickets',
array($this, 'renderApp')
);
if (PermissionManager::currentUserCan('fst_view_all_reports')) {
add_submenu_page(
'fluent-support',
__('Reports', 'fluent-support'),
__('Reports', 'fluent-support'),
$capability,
'fluent-support#/reports',
array($this, 'renderApp')
);
}
if (PermissionManager::currentUserCan('fst_sensitive_data')) {
add_submenu_page(
'fluent-support',
__('Customers', 'fluent-support'),
__('Customers', 'fluent-support'),
$capability,
'fluent-support#/customers',
array($this, 'renderApp')
);
}
if (PermissionManager::currentUserCan('fst_view_activity_logs')) {
add_submenu_page(
'fluent-support',
__('Activities', 'fluent-support'),
__('Activities', 'fluent-support'),
$capability,
'fluent-support#/activity',
array($this, 'renderApp')
);
}
if (PermissionManager::currentUserCan('fst_manage_settings')) {
add_submenu_page(
'fluent-support',
__('Business Inboxes', 'fluent-support'),
__('Business Inboxes', 'fluent-support'),
$capability,
'fluent-support#/mailboxes',
array($this, 'renderApp')
);
}
if (PermissionManager::currentUserCan('fst_manage_workflows')) {
add_submenu_page(
'fluent-support',
__('Workflows', 'fluent-support'),
__('Workflows', 'fluent-support'),
$capability,
'fluent-support#/workflows',
array($this, 'renderApp')
);
}
if (PermissionManager::currentUserCan('fst_manage_saved_replies')) {
add_submenu_page(
'fluent-support',
__('Saved Replies', 'fluent-support'),
__('Saved Replies', 'fluent-support'),
$capability,
'fluent-support#/saved-replies',
array($this, 'renderApp')
);
}
if (PermissionManager::currentUserCan('fst_manage_settings')) {
add_submenu_page(
'fluent-support',
__('Settings', 'fluent-support'),
__('Settings', 'fluent-support'),
$capability,
'fluent-support#/settings',
array($this, 'renderApp')
);
}
}
public function getMenuItems()
{
$baseUrl = apply_filters('fluent_support/base_url', admin_url('admin.php?page=fluent-support#/'));
$menuItems = [
'dashboard' => [
'key' => 'dashboard',
'label' => __('Dashboard', 'fluent-support'),
'permalink' => $baseUrl,
],
'tickets' => [
'key' => 'tickets',
'label' => __('Tickets', 'fluent-support'),
'permalink' => $baseUrl . 'tickets',
],
'reports' => [
'key' => 'reports',
'label' => __('Reports', 'fluent-support'),
'permalink' => $baseUrl . 'reports',
],
];
$canManageSettings = PermissionManager::currentUserCan('fst_manage_settings');
if ($canManageSettings) {
$menuItems['mailboxes'] = [
'key' => 'mailboxes',
'label' => __('Business Inboxes', 'fluent-support'),
'permalink' => $baseUrl . 'mailboxes',
];
}
if (PermissionManager::currentUserCan('fst_view_activity_logs')) {
$menuItems['activity'] = [
'key' => 'activity',
'label' => __('Activities', 'fluent-support'),
'permalink' => $baseUrl . 'activity',
];
}
if (PermissionManager::currentUserCan('fst_sensitive_data')) {
$menuItems['customers'] = [
'key' => 'customers',
'label' => __('Customers', 'fluent-support'),
'permalink' => $baseUrl . 'customers',
];
}
$moreChildren = [];
if (PermissionManager::currentUserCan('fst_manage_saved_replies')) {
$moreChildren['saved_replies'] = [
'key' => 'saved_replies',
'label' => __('Saved Replies', 'fluent-support'),
'permalink' => $baseUrl . 'saved-replies',
];
}
if (PermissionManager::currentUserCan('fst_manage_workflows')) {
$moreChildren['workflows'] = [
'key' => 'workflows',
'label' => __('Workflows', 'fluent-support'),
'permalink' => $baseUrl . 'workflows',
];
}
if (!empty($moreChildren)) {
$menuItems['more'] = [
'key' => 'more',
'label' => __('More', 'fluent-support'),
'permalink' => '#',
'children' => $moreChildren,
];
}
if ($canManageSettings) {
$menuItems['settings'] = [
'key' => 'settings',
'label' => __('Global Settings', 'fluent-support'),
'permalink' => $baseUrl . 'settings',
];
}
return apply_filters('fluent_support/menu_items', $menuItems);
}
public function renderApp()
{
$app = App::getInstance();
$assets = $app['url.assets'];
$allItems = $this->getMenuItems();
$secondaryKeys = ['settings'];
$menuItems = [];
$secondaryItems = [];
foreach ($allItems as $key => $item) {
if (in_array($key, $secondaryKeys, true)) {
$secondaryItems[] = $item;
} else {
$menuItems[] = $item;
}
}
$menuItems = apply_filters('fluent_support/primary_menu_items', $menuItems);
$secondaryItems = apply_filters('fluent_support/secondary_menu_items', $secondaryItems);
if (!defined('FLUENT_SUPPORT_PRO_DIR_FILE')) {
$secondaryItems[] = [
'key' => 'upgrade_to_pro',
'label' => 'Upgrade to Pro',
'permalink' => Helper::getUpgradeUrl('sidebar_cta')
];
}
$baseUrl = apply_filters('fluent_support/base_url', admin_url('admin.php?page=fluent-support#/'));
$this->enqueueAssets();
do_action('fluent_support/admin_app_loaded', $app);
$app->view->render('admin.menu', [
'base_url' => $baseUrl,
'logo' => $assets . 'images/logo.svg',
'settingsLogo' => $assets . 'images/gear.svg',
'upgradeLogo' => $assets . 'images/crown.svg',
'assets' => $assets,
'menuItems' => $menuItems,
'secondaryItems' => isset($secondaryItems) ? $secondaryItems : [],
]);
}
public function maybeEnqueueAssets()
{
if (isset($_GET['page']) && sanitize_text_field(wp_unslash($_GET['page'])) === 'fluent-support') {
add_action('admin_head', [$this, 'printDarkModeInit'], 1);
$this->enqueueAssets();
}
}
public function printDarkModeInit()
{
?>
where('person_type', 'agent')
->get()->toArray();
foreach ($agents as $index => $agent) {
$agents[$index]['id'] = strval($agent['id']);
}
$agentGroups = AgentGroup::select(['id', 'title', 'settings'])->get();
$groupPivots = TagPivot::where('source_type', 'agent_group')->get();
foreach ($agentGroups as $group) {
$group->agent_ids = $groupPivots->where('tag_id', $group->id)
->pluck('source_id')
->map(function ($id) { return strval($id); })
->values()
->toArray();
}
$me = Helper::getAgentByUserId(get_current_user_id());
if (!$me && current_user_can('manage_options')) {
// we should create the agent
$user = wp_get_current_user();
$me = Agent::create([
'email' => $user->user_email,
'first_name' => $user->first_name,
'last_name' => $user->last_name,
'user_id' => $user->ID
]);
}
$me->permissions = PermissionManager::currentUserPermissions();
do_action('fluent_support_loading_app', $app);
// Editor default styles.
add_filter('user_can_richedit', '__return_true');
wp_tinymce_inline_scripts();
wp_enqueue_editor();
wp_enqueue_media();
wp_enqueue_script(
'fluent_support_admin_app_start',
Vite::getEnqueuePath('admin/js/start.js'),
array('jquery'),
FLUENT_SUPPORT_VERSION,
true
);
wp_enqueue_script(
'fluent_support_global_admin',
Vite::getEnqueuePath('admin/js/global_admin.js'),
array('jquery'),
FLUENT_SUPPORT_VERSION,
true
);
$integrationDrivers = [];
if (!defined('FLUENTSUPPORTPRO')) {
$integrationDrivers = [
[
'key' => 'telegram_settings',
'title' => __('Telegram', 'fluent-support'),
'description' => __('Send Telegram notifications to Group, Channel or individual person inbox and reply from Telegram inbox', 'fluent-support'),
'promo_heading' => __('Get activity notification to Telegram Messenger and reply directly from Telegram inbox', 'fluent-support'),
'require_pro' => true
],
[
'key' => 'slack_settings',
'title' => __('Slack', 'fluent-support'),
'description' => __('Send ticket activity notifications to slack', 'fluent-support'),
'promo_heading' => __('Get activity notification to Slack Channel and keep your support team super engaged', 'fluent-support'),
'require_pro' => true
]
];
}
/*
* Filter integration driver
* @param array $integrationDrivers
*/
$integrationDrivers = apply_filters('fluent_support/integration_drivers', $integrationDrivers);
$tags = TicketTag::select(['id', 'title'])->get()->toArray();
$tags = array_map(function ($tag) {
$tag['id'] = strval($tag['id']);
return $tag;
}, $tags);
$i18ns = TranslationStrings::getAdminStrings();
$i18ns['allowed_files_and_size'] = Helper::getFileUploadMessage();
$i18ns['open'] = __('Open', 'fluent-support');
$i18ns['all'] = __('All', 'fluent-support');
/*
* Filter agent portal localize javascript data
*
* @since v1.0.0
*
* @param array $appVars
*/
$appVars = apply_filters('fluent_support_app_vars', array(
'slug' => $slug = $app->config->get('app.slug'),
'nonce' => wp_create_nonce($slug),
'rest' => $this->getRestInfo($app),
'brand_logo' => $this->getMenuIcon(),
'firstEntry' => '',
'lastEntry' => '',
'asset_url' => $assets,
'support_agents' => $agents,
'agent_groups' => $agentGroups,
'support_products' => Product::select(['id', 'title'])->orderedByTitle()->get(),
'client_priorities' => Helper::customerTicketPriorities(),
'ticket_statuses' => Helper::ticketStatuses(),
'ticket_statuses_group' => Helper::ticketStatusGroups(),
'changeable_ticket_statuses' => Helper::changeableTicketStatuses(),
'admin_priorities' => Helper::adminTicketPriorities(),
'mailboxes' => MailBox::getAccessibleBoxes(),
// Whether the site has any inbox at all, regardless of what this agent may see.
// `mailboxes` is restriction-filtered and can legitimately be empty, so it cannot
// double as the "is Fluent Support set up yet?" signal the setup wizard keys off.
'has_mailboxes' => MailBox::count() > 0,
'me' => $me,
// Deleting a customer needs fst_sensitive_data plus administrator rights unless
// the site turns the administrator part off.
'customer_delete_requires_admin' => (bool) apply_filters('fluent_support/customer_delete_requires_admin', true),
'pref' => [
'go_back_after_reply' => 'yes'
],
'notification_integrations' => $integrationDrivers,
'internal_notification_settings' => (new NotificationSettings())->get(false),
'server_time' => gmdate('Y-m-d\TH:i:sP'),
'has_email_parser' => defined('FLUENTSUPPORTPRO_PLUGIN_VERSION'),
'ticket_tags' => $tags,
'i18n' => $i18ns,
'custom_fields' => apply_filters('fluent_support/ticket_custom_fields', []),
'has_file_upload' => !!Helper::ticketAcceptedFileMiles(),
'repost_export_options' => Helper::getExportOptions(),
'enable_draft_mode' => Helper::getBusinessSettings('enable_draft_mode', 'no'),
'keyboard_shortcuts' => Helper::getBusinessSettings('keyboard_shortcuts', 'no'),
'agent_time_tracking' => Helper::getBusinessSettings('agent_time_tracking', 'no'),
'max_file_upload' => Helper::getBusinessSettings('max_file_upload', 3),
'ajaxurl' => admin_url('admin-ajax.php'),
'auth_provider' => Helper::getAuthProvider(),
'fluent_bot_integration' => Helper::fluentBotIntegrationStatus(),
));
$appVars['fluent_booking'] = (new FluentBookingService())->getStatus();
if (defined('FLUENTCRM')) {
$appVars['fluentcrm_config'] = Helper::getFluentCRMTagConfig();
}
if (defined('FLUENT_BOARDS')) {
$appVars['fluent_boards'] = true;
}
$appVars['has_pro'] = defined('FLUENTSUPPORTPRO_PLUGIN_VERSION');
$appVars['version'] = FLUENT_SUPPORT_VERSION;
// Single source of truth for upgrade CTAs; the SPA only re-points utm_content on this.
$appVars['upgrade_url'] = Helper::getUpgradeUrl();
if ($appVars['has_pro']) {
$appVars['agent_feedback_rating'] = Helper::getBusinessSettings('agent_feedback_rating', 'no');
$appVars['open_ai_integration'] = Helper::openAIIntegrationStatus();
}
wp_localize_script('fluent_support_admin_app_start', 'fluentSupportAdmin', $appVars);
}
protected function getRestInfo($app)
{
$ns = $app->config->get('app.rest_namespace');
$v = $app->config->get('app.rest_version');
return [
'base_url' => esc_url_raw(rest_url()),
'url' => rest_url($ns . '/' . $v),
'nonce' => wp_create_nonce('wp_rest'),
'namespace' => $ns,
'version' => $v,
];
}
protected function getMenuIcon()
{
$app = App::getInstance();
$assets = $app['path.assets'];
return 'data:image/svg+xml;base64,' . base64_encode(
''
);
}
}