PluginProbe
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses / 2.10.0
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses v2.10.0
2.10.0 2.10.01 2.9.1 2.9.0 2.8.1 2.8.0 2.7.7 2.7.5 2.7.0 2.6.01 2.6.0 2.5.0 2.4.01 trunk 1.0.90 1.0.91 1.0.92 1.0.93 1.0.94 1.0.95 1.0.96 1.0.97 1.0.98 1.0.99 1.1.0 All 77 releases
← All changes | app/Functions/Utility.php +1016 -65 1.0.922.10.0 View file →
@@ -1,24 +1,43 @@
1 1 <?php
2 2
3 3 namespace FluentCommunity\App\Functions;
4 4
5 +use FluentCommunity\App\App;
5 6 use FluentCommunity\App\Models\Meta;
6 7 use FluentCommunity\App\Models\Space;
7 8 use FluentCommunity\App\Models\SpaceGroup;
8 9 use FluentCommunity\App\Models\Term;
9 10 use FluentCommunity\App\Services\FeedsHelper;
11 +use FluentCommunity\App\Services\Helper;
10 12 use FluentCommunity\Framework\Support\Arr;
11 13 use FluentCommunity\Modules\Course\Model\Course;
14 +use FluentCommunity\Modules\PushNotification\PushNotificationModule;
12 15
13 16 class Utility
14 17 {
18 + public static function isDev()
19 + {
20 + static $isDev = null;
21 + if ($isDev !== null) {
22 + return $isDev;
23 + }
15 24
25 + $config = App::getInstance()->config;
26 + $isDev = $config->get('app.env') === 'dev';
27 + return $isDev;
28 + }
29 +
16 30 public static function getApp($instance = null)
17 31 {
18 32 return \FluentCommunity\App\App::getInstance($instance);
19 33 }
20 34
35 + public static function extender()
36 + {
37 + return new FluentExtendApi();
38 + }
39 +
21 40 /**
22 41 * Get Global Fluent Community Option
23 42 * @param string $key The option name
24 43 * @param mixed $default the default value of the option if option is not available
@@ -38,8 +57,45 @@
38 57 return $default;
39 58 });
40 59 }
41 60
61 + /**
62 + * Update Global Fluent Community Option
63 + * @param string $key The option name
64 + * @param mixed $value the value of the option
65 + * @return \FluentCommunity\App\Models\Meta
66 + */
67 + public static function updateOption($key, $value)
68 + {
69 + $exist = \FluentCommunity\App\Models\Meta::where('object_type', 'option')
70 + ->where('meta_key', $key)
71 + ->first();
72 + if ($exist) {
73 + $exist->value = $value;
74 + $exist->save();
75 +
76 + } else {
77 + $exist = \FluentCommunity\App\Models\Meta::create([
78 + 'meta_key' => $key, // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
79 + 'object_type' => 'option',
80 + 'value' => $value
81 + ]);
82 + }
83 +
84 + self::setCache('option_' . $key, $value);
85 +
86 + return $exist;
87 + }
88 +
89 + public static function deleteOption($key)
90 + {
91 + \FluentCommunity\App\Models\Meta::where('object_type', 'option')
92 + ->where('meta_key', $key)
93 + ->delete();
94 +
95 + self::forgetCache('option_' . $key);
96 + }
97 +
42 98 public static function getFeaturesConfig()
43 99 {
44 100 static $features = null;
45 101
@@ -49,19 +105,23 @@
49 105
50 106 $features = self::getOption('fluent_community_features', []);
51 107
52 108 $defaults = [
53 - 'leader_board_module' => 'yes',
54 - 'course_module' => 'yes',
55 - 'giphy_module' => 'no',
56 - 'giphy_api_key' => '',
57 - 'emoji_module' => 'yes',
58 - 'cloud_storage' => 'no',
59 - 'invitation' => 'yes',
60 - 'user_badge' => 'yes',
109 + 'leader_board_module' => 'yes',
110 + 'course_module' => 'yes',
111 + 'giphy_module' => 'no',
112 + 'giphy_api_key' => '',
113 + 'emoji_module' => 'yes',
114 + 'cloud_storage' => 'no',
115 + 'invitation' => 'yes',
116 + 'user_badge' => 'yes',
117 + 'has_crm_sync' => 'no',
118 + 'content_moderation' => 'no',
119 + 'followers_module' => 'no',
120 + 'custom_profile_fields' => 'no',
121 + 'pwa_module' => 'no',
61 122 ];
62 123
63 -
64 124 if (defined('FLUENT_COMMUNITY_CLOUD_STORAGE') && FLUENT_COMMUNITY_CLOUD_STORAGE) {
65 125 $features['cloud_storage'] = 'yes';
66 126 }
67 127
@@ -67,8 +127,9 @@
67 127
68 128 $features = wp_parse_args($features, $defaults);
69 129
70 130 $hasPro = defined('FLUENT_COMMUNITY_PRO') && FLUENT_COMMUNITY_PRO;
131 +
71 132 if (!$hasPro) {
72 133 $features['leader_board_module'] = 'no';
73 134 $features['giphy_module'] = 'no';
74 135 $features['emoji_module'] = 'no';
@@ -73,8 +134,11 @@
73 134 $features['giphy_module'] = 'no';
74 135 $features['emoji_module'] = 'no';
75 136 $features['cloud_storage'] = 'no';
76 137 $features['user_badge'] = 'no';
138 + $features['followers_module'] = 'no';
139 + $features['custom_profile_fields'] = 'no';
140 + $features['pwa_module'] = 'no';
77 141 }
78 142
79 143 return $features;
80 144 }
@@ -79,36 +143,8 @@
79 143 return $features;
80 144 }
81 145
82 146 /**
83 - * Update Global Fluent Community Option
84 - * @param string $key The option name
85 - * @param mixed $value the value of the option
86 - * @return \FluentCommunity\App\Models\Meta
87 - */
88 - public static function updateOption($key, $value)
89 - {
90 - $exist = \FluentCommunity\App\Models\Meta::where('object_type', 'option')
91 - ->where('meta_key', $key)
92 - ->first();
93 - if ($exist) {
94 - $exist->value = $value;
95 - $exist->save();
96 -
97 - } else {
98 - $exist = \FluentCommunity\App\Models\Meta::create([
99 - 'meta_key' => $key,
100 - 'object_type' => 'option',
101 - 'value' => $value
102 - ]);
103 - }
104 -
105 - self::setCache('option_' . $key, $value);
106 -
107 - return $exist;
108 - }
109 -
110 - /**
111 147 * @param $key
112 148 * @param $callback
113 149 * @param $expire
114 150 * @return false|mixed
@@ -167,30 +203,40 @@
167 203 return $settings;
168 204 }
169 205
170 206 $defaults = [
171 - 'dark_mode' => 'yes',
172 - 'fixed_page_header' => 'yes',
173 - 'show_powered_by' => 'yes',
174 - 'feed_link_on_sidebar' => 'yes',
175 - 'fixed_sidebar' => 'no',
176 - 'icon_on_header_menu' => 'no',
177 - 'affiliate_id' => '',
178 - 'rich_post_layout' => 'classic',
179 - 'post_title_pref' => 'optional',
180 - 'a11y_enhancement_style' => 'no',
207 + 'dark_mode' => 'yes',
208 + 'default_theme_mode' => 'light',
209 + 'fixed_page_header' => 'yes',
210 + 'show_powered_by' => 'yes',
211 + 'feed_link_on_sidebar' => 'yes',
212 + 'show_post_modal' => 'yes',
213 + 'fixed_sidebar' => 'no',
214 + 'icon_on_header_menu' => 'no',
215 + 'affiliate_id' => '',
216 + 'rich_post_layout' => 'classic',
217 + 'member_list_layout' => 'classic', // grid, classic
218 + 'default_feed_layout' => 'timeline', // list, timeline
219 + 'disable_feed_layout' => 'no',
220 + 'post_title_pref' => 'optional',
221 + 'max_media_per_post' => 4,
222 + 'disable_feed_sort_by' => 'no',
223 + 'default_feed_sort_by' => '',
224 + 'collapse_sidebar_groups' => 'no',
225 + 'hide_header_on_scroll' => 'no',
226 + 'enable_sidebar_toggle' => 'no'
181 227 ];
182 -
183 228 $settings = self::getOption('customization_settings', $defaults);
184 229
185 230 $settings = wp_parse_args($settings, $defaults);
186 -
231 + $settings = apply_filters('fluent_community/customization_settings', $settings);
187 232 if (!defined('FLUENT_COMMUNITY_PRO')) {
188 233 $settings['show_powered_by'] = 'yes';
189 234 $settings['affiliate_id'] = '';
190 235 $settings['rich_post_layout'] = 'classic';
236 + $settings['member_list_layout'] = 'classic';
237 + $settings['enable_sidebar_toggle'] = 'no';
191 238 }
192 -
193 239 return $settings;
194 240 }
195 241
196 242 public static function getCustomizationSetting($key)
@@ -208,8 +254,118 @@
208 254
209 255 return $settings;
210 256 }
211 257
258 + public static function getPrivacySettings()
259 + {
260 + static $settings;
261 +
262 + if ($settings) {
263 + return $settings;
264 + }
265 +
266 + $defaults = [
267 + 'can_customize_username' => 'no',
268 + 'can_change_email' => 'no',
269 + 'can_change_password' => 'yes',
270 + 'show_last_activity' => 'yes',
271 + 'can_deactive_account' => 'no',
272 + 'email_auto_login' => 'yes',
273 + 'enable_gravatar' => 'yes',
274 + 'enable_user_sync' => 'yes',
275 + 'skip_crm_undeliverable_emails' => 'yes',
276 + 'members_page_status' => 'everybody', // everybody, logged_in, admin_only
277 + 'profile_page_visibility' => 'everybody', // everybody, logged_in, admin_only
278 + 'user_space_visibility' => 'everybody', // everybody, logged_in, admin_only
279 + 'leaderboard_members_visibility' => 'everybody', // everybody, logged_in, admin_only
280 + ];
281 +
282 + $settings = self::getOption('privacy_settings', $defaults);
283 +
284 + $settings = wp_parse_args($settings, $defaults);
285 +
286 + if (!defined('FLUENT_COMMUNITY_PRO')) {
287 + $settings['can_customize_username'] = 'no';
288 + $settings['can_change_email'] = 'no';
289 + $settings['email_auto_login'] = 'no';
290 + }
291 +
292 + return $settings;
293 + }
294 +
295 + public static function canViewMembersPage()
296 + {
297 + $pageStatus = self::getPrivacySetting('members_page_status');
298 +
299 + if ($pageStatus == 'everybody') {
300 + return apply_filters('fluent_community/can_view_members_page', true, $pageStatus);
301 + }
302 +
303 + if ($pageStatus == 'logged_in') {
304 + return apply_filters('fluent_community/can_view_members_page', is_user_logged_in(), $pageStatus);
305 + }
306 +
307 + return apply_filters('fluent_community/can_view_members_page', Helper::isModerator(), $pageStatus);
308 + }
309 +
310 + public static function canViewLeaderboardMembers()
311 + {
312 + $pageStatus = self::getPrivacySetting('leaderboard_members_visibility');
313 +
314 + if ($pageStatus == 'everybody') {
315 + return apply_filters('fluent_community/can_view_leaderboard_members', true, $pageStatus);
316 + }
317 +
318 + if ($pageStatus == 'logged_in') {
319 + return apply_filters('fluent_community/can_view_leaderboard_members', is_user_logged_in(), $pageStatus);
320 + }
321 +
322 + return apply_filters('fluent_community/can_view_leaderboard_members', Helper::isModerator(), $pageStatus);
323 + }
324 +
325 + public static function canViewUserProfile($targetUserId = null)
326 + {
327 + $pageStatus = self::getPrivacySetting('profile_page_visibility');
328 +
329 + if ($pageStatus == 'everybody') {
330 + return apply_filters('fluent_community/can_view_user_profile', true, $pageStatus, $targetUserId);
331 + }
332 +
333 + if ($pageStatus == 'logged_in') {
334 + return apply_filters('fluent_community/can_view_user_profile', is_user_logged_in(), $pageStatus, $targetUserId);
335 + }
336 +
337 + $isOwn = $targetUserId && (get_current_user_id() === $targetUserId);
338 +
339 + return apply_filters('fluent_community/can_view_user_profile', ($isOwn || Helper::isModerator()), $pageStatus, $targetUserId);
340 + }
341 +
342 + public static function getPrivacySetting($key)
343 + {
344 + $settings = self::getPrivacySettings();
345 + return Arr::get($settings, $key);
346 + }
347 +
348 + public static function updatePrivacySettings($settings)
349 + {
350 + $preSettings = self::getPrivacySettings();
351 + $settings = Arr::only($settings, array_keys($preSettings));
352 +
353 + $settings = array_map(function ($value) {
354 + return is_scalar($value) ? sanitize_text_field($value) : '';
355 + }, $settings);
356 +
357 + self::updateOption('privacy_settings', $settings);
358 + self::forgetCache('privacy_settings');
359 +
360 + return $settings;
361 + }
362 +
363 + public static function showLastActivity()
364 + {
365 + return self::getPrivacySetting('show_last_activity') === 'yes' || Helper::isModerator();
366 + }
367 +
212 368 public static function isCustomizationEnabled($key, $matchingValue = 'yes')
213 369 {
214 370 $settings = self::getCustomizationSettings();
215 371 return isset($settings[$key]) && $settings[$key] === $matchingValue;
@@ -214,17 +370,19 @@
214 370 $settings = self::getCustomizationSettings();
215 371 return isset($settings[$key]) && $settings[$key] === $matchingValue;
216 372 }
217 373
218 - public static function getProductUrl($isPowered = false)
374 + public static function getProductUrl($isPowered = false, $params = [])
219 375 {
220 376 $url = 'https://fluentcommunity.co/';
221 377 if ($isPowered) {
222 - $params = [
378 + $defaultParams = [
223 379 'utm_source' => 'power_footer',
224 380 'utm_medium' => 'site',
225 381 'utm_campaign' => 'powered_by'
226 382 ];
383 + $params = wp_parse_args($params, $defaultParams);
384 +
227 385 $settings = self::getCustomizationSettings();
228 386 $affId = Arr::get($settings, 'affiliate_id');
229 387 if ($affId) {
230 388 $params['ref'] = $affId;
@@ -229,19 +387,57 @@
229 387 if ($affId) {
230 388 $params['ref'] = $affId;
231 389 }
232 390
233 - $url = add_query_arg($params, $url);
391 + return add_query_arg($params, $url);
234 392 }
235 393
236 394 return add_query_arg([
237 395 'utm_source' => 'plugin',
238 396 'utm_medium' => 'site',
239 - 'utm_campaign' => 'pligin_ui'
397 + 'utm_campaign' => 'plugin_ui'
240 398 ], $url);
241 399 }
242 400
243 401 /**
402 + * Build a spec-compliant "Upgrade to Pro" URL.
403 + *
404 + * Follows the shared Fluent* UTM spec:
405 + * utm_source = fluent-community (fixed vocabulary, never the wp.org slug)
406 + * utm_medium = free_plugin | pro_plugin (acquisition vs cross-sell)
407 + * utm_campaign= upgrade_pro (override for xsell_<target> / license_* )
408 + * utm_content = the exact placement, e.g. feature_lock_moderation, upgrade_page
409 + * utm_term = plugin version that generated the link
410 + * utm_id = promo id, blank normally (omit unless passed)
411 + *
412 + * @param string $content The utm_content placement.
413 + * @param array $overrides Override any utm_* param (e.g. utm_campaign for cross-sell).
414 + * @return string
415 + */
416 + public static function getProUpgradeUrl($content = 'upgrade_page', $overrides = [])
417 + {
418 + $baseUrl = apply_filters(
419 + 'fluent_community/pro_upgrade_base_url',
420 + 'https://fluentcommunity.co/pricing/'
421 + );
422 +
423 + $params = wp_parse_args($overrides, [
424 + 'utm_source' => 'fluent-community',
425 + 'utm_medium' => defined('FLUENT_COMMUNITY_PRO_VERSION') ? 'pro_plugin' : 'free_plugin',
426 + 'utm_campaign' => 'upgrade_pro',
427 + 'utm_content' => $content,
428 + 'utm_term' => FLUENT_COMMUNITY_PLUGIN_VERSION,
429 + ]);
430 +
431 + // Drop any blank params (e.g. an unset utm_id) so they never hit the URL.
432 + $params = array_filter($params, function ($value) {
433 + return $value !== '' && $value !== null;
434 + });
435 +
436 + return add_query_arg($params, $baseUrl);
437 + }
438 +
439 + /**
244 440 * Get the email notification settings.
245 441 *
246 442 * @return array The email notification settings.
247 443 */
@@ -262,13 +458,14 @@
262 458 'send_from_email' => '',
263 459 'send_from_name' => '',
264 460 'reply_to_email' => '',
265 461 'reply_to_name' => '',
266 - 'email_footer' => 'You are getting this email because you are a member of {{site_name_with_url}}.\n\n{{manage_email_notification_url|Manage Your Email Notifications Preference}}.',
462 + 'email_footer' => 'You are getting this email because you are a member of {{site_name_with_url}}.' . PHP_EOL . PHP_EOL . '{{manage_email_notification_url|Manage Your Email Notifications Preference}}.',
267 463 'disable_powered_by' => 'no',
464 + 'logo' => ''
268 465 ];
269 466
270 - $settings = self::getOption('global_email_settings', $default);
467 + $settings = array_filter(self::getOption('global_email_settings', $default));
271 468 $settings = wp_parse_args($settings, $default);
272 469
273 470 if (!defined('FLUENT_COMMUNITY_PRO')) {
274 471 $settings['disable_powered_by'] = 'no';
@@ -280,8 +477,35 @@
280 477
281 478 return $settings;
282 479 }
283 480
481 + public static function getPushNotificationSettings()
482 + {
483 + static $settings;
484 + if ($settings) return $settings;
485 +
486 + $default = [
487 + 'push_enabled' => 'yes',
488 + 'com_my_post_push' => 'yes',
489 + 'reply_my_com_push' => 'yes',
490 + 'mention_push' => 'yes',
491 + 'co_com_push' => 'yes',
492 + 'prompt_placements' => PushNotificationModule::PROMPT_PLACEMENTS
493 + ];
494 +
495 + $settings = self::getOption('global_push_settings', $default);
496 +
497 + $settings = wp_parse_args($settings, $default);
498 +
499 + return $settings;
500 + }
501 +
502 + public static function hasEmailAnnouncementEnabled()
503 + {
504 + $settings = self::getEmailNotificationSettings();
505 + return Arr::get($settings, 'mention_mail', 'no') === 'yes';
506 + }
507 +
284 508 public static function postTitlePref()
285 509 {
286 510 $pref = self::getCustomizationSetting('post_title_pref');
287 511
@@ -297,9 +521,9 @@
297 521 if ($byGroups) {
298 522 return SpaceGroup::orderBy('serial', 'ASC')->with('spaces', function ($q) {
299 523 $q->orderBy('serial', 'ASC')
300 524 ->where('type', 'community');
301 - })->all();
525 + })->get();
302 526 }
303 527
304 528 return Space::where('type', 'community')->orderBy('serial', 'ASC')->get();
305 529 }
@@ -309,9 +533,9 @@
309 533 if ($byGroups) {
310 534 return SpaceGroup::orderBy('serial', 'ASC')->with('spaces', function ($q) {
311 535 $q->orderBy('serial', 'ASC')
312 536 ->where('type', 'course');
313 - })->all();
537 + })->get();
314 538 }
315 539
316 540 return Course::orderBy('serial', 'ASC')->get();
317 541 }
@@ -326,8 +550,25 @@
326 550 $key = 'fluent_community_post_topics';
327 551 $topics = self::getFromCache($key, function () {
328 552 $topics = Term::where('taxonomy_name', 'post_topic')->orderBy('title', 'ASC')->get();
329 553
554 + // Respect the admin-defined order (settings.serial) when present;
555 + // topics without a serial fall back to the alphabetical order above.
556 + $topics = $topics->sort(function ($a, $b) {
557 + $serialA = Arr::get($a->settings, 'serial');
558 + $serialB = Arr::get($b->settings, 'serial');
559 + if ($serialA === null && $serialB === null) {
560 + return 0;
561 + }
562 + if ($serialA === null) {
563 + return 1;
564 + }
565 + if ($serialB === null) {
566 + return -1;
567 + }
568 + return (int) $serialA <=> (int) $serialB;
569 + })->values();
570 +
330 571 /*
331 572 * object_id = term_id
332 573 * meta_key = space_id
333 574 */
@@ -345,13 +586,15 @@
345 586
346 587 $formattedTopics = [];
347 588 foreach ($topics as $topic) {
348 589 $formattedTopics[] = [
349 - 'id' => $topic->id,
350 - 'title' => $topic->title,
351 - 'slug' => $topic->slug,
352 - 'admin_only' => Arr::get($topic->settings, 'admin_only', 'no'),
353 - 'space_ids' => isset($relations[$topic->id]) ? $relations[$topic->id] : []
590 + 'id' => $topic->id,
591 + 'title' => $topic->title,
592 + 'description' => $topic->description,
593 + 'slug' => $topic->slug,
594 + 'admin_only' => Arr::get($topic->settings, 'admin_only', 'no'),
595 + 'serial' => Arr::get($topic->settings, 'serial'),
596 + 'space_ids' => isset($relations[$topic->id]) ? $relations[$topic->id] : []
354 597 ];
355 598 }
356 599
357 600 return $formattedTopics;
@@ -362,13 +605,721 @@
362 605
363 606 public static function getTopicsBySpaceId($spaceId)
364 607 {
365 608 $topics = self::getTopics();
366 -
367 609 $topics = array_filter($topics, function ($topic) use ($spaceId) {
368 610 return in_array($spaceId, $topic['space_ids']);
369 611 });
612 + return array_values($topics);
613 + }
370 614
371 - return $topics;
615 + public static function getMaxRunTime()
616 + {
617 + if (function_exists('ini_get')) {
618 + $maxRunTime = (int)ini_get('max_execution_time');
619 + if ($maxRunTime === 0) {
620 + $maxRunTime = 60;
621 + }
622 + // If set to 0 (unlimited) or a negative value, return a large number
623 + if ($maxRunTime <= 0) {
624 + return PHP_INT_MAX;
625 + }
626 +
627 + } else {
628 + $maxRunTime = 30;
629 + }
630 +
631 + if ($maxRunTime > 58) {
632 + $maxRunTime = 58;
633 + }
634 +
635 + $maxRunTime = $maxRunTime - 3;
636 +
637 + return apply_filters('fluent_community/max_execution_time', $maxRunTime);
372 638 }
373 639
640 + public static function getColorSchemas()
641 + {
642 + $defaultCustom = [
643 + 'title' => __('Custom', 'fluent-community'),
644 + 'selectors' => [
645 + 'body' => [],
646 + 'fcom_top_menu' => [],
647 + 'spaces' => []
648 + ],
649 + ];
650 + $shemas = apply_filters('fluent-community/color_schemas', [
651 + 'lightSkins' => [
652 + 'default' => [
653 + 'title' => __('Default', 'fluent-community'),
654 + 'selectors' => [
655 + 'body' => [
656 + 'primary_bg' => '#ffffff',
657 + 'secondary_bg' => '#f0f2f5',
658 + 'secondary_content_bg' => '#f0f3f5',
659 + 'active_bg' => '#f0f3f5',
660 + 'light_bg' => '#E1E4EA',
661 + 'deep_bg' => '#222530',
662 + 'menu_text' => '#545861',
663 + 'primary_text' => '#19283a',
664 + 'secondary_text' => '#525866',
665 + 'text_off' => '#959595',
666 + 'primary_button' => '#2B2E33',
667 + 'primary_button_text' => '#ffffff',
668 + 'primary_border' => '#e3e8ee',
669 + 'secondary_border' => '#9CA3AF',
670 + 'highlight_bg' => '#fffce3',
671 + 'text_link' => '#2271b1',
672 + ],
673 + 'fcom_top_menu' => [
674 + 'primary_bg' => '#ffffff',
675 + 'primary_border' => '#e3e8ee',
676 + 'menu_text' => '#545861',
677 + 'menu_text_active' => '#545861',
678 + 'active_bg' => '#f0f3f5',
679 + 'menu_text_hover' => '#545861',
680 + 'menu_bg_hover' => '#f0f3f5',
681 + ],
682 + 'spaces' => [
683 + 'primary_bg' => '#ffffff',
684 + 'primary_border' => '#e3e8ee',
685 + 'menu_text' => '#545861',
686 + 'menu_text_active' => '#545861',
687 + 'menu_text_hover' => '#545861',
688 + 'menu_bg_hover' => '#f0f3f5',
689 + 'active_bg' => '#f0f3f5',
690 + ]
691 + ],
692 + ],
693 + 'sunset_sands' => [
694 + 'title' => __('Sunset Sands', 'fluent-community'),
695 + 'selectors' => [
696 + 'body' => [
697 + 'primary_bg' => '#FFFFFF',
698 + 'secondary_bg' => '#FDF6F0',
699 + 'secondary_content_bg' => '#FDF6F0',
700 + 'active_bg' => '#FCF0E6',
701 + 'light_bg' => '#FAE5D3',
702 + 'deep_bg' => '#2D2D2D',
703 + 'menu_text' => '#5D5D5D',
704 + 'primary_text' => '#333333',
705 + 'secondary_text' => '#666666',
706 + 'text_off' => '#999999',
707 + 'text_link' => '#E67E22',
708 + 'primary_button' => '#E67E22',
709 + 'primary_button_text' => '#FFFFFF',
710 + 'primary_border' => '#EADDD3',
711 + 'secondary_border' => '#E0D0C3',
712 + 'highlight_bg' => '#FFF5EC',
713 + ],
714 + 'fcom_top_menu' => [
715 + 'primary_bg' => '#FFFFFF',
716 + 'primary_border' => '#EADDD3',
717 + 'menu_text' => '#5D5D5D',
718 + 'menu_text_active' => '#E67E22',
719 + 'active_bg' => '#FFF5EC',
720 + 'menu_text_hover' => '#E67E22',
721 + 'menu_bg_hover' => '#FFF5EC',
722 + ],
723 + 'spaces' => [
724 + 'primary_bg' => '#FFFFFF',
725 + 'primary_border' => '#EADDD3',
726 + 'menu_text' => '#5D5D5D',
727 + 'menu_text_hover' => '#E67E22',
728 + 'menu_bg_hover' => '#FFF5EC',
729 + 'menu_text_active' => '#FFFFFF',
730 + 'active_bg' => '#E67E22',
731 + ]
732 + ]
733 + ],
734 + 'ocean_blue' => [
735 + 'title' => __('Ocean Blue', 'fluent-community'),
736 + 'selectors' => [
737 + 'body' => [
738 + 'primary_bg' => '#FFFFFF',
739 + 'secondary_bg' => '#F0F2F5',
740 + 'secondary_content_bg' => '#f0f3f5',
741 + 'active_bg' => '#E7F3FF',
742 + 'light_bg' => '#F6F9FA',
743 + 'deep_bg' => '#18191A',
744 + 'menu_text' => '#65676B',
745 + 'primary_text' => '#050505',
746 + 'secondary_text' => '#65676B',
747 + 'text_off' => '#8A8D91',
748 + 'text_link' => '#216FDB',
749 + 'primary_button' => '#1877F2',
750 + 'primary_button_text' => '#FFFFFF',
751 + 'primary_border' => '#DADDE1',
752 + 'secondary_border' => '#CED0D4',
753 + 'highlight_bg' => '#E7F3FF'
754 + ],
755 + 'fcom_top_menu' => [
756 + 'primary_bg' => '#FFFFFF',
757 + 'primary_border' => '#DADDE1',
758 + 'menu_text' => '#65676B',
759 + 'menu_text_active' => '#1877F2',
760 + 'active_bg' => '#E7F3FF',
761 + 'menu_text_hover' => '#1877F2',
762 + 'menu_bg_hover' => '#E7F3FF',
763 + ],
764 + 'spaces' => [
765 + 'primary_bg' => '#FFFFFF',
766 + 'primary_border' => '#DADDE1',
767 + 'menu_text' => '#65676B',
768 + 'menu_text_hover' => '#1877F2',
769 + 'menu_bg_hover' => '#E7F3FF',
770 + 'menu_text_active' => '#FFFFFF',
771 + 'active_bg' => '#1877F2'
772 + ]
773 + ]
774 + ],
775 + 'sky_blue' => [
776 + 'title' => __('Sky Blue', 'fluent-community'),
777 + 'selectors' => [
778 + 'body' => [
779 + 'primary_bg' => '#FFFFFF',
780 + 'secondary_bg' => '#F7F9FA',
781 + 'secondary_content_bg' => '#f0f3f5',
782 + 'active_bg' => '#E8F5FD',
783 + 'light_bg' => '#F7F9FA',
784 + 'deep_bg' => '#15202B',
785 + 'menu_text' => '#536471',
786 + 'primary_text' => '#0F1419',
787 + 'secondary_text' => '#536471',
788 + 'text_off' => '#8899A6',
789 + 'text_link' => '#1D9BF0',
790 + 'primary_button' => '#1D9BF0',
791 + 'primary_button_text' => '#FFFFFF',
792 + 'primary_border' => '#EFF3F4',
793 + 'secondary_border' => '#CFD9DE',
794 + 'highlight_bg' => '#E8F5FD'
795 + ],
796 + 'fcom_top_menu' => [
797 + 'primary_bg' => '#FFFFFF',
798 + 'primary_border' => '#EFF3F4',
799 + 'menu_text' => '#536471',
800 + 'menu_text_active' => '#1D9BF0',
801 + 'active_bg' => '#E8F5FD',
802 + 'menu_bg_hover' => '#E8F5FD',
803 + 'menu_text_hover' => '#536471',
804 + ],
805 + 'spaces' => [
806 + 'primary_bg' => '#FFFFFF',
807 + 'primary_border' => '#EFF3F4',
808 + 'menu_text' => '#536471',
809 + 'menu_text_hover' => '#1D9BF0',
810 + 'menu_bg_hover' => '#E8F5FD',
811 + 'menu_text_active' => '#FFFFFF',
812 + 'active_bg' => '#1D9BF0'
813 + ]
814 + ]
815 + ],
816 + 'emerald_essence' => [
817 + 'title' => __('Emerald Essence', 'fluent-community'),
818 + 'selectors' => [
819 + 'body' => [
820 + 'primary_bg' => '#FFFFFF',
821 + 'secondary_bg' => '#F0F7F4',
822 + 'secondary_content_bg' => '#f0f3f5',
823 + 'active_bg' => '#E3F2ED',
824 + 'light_bg' => '#F7FAFA',
825 + 'deep_bg' => '#1A2B32',
826 + 'menu_text' => '#4A5D5E',
827 + 'primary_text' => '#1F2937',
828 + 'secondary_text' => '#4B5563',
829 + 'text_off' => '#9CA3AF',
830 + 'text_link' => '#059669',
831 + 'primary_button' => '#10B981',
832 + 'primary_button_text' => '#FFFFFF',
833 + 'primary_border' => '#D1E7DD',
834 + 'secondary_border' => '#A7C4BC',
835 + 'highlight_bg' => '#ECFDF5'
836 + ],
837 + 'fcom_top_menu' => [
838 + 'primary_bg' => '#FFFFFF',
839 + 'primary_border' => '#D1E7DD',
840 + 'menu_text' => '#4A5D5E',
841 + 'menu_text_active' => '#059669',
842 + 'active_bg' => '#ECFDF5',
843 + 'menu_bg_hover' => '#ECFDF5',
844 + 'menu_text_hover' => '#4A5D5E',
845 + ],
846 + 'spaces' => [
847 + 'primary_bg' => '#FFFFFF',
848 + 'primary_border' => '#D1E7DD',
849 + 'menu_text' => '#4A5D5E',
850 + 'menu_text_hover' => '#059669',
851 + 'menu_bg_hover' => '#ECFDF5',
852 + 'menu_text_active' => '#FFFFFF',
853 + 'active_bg' => '#10B981'
854 + ]
855 + ]
856 + ]
857 + ],
858 + 'darkSkins' => [
859 + 'default' => [
860 + 'title' => __('Default (Dark)', 'fluent-community'),
861 + 'selectors' => [
862 + 'body' => [
863 + 'primary_bg' => '#2B2E33',
864 + 'secondary_bg' => '#191B1F',
865 + 'secondary_content_bg' => '#42464D',
866 + 'active_bg' => '#42464D',
867 + 'light_bg' => '#2B303B',
868 + 'deep_bg' => '#E1E4EA',
869 + 'menu_text' => '#E4E7EB',
870 + 'menu_text_active' => '#E4E7EB',
871 + 'primary_text' => '#F0F3F5',
872 + 'secondary_text' => '#99A0AE',
873 + 'menu_bg_hover' => '#E1E4EA',
874 + 'text_off' => '#A5A9AD',
875 + 'text_link' => '#60a5fa',
876 + 'primary_button' => '#FFFFFF',
877 + 'primary_button_text' => '#2B2E33',
878 + 'primary_border' => '#42464D',
879 + 'secondary_border' => '#A5A9AD',
880 + 'highlight_bg' => '#2c2c1a',
881 + ],
882 + 'fcom_top_menu' => [
883 + 'primary_bg' => '#2B2E33',
884 + 'primary_border' => '#42464D',
885 + 'menu_text' => '#E4E7EB',
886 + 'menu_text_active' => '#E4E7EB',
887 + 'active_bg' => '#42464D',
888 + 'menu_bg_hover' => '#42464D',
889 + 'menu_text_hover' => '#E4E7EB',
890 + ],
891 + 'spaces' => [
892 + 'primary_bg' => '#2B2E33',
893 + 'primary_border' => '#42464D',
894 + 'menu_text' => '#E4E7EB',
895 + 'menu_text_active' => '#E4E7EB',
896 + 'active_bg' => '#42464D',
897 + 'menu_bg_hover' => '#42464D',
898 + 'menu_text_hover' => '#fff',
899 + ]
900 + ],
901 + ],
902 + 'sunset_sands' => [
903 + 'title' => __('Sunset Sands (Dark)', 'fluent-community'),
904 + 'selectors' => [
905 + 'body' => [
906 + 'primary_bg' => '#1A1A1A',
907 + 'secondary_bg' => '#222222',
908 + 'secondary_content_bg' => '#222222',
909 + 'active_bg' => '#2A2420',
910 + 'light_bg' => '#33302E',
911 + 'deep_bg' => '#111111',
912 + 'menu_text' => '#B0B0B0',
913 + 'primary_text' => '#E0E0E0',
914 + 'secondary_text' => '#A0A0A0',
915 + 'text_off' => '#707070',
916 + 'text_link' => '#F39C12',
917 + 'primary_button' => '#F39C12',
918 + 'primary_border' => '#3A3632',
919 + 'primary_button_text' => '#1A1A1A',
920 + 'secondary_border' => '#4C4D4F',
921 + 'highlight_bg' => '#2A2420',
922 + ],
923 + 'fcom_top_menu' => [
924 + 'primary_bg' => '#1A1A1A',
925 + 'primary_border' => '#3A3632',
926 + 'menu_text' => '#B0B0B0',
927 + 'menu_text_active' => '#F39C12',
928 + 'active_bg' => '#2A2420',
929 + 'menu_text_hover' => '#F39C12',
930 + 'menu_bg_hover' => '#2A2420',
931 + ],
932 + 'spaces' => [
933 + 'primary_bg' => '#1A1A1A',
934 + 'primary_border' => '#3A3632',
935 + 'menu_text' => '#B0B0B0',
936 + 'menu_text_hover' => '#F39C12',
937 + 'menu_bg_hover' => '#2A2420',
938 + 'menu_text_active' => '#1A1A1A',
939 + 'active_bg' => '#F39C12',
940 + ]
941 + ]
942 + ],
943 + 'ocean_blue' => [
944 + 'title' => __('Ocean Blue (Dark)', 'fluent-community'),
945 + 'selectors' => [
946 + 'body' => [
947 + 'primary_border' => '#3E4042',
948 + 'menu_text' => '#B0B3B8',
949 + 'menu_text_active' => '#2D88FF',
950 + 'active_bg' => '#263951',
951 + 'menu_text_hover' => '#2D88FF',
952 + 'menu_bg_hover' => '#263951',
953 + 'primary_bg' => '#2B2E33',
954 + 'secondary_content_bg' => '#42464D',
955 + 'secondary_bg' => '#191B1F',
956 + 'light_bg' => '#2B303B',
957 + 'deep_bg' => '#E1E4EA',
958 + 'primary_text' => '#F0F3F5',
959 + 'secondary_text' => '#99A0AE',
960 + 'text_off' => '#A5A9AD',
961 + 'primary_button' => '#FFFFFF',
962 + 'primary_button_text' => '#191B1F',
963 + 'secondary_border' => '#A5A9AD',
964 + 'highlight_bg' => '#2c2c1a',
965 + 'text_link' => '#2d88ff',
966 + ],
967 + 'fcom_top_menu' => [
968 + 'primary_bg' => '#242526',
969 + 'primary_border' => '#3E4042',
970 + 'menu_text' => '#B0B3B8',
971 + 'menu_text_active' => '#fff',
972 + 'active_bg' => '#263951',
973 + 'menu_text_hover' => '#fff',
974 + 'menu_bg_hover' => '#263951',
975 + ],
976 + 'spaces' => [
977 + 'primary_bg' => '#242526',
978 + 'primary_border' => '#3E4042',
979 + 'menu_text' => '#B0B3B8',
980 + 'menu_text_hover' => '#2D88FF',
981 + 'menu_bg_hover' => '#263951',
982 + 'menu_text_active' => '#FFFFFF',
983 + 'active_bg' => '#2D88FF'
984 + ]
985 + ]
986 + ],
987 + 'sky_blue' => [
988 + 'title' => __('Sky Blue (Dark)', 'fluent-community'),
989 + 'selectors' => [
990 + 'body' => [
991 + 'primary_bg' => '#15202B',
992 + 'secondary_bg' => '#1E2732',
993 + 'secondary_content_bg' => '#2C3640',
994 + 'active_bg' => '#1D2F41',
995 + 'light_bg' => '#22303C',
996 + 'deep_bg' => '#E7E9EA',
997 + 'menu_text' => '#8B98A5',
998 + 'primary_text' => '#E7E9EA',
999 + 'secondary_text' => '#8B98A5',
1000 + 'text_off' => '#536471',
1001 + 'text_link' => '#1D9BF0',
1002 + 'primary_button' => '#1D9BF0',
1003 + 'primary_button_text' => '#15202B',
1004 + 'primary_border' => '#38444D',
1005 + 'secondary_border' => '#536471',
1006 + 'highlight_bg' => '#1D2F41'
1007 + ],
1008 + 'fcom_top_menu' => [
1009 + 'primary_bg' => '#15202B',
1010 + 'primary_border' => '#38444D',
1011 + 'menu_text' => '#8B98A5',
1012 + 'menu_text_active' => '#1D9BF0',
1013 + 'active_bg' => '#1D2F41',
1014 + 'menu_bg_hover' => '#1D2F41',
1015 + 'menu_text_hover' => '#E7E9EA',
1016 + ],
1017 + 'spaces' => [
1018 + 'primary_bg' => '#15202B',
1019 + 'primary_border' => '#38444D',
1020 + 'menu_text' => '#8B98A5',
1021 + 'menu_text_hover' => '#1D9BF0',
1022 + 'menu_bg_hover' => '#1D2F41',
1023 + 'menu_text_active' => '#FFFFFF',
1024 + 'active_bg' => '#1D9BF0'
1025 + ]
1026 + ]
1027 + ],
1028 + 'emerald_essence' => [
1029 + 'title' => __('Emerald Essence (Dark)', 'fluent-community'),
1030 + 'selectors' => [
1031 + 'body' => [
1032 + 'primary_bg' => '#1A2B32',
1033 + 'secondary_bg' => '#243B43',
1034 + 'secondary_content_bg' => '#2C464F',
1035 + 'active_bg' => '#1E3A31',
1036 + 'light_bg' => '#2A3F48',
1037 + 'deep_bg' => '#E2E8F0',
1038 + 'menu_text' => '#A7BCBF',
1039 + 'primary_text' => '#E2E8F0',
1040 + 'secondary_text' => '#A7BCBF',
1041 + 'text_off' => '#64748B',
1042 + 'text_link' => '#34D399',
1043 + 'primary_button' => '#10B981',
1044 + 'primary_border' => '#2F4C41',
1045 + 'primary_button_text' => '#1A2B32',
1046 + 'secondary_border' => '#3D5C52',
1047 + 'highlight_bg' => '#064E3B'
1048 + ],
1049 + 'fcom_top_menu' => [
1050 + 'primary_bg' => '#1A2B32',
1051 + 'primary_border' => '#2F4C41',
1052 + 'menu_text' => '#A7BCBF',
1053 + 'menu_text_active' => '#34D399',
1054 + 'active_bg' => '#064E3B',
1055 + 'menu_bg_hover' => '#064E3B',
1056 + 'menu_text_hover' => '#E2E8F0',
1057 + ],
1058 + 'spaces' => [
1059 + 'primary_bg' => '#1A2B32',
1060 + 'primary_border' => '#2F4C41',
1061 + 'menu_text' => '#A7BCBF',
1062 + 'menu_text_hover' => '#34D399',
1063 + 'menu_bg_hover' => '#064E3B',
1064 + 'menu_text_active' => '#FFFFFF',
1065 + 'active_bg' => '#10B981'
1066 + ]
1067 + ]
1068 + ]
1069 + ]
1070 + ]);
1071 +
1072 + $customSchemaConfig = self::getColorConfig('edit');
1073 +
1074 + $shemas['lightSkins']['custom'] = [
1075 + 'title' => __('Custom', 'fluent-community'),
1076 + 'selectors' => $customSchemaConfig['light_config'] ?? $defaultCustom
1077 + ];
1078 +
1079 + $shemas['darkSkins']['custom'] = [
1080 + 'title' => __('Custom', 'fluent-community'),
1081 + 'selectors' => $customSchemaConfig['dark_config'] ?? $defaultCustom
1082 + ];
1083 +
1084 + return $shemas;
1085 + }
1086 +
1087 + public static function generateCss($sectors, $prefix = '')
1088 + {
1089 + if (!$sectors) {
1090 + return '';
1091 + }
1092 +
1093 + $bodyPrefix = 'body';
1094 + if ($prefix) {
1095 + $bodyPrefix = $prefix . ' body';
1096 + }
1097 +
1098 + $elementPlusMap = [
1099 + 'primary_text' => '--el-color-primary',
1100 + 'secondary_bg' => '--el-color-white'
1101 + ];
1102 +
1103 + $css = '';
1104 + foreach ($sectors as $selector => $props) {
1105 + $isBody = $selector === 'body';
1106 + $prefix = $isBody ? $bodyPrefix : $bodyPrefix . ' .' . $selector;
1107 + $prefix .= '{';
1108 +
1109 + $css .= $prefix;
1110 +
1111 + foreach ($props as $prop => $value) {
1112 + $cssVar = '--fcom-' . str_replace('_', '-', $prop);
1113 + $css .= $cssVar . ':' . $value . ';';
1114 +
1115 + if ($isBody && isset($elementPlusMap[$prop])) {
1116 + $css .= $elementPlusMap[$prop] . ':' . $value . ';';
1117 + }
1118 + }
1119 + $css .= '} ';
1120 + }
1121 +
1122 + return $css;
1123 + }
1124 +
1125 + public static function getColorConfig($context = 'view')
1126 + {
1127 + return apply_filters('fluent_community/color_schmea_config', [
1128 + 'light_schema' => 'default',
1129 + 'dark_schema' => 'default',
1130 + 'light_config' => [
1131 + 'body' => [],
1132 + 'fcom_top_menu' => [],
1133 + 'spaces' => []
1134 + ],
1135 + 'dark_config' => [
1136 + 'body' => [],
1137 + 'fcom_top_menu' => [],
1138 + 'spaces' => []
1139 + ],
1140 + 'version' => FLUENT_COMMUNITY_PLUGIN_VERSION
1141 + ], $context);
1142 + }
1143 +
1144 + public static function getColorCssVariables()
1145 + {
1146 + $customSchemaConfig = self::getColorConfig('view');
1147 +
1148 + if (!empty($customSchemaConfig['cached_css'])) {
1149 + if ($customSchemaConfig['version'] != FLUENT_COMMUNITY_PLUGIN_VERSION) {
1150 + do_action('fluent_community/recache_color_schema');
1151 + }
1152 +
1153 + return (string)$customSchemaConfig['cached_css'];
1154 + }
1155 +
1156 + $schemas = self::getColorSchemas();
1157 +
1158 + $lightName = Arr::get($customSchemaConfig, 'light_schema', 'default');
1159 + $darkName = Arr::get($customSchemaConfig, 'dark_schema', 'default');
1160 +
1161 + $lightCss = self::generateCss(Arr::get($schemas, "lightSkins.$lightName.selectors"));
1162 + $darkCss = self::generateCss(Arr::get($schemas, "darkSkins.$darkName.selectors"), 'html.dark');
1163 + return $lightCss . $darkCss;
1164 + }
1165 +
1166 + public static function getThemeColor($scope = 'theme')
1167 + {
1168 + static $cache = [];
1169 + if (isset($cache[$scope])) {
1170 + return $cache[$scope];
1171 + }
1172 +
1173 + $map = [
1174 + 'theme' => ['key' => 'primary_button', 'default' => '#2B2E33'],
1175 + 'theme_button_text' => ['key' => 'primary_button_text', 'default' => '#ffffff'],
1176 + ];
1177 + $entry = Arr::get($map, $scope, ['key' => $scope, 'default' => '']);
1178 +
1179 + $schemas = self::getColorSchemas();
1180 + $lightName = Arr::get(self::getColorConfig('view'), 'light_schema', 'default');
1181 + $color = Arr::get($schemas, "lightSkins.$lightName.selectors.body.{$entry['key']}", $entry['default']);
1182 +
1183 + $cache[$scope] = apply_filters('fluent_community/' . $scope . '_color', $color);
1184 +
1185 + return $cache[$scope];
1186 + }
1187 +
1188 + public static function getColorSchemaConfig()
1189 + {
1190 + $customSchemaConfig = self::getColorConfig('view');
1191 + $lightName = Arr::get($customSchemaConfig, 'light_schema', 'default');
1192 + $darkName = Arr::get($customSchemaConfig, 'dark_schema', 'default');
1193 + $schemas = self::getColorSchemas();
1194 +
1195 + return [
1196 + 'dark' => Arr::get($schemas, "lightSkins.$darkName.selectors"),
1197 + 'light' => Arr::get($schemas, "darkSkins.$lightName.selectors"),
1198 + ];
1199 + }
1200 +
1201 + public static function getSuggestedColors()
1202 + {
1203 + $pallets = current((array)get_theme_support('editor-color-palette'));
1204 +
1205 + $colors = [];
1206 +
1207 + if ($pallets && is_array($pallets)) {
1208 + $colors = array_map(function ($color) {
1209 + $colorString = Arr::get($color, 'color');
1210 + // Trim any whitespace
1211 + $colorString = trim($colorString);
1212 + // Check if it's a CSS variable
1213 + if (strpos($colorString, 'var(') === 0) {
1214 + // Extract the fallback color if present
1215 + preg_match('/var\(.*,\s*(#[A-Fa-f0-9]{6})\)/', $colorString, $matches);
1216 + if (!empty($matches[1])) {
1217 + return $matches[1];
1218 + }
1219 + // If no fallback color, return an empty string
1220 + return '';
1221 + }
1222 +
1223 + if (preg_match('/#[A-Fa-f0-9]{6}/', $colorString, $matches)) {
1224 + return $matches[0];
1225 + }
1226 +
1227 + return $colorString;
1228 + }, $pallets);
1229 +
1230 + $colors = array_filter($colors);
1231 + }
1232 +
1233 + if (!$colors) {
1234 + $colors = ['#000000', '#abb8c3', '#ffffff', '#f78da7', '#ff6900', '#fcb900', '#7bdcb5', '#00d084', '#8ed1fc', '#0693e3', '#9b51e0'];
1235 + }
1236 +
1237 + return apply_filters('fluent_community/suggested_colors', $colors);
1238 + }
1239 +
1240 + public static function slugify($text, $fallback = '')
1241 + {
1242 + $title = preg_replace('/[\x{10000}-\x{10FFFF}]/u', '', $text);
1243 +
1244 + $title = Helper::normalizeToAscii($title);
1245 +
1246 + $title = remove_accents($title);
1247 +
1248 + $title = strtolower($title);
1249 + // only allow alphanumeric, dash, and underscore
1250 + $title = trim(preg_replace('/[^a-z0-9-_]/', ' ', $title));
1251 +
1252 + if (!$title) {
1253 + $title = $fallback;
1254 + }
1255 +
1256 + if (!$title) {
1257 + return $title;
1258 + }
1259 +
1260 + return sanitize_title($title, $fallback);
1261 + }
1262 +
1263 + public static function hasAnalyticsEnabled()
1264 + {
1265 + $defaultSettings = ['status' => 'no'];
1266 +
1267 + $settings = apply_filters('fluent_community/features/analytics', $defaultSettings);
1268 +
1269 + $status = Arr::get($settings, 'status');
1270 +
1271 + return $status === 'yes';
1272 + }
1273 +
1274 + public static function getPortalSidebarData($scope = 'sidebar')
1275 + {
1276 + $userModel = Helper::getCurrentUser();
1277 + $spaceGroups = Helper::getCommunityMenuGroups($userModel);
1278 + $settingsMenu = apply_filters('fluent_community/settings_menu', [], $userModel);
1279 + $menuGroups = Helper::getMenuItemsGroup('view');
1280 + $topInlines = Arr::get($menuGroups, 'beforeCommunityMenuItems', []);
1281 + $bottomLinkGroups = Arr::get($menuGroups, 'afterCommunityLinkGroups', []);
1282 + $primaryMenuItems = Arr::get($menuGroups, 'mainMenuItems', []);
1283 + $primaryMenuItems = apply_filters('fluent_community/main_menu_items', $primaryMenuItems, $scope);
1284 +
1285 + return apply_filters('fluent_community/sidebar_menu_groups_config', [
1286 + 'primaryItems' => $primaryMenuItems,
1287 + 'spaceGroups' => $spaceGroups,
1288 + 'settingsItems' => $settingsMenu,
1289 + 'topInlineLinks' => $topInlines,
1290 + 'bottomLinkGroups' => $bottomLinkGroups,
1291 + 'is_admin' => Helper::isSiteAdmin(null, $userModel),
1292 + 'has_color_scheme' => Helper::hasColorScheme(),
1293 + 'context' => $scope,
1294 + ], $userModel);
1295 + }
1296 +
1297 + public static function getVerifiedSenders()
1298 + {
1299 + $verifiedSenders = [];
1300 +
1301 + if (defined('FLUENTMAIL')) {
1302 + $smtpSettings = get_option('fluentmail-settings', []);
1303 + if ($smtpSettings && count($smtpSettings['mappings'])) {
1304 + $verifiedSenders = array_keys($smtpSettings['mappings']);
1305 + }
1306 + }
1307 +
1308 + return apply_filters('fluent_community/verified_email_senders', $verifiedSenders);
1309 + }
1310 +
1311 + public static function safeUnserialize($data)
1312 + {
1313 + if (!$data) {
1314 + return $data;
1315 + }
1316 +
1317 + if (is_serialized($data)) { // Don't attempt to unserialize data that wasn't serialized going in.
1318 + return @unserialize(trim($data), [
1319 + 'allowed_classes' => false,
1320 + ]);
1321 + }
1322 +
1323 + return $data;
1324 + }
374 1325 }