PluginProbe
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses / 2.11.0
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses v2.11.0
2.11.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 All 78 releases
← All changes | app/Functions/Utility.php +368 -43 1.0.982.11.0 View file →
@@ -10,12 +10,12 @@
10 10 use FluentCommunity\App\Services\FeedsHelper;
11 11 use FluentCommunity\App\Services\Helper;
12 12 use FluentCommunity\Framework\Support\Arr;
13 13 use FluentCommunity\Modules\Course\Model\Course;
14 +use FluentCommunity\Modules\PushNotification\PushNotificationModule;
14 15
15 16 class Utility
16 17 {
17 -
18 18 public static function isDev()
19 19 {
20 20 static $isDev = null;
21 21 if ($isDev !== null) {
@@ -31,8 +31,13 @@
31 31 {
32 32 return \FluentCommunity\App\App::getInstance($instance);
33 33 }
34 34
35 + public static function extender()
36 + {
37 + return new FluentExtendApi();
38 + }
39 +
35 40 /**
36 41 * Get Global Fluent Community Option
37 42 * @param string $key The option name
38 43 * @param mixed $default the default value of the option if option is not available
@@ -69,9 +74,9 @@
69 74 $exist->save();
70 75
71 76 } else {
72 77 $exist = \FluentCommunity\App\Models\Meta::create([
73 - 'meta_key' => $key,
78 + 'meta_key' => $key, // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
74 79 'object_type' => 'option',
75 80 'value' => $value
76 81 ]);
77 82 }
@@ -80,8 +85,17 @@
80 85
81 86 return $exist;
82 87 }
83 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 +
84 98 public static function getFeaturesConfig()
85 99 {
86 100 static $features = null;
87 101
@@ -91,19 +105,23 @@
91 105
92 106 $features = self::getOption('fluent_community_features', []);
93 107
94 108 $defaults = [
95 - 'leader_board_module' => 'yes',
96 - 'course_module' => 'yes',
97 - 'giphy_module' => 'no',
98 - 'giphy_api_key' => '',
99 - 'emoji_module' => 'yes',
100 - 'cloud_storage' => 'no',
101 - 'invitation' => 'yes',
102 - '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',
103 122 ];
104 123
105 -
106 124 if (defined('FLUENT_COMMUNITY_CLOUD_STORAGE') && FLUENT_COMMUNITY_CLOUD_STORAGE) {
107 125 $features['cloud_storage'] = 'yes';
108 126 }
109 127
@@ -109,8 +127,9 @@
109 127
110 128 $features = wp_parse_args($features, $defaults);
111 129
112 130 $hasPro = defined('FLUENT_COMMUNITY_PRO') && FLUENT_COMMUNITY_PRO;
131 +
113 132 if (!$hasPro) {
114 133 $features['leader_board_module'] = 'no';
115 134 $features['giphy_module'] = 'no';
116 135 $features['emoji_module'] = 'no';
@@ -115,8 +134,11 @@
115 134 $features['giphy_module'] = 'no';
116 135 $features['emoji_module'] = 'no';
117 136 $features['cloud_storage'] = 'no';
118 137 $features['user_badge'] = 'no';
138 + $features['followers_module'] = 'no';
139 + $features['custom_profile_fields'] = 'no';
140 + $features['pwa_module'] = 'no';
119 141 }
120 142
121 143 return $features;
122 144 }
@@ -182,28 +204,39 @@
182 204 }
183 205
184 206 $defaults = [
185 207 'dark_mode' => 'yes',
208 + 'default_theme_mode' => 'light',
186 209 'fixed_page_header' => 'yes',
187 210 'show_powered_by' => 'yes',
188 211 'feed_link_on_sidebar' => 'yes',
212 + 'show_post_modal' => 'yes',
189 213 'fixed_sidebar' => 'no',
190 214 'icon_on_header_menu' => 'no',
191 215 'affiliate_id' => '',
192 216 'rich_post_layout' => 'classic',
217 + 'member_list_layout' => 'classic', // grid, classic
218 + 'default_feed_layout' => 'timeline', // list, timeline
219 + 'disable_feed_layout' => 'no',
193 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'
194 227 ];
195 -
196 228 $settings = self::getOption('customization_settings', $defaults);
197 229
198 230 $settings = wp_parse_args($settings, $defaults);
199 -
231 + $settings = apply_filters('fluent_community/customization_settings', $settings);
200 232 if (!defined('FLUENT_COMMUNITY_PRO')) {
201 233 $settings['show_powered_by'] = 'yes';
202 234 $settings['affiliate_id'] = '';
203 235 $settings['rich_post_layout'] = 'classic';
236 + $settings['member_list_layout'] = 'classic';
237 + $settings['enable_sidebar_toggle'] = 'no';
204 238 }
205 -
206 239 return $settings;
207 240 }
208 241
209 242 public static function getCustomizationSetting($key)
@@ -229,29 +262,34 @@
229 262 if ($settings) {
230 263 return $settings;
231 264 }
232 265
233 - $settings = self::getFromCache('privacy_settings', function () {
234 - $defaults = [
235 - 'members_page_status' => 'everybody', // everybody, logged_in, admin_only
236 - 'can_customize_username' => 'no',
237 - 'show_last_activity' => 'yes',
238 - 'email_auto_login' => 'yes',
239 - 'user_space_visibility' => 'everybody', // everybody, logged_in, admin_only
240 - ];
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 + ];
241 281
242 - $settings = self::getOption('privacy_settings', $defaults);
282 + $settings = self::getOption('privacy_settings', $defaults);
243 283
244 - $settings = wp_parse_args($settings, $defaults);
284 + $settings = wp_parse_args($settings, $defaults);
245 285
246 - if (!defined('FLUENT_COMMUNITY_PRO')) {
247 - $settings['can_customize_username'] = 'no';
248 - $settings['email_auto_login'] = 'no';
249 - }
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 + }
250 291
251 - return $settings;
252 - });
253 -
254 292 return $settings;
255 293 }
256 294
257 295 public static function canViewMembersPage()
@@ -268,8 +306,40 @@
268 306
269 307 return apply_filters('fluent_community/can_view_members_page', Helper::isModerator(), $pageStatus);
270 308 }
271 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 +
272 342 public static function getPrivacySetting($key)
273 343 {
274 344 $settings = self::getPrivacySettings();
275 345 return Arr::get($settings, $key);
@@ -279,8 +349,12 @@
279 349 {
280 350 $preSettings = self::getPrivacySettings();
281 351 $settings = Arr::only($settings, array_keys($preSettings));
282 352
353 + $settings = array_map(function ($value) {
354 + return is_scalar($value) ? sanitize_text_field($value) : '';
355 + }, $settings);
356 +
283 357 self::updateOption('privacy_settings', $settings);
284 358 self::forgetCache('privacy_settings');
285 359
286 360 return $settings;
@@ -285,8 +359,13 @@
285 359
286 360 return $settings;
287 361 }
288 362
363 + public static function showLastActivity()
364 + {
365 + return self::getPrivacySetting('show_last_activity') === 'yes' || Helper::isModerator();
366 + }
367 +
289 368 public static function isCustomizationEnabled($key, $matchingValue = 'yes')
290 369 {
291 370 $settings = self::getCustomizationSettings();
292 371 return isset($settings[$key]) && $settings[$key] === $matchingValue;
@@ -291,17 +370,19 @@
291 370 $settings = self::getCustomizationSettings();
292 371 return isset($settings[$key]) && $settings[$key] === $matchingValue;
293 372 }
294 373
295 - public static function getProductUrl($isPowered = false)
374 + public static function getProductUrl($isPowered = false, $params = [])
296 375 {
297 376 $url = 'https://fluentcommunity.co/';
298 377 if ($isPowered) {
299 - $params = [
378 + $defaultParams = [
300 379 'utm_source' => 'power_footer',
301 380 'utm_medium' => 'site',
302 381 'utm_campaign' => 'powered_by'
303 382 ];
383 + $params = wp_parse_args($params, $defaultParams);
384 +
304 385 $settings = self::getCustomizationSettings();
305 386 $affId = Arr::get($settings, 'affiliate_id');
306 387 if ($affId) {
307 388 $params['ref'] = $affId;
@@ -306,19 +387,57 @@
306 387 if ($affId) {
307 388 $params['ref'] = $affId;
308 389 }
309 390
310 - $url = add_query_arg($params, $url);
391 + return add_query_arg($params, $url);
311 392 }
312 393
313 394 return add_query_arg([
314 395 'utm_source' => 'plugin',
315 396 'utm_medium' => 'site',
316 - 'utm_campaign' => 'pligin_ui'
397 + 'utm_campaign' => 'plugin_ui'
317 398 ], $url);
318 399 }
319 400
320 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 + /**
321 440 * Get the email notification settings.
322 441 *
323 442 * @return array The email notification settings.
324 443 */
@@ -341,8 +460,9 @@
341 460 'reply_to_email' => '',
342 461 'reply_to_name' => '',
343 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}}.',
344 463 'disable_powered_by' => 'no',
464 + 'logo' => ''
345 465 ];
346 466
347 467 $settings = array_filter(self::getOption('global_email_settings', $default));
348 468 $settings = wp_parse_args($settings, $default);
@@ -357,8 +477,35 @@
357 477
358 478 return $settings;
359 479 }
360 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 +
361 508 public static function postTitlePref()
362 509 {
363 510 $pref = self::getCustomizationSetting('post_title_pref');
364 511
@@ -403,8 +550,25 @@
403 550 $key = 'fluent_community_post_topics';
404 551 $topics = self::getFromCache($key, function () {
405 552 $topics = Term::where('taxonomy_name', 'post_topic')->orderBy('title', 'ASC')->get();
406 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 +
407 571 /*
408 572 * object_id = term_id
409 573 * meta_key = space_id
410 574 */
@@ -427,8 +591,9 @@
427 591 'title' => $topic->title,
428 592 'description' => $topic->description,
429 593 'slug' => $topic->slug,
430 594 'admin_only' => Arr::get($topic->settings, 'admin_only', 'no'),
595 + 'serial' => Arr::get($topic->settings, 'serial'),
431 596 'space_ids' => isset($relations[$topic->id]) ? $relations[$topic->id] : []
432 597 ];
433 598 }
434 599
@@ -443,9 +608,9 @@
443 608 $topics = self::getTopics();
444 609 $topics = array_filter($topics, function ($topic) use ($spaceId) {
445 610 return in_array($spaceId, $topic['space_ids']);
446 611 });
447 - return $topics;
612 + return array_values($topics);
448 613 }
449 614
450 615 public static function getMaxRunTime()
451 616 {
@@ -453,8 +618,13 @@
453 618 $maxRunTime = (int)ini_get('max_execution_time');
454 619 if ($maxRunTime === 0) {
455 620 $maxRunTime = 60;
456 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 +
457 627 } else {
458 628 $maxRunTime = 30;
459 629 }
460 630
@@ -463,9 +633,9 @@
463 633 }
464 634
465 635 $maxRunTime = $maxRunTime - 3;
466 636
467 - return apply_filters('fluent_communutt/max_execution_time', $maxRunTime);
637 + return apply_filters('fluent_community/max_execution_time', $maxRunTime);
468 638 }
469 639
470 640 public static function getColorSchemas()
471 641 {
@@ -493,8 +663,9 @@
493 663 'primary_text' => '#19283a',
494 664 'secondary_text' => '#525866',
495 665 'text_off' => '#959595',
496 666 'primary_button' => '#2B2E33',
667 + 'primary_button_text' => '#ffffff',
497 668 'primary_border' => '#e3e8ee',
498 669 'secondary_border' => '#9CA3AF',
499 670 'highlight_bg' => '#fffce3',
500 671 'text_link' => '#2271b1',
@@ -518,9 +689,9 @@
518 689 'active_bg' => '#f0f3f5',
519 690 ]
520 691 ],
521 692 ],
522 - 'sunset_sands' => [
693 + 'sunset_sands' => [
523 694 'title' => __('Sunset Sands', 'fluent-community'),
524 695 'selectors' => [
525 696 'body' => [
526 697 'primary_bg' => '#FFFFFF',
@@ -534,8 +705,9 @@
534 705 'secondary_text' => '#666666',
535 706 'text_off' => '#999999',
536 707 'text_link' => '#E67E22',
537 708 'primary_button' => '#E67E22',
709 + 'primary_button_text' => '#FFFFFF',
538 710 'primary_border' => '#EADDD3',
539 711 'secondary_border' => '#E0D0C3',
540 712 'highlight_bg' => '#FFF5EC',
541 713 ],
@@ -574,8 +746,9 @@
574 746 'secondary_text' => '#65676B',
575 747 'text_off' => '#8A8D91',
576 748 'text_link' => '#216FDB',
577 749 'primary_button' => '#1877F2',
750 + 'primary_button_text' => '#FFFFFF',
578 751 'primary_border' => '#DADDE1',
579 752 'secondary_border' => '#CED0D4',
580 753 'highlight_bg' => '#E7F3FF'
581 754 ],
@@ -614,8 +787,9 @@
614 787 'secondary_text' => '#536471',
615 788 'text_off' => '#8899A6',
616 789 'text_link' => '#1D9BF0',
617 790 'primary_button' => '#1D9BF0',
791 + 'primary_button_text' => '#FFFFFF',
618 792 'primary_border' => '#EFF3F4',
619 793 'secondary_border' => '#CFD9DE',
620 794 'highlight_bg' => '#E8F5FD'
621 795 ],
@@ -654,8 +828,9 @@
654 828 'secondary_text' => '#4B5563',
655 829 'text_off' => '#9CA3AF',
656 830 'text_link' => '#059669',
657 831 'primary_button' => '#10B981',
832 + 'primary_button_text' => '#FFFFFF',
658 833 'primary_border' => '#D1E7DD',
659 834 'secondary_border' => '#A7C4BC',
660 835 'highlight_bg' => '#ECFDF5'
661 836 ],
@@ -698,8 +873,9 @@
698 873 'menu_bg_hover' => '#E1E4EA',
699 874 'text_off' => '#A5A9AD',
700 875 'text_link' => '#60a5fa',
701 876 'primary_button' => '#FFFFFF',
877 + 'primary_button_text' => '#2B2E33',
702 878 'primary_border' => '#42464D',
703 879 'secondary_border' => '#A5A9AD',
704 880 'highlight_bg' => '#2c2c1a',
705 881 ],
@@ -739,8 +915,9 @@
739 915 'text_off' => '#707070',
740 916 'text_link' => '#F39C12',
741 917 'primary_button' => '#F39C12',
742 918 'primary_border' => '#3A3632',
919 + 'primary_button_text' => '#1A1A1A',
743 920 'secondary_border' => '#4C4D4F',
744 921 'highlight_bg' => '#2A2420',
745 922 ],
746 923 'fcom_top_menu' => [
@@ -781,8 +958,9 @@
781 958 'primary_text' => '#F0F3F5',
782 959 'secondary_text' => '#99A0AE',
783 960 'text_off' => '#A5A9AD',
784 961 'primary_button' => '#FFFFFF',
962 + 'primary_button_text' => '#191B1F',
785 963 'secondary_border' => '#A5A9AD',
786 964 'highlight_bg' => '#2c2c1a',
787 965 'text_link' => '#2d88ff',
788 966 ],
@@ -821,8 +999,9 @@
821 999 'secondary_text' => '#8B98A5',
822 1000 'text_off' => '#536471',
823 1001 'text_link' => '#1D9BF0',
824 1002 'primary_button' => '#1D9BF0',
1003 + 'primary_button_text' => '#15202B',
825 1004 'primary_border' => '#38444D',
826 1005 'secondary_border' => '#536471',
827 1006 'highlight_bg' => '#1D2F41'
828 1007 ],
@@ -862,8 +1041,9 @@
862 1041 'text_off' => '#64748B',
863 1042 'text_link' => '#34D399',
864 1043 'primary_button' => '#10B981',
865 1044 'primary_border' => '#2F4C41',
1045 + 'primary_button_text' => '#1A2B32',
866 1046 'secondary_border' => '#3D5C52',
867 1047 'highlight_bg' => '#064E3B'
868 1048 ],
869 1049 'fcom_top_menu' => [
@@ -982,19 +1162,164 @@
982 1162 $darkCss = self::generateCss(Arr::get($schemas, "darkSkins.$darkName.selectors"), 'html.dark');
983 1163 return $lightCss . $darkCss;
984 1164 }
985 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 +
986 1201 public static function getSuggestedColors()
987 1202 {
988 1203 $pallets = current((array)get_theme_support('editor-color-palette'));
989 - if ($pallets) {
1204 +
1205 + $colors = [];
1206 +
1207 + if ($pallets && is_array($pallets)) {
990 1208 $colors = array_map(function ($color) {
991 - return $color['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;
992 1228 }, $pallets);
993 - } else {
994 - $colors =
995 - ['#000000', '#abb8c3', '#ffffff', '#f78da7', '#ff6900', '#fcb900', '#7bdcb5', '#00d084', '#8ed1fc', '#0693e3', '#9b51e0'];
1229 +
1230 + $colors = array_filter($colors);
996 1231 }
997 1232
1233 + if (!$colors) {
1234 + $colors = ['#000000', '#abb8c3', '#ffffff', '#f78da7', '#ff6900', '#fcb900', '#7bdcb5', '#00d084', '#8ed1fc', '#0693e3', '#9b51e0'];
1235 + }
1236 +
998 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;
999 1324 }
1000 1325 }