PluginProbe
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses / 1.1.0
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses v1.1.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
fluent-community / app / Hooks / Handlers / PortalHandler.php

PortalHandler.php in FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses 1.1.0, at app/Hooks/Handlers/PortalHandler.php

1,000 lines 51.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentCommunity\App\Hooks\Handlers;
4
5 use FluentCommunity\App\App;
6 use FluentCommunity\App\Functions\Utility;
7 use FluentCommunity\App\Models\Space;
8 use FluentCommunity\App\Models\Feed;
9 use FluentCommunity\App\Models\BaseSpace;
10 use FluentCommunity\App\Models\SpaceGroup;
11 use FluentCommunity\App\Models\User;
12 use FluentCommunity\App\Models\XProfile;
13 use FluentCommunity\App\Services\CustomSanitizer;
14 use FluentCommunity\App\Services\Helper;
15 use FluentCommunity\App\Services\LockscreenService;
16 use FluentCommunity\App\Services\ProfileHelper;
17 use FluentCommunity\App\Services\TransStrings;
18 use FluentCommunity\App\Vite;
19 use FluentCommunity\Framework\Support\Arr;
20 use FluentCommunity\App\Services\FeedsHelper;
21 use FluentCommunity\Modules\Auth\AuthHelper;
22
23 class PortalHandler
24 {
25 protected $currentPath = '';
26
27 protected $slug = null;
28
29 public function register()
30 {
31 /**
32 * Register the portal route
33 */
34 add_action('init', function () {
35 $this->slug = Helper::getPortalSlug();
36 if ($this->slug !== '') {
37 add_rewrite_rule('^' . $this->slug . '/?$', 'index.php?fcom_route=portal_home', 'top'); // For /hooks
38 add_rewrite_rule('^' . $this->slug . '/(.+)/?', 'index.php?fcom_route=$matches[1]', 'top');
39 }
40 });
41
42 add_filter('query_vars', function ($vars) {
43 $vars[] = 'fcom_route';
44 return $vars;
45 });
46
47 add_action('template_redirect', function () {
48 $hook_path = get_query_var('fcom_route');
49 if ($hook_path) {
50 $this->currentPath = $hook_path;
51 $this->renderFullApp();
52 }
53
54 if ($this->slug === '') {
55 global $wp;
56 $currentRequest = $wp->request;
57 if ($hookPath = Helper::getPortalRequestPath($currentRequest)) {
58 $this->currentPath = $hookPath;
59 $this->renderFullApp();
60 }
61 }
62 }, 1);
63
64 add_action('fluent_community/portal_html', function () {
65 App::make('view')->render('portal.portal');
66 });
67
68 add_action('fluent_community/portal_header', function ($context) {
69 $this->getPortalHeader(true, $context);
70 });
71
72 add_action('fluent_community/portal_sidebar', function ($context) {
73 $this->getPortalSidebar(true, $context);
74 });
75
76 add_action('fluent_community/enqueue_global_assets', function ($useDefaultTheme = true) {
77 wp_enqueue_style('fluent_community_global', Vite::getDynamicSrcUrl('global.scss'), [], time(), 'screen');
78 if ($useDefaultTheme) {
79 wp_enqueue_style('fluent_community_default_theme', Vite::getDynamicSrcUrl('theme-default.scss'), [], FLUENT_COMMUNITY_PLUGIN_VERSION, 'screen');
80 }
81
82 $css = Utility::getColorCssVariables();
83
84 wp_add_inline_style('fluent_community_global', $css);
85
86 wp_enqueue_script('portal_general', Vite::getStaticSrcUrl('portal_general.js'), [], FLUENT_COMMUNITY_PLUGIN_VERSION, true);
87
88 wp_localize_script('portal_general', 'fcom_portal_general', [
89 'is_wp' => true
90 ]);
91 });
92
93 add_action('admin_bar_menu', function ($wp_admin_bar) {
94 if (!\FluentCommunity\App\Services\Helper::canAccessPortal()) {
95 return;
96 }
97
98 // Add custom link within site name dropdown
99 $wp_admin_bar->add_node(array(
100 'id' => 'fluent-community-link',
101 'title' => __('Visit Community Portal', 'fluent-community'),
102 'href' => \FluentCommunity\App\Services\Helper::baseUrl('/'),
103 'parent' => 'site-name'
104 ));
105 }, 99);
106
107 add_action('fluent_community/top_menu_right_items', [$this, 'renderTopMenuRightItems']);
108
109 add_action('fluent_community/after_portal_sidebar', function () {
110
111 if (did_action('fluent_community/after_header_right_menu_items')) {
112 echo '<div role="region" aria-label="Portal Settings" class="fcom_side_footer">';
113 if (Helper::isSiteAdmin()) {
114 ?>
115 <div style="display: flex;justify-content: space-between;" class="fcom_admin_menu">
116 <?php if (!defined('FLUENT_COMMUNITY_PRO')): ?>
117 <a title="Upgrade to Pro" target="_blank" rel="noopener" class="fcom_inline_icon_link_item"
118 href="<?php echo esc_url(Utility::getProductUrl(true)) ?>">
119 <span class="el-icon">
120 <svg width="126" height="125" viewBox="0 0 126 125" fill="none">
121 <rect x="0.22139" width="125" height="125" rx="17.8571" fill="#4A5FE0"/>
122 <path
123 d="M47.9424 75.1832L61.6888 67.2467L69.6253 80.9931C62.0334 85.3763 52.3256 82.7751 47.9424 75.1832Z"
124 fill="white"/>
125 <path fill-rule="evenodd" clip-rule="evenodd"
126 d="M75.4348 59.3101L61.6884 67.2466L69.6249 80.993L83.3713 73.0565L75.4348 59.3101ZM89.1821 51.3734L75.4356 59.3099L83.3721 73.0564L97.1186 65.1199L89.1821 51.3734Z"
127 fill="white"/>
128 <path
129 d="M89.182 51.3736C92.978 49.182 97.8319 50.4826 100.023 54.2786L103.992 61.1518L97.1185 65.12L89.182 51.3736Z"
130 fill="white"/>
131 <path
132 d="M64.593 56.4052L50.8466 64.3417L42.9101 50.5953L56.6565 42.6588L64.593 56.4052Z"
133 fill="white"/>
134 <path
135 d="M78.3397 48.4683L64.5933 56.4048L56.6568 42.6584C64.2487 38.2752 73.9565 40.8764 78.3397 48.4683Z"
136 fill="white"/>
137 <path
138 d="M50.847 64.3418L37.1006 72.2783L29.1641 58.5318L42.9105 50.5953L50.847 64.3418Z"
139 fill="white"/>
140 <path
141 d="M37.1011 72.2783C33.3051 74.4699 28.4512 73.1693 26.2596 69.3733L22.2913 62.5001L29.1646 58.5319L37.1011 72.2783Z"
142 fill="white"/>
143 </svg>
144 </span>
145 <span>Upgrade</span>
146 </a>
147 <?php else: ?>
148 <a title="Go to /wp-admin" class="fcom_inline_icon_link_item fcom_wp_admin_link"
149 href="<?php echo esc_url(admin_url()); ?>">
150 <span class="el-icon">
151 <svg viewBox="0 0 122.52 122.523"><g fill="currentColor"><path
152 d="m8.708 61.26c0 20.802 12.089 38.779 29.619 47.298l-25.069-68.686c-2.916 6.536-4.55 13.769-4.55 21.388z"/><path
153 d="m96.74 58.608c0-6.495-2.333-10.993-4.334-14.494-2.664-4.329-5.161-7.995-5.161-12.324 0-4.831 3.664-9.328 8.825-9.328.233 0 .454.029.681.042-9.35-8.566-21.807-13.796-35.489-13.796-18.36 0-34.513 9.42-43.91 23.688 1.233.037 2.395.063 3.382.063 5.497 0 14.006-.667 14.006-.667 2.833-.167 3.167 3.994.337 4.329 0 0-2.847.335-6.015.501l19.138 56.925 11.501-34.493-8.188-22.434c-2.83-.166-5.511-.501-5.511-.501-2.832-.166-2.5-4.496.332-4.329 0 0 8.679.667 13.843.667 5.496 0 14.006-.667 14.006-.667 2.835-.167 3.168 3.994.337 4.329 0 0-2.853.335-6.015.501l18.992 56.494 5.242-17.517c2.272-7.269 4.001-12.49 4.001-16.989z"/><path
154 d="m62.184 65.857-15.768 45.819c4.708 1.384 9.687 2.141 14.846 2.141 6.12 0 11.989-1.058 17.452-2.979-.141-.225-.269-.464-.374-.724z"/><path
155 d="m107.376 36.046c.226 1.674.354 3.471.354 5.404 0 5.333-.996 11.328-3.996 18.824l-16.053 46.413c15.624-9.111 26.133-26.038 26.133-45.426.001-9.137-2.333-17.729-6.438-25.215z"/><path
156 d="m61.262 0c-33.779 0-61.262 27.481-61.262 61.26 0 33.783 27.483 61.263 61.262 61.263 33.778 0 61.265-27.48 61.265-61.263-.001-33.779-27.487-61.26-61.265-61.26zm0 119.715c-32.23 0-58.453-26.223-58.453-58.455 0-32.23 26.222-58.451 58.453-58.451 32.229 0 58.45 26.221 58.45 58.451 0 32.232-26.221 58.455-58.45 58.455z"/></g></svg>
157 </span>
158 </a>
159 <?php endif; ?>
160 <a title="Portal Settings" class="fcom_inline_icon_link_item"
161 href="<?php echo esc_url(Helper::baseUrl('admin/settings')); ?>">
162 <span class="el-icon">
163 <svg viewBox="0 0 1024 1024" data-v-d2e47025=""><path fill="currentColor"
164 d="M600.704 64a32 32 0 0 1 30.464 22.208l35.2 109.376c14.784 7.232 28.928 15.36 42.432 24.512l112.384-24.192a32 32 0 0 1 34.432 15.36L944.32 364.8a32 32 0 0 1-4.032 37.504l-77.12 85.12a357.12 357.12 0 0 1 0 49.024l77.12 85.248a32 32 0 0 1 4.032 37.504l-88.704 153.6a32 32 0 0 1-34.432 15.296L708.8 803.904c-13.44 9.088-27.648 17.28-42.368 24.512l-35.264 109.376A32 32 0 0 1 600.704 960H423.296a32 32 0 0 1-30.464-22.208L357.696 828.48a351.616 351.616 0 0 1-42.56-24.64l-112.32 24.256a32 32 0 0 1-34.432-15.36L79.68 659.2a32 32 0 0 1 4.032-37.504l77.12-85.248a357.12 357.12 0 0 1 0-48.896l-77.12-85.248A32 32 0 0 1 79.68 364.8l88.704-153.6a32 32 0 0 1 34.432-15.296l112.32 24.256c13.568-9.152 27.776-17.408 42.56-24.64l35.2-109.312A32 32 0 0 1 423.232 64H600.64zm-23.424 64H446.72l-36.352 113.088-24.512 11.968a294.113 294.113 0 0 0-34.816 20.096l-22.656 15.36-116.224-25.088-65.28 113.152 79.68 88.192-1.92 27.136a293.12 293.12 0 0 0 0 40.192l1.92 27.136-79.808 88.192 65.344 113.152 116.224-25.024 22.656 15.296a294.113 294.113 0 0 0 34.816 20.096l24.512 11.968L446.72 896h130.688l36.48-113.152 24.448-11.904a288.282 288.282 0 0 0 34.752-20.096l22.592-15.296 116.288 25.024 65.28-113.152-79.744-88.192 1.92-27.136a293.12 293.12 0 0 0 0-40.256l-1.92-27.136 79.808-88.128-65.344-113.152-116.288 24.96-22.592-15.232a287.616 287.616 0 0 0-34.752-20.096l-24.448-11.904L577.344 128zM512 320a192 192 0 1 1 0 384 192 192 0 0 1 0-384m0 64a128 128 0 1 0 0 256 128 128 0 0 0 0-256"></path></svg>
165 </span>
166 <span><?php esc_html_e('Settings', 'fluent-community'); ?></span>
167 </a>
168 </div>
169 <?php
170 } else if (Utility::isCustomizationEnabled('show_powered_by')) {
171 ?>
172 <a target="_blank" rel="noopener" style="font-size: 80%; cursor: pointer;"
173 class="fcom_inline_icon_link_item" href="<?php echo esc_url(Utility::getProductUrl(true)) ?>">
174 <?php echo esc_html('Powered by FluentCommunity', 'fluent-community'); ?>
175 </a>
176 <?php
177 }
178 echo '</div>';
179 return;
180 }
181
182 if (Helper::isSiteAdmin()) {
183 add_action('fluent_community/before_header_menu_items', function () {
184 ?>
185 <li class="top_menu_item fcom_icon_link">
186 <a href="<?php echo esc_url(Helper::baseUrl('admin/settings')); ?>">
187 <span class="el-icon">
188 <svg viewBox="0 0 1024 1024" data-v-d2e47025=""><path fill="currentColor"
189 d="M600.704 64a32 32 0 0 1 30.464 22.208l35.2 109.376c14.784 7.232 28.928 15.36 42.432 24.512l112.384-24.192a32 32 0 0 1 34.432 15.36L944.32 364.8a32 32 0 0 1-4.032 37.504l-77.12 85.12a357.12 357.12 0 0 1 0 49.024l77.12 85.248a32 32 0 0 1 4.032 37.504l-88.704 153.6a32 32 0 0 1-34.432 15.296L708.8 803.904c-13.44 9.088-27.648 17.28-42.368 24.512l-35.264 109.376A32 32 0 0 1 600.704 960H423.296a32 32 0 0 1-30.464-22.208L357.696 828.48a351.616 351.616 0 0 1-42.56-24.64l-112.32 24.256a32 32 0 0 1-34.432-15.36L79.68 659.2a32 32 0 0 1 4.032-37.504l77.12-85.248a357.12 357.12 0 0 1 0-48.896l-77.12-85.248A32 32 0 0 1 79.68 364.8l88.704-153.6a32 32 0 0 1 34.432-15.296l112.32 24.256c13.568-9.152 27.776-17.408 42.56-24.64l35.2-109.312A32 32 0 0 1 423.232 64H600.64zm-23.424 64H446.72l-36.352 113.088-24.512 11.968a294.113 294.113 0 0 0-34.816 20.096l-22.656 15.36-116.224-25.088-65.28 113.152 79.68 88.192-1.92 27.136a293.12 293.12 0 0 0 0 40.192l1.92 27.136-79.808 88.192 65.344 113.152 116.224-25.024 22.656 15.296a294.113 294.113 0 0 0 34.816 20.096l24.512 11.968L446.72 896h130.688l36.48-113.152 24.448-11.904a288.282 288.282 0 0 0 34.752-20.096l22.592-15.296 116.288 25.024 65.28-113.152-79.744-88.192 1.92-27.136a293.12 293.12 0 0 0 0-40.256l-1.92-27.136 79.808-88.128-65.344-113.152-116.288 24.96-22.592-15.232a287.616 287.616 0 0 0-34.752-20.096l-24.448-11.904L577.344 128zM512 320a192 192 0 1 1 0 384 192 192 0 0 1 0-384m0 64a128 128 0 1 0 0 256 128 128 0 0 0 0-256"></path></svg>
190 </a>
191 </li>
192 <?php
193 });
194 }
195
196 echo '<div class="fcom_side_footer">';
197 $this->renderTopMenuRightItems();
198 echo '</div>';
199 });
200
201 }
202
203 public function renderTopMenuRightItems()
204 {
205 $auth_url = $this->getAuthUrl();
206 $auth = Helper::getCurrentProfile();
207 $has_color_scheme = Helper::hasColorScheme();
208 $profileLinks = $this->getProfileLinks($auth);
209 ?>
210 <ul class="fcom_user_context_menu_items">
211 <?php do_action('fluent_community/before_header_right_menu_items', $auth); ?>
212 <?php if ($has_color_scheme): ?>
213 <li>
214 <span class="fcom_color_mode_core">
215 <span class="fcom_color_mode_action fcom_mode_switch el-icon">
216 <svg class="show_on_light" width="20" height="20" viewBox="0 0 20 20" fill="none"
217 xmlns="http://www.w3.org/2000/svg">
218 <path
219 d="M17.9163 11.7317C16.9166 12.2654 15.7748 12.5681 14.5623 12.5681C10.6239 12.5681 7.43128 9.37543 7.43128 5.43705C7.43128 4.22456 7.73388 3.08274 8.2677 2.08301C4.72272 2.91382 2.08301 6.09562 2.08301 9.89393C2.08301 14.3246 5.67476 17.9163 10.1054 17.9163C13.9038 17.9163 17.0855 15.2767 17.9163 11.7317Z"
220 stroke="#525866" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
221 </svg>
222 <svg class="show_on_dark" width="20" height="20" viewBox="0 0 20 20" fill="none"
223 xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#clip0_2906_20675)">
224 <path
225 d="M14.1663 10.0007C14.1663 12.3018 12.3009 14.1673 9.99967 14.1673C7.69849 14.1673 5.83301 12.3018 5.83301 10.0007C5.83301 7.69946 7.69849 5.83398 9.99967 5.83398C12.3009 5.83398 14.1663 7.69946 14.1663 10.0007Z"
226 stroke="currentColor" stroke-width="1.5"/><path
227 d="M9.99984 1.66699V2.91699M9.99984 17.0837V18.3337M15.8922 15.8931L15.0083 15.0092M4.99089 4.99137L4.107 4.10749M18.3332 10.0003H17.0832M2.9165 10.0003H1.6665M15.8926 4.10758L15.0087 4.99147M4.99129 15.0093L4.10741 15.8932"
228 stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></g><defs><clipPath
229 id="clip0_2906_20675"><rect width="20" height="20"
230 fill="correntColor"/></clipPath></defs>
231 </svg>
232 </span>
233 </span>
234 </li>
235 <?php endif; ?>
236 <li class="top_menu_item fcom_search_holder"></li>
237 <li class="top_menu_item fcom_notification_holder"></li>
238 <?php do_action('fluent_community/before_header_menu_items', $auth); ?>
239 <?php if ($auth): ?>
240 <li class="top_menu_item fcom_menu_item_user">
241 <div class="fcom_user_menu_item">
242 <div class="fcom_profile_extend">
243 <div class="fcom_profile_menu">
244 <div class="user_avatar">
245 <img alt="User Photo" src="<?php echo esc_url($auth->avatar); ?>"/>
246 <span class="avatar_icon">
247 <svg xmlns="http://www.w3.org/2000/svg" height="8" width="8"
248 viewBox="0 0 1024 1024" data-v-d2e47025="">
249 <path fill="currentColor"
250 d="M104.704 338.752a64 64 0 0 1 90.496 0l316.8 316.8 316.8-316.8a64 64 0 0 1 90.496 90.496L557.248 791.296a64 64 0 0 1-90.496 0L104.704 429.248a64 64 0 0 1 0-90.496z"></path>
251 </svg>
252 </span>
253 </div>
254 <span class="user_name">
255 <?php echo esc_html($auth->display_name); ?>
256 </span>
257 <ul class="fcom_profile_sub_menu">
258 <li class="fcom_profile_block">
259 <a href="<?php echo esc_url(Helper::baseUrl('/u/' . $auth->username)); ?>">
260 <div class="fcom_profile_avatar">
261 <img src="<?php echo esc_url($auth->avatar); ?>"
262 alt="<?php echo esc_attr($auth->display_name); ?>">
263 </div>
264 <div class="fcom_user_info">
265 <p class="fcom_user_name"><?php echo esc_html($auth->display_name); ?></p>
266 <p class="fcom_user_email"><?php echo esc_html($auth->user->user_email); ?></p>
267 </div>
268 </a>
269 </li>
270 <?php foreach ($profileLinks as $link): ?>
271 <li>
272 <?php Helper::renderLink($link, 'fcom_menu_link', ''); ?>
273 </li>
274 <?php endforeach; ?>
275 </ul>
276 </div>
277 </div>
278 </li>
279 <?php else: ?>
280 <li class="top_menu_item fcom_login_li">
281 <a class="fcom_login_btn" href="<?php echo esc_url($auth_url); ?>">
282 <span><?php esc_html_e('Login', 'fluent-community'); ?></span>
283 </a>
284 </li>
285 <?php endif; ?>
286 <?php do_action('fluent_community/after_header_right_menu_items', $auth); ?>
287 </ul>
288 <?php
289 }
290
291 protected function appVars()
292 {
293 $userModel = User::where('ID', get_current_user_id())->first();
294 $xprofile = null;
295
296 if ($userModel) {
297 $xprofile = XProfile::where('user_id', get_current_user_id())->first();
298 if (!$xprofile) {
299 $xprofile = $userModel->syncXProfile();
300 }
301 }
302
303 $authData = null;
304 $spaceSlugs = [];
305 $spaceGroups = [];
306
307 if ($userModel && $xprofile) {
308 $wpUser = get_user_by('ID', $userModel->ID);
309
310 if ($userModel->isCommunityModerator()) {
311 $userSpaces = Space::orderBy('serial', 'ASC')->get();
312 $spaceGroups = SpaceGroup::orderBy('serial', 'ASC')
313 ->select(['id', 'title', 'slug', 'settings'])
314 ->get();
315 } else {
316 $userSpaces = Space::orderBy('serial', 'ASC')
317 ->whereHas('members', function ($q) {
318 $q->where('user_id', get_current_user_id())
319 ->where('status', 'active');
320 })
321 ->get();
322
323 $userSpaceParentIds = $userSpaces->pluck('parent_id')->filter()->unique()->toArray();
324
325 $spaceGroups = SpaceGroup::orderBy('serial', 'ASC')
326 ->select(['id', 'title', 'slug', 'settings'])
327 ->whereIn('id', $userSpaceParentIds)
328 ->get();
329 }
330
331 $userSpaces->each(function ($space) use ($userModel) {
332 $userId = get_current_user_id();
333 $space->permissions = $space->getUserPermissions($userModel);
334 $space->membership = $space->getMembership($userId);
335 $space->description_rendered = FeedsHelper::mdToHtml($space->description);
336 if (!$space->membership) {
337 $space->lockscreen_config = LockscreenService::getLockscreenConfig($space, $space->membership);
338 }
339 $space->topics = Utility::getTopicsBySpaceId($space->id);
340 do_action_ref_array('fluent_community/space', [&$space]);
341 });
342
343 $userSpaces = $userSpaces->keyBy('slug');
344
345 $userModel->cacheAccessSpaces();
346
347 $spaceSlugs = $userSpaces->pluck('slug')->toArray();
348
349 $authData = [
350 'id' => $xprofile->user_id,
351 'user_id' => $xprofile->user_id,
352 'username' => $xprofile->username,
353 'display_name' => $xprofile->display_name,
354 'first_name' => $wpUser->first_name ? $wpUser->first_name : $xprofile->getFirstName(),
355 'avatar' => $xprofile->avatar,
356 'total_points' => $xprofile->total_points,
357 'last_activity' => $xprofile->last_activity,
358 'email' => $userModel->user_email,
359 'spaces' => $userSpaces,
360 'community_roles' => $userModel->getCommunityRoles(),
361 'is_verified' => $xprofile->is_verified,
362 'compilation_score' => $xprofile->getCompletionScore(),
363 'meta' => $xprofile->meta
364 ];
365 } else {
366 $authData = [
367 'id' => 0,
368 'user_id' => 0,
369 'spaces' => (object)[],
370 'community_roles' => [],
371 'compilation_score' => 100
372 ];
373 }
374
375 $settings = Helper::generalSettings();
376
377 $onboardSettings = Helper::getOnboardingSettings();
378
379 global $wp_version;
380
381 $isRtl = Helper::isRtl();
382
383 $isAbsoluteUrl = defined('FLUENT_COMMUNITY_PORTAL_SLUG') && FLUENT_COMMUNITY_PORTAL_SLUG == '';
384
385 $portalVars = apply_filters('fluent_community/portal_vars', [
386 'portal_notices' => apply_filters('fluent_community/portal_notices', []),
387 'i18n' => TransStrings::getStrings(),
388 'auth' => $authData,
389 'ajaxurl' => admin_url('admin-ajax.php'),
390 'slug' => 'fluent-community',
391 'rest' => $this->getRestInfo(),
392 'user_id' => $userModel ? $userModel->ID : null,
393 'assets_url' => FLUENT_COMMUNITY_PLUGIN_URL . 'assets/',
394 'permissions' => $userModel ? $userModel->getPermissions() : ['read' => true],
395 'logo' => Arr::get($settings, 'logo'),
396 'site_title' => Arr::get($settings, 'site_title'),
397 'user_membership_slugs' => $spaceSlugs,
398 'block_editor_assets' => [
399 'scripts' => [
400 'react' => Vite::getStaticSrcUrl('libs/isolated-editor/react.production.min.js'),
401 'react-dom' => Vite::getStaticSrcUrl(
402 'libs/isolated-editor/react-dom.production.min.js'
403 ),
404 'isolated-block-editor' => Vite::getStaticSrcUrl('libs/isolated-editor/isolated-block-editor.js')
405 ],
406 'styles' => [
407 $isRtl ? Vite::getStaticSrcUrl('libs/isolated-editor/core.rtl.css') : Vite::getStaticSrcUrl('libs/isolated-editor/core.css'),
408 $isRtl ? Vite::getStaticSrcUrl('libs/isolated-editor/isolated-block-editor.rtl.css') : Vite::getStaticSrcUrl('libs/isolated-editor/isolated-block-editor.css'),
409 includes_url('css/dist/block-editor/content.min.css?ver=' . $wp_version),
410 ]
411 ],
412 'features' => [
413 'disable_global_posts' => Arr::get($settings, 'disable_global_posts', '') == 'yes',
414 'has_survey_poll' => true,
415 'is_onboarding_enabled' => Arr::get($onboardSettings, 'is_onboarding_enabled', 'no') == 'yes',
416 'can_switch_layout' => true,
417 'max_media_per_post' => apply_filters('fluent_community/max_media_per_post', 4),
418 'has_post_title' => Utility::postTitlePref(),
419 'has_course' => Helper::isFeatureEnabled('course_module'),
420 'skicky_sidebar' => Utility::isCustomizationEnabled('fixed_sidebar'),
421 'post_layout' => Utility::getCustomizationSetting('rich_post_layout'),
422 'video_embeder' => apply_filters('fluent_community/has_video_embeder', true),
423 'has_topics' => !!Utility::getTopics()
424 ],
425 'route_classes' => array_filter([
426 'fcom_sticky_header' => Utility::isCustomizationEnabled('fixed_page_header'),
427 'fcom_sticky_sidebar' => Utility::isCustomizationEnabled('fixed_sidebar'),
428 'fcom_has_icon_on_header_menu' => Utility::isCustomizationEnabled('icon_on_header_menu')
429 ]),
430 'urls' => [
431 'site_url' => site_url(),
432 'portal_base' => Helper::baseUrl('/'),
433 'global_search' => Helper::baseUrl(),
434 ],
435 'last_feed_id' => FeedsHelper::getLastFeedId(),
436 'unread_notification_count' => $userModel ? $userModel->getUnreadNotificationCount() : 0,
437 'unread_feed_ids' => $userModel ? $userModel->getUnreadNotificationFeedIds() : [],
438 'date_offset' => time() - current_time('timestamp'),
439 'portal_slug' => Helper::getPortalSlug(true),
440 'mobileMenuItems' => apply_filters('fluent_community/mobile_menu', [
441 [
442 'route' => [
443 'name' => 'all_feeds'
444 ],
445 'icon_svg' => '<svg width="20" height="18" viewBox="0 0 20 18" fill="none"><path fill-rule="evenodd" clip-rule="evenodd" d="M10 13.166H10.0075H10Z" fill="currentColor"></path><path d="M10 13.166H10.0075" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path><path d="M16.6666 6.08301V10.2497C16.6666 13.3924 16.6666 14.9637 15.6903 15.94C14.714 16.9163 13.1426 16.9163 9.99992 16.9163C6.85722 16.9163 5.28587 16.9163 4.30956 15.94C3.33325 14.9637 3.33325 13.3924 3.33325 10.2497V6.08301" stroke="currentColor" stroke-width="1.5"></path><path d="M18.3333 7.74967L14.714 4.27925C12.4918 2.14842 11.3807 1.08301 9.99996 1.08301C8.61925 1.08301 7.50814 2.14842 5.28592 4.27924L1.66663 7.74967" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"></path></svg>'
446 ],
447 [
448 'route' => [
449 'name' => 'spaces'
450 ],
451 'icon_svg' => '<svg version="1.1" viewBox="0 0 128 128" xml:space="preserve"><g><path d="M64,42c-13.2,0-24,10.8-24,24s10.8,24,24,24s24-10.8,24-24S77.2,42,64,42z M64,82c-8.8,0-16-7.2-16-16s7.2-16,16-16 s16,7.2,16,16S72.8,82,64,82z"></path><path d="M64,100.8c-14.9,0-29.2,6.2-39.4,17.1l-2.7,2.9l5.8,5.5l2.7-2.9c8.8-9.4,20.7-14.6,33.6-14.6s24.8,5.2,33.6,14.6l2.7,2.9 l5.8-5.5l-2.7-2.9C93.2,107.1,78.9,100.8,64,100.8z"></path><path d="M97,47.9v8c9.4,0,18.1,3.8,24.6,10.7l5.8-5.5C119.6,52.7,108.5,47.9,97,47.9z"></path><path d="M116.1,20c0-10.5-8.6-19.1-19.1-19.1S77.9,9.5,77.9,20S86.5,39.1,97,39.1S116.1,30.5,116.1,20z M85.9,20 c0-6.1,5-11.1,11.1-11.1s11.1,5,11.1,11.1s-5,11.1-11.1,11.1S85.9,26.1,85.9,20z"></path><path d="M31,47.9c-11.5,0-22.6,4.8-30.4,13.2l5.8,5.5c6.4-6.9,15.2-10.7,24.6-10.7V47.9z"></path><path d="M50.1,20C50.1,9.5,41.5,0.9,31,0.9S11.9,9.5,11.9,20S20.5,39.1,31,39.1S50.1,30.5,50.1,20z M31,31.1 c-6.1,0-11.1-5-11.1-11.1S24.9,8.9,31,8.9s11.1,5,11.1,11.1S37.1,31.1,31,31.1z"></path></g></svg>'
452 ]
453 ]),
454 'socialLinkProviders' => ProfileHelper::socialLinkProviders(),
455 'space_groups' => $spaceGroups,
456 'feed_links' => Helper::getEnabledFeedLinks(),
457 'routing_system' => Helper::getPortalRouteType(),
458 'portal_url' => Helper::baseUrl('/'),
459 'upgrade_url' => 'https://fluentcommunity.co/discount-deal/?utm_source=wp&utm_medium=upgrade&utm_campaign=upgrade',
460 'dateTime18n' => apply_filters('fluent_community/date_time_i18n', [
461 /* translators: weekday. Please keep the serial and format */
462 'weekdays' => __('Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday', 'fluent-community'),
463 /* translators: Months Please keep the serial and format*/
464 'months' => __('January_February_March_April_May_June_July_August_September_October_November_December', 'fluent-community'),
465 /* translators: weekday short Please keep the serial and format*/
466 'weekdaysShort' => __('Sun_Mon_Tue_Wed_Thu_Fri_Sat', 'fluent-community'),
467 /* translators: Months short Please keep the serial and format*/
468 'monthsShort' => __('Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec', 'fluent-community'),
469 /* translators: weekday min Please keep the serial and format*/
470 'weekdaysMin' => __('Su_Mo_Tu_We_Th_Fr_Sa', 'fluent-community'),
471 'relativeTime' => [
472 /* translators: Relative Date Formats. Please do not alter %s*/
473 'future' => __('in %s', 'fluent-community'),
474 /* translators: Relative Date Formats. Please do not alter %s*/
475 'past' => __('%s ago', 'fluent-community'),
476 /* translators: Relative Date Formats.*/
477 's' => __('a few seconds', 'fluent-community'),
478 /* translators: Relative Date Formats.*/
479 'm' => __('a minute', 'fluent-community'),
480 /* translators: Relative Date Formats. Don't alter %d*/
481 'mm' => __('%d minutes', 'fluent-community'),
482 /* translators: Relative Date Formats*/
483 'h' => __('an hour', 'fluent-community'),
484 /* translators: Relative Date Formats. Don't alter %d*/
485 'hh' => __('%d hours', 'fluent-community'),
486 /* translators: Relative Date Formats*/
487 'd' => __('a day', 'fluent-community'),
488 /* translators: Relative Date Formats. Don't alter %d*/
489 'dd' => __('%d days', 'fluent-community'),
490 /* translators: Relative Date Formats*/
491 'M' => __('a month', 'fluent-community'),
492 /* translators: Relative Date Formats. Don't alter %d*/
493 'MM' => __('%d months', 'fluent-community'),
494 /* translators: Relative Date Formats*/
495 'y' => __('a year', 'fluent-community'),
496 /* translators: Relative Date Formats. Don't alter %d*/
497 'yy' => __('%d years', 'fluent-community')
498 ],
499 'relativeTimeMobile' => [
500 /* translators: Relative Date Formats. Please do not alter %s*/
501 'future' => __('in %s', 'fluent-community'),
502 /* translators: Relative Date Formats. Please do not alter %s*/
503 'past' => __('%s ago', 'fluent-community'),
504 /* translators: Relative Date Formats.*/
505 's' => __('few sec', 'fluent-community'),
506 /* translators: Relative Date Formats.*/
507 'm' => __('1min', 'fluent-community'),
508 /* translators: Relative Date Formats. Don't alter %d*/
509 'mm' => __('%dmin', 'fluent-community'),
510 /* translators: Relative Date Formats*/
511 'h' => __('1h', 'fluent-community'),
512 /* translators: Relative Date Formats. Don't alter %d*/
513 'hh' => __('%dh', 'fluent-community'),
514 /* translators: Relative Date Formats*/
515 'd' => __('1d', 'fluent-community'),
516 /* translators: Relative Date Formats. Don't alter %d*/
517 'dd' => __('%dd', 'fluent-community'),
518 /* translators: Relative Date Formats*/
519 'M' => __('1m', 'fluent-community'),
520 /* translators: Relative Date Formats. Don't alter %d*/
521 'MM' => __('%dm', 'fluent-community'),
522 /* translators: Relative Date Formats*/
523 'y' => __('1y', 'fluent-community'),
524 /* translators: Relative Date Formats. Don't alter %d*/
525 'yy' => __('%dy', 'fluent-community')
526 ]
527 ]),
528 'topicsConfig' => Helper::getTopicsConfig(),
529 'is_absolute_url' => $isAbsoluteUrl,
530 'portal_paths' => $isAbsoluteUrl ? Helper::portalRoutePaths() : [],
531 'suggestedColors' => Utility::getSuggestedColors()
532 ]);
533
534 if ($xprofile) {
535 $portalVars['mobileMenuItems'][] = [
536 'route' => [
537 'name' => 'user_profile',
538 'params' => [
539 'username' => $xprofile->username
540 ]
541 ],
542 'icon' => 'Avatar'
543 ];
544 }
545
546 $portalVars['welcome_banner'] = Helper::getWelcomeBanner($userModel ? 'login' : 'logout');
547
548 if (!$xprofile) {
549 $portalVars['auth_url'] = $this->getAuthUrl();
550 $portalVars['allow_signup'] = !!AuthHelper::isRegistrationEnabled();
551 }
552
553 return $portalVars;
554 }
555
556 protected function getRestInfo()
557 {
558 $app = fluentCommunityApp();
559 $ns = $app->config->get('app.rest_namespace');
560 $v = $app->config->get('app.rest_version');
561
562 return [
563 'base_url' => esc_url_raw(rest_url()),
564 'url' => rest_url($ns . '/' . $v),
565 'nonce' => wp_create_nonce('wp_rest'),
566 'namespace' => $ns,
567 'version' => $v,
568 ];
569 }
570
571 protected function renderFullApp()
572 {
573 if (isset($_REQUEST['fcom_action'])) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
574 $action = sanitize_text_field(wp_unslash($_REQUEST['fcom_action'])); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
575 do_action('fluent_community/portal_action_' . $action, $_GET); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
576 }
577
578 $userId = get_current_user_id();
579
580 if (!$userId) {
581 if (!Helper::isPublicAccessible()) {
582 $url = home_url(add_query_arg($_REQUEST, $GLOBALS['wp']->request)); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
583 $settings = Helper::generalSettings();
584 $authUrl = Arr::get($settings, 'auth_url', '');
585 if ($authUrl) {
586 $authUrl = add_query_arg([
587 'redirect_to' => $url
588 ], $authUrl);
589 } else {
590 $authUrl = $this->getAuthUrl();
591 }
592
593 do_action('fluent_community/portal/not_logged_in', $authUrl);
594 wp_redirect($authUrl);
595 exit();
596 }
597 }
598
599 do_action('fluent_community/portal/viewed');
600 $xprofile = Helper::getCurrentProfile();
601
602 if ($xprofile && $xprofile->status != 'active') {
603 if ($xprofile->status == 'pending') {
604 $this->viewErrorPage('You request is on pending', 'An admin need to approve your join request. Please contact with an admin to get approval');
605 } else {
606 $this->viewErrorPage('Access denied', 'Sorry, You can not access to this portal');
607 }
608 }
609
610 if ($xprofile) {
611 if (!Helper::canAccessPortal()) {
612 $generalSettings = Helper::generalSettings();
613 $this->viewErrorPage('Access Denied', Arr::get($generalSettings, 'restricted_role_content'));
614 }
615 if ($xprofile->user) {
616 $xprofile->user->cacheAccessSpaces();
617 }
618
619 /*
620 * Just in case if username is not sanitized
621 */
622 if ($xprofile->username != CustomSanitizer::sanitizeUserName($xprofile->username)) {
623 $xprofile->username = ProfileHelper::generateUserName($xprofile->user_id);
624 $xprofile->save();
625 }
626
627 do_action('fluent_community/portal_render_for_user', $xprofile);
628 do_action('fluent_communit/track_activity');
629 }
630
631 $data = $this->getAppData();
632 $data = $this->maybePushDynamicMetaData($data);
633
634 $data['isHeadless'] = Helper::isHeadless();
635
636 if (!$data['isHeadless']) {
637 $this->loadClassicPortalAssets($data);
638 } else {
639 do_action('fluent_community/rendering_headless_portal', $data);
640 }
641
642 do_action('fluent_community/before_portal_rendered', $data);
643
644 status_header(200);
645 App::make('view')->render('portal_page', $data);
646 exit(200);
647 }
648
649 public function loadClassicPortalAssets($data)
650 {
651 $cssFiles = $data['css_files'];
652
653 unset($cssFiles['fcom_theme_default']);
654
655 foreach ($cssFiles as $fileName => $cssFile) {
656 wp_enqueue_style($fileName, $cssFile['url'], [], FLUENT_COMMUNITY_PLUGIN_VERSION, 'screen');
657 }
658
659 $jsFiles = $data['js_files'];
660 $jsTags = array_keys($jsFiles);
661 add_filter('script_loader_tag', function ($tag, $handle) use ($jsTags) {
662 if (!in_array($handle, $jsTags)) {
663 return $tag;
664 }
665 $tag = str_replace(' src', ' type="module" src', $tag);
666 return $tag;
667 }, 10, 2);
668 foreach ($jsFiles as $fileName => $jsFile) {
669 wp_enqueue_script($fileName, $jsFile['url'], $jsFile['deps'], FLUENT_COMMUNITY_PLUGIN_VERSION, [
670 'in_footer' => true,
671 'strategy' => 'defer',
672 'type' => 'module'
673 ]);
674 }
675
676 foreach ($data['js_vars'] as $varKey => $values) {
677 wp_localize_script('fcom_strat', $varKey, $values);
678 }
679 }
680
681 public function getAppData()
682 {
683
684 $isRtl = Helper::isRtl();
685
686 $userId = get_current_user_id();
687 $url = home_url(add_query_arg($_REQUEST, $GLOBALS['wp']->request)); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
688
689 $appVars = $this->appVars();
690 $generalSettings = Helper::generalSettings();
691
692 $dataVars = [
693 'title' => Arr::get($generalSettings, 'site_title'),
694 'description' => get_bloginfo('description'),
695 'featured_image' => Arr::get($generalSettings, 'featured_image', ''),
696 'js_files' => [
697 'fcom_strat' => [
698 'url' => Vite::getStaticSrcUrl('start.js'),
699 'deps' => []
700 ],
701 'fcom_app' => [
702 'url' => Vite::getStaticSrcUrl('app.js'),
703 'deps' => []
704 ],
705 'fcom_general' => [
706 'url' => Vite::getStaticSrcUrl('portal_general.js'),
707 'deps' => []
708 ]
709 ],
710 'js_vars' => [
711 'fluentComAdmin' => $appVars,
712 ],
713 'css_files' => array_filter([
714 'fcom_theme_default' => [
715 'url' => Vite::getDynamicSrcUrl('theme-default.scss', $isRtl)
716 ],
717 'fcom_global' => [
718 'url' => Vite::getDynamicSrcUrl('global.scss', $isRtl)
719 ]
720 ]),
721 'url' => $url,
722 'current_route' => $this->currentPath,
723 'contact' => $appVars['auth'],
724 'user' => $userId ? get_user_by('ID', $userId) : null,
725 'route_group' => Helper::getRouteNameByRequestPath($this->currentPath)
726 ];
727
728 if (!Utility::isDev()) {
729
730 if($isRtl) {
731 $fileName = 'app.rtl.css';
732 } else {
733 $fileName = 'app.css';
734 }
735
736 $dataVars['css_files']['fcom_vendor'] = [
737 'url' => Vite::getStaticSrcUrl($fileName)
738 ];
739 } else {
740 $dataVars['css_files']['fcom_vendor'] = [
741 'url' => Vite::getDynamicSrcUrl('app_css.scss')
742 ];
743 }
744
745 return apply_filters('fluent_community/portal_data_vars', $dataVars);
746 }
747
748 protected function maybePushDynamicMetaData($data)
749 {
750 $dynamicRoute = Arr::get($data, 'route_group');
751 $validGroups = [
752 'user_profile',
753 'community_view',
754 'course_view',
755 'feed_view'
756 ];
757
758 if (!in_array($dynamicRoute, $validGroups)) {
759 return $data;
760 }
761
762 if ($dynamicRoute == 'user_profile') {
763 $uriParts = explode('/', $this->currentPath);
764 if (count($uriParts) >= 2) {
765 $userName = $uriParts[1];
766 $xProfile = XProfile::where('username', $userName)->first();
767 if ($xProfile) {
768 $data['title'] = esc_html($xProfile->display_name) . ' - ' . $data['title'];
769 if ($xProfile->short_description) {
770 $data['description'] = Helper::getHumanExcerpt($xProfile->short_description, 100);
771 }
772 if ($coverPhoto = Arr::get($xProfile->meta, 'cover_photo')) {
773 $data['featured_image'] = $coverPhoto;
774 }
775 }
776 }
777 return $data;
778 }
779
780 if ($dynamicRoute == 'community_view' || $dynamicRoute == 'course_view') {
781 $uriParts = explode('/', $this->currentPath);
782 if (count($uriParts) >= 2) {
783 $paceSlug = $uriParts[1];
784
785 $space = BaseSpace::query()->withoutGlobalScopes()->where('slug', $paceSlug)->first();
786
787 if ($space && $space->privacy != 'secret') {
788
789 if ($dynamicRoute == 'course_view') {
790 $data['title'] = sprintf(__('Enroll %s', 'fluent-community'), esc_html($space->title) . ' - ' . $data['title']);
791 } else {
792 $data['title'] = sprintf(__('Join %s', 'fluent-community'), esc_html($space->title) . ' - ' . $data['title']);
793 }
794
795 if ($space->description) {
796 $data['description'] = Helper::getHumanExcerpt($space->description, 100);
797 }
798 if ($ogImage = Arr::get($space->settings, 'og_image')) {
799 $data['featured_image'] = $ogImage;
800 } else if ($space->cover_photo) {
801 $data['featured_image'] = $space->cover_photo;
802 }
803 }
804 }
805 return $data;
806 }
807
808 if ($dynamicRoute == 'feed_view') {
809 $uriParts = explode('/', $this->currentPath);
810
811 if (count($uriParts) >= 2) {
812 $postSlug = end($uriParts);
813 $feed = Feed::where('slug', $postSlug)
814 ->with([
815 'xprofile' => function ($q) {
816 $q->select(ProfileHelper::getXProfilePublicFields());
817 },
818 'space'
819 ])
820 ->byUserAccess(get_current_user_id())
821 ->first();
822
823 if (!$feed) {
824 return $data;
825 }
826
827 if ($feed->title) {
828 $data['title'] = esc_html($feed->title) . ' - ' . $data['title'];
829 } else {
830 $data['title'] = esc_html($feed->xprofile->display_name) . ' posted at ' . $data['title'];
831 }
832
833 if ($feed->message) {
834 $data['description'] = esc_html(Helper::getHumanExcerpt($feed->message, 100));
835 }
836
837 if ($mediaPreview = Arr::get($feed->meta, 'media_preview.image')) {
838 $data['featured_image'] = esc_url($mediaPreview);
839 } else if ($feed->space) {
840 $space = $feed->space;
841 if ($ogImage = Arr::get($space->settings, 'og_image')) {
842 $data['featured_image'] = $ogImage;
843 } else if ($space->cover_photo) {
844 $data['featured_image'] = $space->cover_photo;
845 }
846 }
847 }
848
849 return $data;
850 }
851
852 return $data;
853 }
854
855 protected function getMainMenuItems($scope = 'sidebar')
856 {
857 $menuGroups = Helper::getMenuItemsGroup('view');
858
859 $items = Arr::get($menuGroups, 'mainMenuItems', []);
860
861 return apply_filters('fluent_community/main_menu_items', $items, $scope);
862 }
863
864 public function getPortalHeader($echo = false, $context = 'headless')
865 {
866 $settings = Helper::generalSettings();
867 $userId = get_current_user_id();
868
869 if ($userId) {
870 $xprofile = XProfile::where('user_id', get_current_user_id())
871 ->first();
872 } else {
873 $xprofile = null;
874 }
875
876
877 $authUrl = $this->getAuthUrl();
878
879 if ($xprofile) {
880 $xprofile->logout_url = wp_logout_url(Helper::baseUrl());
881 }
882
883 $logo = Arr::get($settings, 'logo', '');
884 $whiteLogo = Arr::get($settings, 'white_logo', '');
885 if (!$whiteLogo) {
886 $whiteLogo = $logo;
887 }
888
889 $data = apply_filters('fluent_community/header_vars', [
890 'portal_url' => Helper::baseUrl('/'),
891 'logo' => $logo,
892 'white_logo' => $whiteLogo,
893 'site_title' => Arr::get($settings, 'site_title'),
894 'profile_url' => $userId ? Helper::baseUrl('u/' . $xprofile->username . '/') : '',
895 'auth' => $xprofile ? $xprofile : null,
896 'auth_url' => $authUrl,
897 'menuItems' => $this->getMainMenuItems('header')
898 ]);
899
900 if ($echo) {
901 App::make('view')->render('portal.header', $data);
902 return;
903 }
904
905 return (string)App::make('view')->make('portal.header', $data);
906 }
907
908 private function getProfileLinks($xprofile = null)
909 {
910 if (!$xprofile) {
911 $xprofile = Helper::getCurrentProfile();
912 }
913
914 $profileLinks = [];
915 $menuGroups = Helper::getMenuItemsGroup('view');
916 if ($xprofile) {
917 $profileLinks = Arr::get($menuGroups, 'profileDropdownItems', []);
918
919 $replaces = [
920 '#{{user_url}}' => Helper::baseUrl('u/' . $xprofile->username),
921 '#user_url' => Helper::baseUrl('u/' . $xprofile->username),
922 '#{{logout_url}}' => wp_logout_url(Helper::baseUrl()),
923 '#logout_url' => wp_logout_url(Helper::baseUrl())
924 ];
925
926 foreach ($profileLinks as &$link) {
927 $slug = Arr::get($link, 'slug', '');
928
929 if ($slug == 'my_spaces') {
930 $link['permalink'] = Helper::baseUrl('u/' . $xprofile->username . '/spaces');
931 } else if ($slug == 'logout') {
932 $link['permalink'] = wp_logout_url(Helper::baseUrl());
933 } else if ($slug == 'profile') {
934 $link['permalink'] = Helper::baseUrl('u/' . $xprofile->username);
935 }
936
937 $link['permalink'] = str_replace(array_keys($replaces), array_values($replaces), $link['permalink']);
938 }
939 }
940
941 return $profileLinks;
942 }
943
944 public function getPortalSidebar($echo = false, $context = 'headless')
945 {
946 $primaryMenuItems = $this->getMainMenuItems('sidebar');
947
948 $userModel = Helper::getCurrentUser();
949 $spaceGroups = Helper::getCommunityMenuGroups($userModel);
950
951 $settingsMenu = apply_filters('fluent_community/settings_menu', [], $userModel);
952
953 $menuGroups = Helper::getMenuItemsGroup('view');
954 $topInlines = Arr::get($menuGroups, 'beforeCommunityMenuItems', []);
955 $bottomLinkGroups = Arr::get($menuGroups, 'afterCommunityLinkGroups', []);
956
957 $data = [
958 'primaryItems' => $primaryMenuItems,
959 'spaceGroups' => $spaceGroups,
960 'settingsItems' => $settingsMenu,
961 'topInlineLinks' => $topInlines,
962 'bottomLinkGroups' => $bottomLinkGroups,
963 'is_admin' => Helper::isSiteAdmin(),
964 'has_color_scheme' => Helper::hasColorScheme(),
965 'context' => $context
966 ];
967
968 if ($echo) {
969 App::make('view')->render('portal.main_sidebar', $data);
970 return;
971 }
972
973 return (string)App::make('view')->make('portal.main_sidebar', $data);
974 }
975
976 protected function getAuthUrl()
977 {
978 return apply_filters('fluent_community/auth/login_url', Helper::getAuthUrl());
979 }
980
981 protected function viewErrorPage($title, $message = '', $showBtn = true)
982 {
983 $data = [
984 'title' => $title,
985 'description' => $message,
986 'btn_txt' => 'Go to home page',
987 'url' => site_url()
988 ];
989
990 if (!$showBtn) {
991 $data['btn_txt'] = '';
992 }
993
994 status_header(200);
995 App::make('view')->render('error_page', $data);
996 exit();
997 }
998
999 }
1000