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

1,013 lines 51.5 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
22 class PortalHandler
23 {
24 protected $currentPath = '';
25
26 protected $slug = null;
27
28 public function register()
29 {
30 /**
31 * Register the portal route
32 */
33 add_action('init', function () {
34 $this->slug = Helper::getPortalSlug();
35 if ($this->slug !== '') {
36 add_rewrite_rule('^' . $this->slug . '/?$', 'index.php?fcom_route=portal_home', 'top'); // For /hooks
37 add_rewrite_rule('^' . $this->slug . '/(.+)/?', 'index.php?fcom_route=$matches[1]', 'top');
38 }
39 });
40
41 add_filter('query_vars', function ($vars) {
42 $vars[] = 'fcom_route';
43 return $vars;
44 });
45
46 add_action('template_redirect', function () {
47 $hook_path = get_query_var('fcom_route');
48 if ($hook_path) {
49 $this->currentPath = $hook_path;
50 $this->renderFullApp();
51 }
52
53 if ($this->slug === '') {
54 global $wp;
55 $currentRequest = $wp->request;
56 if ($hookPath = Helper::getPortalRequestPath($currentRequest)) {
57 $this->currentPath = $hookPath;
58 $this->renderFullApp();
59 }
60 }
61 }, 1);
62
63 add_action('fluent_community/portal_html', function () {
64 App::make('view')->render('portal.portal');
65 });
66
67 add_action('fluent_community/portal_header', function ($context) {
68 $this->getPortalHeader(true, $context);
69 });
70
71 add_action('fluent_community/portal_sidebar', function ($context) {
72 $this->getPortalSidebar(true, $context);
73 });
74
75 // add a link to admin menu which will redirect to /portal
76 add_action('admin_menu', function () {
77 add_menu_page(
78 __('FluentCommunity', 'fluent-community'),
79 __('FluentCommunity', 'fluent-community'),
80 'edit_posts',
81 'fluent-community',
82 [$this, 'showAdminPage'],
83 $this->getMenuIcon(),
84 130
85 );
86 });
87
88 add_action('fluent_community/enqueue_global_assets', function ($useDefaultTheme = true) {
89 wp_enqueue_style('fluent_community_global', Vite::getDynamicSrcUrl('global.scss'), [], time(), 'screen');
90 if ($useDefaultTheme) {
91 wp_enqueue_style('fluent_community_default_theme', Vite::getDynamicSrcUrl('theme-default.scss'), [], FLUENT_COMMUNITY_PLUGIN_VERSION, 'screen');
92 }
93
94 wp_enqueue_script('portal_general', Vite::getStaticSrcUrl('portal_general.js'), [], FLUENT_COMMUNITY_PLUGIN_VERSION, true);
95
96 wp_localize_script('portal_general', 'fcom_portal_general', [
97 'is_wp' => true
98 ]);
99 });
100
101 add_action('admin_bar_menu', function ($wp_admin_bar) {
102 if (!\FluentCommunity\App\Services\Helper::canAccessPortal()) {
103 return;
104 }
105
106 // Add custom link within site name dropdown
107 $wp_admin_bar->add_node(array(
108 'id' => 'fluent-community-link',
109 'title' => __('Visit Community Portal', 'fluent-community'),
110 'href' => \FluentCommunity\App\Services\Helper::baseUrl('/'),
111 'parent' => 'site-name'
112 ));
113 }, 99);
114
115 add_action('fluent_community/top_menu_right_items', [$this, 'renderTopMenuRightItems']);
116
117 add_action('fluent_community/after_portal_sidebar', function () {
118
119 if (did_action('fluent_community/after_header_right_menu_items')) {
120 echo '<div role="region" aria-label="Portal Settings" class="fcom_side_footer">';
121 if (Helper::isSiteAdmin()) {
122 ?>
123 <div style="display: flex;justify-content: space-between;" class="fcom_admin_menu">
124 <?php if (!defined('FLUENT_COMMUNITY_PRO')): ?>
125 <a title="Upgrade to Pro" target="_blank" rel="noopener" class="fcom_inline_icon_link_item"
126 href="<?php echo esc_url(Utility::getProductUrl(true)) ?>">
127 <span class="el-icon">
128 <svg width="126" height="125" viewBox="0 0 126 125" fill="none">
129 <rect x="0.22139" width="125" height="125" rx="17.8571" fill="#4A5FE0"/>
130 <path
131 d="M47.9424 75.1832L61.6888 67.2467L69.6253 80.9931C62.0334 85.3763 52.3256 82.7751 47.9424 75.1832Z"
132 fill="white"/>
133 <path fill-rule="evenodd" clip-rule="evenodd"
134 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"
135 fill="white"/>
136 <path
137 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"
138 fill="white"/>
139 <path
140 d="M64.593 56.4052L50.8466 64.3417L42.9101 50.5953L56.6565 42.6588L64.593 56.4052Z"
141 fill="white"/>
142 <path
143 d="M78.3397 48.4683L64.5933 56.4048L56.6568 42.6584C64.2487 38.2752 73.9565 40.8764 78.3397 48.4683Z"
144 fill="white"/>
145 <path
146 d="M50.847 64.3418L37.1006 72.2783L29.1641 58.5318L42.9105 50.5953L50.847 64.3418Z"
147 fill="white"/>
148 <path
149 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"
150 fill="white"/>
151 </svg>
152 </span>
153 <span>Upgrade</span>
154 </a>
155 <?php else: ?>
156 <a title="Go to /wp-admin" class="fcom_inline_icon_link_item fcom_wp_admin_link"
157 href="<?php echo esc_url(admin_url()); ?>">
158 <span class="el-icon">
159 <svg viewBox="0 0 122.52 122.523"><g fill="currentColor"><path
160 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
161 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
162 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
163 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
164 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>
165 </span>
166 </a>
167 <?php endif; ?>
168 <a title="Portal Settings" class="fcom_inline_icon_link_item"
169 href="<?php echo esc_url(Helper::baseUrl('admin/settings')); ?>">
170 <span class="el-icon">
171 <svg viewBox="0 0 1024 1024" data-v-d2e47025=""><path fill="currentColor"
172 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>
173 </span>
174 <span><?php esc_html_e('Settings', 'fluent-community'); ?></span>
175 </a>
176 </div>
177 <?php
178 } else if (Utility::isCustomizationEnabled('show_powered_by')) {
179 ?>
180 <a target="_blank" rel="noopener" style="font-size: 80%; cursor: pointer;"
181 class="fcom_inline_icon_link_item" href="<?php echo esc_url(Utility::getProductUrl(true)) ?>">
182 <?php echo esc_html('Powered by FluentCommunity', 'fluent-community'); ?>
183 </a>
184 <?php
185 }
186 echo '</div>';
187 return;
188 }
189
190 if (Helper::isSiteAdmin()) {
191 add_action('fluent_community/before_header_menu_items', function () {
192 ?>
193 <li class="top_menu_item fcom_icon_link">
194 <a href="<?php echo esc_url(Helper::baseUrl('admin/settings')); ?>">
195 <span class="el-icon">
196 <svg viewBox="0 0 1024 1024" data-v-d2e47025=""><path fill="currentColor"
197 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>
198 </a>
199 </li>
200 <?php
201 });
202 }
203
204 echo '<div class="fcom_side_footer">';
205 $this->renderTopMenuRightItems();
206 echo '</div>';
207 });
208
209 }
210
211 public function renderTopMenuRightItems()
212 {
213 $auth_url = $this->getAuthUrl();
214 $auth = Helper::getCurrentProfile();
215 $has_color_scheme = Helper::hasColorScheme();
216 $profileLinks = $this->getProfileLinks($auth);
217 ?>
218 <ul class="fcom_user_context_menu_items">
219 <?php if ($has_color_scheme): ?>
220 <li>
221 <span class="fcom_color_mode_core">
222 <span class="fcom_color_mode_action fcom_mode_switch el-icon">
223 <svg class="show_on_light" width="20" height="20" viewBox="0 0 20 20" fill="none"
224 xmlns="http://www.w3.org/2000/svg">
225 <path
226 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"
227 stroke="#525866" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
228 </svg>
229 <svg class="show_on_dark" width="20" height="20" viewBox="0 0 20 20" fill="none"
230 xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#clip0_2906_20675)">
231 <path
232 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"
233 stroke="currentColor" stroke-width="1.5"/><path
234 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"
235 stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></g><defs><clipPath
236 id="clip0_2906_20675"><rect width="20" height="20"
237 fill="correntColor"/></clipPath></defs>
238 </svg>
239 </span>
240 </span>
241 </li>
242 <?php endif; ?>
243 <li class="top_menu_item fcom_search_holder"></li>
244 <li class="top_menu_item fcom_notification_holder"></li>
245 <?php do_action('fluent_community/before_header_menu_items', $auth); ?>
246 <?php if ($auth): ?>
247 <li class="top_menu_item fcom_menu_item_user">
248 <div class="fcom_user_menu_item">
249 <div class="fcom_profile_extend">
250 <div class="fcom_profile_menu">
251 <div class="user_avatar">
252 <img alt="User Photo" src="<?php echo esc_url($auth->avatar); ?>"/>
253 <span class="avatar_icon">
254 <svg xmlns="http://www.w3.org/2000/svg" height="8" width="8"
255 viewBox="0 0 1024 1024" data-v-d2e47025="">
256 <path fill="currentColor"
257 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>
258 </svg>
259 </span>
260 </div>
261 <span class="user_name">
262 <?php echo esc_html($auth->display_name); ?>
263 </span>
264 <ul class="fcom_profile_sub_menu">
265 <li class="fcom_profile_block">
266 <a href="<?php echo esc_url(Helper::baseUrl('/u/' . $auth->username)); ?>">
267 <div class="fcom_profile_avatar">
268 <img src="<?php echo esc_url($auth->avatar); ?>"
269 alt="<?php echo esc_attr($auth->display_name); ?>">
270 </div>
271 <div class="fcom_user_info">
272 <p class="fcom_user_name"><?php echo esc_html($auth->display_name); ?></p>
273 <p class="fcom_user_email"><?php echo esc_html($auth->user->user_email); ?></p>
274 </div>
275 </a>
276 </li>
277 <?php foreach ($profileLinks as $link): ?>
278 <li>
279 <?php Helper::renderLink($link, 'fcom_menu_link', ''); ?>
280 </li>
281 <?php endforeach; ?>
282 </ul>
283 </div>
284 </div>
285 </li>
286 <?php else: ?>
287 <li class="top_menu_item fcom_login_li">
288 <a class="fcom_login_btn" href="<?php echo esc_url($auth_url); ?>">
289 <span><?php esc_html_e('Login', 'fluent-community'); ?></span>
290 </a>
291 </li>
292 <?php endif; ?>
293 <?php do_action('fluent_community/after_header_right_menu_items', $auth); ?>
294 </ul>
295 <?php
296 }
297
298 protected function appVars()
299 {
300 $userModel = User::where('ID', get_current_user_id())->first();
301 $xprofile = null;
302
303 if ($userModel) {
304 $xprofile = XProfile::where('user_id', get_current_user_id())->first();
305 if (!$xprofile) {
306 $xprofile = $userModel->syncXProfile();
307 }
308 }
309
310 $authData = null;
311 $spaceSlugs = [];
312 $spaceGroups = [];
313
314 if ($userModel && $xprofile) {
315 $wpUser = get_user_by('ID', $userModel->ID);
316
317 if ($userModel->isCommunityModerator()) {
318 $userSpaces = Space::orderBy('serial', 'ASC')->get();
319 $spaceGroups = SpaceGroup::orderBy('serial', 'ASC')
320 ->select(['id', 'title', 'slug', 'settings'])
321 ->get();
322 } else {
323 $userSpaces = Space::orderBy('serial', 'ASC')
324 ->whereHas('members', function ($q) {
325 $q->where('user_id', get_current_user_id())
326 ->where('status', 'active');
327 })
328 ->get();
329
330 $userSpaceParentIds = $userSpaces->pluck('parent_id')->filter()->unique()->toArray();
331
332 $spaceGroups = SpaceGroup::orderBy('serial', 'ASC')
333 ->select(['id', 'title', 'slug', 'settings'])
334 ->whereIn('id', $userSpaceParentIds)
335 ->get();
336 }
337
338 $userSpaces->each(function ($space) use ($userModel) {
339 $userId = get_current_user_id();
340 $space->permissions = $space->getUserPermissions($userModel);
341 $space->membership = $space->getMembership($userId);
342 $space->description_rendered = FeedsHelper::mdToHtml($space->description);
343 if (!$space->membership) {
344 $space->lockscreen_config = LockscreenService::getLockscreenConfig($space, $space->membership);
345 }
346 $space->topics = Utility::getTopicsBySpaceId($space->id);
347 });
348
349 $userSpaces = $userSpaces->keyBy('slug');
350
351 $userModel->cacheAccessSpaces();
352
353 $spaceSlugs = $userSpaces->pluck('slug')->toArray();
354
355 $authData = [
356 'id' => $xprofile->user_id,
357 'user_id' => $xprofile->user_id,
358 'username' => $xprofile->username,
359 'display_name' => $xprofile->display_name,
360 'first_name' => $wpUser->first_name ? $wpUser->first_name : $xprofile->getFirstName(),
361 'avatar' => $xprofile->avatar,
362 'total_points' => $xprofile->total_points,
363 'last_activity' => $xprofile->last_activity,
364 'email' => $userModel->user_email,
365 'spaces' => $userSpaces,
366 'community_roles' => $userModel->getCommunityRoles(),
367 'is_verified' => $xprofile->is_verified,
368 'compilation_score' => $xprofile->getCompletionScore(),
369 'meta' => $xprofile->meta
370 ];
371 } else {
372 $authData = [
373 'id' => 0,
374 'user_id' => 0,
375 'spaces' => (object)[],
376 'community_roles' => [],
377 'compilation_score' => 100
378 ];
379 }
380
381 $settings = Helper::generalSettings();
382
383 $onboardSettings = Helper::getOnboardingSettings();
384
385 global $wp_version;
386
387 $isRtl = Helper::isRtl();
388
389 $portalVars = apply_filters('fluent_community/portal_vars', [
390 'portal_notices' => apply_filters('fluent_community/portal_notices', []),
391 'i18n' => TransStrings::getStrings(),
392 'auth' => $authData,
393 'ajaxurl' => admin_url('admin-ajax.php'),
394 'slug' => 'fluent-community',
395 'rest' => $this->getRestInfo(),
396 'user_id' => $userModel ? $userModel->ID : null,
397 'assets_url' => FLUENT_COMMUNITY_PLUGIN_URL . 'assets/',
398 'permissions' => $userModel ? $userModel->getPermissions() : ['read' => true],
399 'logo' => Arr::get($settings, 'logo'),
400 'site_title' => Arr::get($settings, 'site_title'),
401 'user_membership_slugs' => $spaceSlugs,
402 'block_editor_assets' => [
403 'scripts' => [
404 'react' => Vite::getStaticSrcUrl('libs/isolated-editor/react.production.min.js'),
405 'react-dom' => Vite::getStaticSrcUrl(
406 'libs/isolated-editor/react-dom.production.min.js'
407 ),
408 'isolated-block-editor' => Vite::getStaticSrcUrl('libs/isolated-editor/isolated-block-editor.js')
409 ],
410 'styles' => [
411 $isRtl ? Vite::getStaticSrcUrl('libs/isolated-editor/core.rtl.css') : Vite::getStaticSrcUrl('libs/isolated-editor/core.css'),
412 $isRtl ? Vite::getStaticSrcUrl('libs/isolated-editor/isolated-block-editor.rtl.css') : Vite::getStaticSrcUrl('libs/isolated-editor/isolated-block-editor.css'),
413 includes_url('css/dist/block-editor/content.min.css?ver=' . $wp_version),
414 ]
415 ],
416 'features' => [
417 'disable_global_posts' => Arr::get($settings, 'disable_global_posts', '') == 'yes',
418 'has_survey_poll' => true,
419 'is_onboarding_enabled' => Arr::get($onboardSettings, 'is_onboarding_enabled', 'no') == 'yes',
420 'can_switch_layout' => true,
421 'max_media_per_post' => apply_filters('fluent_community/max_media_per_post', 4),
422 'max_topic_per_post' => apply_filters('fluent_community/max_topic_per_post', 5),
423 'has_post_title' => Utility::postTitlePref(),
424 'has_course' => Helper::isFeatureEnabled('course_module'),
425 'skicky_sidebar' => Utility::isCustomizationEnabled('fixed_sidebar'),
426 'post_layout' => Utility::getCustomizationSetting('rich_post_layout'),
427 'video_embeder' => apply_filters('fluent_community/has_video_embeder', true),
428 'has_topics' => !!Utility::getTopics()
429 ],
430 'route_classes' => array_filter([
431 'fcom_sticky_header' => Utility::isCustomizationEnabled('fixed_page_header'),
432 'fcom_sticky_sidebar' => Utility::isCustomizationEnabled('fixed_sidebar'),
433 'fcom_has_icon_on_header_menu' => Utility::isCustomizationEnabled('icon_on_header_menu')
434 ]),
435 'urls' => [
436 'site_url' => site_url(),
437 'portal_base' => Helper::baseUrl('/'),
438 'global_search' => Helper::baseUrl(),
439 ],
440 'last_feed_id' => FeedsHelper::getLastFeedId(),
441 'unread_notification_count' => $userModel ? $userModel->getUnreadNotificationCount() : 0,
442 'unread_feed_ids' => $userModel ? $userModel->getUnreadNotificationFeedIds() : [],
443 'date_offset' => time() - current_time('timestamp'),
444 'portal_slug' => Helper::getPortalSlug(true),
445 'mobileMenuItems' => apply_filters('fluent_community/mobile_menu', [
446 [
447 'route' => [
448 'name' => 'all_feeds'
449 ],
450 'icon' => 'HomeFilled'
451 ],
452 [
453 'route' => [
454 'name' => 'spaces'
455 ],
456 'icon_svg' => '<svg version="1.1" viewBox="0 0 128 128"><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>'
457 ]
458 ]),
459 'socialLinkProviders' => ProfileHelper::socialLinkProviders(),
460 'space_groups' => $spaceGroups,
461 'feed_links' => Helper::getEnabledFeedLinks(),
462 'routing_system' => Helper::getPortalRouteType(),
463 'portal_url' => Helper::baseUrl('/'),
464 'upgrade_url' => 'https://fluentcommunity.co/?utm_source=wp&utm_medium=upgrade&utm_campaign=upgrade',
465 'dateTime18n' => apply_filters('fluent_community/date_time_i18n', [
466 /* translators: weekday. Please keep the serial and format */
467 'weekdays' => __('Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday', 'fluent-community'),
468 /* translators: Months Please keep the serial and format*/
469 'months' => __('January_February_March_April_May_June_July_August_September_October_November_December', 'fluent-community'),
470 /* translators: weekday short Please keep the serial and format*/
471 'weekdaysShort' => __('Sun_Mon_Tue_Wed_Thu_Fri_Sat', 'fluent-community'),
472 /* translators: Months short Please keep the serial and format*/
473 'monthsShort' => __('Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec', 'fluent-community'),
474 /* translators: weekday min Please keep the serial and format*/
475 'weekdaysMin' => __('Su_Mo_Tu_We_Th_Fr_Sa', 'fluent-community'),
476 'relativeTime' => [
477 /* translators: Relative Date Formats. Please do not alter %s*/
478 'future' => __('in %s', 'fluent-community'),
479 /* translators: Relative Date Formats. Please do not alter %s*/
480 'past' => __('%s ago', 'fluent-community'),
481 /* translators: Relative Date Formats.*/
482 's' => __('a few seconds', 'fluent-community'),
483 /* translators: Relative Date Formats.*/
484 'm' => __('a minute', 'fluent-community'),
485 /* translators: Relative Date Formats. Don't alter %d*/
486 'mm' => __('%d minutes', 'fluent-community'),
487 /* translators: Relative Date Formats*/
488 'h' => __('an hour', 'fluent-community'),
489 /* translators: Relative Date Formats. Don't alter %d*/
490 'hh' => __('%d hours', 'fluent-community'),
491 /* translators: Relative Date Formats*/
492 'd' => __('a day', 'fluent-community'),
493 /* translators: Relative Date Formats. Don't alter %d*/
494 'dd' => __('%d days', 'fluent-community'),
495 /* translators: Relative Date Formats*/
496 'M' => __('a month', 'fluent-community'),
497 /* translators: Relative Date Formats. Don't alter %d*/
498 'MM' => __('%d months', 'fluent-community'),
499 /* translators: Relative Date Formats*/
500 'y' => __('a year', 'fluent-community'),
501 /* translators: Relative Date Formats. Don't alter %d*/
502 'yy' => __('%d years', 'fluent-community')
503 ]
504 ])
505 ]);
506
507 if ($xprofile) {
508 $portalVars['mobileMenuItems'][] = [
509 'route' => [
510 'name' => 'user_profile',
511 'params' => [
512 'username' => $xprofile->username
513 ]
514 ],
515 'icon' => 'Avatar'
516 ];
517 }
518
519 $portalVars['welcome_banner'] = Helper::getWelcomeBanner($userModel ? 'login' : 'logout');
520
521 if (!$xprofile) {
522 $portalVars['auth_url'] = $this->getAuthUrl();
523 }
524
525 return $portalVars;
526 }
527
528 protected function getRestInfo()
529 {
530 $app = fluentCommunityApp();
531 $ns = $app->config->get('app.rest_namespace');
532 $v = $app->config->get('app.rest_version');
533
534 return [
535 'base_url' => esc_url_raw(rest_url()),
536 'url' => rest_url($ns . '/' . $v),
537 'nonce' => wp_create_nonce('wp_rest'),
538 'namespace' => $ns,
539 'version' => $v,
540 ];
541 }
542
543 protected function renderFullApp()
544 {
545 if (isset($_REQUEST['fcom_action'])) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
546 $action = sanitize_text_field(wp_unslash($_REQUEST['fcom_action'])); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
547 do_action('fluent_community/portal_action_' . $action, $_GET); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
548 }
549
550 $userId = get_current_user_id();
551
552 if (!$userId) {
553 if (!Helper::isPublicAccessible()) {
554 $url = home_url(add_query_arg($_REQUEST, $GLOBALS['wp']->request)); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
555 $settings = Helper::generalSettings();
556 $authUrl = Arr::get($settings, 'auth_url', '');
557 if ($authUrl) {
558 $authUrl = add_query_arg([
559 'redirect_to' => $url
560 ], $authUrl);
561 } else {
562 $authUrl = $this->getAuthUrl();
563 }
564
565 do_action('fluent_community/portal/not_logged_in', $authUrl);
566 wp_redirect($authUrl);
567 exit();
568 }
569 }
570
571 do_action('fluent_community/portal/viewed');
572 $xprofile = Helper::getCurrentProfile();
573
574 if ($xprofile && $xprofile->status != 'active') {
575 if ($xprofile->status == 'pending') {
576 $this->viewErrorPage('You request is on pending', 'An admin need to approve your join request. Please contact with an admin to get approval');
577 } else {
578 $this->viewErrorPage('Access denied', 'Sorry, You can not access to this portal');
579 }
580 }
581
582 if ($xprofile) {
583 if (!Helper::canAccessPortal()) {
584 $generalSettings = Helper::generalSettings();
585 $this->viewErrorPage('Access Denied', Arr::get($generalSettings, 'restricted_role_content'));
586 }
587 if ($xprofile->user) {
588 $xprofile->user->cacheAccessSpaces();
589 }
590
591 /*
592 * Just in case if username is not sanitized
593 */
594 if ($xprofile->username != CustomSanitizer::sanitizeUserName($xprofile->username)) {
595 $xprofile->username = ProfileHelper::generateUserName($xprofile->user_id);
596 $xprofile->save();
597 }
598
599 do_action('fluent_community/portal_render_for_user', $xprofile);
600 do_action('fluent_communit/track_activity');
601 }
602
603 $data = $this->getAppData();
604 $data = $this->maybePushDynamicMetaData($data);
605
606 $data['isHeadless'] = Helper::isHeadless();
607 $data['a11y_enhancement_style'] = Utility::getCustomizationSetting('a11y_enhancement_style') === 'yes';
608
609 if (!$data['isHeadless']) {
610 $this->loadClassicPortalAssets($data);
611 } else {
612 do_action('fluent_community/rendering_headless_portal', $data);
613 }
614
615 status_header(200);
616 App::make('view')->render('portal_page', $data);
617 exit(200);
618 }
619
620 public function loadClassicPortalAssets($data)
621 {
622 $cssFiles = $data['css_files'];
623
624 unset($cssFiles['fcom_theme_default']);
625
626 foreach ($cssFiles as $fileName => $cssFile) {
627 wp_enqueue_style($fileName, $cssFile['url'], [], FLUENT_COMMUNITY_PLUGIN_VERSION, 'screen');
628 }
629
630 $jsFiles = $data['js_files'];
631 $jsTags = array_keys($jsFiles);
632 add_filter('script_loader_tag', function ($tag, $handle) use ($jsTags) {
633 if (!in_array($handle, $jsTags)) {
634 return $tag;
635 }
636 $tag = str_replace(' src', ' type="module" src', $tag);
637 return $tag;
638 }, 10, 2);
639 foreach ($jsFiles as $fileName => $jsFile) {
640 wp_enqueue_script($fileName, $jsFile['url'], $jsFile['deps'], FLUENT_COMMUNITY_PLUGIN_VERSION, [
641 'in_footer' => true,
642 'strategy' => 'defer',
643 'type' => 'module'
644 ]);
645 }
646
647 foreach ($data['js_vars'] as $varKey => $values) {
648 wp_localize_script('fcom_strat', $varKey, $values);
649 }
650 }
651
652 public function getAppData()
653 {
654
655 $isRtl = Helper::isRtl();
656
657 $userId = get_current_user_id();
658 $url = home_url(add_query_arg($_REQUEST, $GLOBALS['wp']->request)); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
659
660 $appVars = $this->appVars();
661 $generalSettings = Helper::generalSettings();
662 return apply_filters('fluent_community/portal_data_vars', [
663 'title' => Arr::get($generalSettings, 'site_title'),
664 'description' => get_bloginfo('description'),
665 'featured_image' => Arr::get($generalSettings, 'featured_image', ''),
666 'js_files' => [
667 'fcom_strat' => [
668 'url' => Vite::getStaticSrcUrl('start.js'),
669 'deps' => []
670 ],
671 'fcom_app' => [
672 'url' => Vite::getStaticSrcUrl('app.js'),
673 'deps' => []
674 ],
675 'fcom_general' => [
676 'url' => Vite::getStaticSrcUrl('portal_general.js'),
677 'deps' => []
678 ]
679 ],
680 'js_vars' => [
681 'fluentComAdmin' => $appVars,
682 ],
683 'css_files' => array_filter([
684 'fcom_theme_default' => [
685 'url' => Vite::getDynamicSrcUrl('theme-default.scss', $isRtl)
686 ],
687 'fcom_global' => [
688 'url' => Vite::getDynamicSrcUrl('global.scss', $isRtl)
689 ],
690 'fcom_app' => [
691 'url' => Vite::getDynamicSrcUrl('app_css.scss', $isRtl)
692 ],
693 'fcom_vendor' => [
694 'url' => Vite::getDynamicProductionSrcUrl('app.css', $isRtl) // vite automatically build src/app.css for all components also styles inside components
695 ]
696 ]),
697 'url' => $url,
698 'current_route' => $this->currentPath,
699 'contact' => $appVars['auth'],
700 'user' => $userId ? get_user_by('ID', $userId) : null,
701 'route_group' => Helper::getRouteNameByRequestPath($this->currentPath)
702 ]);
703 }
704
705 protected function maybePushDynamicMetaData($data)
706 {
707 $dynamicRoute = Arr::get($data, 'route_group');
708 $validGroups = [
709 'user_profile',
710 'community_view',
711 'course_view',
712 'feed_view'
713 ];
714
715 if (!in_array($dynamicRoute, $validGroups)) {
716 return $data;
717 }
718
719 if ($dynamicRoute == 'user_profile') {
720 $uriParts = explode('/', $this->currentPath);
721 if (count($uriParts) >= 2) {
722 $userName = $uriParts[1];
723 $xProfile = XProfile::where('username', $userName)->first();
724 if ($xProfile) {
725 $data['title'] = esc_html($xProfile->display_name) . ' - ' . $data['title'];
726 if ($xProfile->short_description) {
727 $data['description'] = Helper::getHumanExcerpt($xProfile->short_description, 100);
728 }
729 if ($coverPhoto = Arr::get($xProfile->meta, 'cover_photo')) {
730 $data['featured_image'] = $coverPhoto;
731 }
732 }
733 }
734 return $data;
735 }
736
737 if ($dynamicRoute == 'community_view' || $dynamicRoute == 'course_view') {
738 $uriParts = explode('/', $this->currentPath);
739 if (count($uriParts) >= 2) {
740 $paceSlug = $uriParts[1];
741
742 $space = BaseSpace::query()->withoutGlobalScopes()->where('slug', $paceSlug)->first();
743
744 if ($space && $space->privacy != 'secret') {
745
746 if ($dynamicRoute == 'course_view') {
747 $data['title'] = sprintf(__('Enroll %s', 'fluent-community'), esc_html($space->title) . ' - ' . $data['title']);
748 } else {
749 $data['title'] = sprintf(__('Join %s', 'fluent-community'), esc_html($space->title) . ' - ' . $data['title']);
750 }
751
752 if ($space->description) {
753 $data['description'] = Helper::getHumanExcerpt($space->description, 100);
754 }
755 if ($ogImage = Arr::get($space->settings, 'og_image')) {
756 $data['featured_image'] = $ogImage;
757 } else if ($space->cover_photo) {
758 $data['featured_image'] = $space->cover_photo;
759 }
760 }
761 }
762 return $data;
763 }
764
765 if ($dynamicRoute == 'feed_view') {
766 $uriParts = explode('/', $this->currentPath);
767
768 if (count($uriParts) >= 2) {
769 $postSlug = end($uriParts);
770 $feed = Feed::where('slug', $postSlug)
771 ->with([
772 'xprofile' => function ($q) {
773 $q->select(ProfileHelper::getXProfilePublicFields());
774 },
775 'space'
776 ])
777 ->byUserAccess(get_current_user_id())
778 ->first();
779
780 if (!$feed) {
781 return $data;
782 }
783
784 if ($feed->title) {
785 $data['title'] = esc_html($feed->title) . ' - ' . $data['title'];
786 } else {
787 $data['title'] = esc_html($feed->xprofile->display_name) . ' posted at ' . $data['title'];
788 }
789
790 if ($feed->message) {
791 $data['description'] = esc_html(Helper::getHumanExcerpt($feed->message, 100));
792 }
793
794 if ($mediaPreview = Arr::get($feed->meta, 'media_preview.image')) {
795 $data['featured_image'] = esc_url($mediaPreview);
796 } else if ($feed->space) {
797 $space = $feed->space;
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
806 return $data;
807 }
808
809 return $data;
810 }
811
812 protected function getMainMenuItems($scope = 'sidebar')
813 {
814 $menuGroups = Helper::getMenuItemsGroup('view');
815
816 $items = Arr::get($menuGroups, 'mainMenuItems', []);
817
818 return apply_filters('fluent_community/main_menu_items', $items, $scope);
819 }
820
821 public function getPortalHeader($echo = false, $context = 'headless')
822 {
823 $settings = Helper::generalSettings();
824 $userId = get_current_user_id();
825
826 if ($userId) {
827 $xprofile = XProfile::where('user_id', get_current_user_id())
828 ->first();
829 } else {
830 $xprofile = null;
831 }
832
833
834 $authUrl = $this->getAuthUrl();
835
836 if ($xprofile) {
837 $xprofile->logout_url = wp_logout_url(Helper::baseUrl());
838 }
839
840 $logo = Arr::get($settings, 'logo', '');
841 $whiteLogo = Arr::get($settings, 'white_logo', '');
842 if (!$whiteLogo) {
843 $whiteLogo = $logo;
844 }
845
846 $data = apply_filters('fluent_community/header_vars', [
847 'portal_url' => Helper::baseUrl('/'),
848 'logo' => $logo,
849 'white_logo' => $whiteLogo,
850 'site_title' => Arr::get($settings, 'site_title'),
851 'profile_url' => $userId ? Helper::baseUrl('u/' . $xprofile->username . '/') : '',
852 'auth' => $xprofile ? $xprofile : null,
853 'auth_url' => $authUrl,
854 'menuItems' => $this->getMainMenuItems('header')
855 ]);
856
857 if ($echo) {
858 App::make('view')->render('portal.header', $data);
859 return;
860 }
861
862 return (string)App::make('view')->make('portal.header', $data);
863 }
864
865 private function getProfileLinks($xprofile = null)
866 {
867 if (!$xprofile) {
868 $xprofile = Helper::getCurrentProfile();
869 }
870
871 $profileLinks = [];
872 $menuGroups = Helper::getMenuItemsGroup('view');
873 if ($xprofile) {
874 $profileLinks = Arr::get($menuGroups, 'profileDropdownItems', []);
875
876 $replaces = [
877 '#{{user_url}}' => Helper::baseUrl('u/' . $xprofile->username),
878 '#user_url' => Helper::baseUrl('u/' . $xprofile->username),
879 '#{{logout_url}}' => wp_logout_url(Helper::baseUrl()),
880 '#logout_url' => wp_logout_url(Helper::baseUrl())
881 ];
882
883 foreach ($profileLinks as &$link) {
884 $slug = Arr::get($link, 'slug', '');
885
886 if ($slug == 'my_spaces') {
887 $link['permalink'] = Helper::baseUrl('u/' . $xprofile->username . '/spaces');
888 } else if ($slug == 'logout') {
889 $link['permalink'] = wp_logout_url(Helper::baseUrl());
890 } else if ($slug == 'profile') {
891 $link['permalink'] = Helper::baseUrl('u/' . $xprofile->username);
892 }
893
894 $link['permalink'] = str_replace(array_keys($replaces), array_values($replaces), $link['permalink']);
895 }
896 }
897
898 return $profileLinks;
899 }
900
901 public function getPortalSidebar($echo = false, $context = 'headless')
902 {
903 $primaryMenuItems = $this->getMainMenuItems('sidebar');
904
905 $userModel = Helper::getCurrentUser();
906 $spaceGroups = Helper::getCommunityMenuGroups($userModel);
907
908 $settingsMenu = apply_filters('fluent_community/settings_menu', [], $userModel);
909
910 $menuGroups = Helper::getMenuItemsGroup('view');
911 $topInlines = Arr::get($menuGroups, 'beforeCommunityMenuItems', []);
912 $bottomLinkGroups = Arr::get($menuGroups, 'afterCommunityLinkGroups', []);
913
914 $data = [
915 'primaryItems' => $primaryMenuItems,
916 'spaceGroups' => $spaceGroups,
917 'settingsItems' => $settingsMenu,
918 'topInlineLinks' => $topInlines,
919 'bottomLinkGroups' => $bottomLinkGroups,
920 'is_admin' => Helper::isSiteAdmin(),
921 'has_color_scheme' => Helper::hasColorScheme(),
922 'context' => $context
923 ];
924
925 if ($echo) {
926 App::make('view')->render('portal.main_sidebar', $data);
927 return;
928 }
929
930 return (string)App::make('view')->make('portal.main_sidebar', $data);
931 }
932
933 protected function getAuthUrl()
934 {
935 return apply_filters('fluent_community/auth/login_url', Helper::baseUrl('?fcom_action=auth&form=login'));
936 }
937
938 protected function viewErrorPage($title, $message = '', $showBtn = true)
939 {
940 $data = [
941 'title' => $title,
942 'description' => $message,
943 'btn_txt' => 'Go to home page',
944 'url' => site_url()
945 ];
946
947 if (!$showBtn) {
948 $data['btn_txt'] = '';
949 }
950
951 status_header(200);
952 App::make('view')->render('error_page', $data);
953 exit();
954 }
955
956 public function showAdminPage()
957 {
958
959 $jsTags = ['fluent_community_onboarding'];
960
961 add_filter('script_loader_tag', function ($tag, $handle) use ($jsTags) {
962 if (!in_array($handle, $jsTags)) {
963 return $tag;
964 }
965 $tag = str_replace(' src', ' type="module" src', $tag);
966 return $tag;
967 }, 10, 2);
968
969 wp_enqueue_script('fluent_community_onboarding', Vite::getDynamicSrcUrl('Onboarding/onboarding.js'), ['jquery'], FLUENT_COMMUNITY_PLUGIN_VERSION, [
970 'in_footer' => true,
971 'strategy' => 'defer',
972 'type' => 'module'
973 ]);
974
975 wp_enqueue_style('fluent_community_onboarding', Vite::getDynamicSrcUrl('Onboarding/onboarding.scss'), [], FLUENT_COMMUNITY_PLUGIN_VERSION, 'screen');
976 wp_localize_script('fluent_community_onboarding', 'fluentComAdmin', [
977 'ajaxurl' => admin_url('admin-ajax.php'),
978 'rest' => $this->getRestInfo(),
979 'urls' => [
980 'site_url' => site_url('/'),
981 'portal_base' => Helper::baseUrl('/'),
982 'permalink_url' => admin_url('options-permalink.php')
983 ],
984 'logo' => Helper::assetUrl('images/logo.png'),
985 'is_onboarded' => !!Utility::getOption('onboarding_sub_settings'),
986 'permalink_structure' => get_option('permalink_structure'),
987 'is_slug_defined' => defined('FLUENT_COMMUNITY_PORTAL_SLUG'),
988 'has_pro' => defined('FLUENT_COMMUNITY_PRO_VERSION'),
989 'upgrade_url' => Utility::getProductUrl(false),
990 'settings_page_url' => admin_url('admin.php?page=fluent-community'),
991 'is_license_page' => isset($_GET['license']) && $_GET['license'] === 'yes',
992 'license_url_page' => defined('FLUENT_COMMUNITY_PRO_VERSION') ? admin_url('admin.php?page=fluent-community&license=yes') : '',
993 ]);
994
995 echo '<div class="wrap"><div id="fcom_onboarding_app"></div></div>';
996 }
997
998 private function getMenuIcon()
999 {
1000 return 'data:image/svg+xml;base64,' . base64_encode('<svg width="82" height="71" viewBox="0 0 82 71" fill="none" xmlns="http://www.w3.org/2000/svg">
1001 <path d="M25.9424 49.1832L39.6888 41.2467L47.6253 54.9931C40.0334 59.3763 30.3256 56.7751 25.9424 49.1832Z" fill="white"/>
1002 <path fill-rule="evenodd" clip-rule="evenodd" d="M53.4348 33.3101L39.6884 41.2466L47.6249 54.993L61.3713 47.0565L53.4348 33.3101ZM67.1821 25.3734L53.4356 33.3099L61.3721 47.0564L75.1186 39.1199L67.1821 25.3734Z" fill="white"/>
1003 <path d="M67.182 25.3736C70.978 23.182 75.8319 24.4826 78.0235 28.2786L81.9917 35.1518L75.1185 39.12L67.182 25.3736Z" fill="white"/>
1004 <path d="M42.593 30.4052L28.8466 38.3417L20.9101 24.5953L34.6565 16.6588L42.593 30.4052Z" fill="white"/>
1005 <path d="M56.3397 22.4683L42.5933 30.4048L34.6568 16.6584C42.2487 12.2752 51.9565 14.8764 56.3397 22.4683Z" fill="white"/>
1006 <path d="M28.847 38.3418L15.1006 46.2783L7.16409 32.5318L20.9105 24.5953L28.847 38.3418Z" fill="white"/>
1007 <path d="M15.1011 46.2783C11.3051 48.4699 6.4512 47.1693 4.25959 43.3733L0.291343 36.5001L7.16456 32.5319L15.1011 46.2783Z" fill="white"/>
1008 </svg>');
1009
1010 }
1011
1012 }
1013