PluginProbe
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses / 2.10.01
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses v2.10.01
2.10.0 2.10.01 2.9.1 2.9.0 2.8.1 2.8.0 2.7.7 2.7.5 2.7.0 2.6.01 2.6.0 2.5.0 2.4.01 trunk 1.0.90 1.0.91 1.0.92 1.0.93 1.0.94 1.0.95 1.0.96 1.0.97 1.0.98 1.0.99 1.1.0 All 77 releases
← All changes | app/Http/Controllers/AdminController.php +192 -48 1.1.02.10.01 View file →
@@ -2,12 +2,15 @@
2 2
3 3 namespace FluentCommunity\App\Http\Controllers;
4 4
5 5 use FluentCommunity\App\Functions\Utility;
6 +use FluentCommunity\App\Models\BaseSpace;
6 7 use FluentCommunity\App\Services\AuthenticationService;
7 8 use FluentCommunity\App\Services\CustomSanitizer;
8 9 use FluentCommunity\App\Services\FeedsHelper;
10 +use FluentCommunity\App\Services\ProfileHelper;
9 11 use FluentCommunity\Modules\Auth\AuthHelper;
12 +use FluentCommunity\Modules\PushNotification\PushNotificationModule;
10 13 use FluentCommunity\App\Services\Helper;
11 14 use FluentCommunity\App\Services\OnboardingService;
12 15 use FluentCommunity\Framework\Http\Request\Request;
13 16 use FluentCommunity\Framework\Support\Arr;
@@ -26,14 +29,15 @@
26 29 }
27 30
28 31 unset($formatedRoles['administrator']);
29 32
30 - return [
31 - 'settings' => $settings,
32 - 'user_roles' => $formatedRoles,
33 - 'users_can_register' => !!get_option('users_can_register'),
33 + $data = [
34 + 'settings' => $settings,
35 + 'user_roles' => $formatedRoles,
36 + 'users_can_register' => !!get_option('users_can_register'),
34 37 'user_registration_enable_url' => admin_url('options-general.php')
35 38 ];
39 + return apply_filters('fluent_community/general_settings_api_response', $data, $request->all());
36 40 }
37 41
38 42 public function saveGeneralSettings(Request $request)
39 43 {
@@ -38,8 +42,9 @@
38 42 public function saveGeneralSettings(Request $request)
39 43 {
40 44 $inputs = $request->get('settings', []);
41 45 $settings = Helper::generalSettings(false);
46 + $storedSettings = $settings;
42 47 $inputs = Arr::only($inputs, array_keys($settings));
43 48
44 49 $settings['logo'] = Arr::get($inputs, 'logo', '');
45 50 $settings['white_logo'] = Arr::get($inputs, 'white_logo', '');
@@ -65,8 +70,10 @@
65 70 $settings['access'] = Arr::get($inputs, 'access', []);
66 71 $settings['auth_content'] = wp_kses_post(Arr::get($inputs, 'auth_content', ''));
67 72 $settings['auth_redirect'] = sanitize_url(Arr::get($inputs, 'auth_redirect', ''));
68 73 $settings['restricted_role_content'] = wp_kses_post(Arr::get($inputs, 'restricted_role_content', ''));
74 + $settings['logo_permalink'] = sanitize_url(Arr::get($inputs, 'logo_permalink', ''));
75 + $settings['logo_permalink_type'] = sanitize_text_field(Arr::get($inputs, 'logo_permalink_type', 'default'));
69 76 $settings['auth_url'] = sanitize_url(Arr::get($inputs, 'auth_url', ''));
70 77 $media = Helper::getMediaFromUrl($settings['logo']);
71 78 $whiteMedia = Helper::getMediaFromUrl($settings['white_logo']);
72 79 $featuredMedia = Helper::getMediaFromUrl($settings['featured_image']);
@@ -71,9 +78,27 @@
71 78 $whiteMedia = Helper::getMediaFromUrl($settings['white_logo']);
72 79 $featuredMedia = Helper::getMediaFromUrl($settings['featured_image']);
73 80 $settings['cutsom_auth_url'] = sanitize_url(Arr::get($inputs, 'cutsom_auth_url', ''));
74 81 $settings['auth_form_type'] = sanitize_text_field(Arr::get($inputs, 'auth_form_type', ''));
82 + $settings['explicit_registration'] = sanitize_text_field(Arr::get($inputs, 'explicit_registration', 'no'));
75 83
84 + $isCustomSignupPage = $settings['auth_form_type'] === 'default' && Arr::get($inputs, 'use_custom_signup_page', 'no') == 'yes';
85 + if (!$isCustomSignupPage) {
86 + $settings['custom_signup_url'] = '';
87 + $settings['use_custom_signup_page'] = 'no';
88 + } else {
89 + $settings['use_custom_signup_page'] = 'yes';
90 +
91 + $url = Arr::get($inputs, 'custom_signup_url', '');
92 +
93 + if (!$url || !filter_var($url, FILTER_VALIDATE_URL)) {
94 + return $this->sendError([
95 + 'message' => __('Please provide a valid signup URL', 'fluent-community')
96 + ]);
97 + }
98 + $settings['custom_signup_url'] = $url;
99 + }
100 +
76 101 if ($media) {
77 102 $settings['logo'] = $media->public_url;
78 103 $media->update([
79 104 'is_active' => true,
@@ -100,13 +125,24 @@
100 125 ]);
101 126 }
102 127
103 128 $slugChanged = false;
104 - if ($settings['slug'] != $inputs['slug'] && !defined('FLUENT_COMMUNITY_PORTAL_SLUG')) {
105 - $settings['slug'] = $inputs['slug'];
129 + $newSlug = sanitize_title($inputs['slug'] ?? '');
130 + if ($newSlug && $settings['slug'] != $newSlug && !defined('FLUENT_COMMUNITY_PORTAL_SLUG')) {
131 + $settings['slug'] = $newSlug;
106 132 $slugChanged = true;
107 133 }
108 134
135 + if (!Helper::isSuperAdmin()) {
136 + foreach (['auth_url', 'cutsom_auth_url', 'auth_form_type', 'auth_redirect', 'custom_signup_url', 'use_custom_signup_page', 'explicit_registration'] as $restrictedKey) {
137 + if ($settings[$restrictedKey] != Arr::get($storedSettings, $restrictedKey, '')) {
138 + return $this->sendError([
139 + 'message' => __('You do not have permission to change the authentication and login settings', 'fluent-community')
140 + ]);
141 + }
142 + }
143 + }
144 +
109 145 update_option('fluent_community_settings', $settings);
110 146
111 147 $redirectUrl = '';
112 148
@@ -124,11 +160,18 @@
124 160 }
125 161
126 162 public function getEmailSettings(Request $request)
127 163 {
128 - return [
129 - 'email_settings' => Utility::getEmailNotificationSettings()
164 + $emailSettings = Utility::getEmailNotificationSettings();
165 + $globalSettings = Helper::generalSettings(false);
166 + if (empty($emailSettings['logo'])) {
167 + $emailSettings['global_logo'] = $globalSettings['logo'];
168 + }
169 +
170 + $data = [
171 + 'email_settings' => $emailSettings
130 172 ];
173 + return apply_filters('fluent_community/email_settings_api_response', $data, $request->all());
131 174 }
132 175
133 176 public function saveEmailSettings(Request $request)
134 177 {
@@ -134,8 +177,22 @@
134 177 {
135 178 $prevSettings = Utility::getEmailNotificationSettings();
136 179 $newSettings = $request->get('email_settings', []);
137 180
181 + $logo = Arr::get($newSettings, 'logo', '');
182 +
183 + if ($logo) {
184 + $logoMedia = Helper::getMediaFromUrl($logo);
185 + if ($logoMedia) {
186 + $newSettings['logo'] = $logoMedia->public_url;
187 + $logoMedia->update([
188 + 'is_active' => true,
189 + 'user_id' => get_current_user_id(),
190 + 'object_source' => 'general'
191 + ]);
192 + }
193 + }
194 +
138 195 $newSettings = wp_parse_args($newSettings, $prevSettings);
139 196 $newSettings = CustomSanitizer::santizeEmailSettings($newSettings);
140 197
141 198 Utility::updateOption('global_email_settings', $newSettings);
@@ -155,8 +212,52 @@
155 212 'message' => __('Email notification settings have been updated', 'fluent-community')
156 213 ];
157 214 }
158 215
216 + public function getPushSettings(Request $request)
217 + {
218 + $data = [
219 + 'push_settings' => Utility::getPushNotificationSettings(),
220 + 'push_available' => PushNotificationModule::isFluentNotifyActive(),
221 + 'push_setup' => [
222 + 'state' => PushNotificationModule::getSetupState(),
223 + 'settings_url' => PushNotificationModule::getSettingsUrl(),
224 + 'can_install' => current_user_can('install_plugins'),
225 + 'can_activate' => current_user_can('activate_plugins'),
226 + 'has_installer' => (bool)has_action('fluent_community/install_fluent_notify_plugin'),
227 + 'learn_more_url' => 'https://fluentnotify.com'
228 + ]
229 + ];
230 +
231 + return apply_filters('fluent_community/push_settings_api_response', $data, $request->all());
232 + }
233 +
234 + public function savePushSettings(Request $request)
235 + {
236 + $prevSettings = Utility::getPushNotificationSettings();
237 +
238 + $settings = Arr::only((array)$request->get('settings', []), array_keys($prevSettings));
239 + $settings = wp_parse_args($settings, $prevSettings);
240 +
241 + foreach ($settings as $key => $value) {
242 + if ($key === 'prompt_placements') {
243 + $settings[$key] = array_values(array_intersect(
244 + array_map('sanitize_text_field', (array)$value),
245 + PushNotificationModule::PROMPT_PLACEMENTS
246 + ));
247 + } else {
248 + $settings[$key] = $value === 'yes' ? 'yes' : 'no';
249 + }
250 + }
251 +
252 + Utility::updateOption('global_push_settings', $settings);
253 +
254 + return [
255 + 'push_settings' => $settings,
256 + 'message' => __('Push notification settings have been updated', 'fluent-community')
257 + ];
258 + }
259 +
159 260 public function getStorageSettings(Request $request)
160 261 {
161 262 if (!defined('FLUENT_COMMUNITY_PRO')) {
162 263 $config = [
@@ -167,9 +268,9 @@
167 268 }
168 269
169 270 return apply_filters('fluent_community/storage_settings_response', [
170 271 'config' => $config
171 - ]);
272 + ], $request->all());
172 273 }
173 274
174 275 public function updateStorageSettings(Request $request)
175 276 {
@@ -174,19 +275,19 @@
174 275 public function updateStorageSettings(Request $request)
175 276 {
176 277 if (!defined('FLUENT_COMMUNITY_PRO')) {
177 278 return $this->sendError([
178 - 'message' => 'Sorry, you can not update this config. Please activate pro'
279 + 'message' => __('Sorry, you cannot update this config. Please activate pro', 'fluent-community')
179 280 ]);
180 281 }
181 282
182 283 if (defined('FLUENT_COMMUNITY_CLOUD_STORAGE') && FLUENT_COMMUNITY_CLOUD_STORAGE) {
183 284 return $this->sendError([
184 - 'message' => 'You can not update the storage settings as it is defined in the config file'
285 + 'message' => __('You cannot update the storage settings as it is defined in the config file', 'fluent-community')
185 286 ]);
186 287 }
187 288
188 - $config = $request->get('config', []);
289 + $config = (array)$request->get('config', []);
189 290
190 291 $driver = Arr::get($config, 'driver', 'local');
191 292
192 293 $validation = [
@@ -192,16 +293,17 @@
192 293 $validation = [
193 294 'driver' => 'required'
194 295 ];
195 296
297 + $isRemote = in_array($driver, ['amazon_s3', 'bunny_cdn', 'cloudflare_r2']);
298 +
196 299 if ($driver == 'cloudflare_r2') {
197 300 $validation = [
198 - 'driver' => 'required',
199 - 'access_key' => 'required',
200 - 'secret_key' => 'required',
201 - 'bucket' => 'required',
202 - 'public_url' => 'required|url',
203 - 'account_id' => 'required',
301 + 'driver' => 'required',
302 + 'access_key' => 'required',
303 + 'secret_key' => 'required',
304 + 'public_url' => 'required|url',
305 + 'endpoint_url' => 'required|url',
204 306 ];
205 307 } else if ($driver == 'amazon_s3') {
206 308 $validation = [
207 309 'driver' => 'required',
@@ -208,14 +310,21 @@
208 310 'access_key' => 'required',
209 311 'secret_key' => 'required',
210 312 'bucket' => 'required'
211 313 ];
314 + } else if ($driver == 'bunny_cdn') {
315 + $validation = [
316 + 'driver' => 'required',
317 + 'access_key' => 'required',
318 + 's3_endpoint' => 'required',
319 + 'bucket' => 'required',
320 + 'public_url' => 'required|url'
321 + ];
212 322 }
213 323
214 324 $this->validate($config, $validation);
215 325
216 - if ($driver === 'cloudflare_r2' || $driver === 'amazon_s3') {
217 -
326 + if ($isRemote) {
218 327 $previousConfig = \FluentCommunityPro\App\Modules\CloudStorage\StorageHelper::getConfig();
219 328 if ($config['access_key'] == 'FCOM_ENCRYPTED_DATA_KEY') {
220 329 $config['access_key'] = Arr::get($previousConfig, 'access_key');
221 330 }
@@ -227,16 +336,17 @@
227 336 $driver = (new \FluentCommunityPro\App\Modules\CloudStorage\CloudStorageModule)->getConnectionDriver($config);
228 337
229 338 if (!$driver) {
230 339 return $this->sendError([
231 - 'message' => 'Could not connect to the remote storage service. Please check your credentials'
340 + 'message' => __('Could not connect to the remote storage service. Please check your credentials', 'fluent-community')
232 341 ]);
233 342 }
234 343
235 344 $test = $driver->testConnection();
236 345 if (!$test || is_wp_error($test)) {
346 + $errorMessage = is_wp_error($test) ? $test->get_error_message() : 'Unknown Error';
237 347 return $this->sendError([
238 - 'message' => 'Could not connect to the remote storage service. Error: ' . is_wp_error($test) ? $test->get_error_message() : 'Unknow Error'
348 + 'message' => __('Could not connect to the remote storage service. Error: ', 'fluent-community') . $errorMessage
239 349 ]);
240 350 }
241 351 }
242 352
@@ -245,8 +355,9 @@
245 355 'access_key',
246 356 'secret_key',
247 357 'bucket',
248 358 'public_url',
359 + 'endpoint_url',
249 360 'account_id',
250 361 'sub_folder',
251 362 's3_endpoint'
252 363 ]);
@@ -274,10 +385,12 @@
274 385 }
275 386
276 387 public function getWelcomeBannerSettings(Request $request)
277 388 {
389 + $settings = apply_filters('fluent_community/get_welcome_banner_settings', Helper::getWelcomeBannerSettings(), $request->all());
390 +
278 391 return [
279 - 'settings' => Helper::getWelcomeBannerSettings()
392 + 'settings' => $settings
280 393 ];
281 394 }
282 395
283 396 public function updateWelcomeBannerSettings(Request $request)
@@ -286,18 +399,20 @@
286 399
287 400 $settings = CustomSanitizer::sanitizeWelcomeBannerSettings($settings);
288 401
289 402 if (Arr::get($settings, 'login.enabled') == 'yes') {
290 - $settings['login']['description_rendered'] = FeedsHelper::mdToHtml(Arr::get($settings, 'login.description'));
403 + $settings['login']['description_rendered'] = wp_kses_post(FeedsHelper::mdToHtml(Arr::get($settings, 'login.description')));
291 404 }
292 405
293 406 if (Arr::get($settings, 'logout.enabled') == 'yes') {
294 - $settings['logout']['description_rendered'] = FeedsHelper::mdToHtml(Arr::get($settings, 'logout.description'));
407 + $settings['logout']['description_rendered'] = wp_kses_post(FeedsHelper::mdToHtml(Arr::get($settings, 'logout.description')));
295 408 if (Arr::get($settings, 'logout.buttonLabel') && Arr::get($settings, 'logout.useCustomUrl') != 'yes') {
296 409 $settings['logout']['buttonLink'] = Helper::getAuthUrl();
297 410 }
298 411 }
299 412
413 + $settings = apply_filters('fluent_community/update_welcome_banner_settings', $settings);
414 +
300 415 Utility::updateOption('welcome_banner_settings', $settings);
301 416
302 417 Utility::setCache('welcome_banner_settings', $settings, WEEK_IN_SECONDS);
303 418
@@ -313,29 +428,15 @@
313 428
314 429 $settings['login']['form']['fields'] = AuthHelper::getLoginFormFields();
315 430 $settings['signup']['form']['fields'] = AuthHelper::getFormFields();
316 431
432 + $settings = apply_filters('fluent_community/get_auth_settings', $settings);
433 +
317 434 return [
318 435 'settings' => $settings
319 436 ];
320 437 }
321 438
322 - public function saveAuthSettings(Request $request)
323 - {
324 - $settings = $request->get('settings', []);
325 -
326 - $formattedSettings = AuthenticationService::formatAuthSettings($settings);
327 -
328 - Utility::updateOption('auth_settings', $formattedSettings);
329 -
330 - Utility::setCache('auth_settings', $formattedSettings, WEEK_IN_SECONDS);
331 -
332 - return [
333 - 'message' => __('Auth settings have been updated successfully', 'fluent-community'),
334 - 'settings' => $formattedSettings
335 - ];
336 - }
337 -
338 439 public function getOnBoardingSettings()
339 440 {
340 441 $settings = Helper::generalSettings();
341 442
@@ -342,19 +443,27 @@
342 443 $currentUser = get_user_by('ID', get_current_user_id());
343 444
344 445 $settings['has_fluentcrm'] = defined('FLUENTCRM') ? 'yes' : 'no';
345 446 $settings['has_fluentsmtp'] = defined('FLUENTMAIL_PLUGIN_FILE') ? 'yes' : 'no';
447 + $settings['has_fluentcart'] = defined('FLUENTCART_VERSION') ? 'yes' : 'no';
346 448 $settings['template'] = '';
347 449 $settings['install_fluentcrm'] = 'yes';
348 450 $settings['install_fluentsmtp'] = 'yes';
451 + $settings['install_fluentcart'] = 'yes';
349 452 $settings['subscribe_to_newsletter'] = 'yes';
350 453 $settings['share_data'] = 'no';
351 - $settings['user_full_name'] = $currentUser->first_name ? $currentUser->first_name . ' ' . $currentUser->last_name : $currentUser->display_name;
352 - $settings['user_email_address'] = $currentUser->user_email;
454 + if ($currentUser) {
455 + $settings['user_full_name'] = $currentUser->first_name ? $currentUser->first_name . ' ' . $currentUser->last_name : $currentUser->display_name;
456 + $settings['user_email_address'] = $currentUser->user_email;
457 + } else {
458 + $settings['user_full_name'] = '';
459 + $settings['user_email_address'] = '';
460 + }
353 461
354 - return [
462 + $data = [
355 463 'settings' => $settings
356 464 ];
465 + return apply_filters('fluent_community/onboarding_settings_api_response', $data, $this->request->all());
357 466 }
358 467
359 468
360 469 public function saveOnBoardingSettings(Request $request)
@@ -382,9 +491,9 @@
382 491
383 492 if (Arr::get($inputs, 'slug') && empty($settings['is_slug_defined'])) {
384 493 $settings['slug'] = sanitize_title(Arr::get($inputs, 'slug'));
385 494 }
386 - update_option('fluent_community_settings', $settings, 'yes');
495 + update_option('fluent_community_settings', $settings, true);
387 496
388 497 // Email Subscription Settings
389 498 $subscriptionSettings = array_filter([
390 499 'user_id' => get_current_user_id(),
@@ -396,11 +505,12 @@
396 505
397 506 Utility::updateOption('onboarding_sub_settings', $subscriptionSettings);
398 507 OnboardingService::maybeCreateSpaceTemplates(Arr::get($inputs, 'template'));
399 508
400 - $installableAddons = array_filter(array_keys([
509 + $installableAddons = array_keys(array_filter([
401 510 'fluent-crm' => Arr::get($inputs, 'install_fluentcrm', 'no') == 'yes',
402 511 'fluent-smtp' => Arr::get($inputs, 'install_fluentsmtp', 'no') == 'yes',
512 + 'fluent-cart' => Arr::get($inputs, 'install_fluentcart', 'no') == 'yes',
403 513 ]));
404 514
405 515 // Install Plugins which are checked
406 516 OnboardingService::installAddons($installableAddons);
@@ -421,15 +531,15 @@
421 531 $newSlug = sanitize_title($request->get('new_slug', ''));
422 532
423 533 if (!$newSlug) {
424 534 return $this->sendError([
425 - 'message' => __('Slug can not be empty', 'fluent-community')
535 + 'message' => __('Slug cannot be empty', 'fluent-community')
426 536 ]);
427 537 }
428 538
429 539 if (defined('FLUENT_COMMUNITY_PORTAL_SLUG')) {
430 540 return $this->sendError([
431 - 'message' => __('You can not change the slug as it is defined in the config file', 'fluent-community')
541 + 'message' => __('You cannot change the slug as it is defined in the config file', 'fluent-community')
432 542 ]);
433 543 }
434 544
435 545 $settings = Helper::generalSettings();
@@ -451,7 +561,41 @@
451 561
452 562 return [
453 563 'message' => __('Slug has been changed successfully', 'fluent-community')
454 564 ];
565 + }
566 +
567 + public function getProfileLinkProviders(Request $request)
568 + {
569 + $data = [
570 + 'providers' => ProfileHelper::socialLinkProviders()
571 + ];
572 + return apply_filters('fluent_community/profile_link_providers_api_response', $data, $request->all());
573 + }
574 +
575 + public function updateProfileLinkProviders(Request $request)
576 + {
577 + $providerKeys = array_keys(ProfileHelper::socialLinkProviders());
578 + $config = $request->get('configs', []);
579 +
580 + $config = array_filter($config, function ($value) use ($providerKeys) {
581 + return in_array($value, $providerKeys);
582 + });
583 +
584 + do_action('fluent_community/update_profile_link_providers', $config);
585 +
586 + return [
587 + 'message' => __('Profile link providers have been updated successfully', 'fluent-community'),
588 + ];
589 + }
590 +
591 + public function getAllSpaceCourses(Request $request)
592 + {
593 + $data = [
594 + 'all_spaces' => BaseSpace::query()->withoutGlobalScopes()
595 + ->whereIn('type', ['community', 'course'])
596 + ->orderBy('serial', 'ASC')->get()
597 + ];
598 + return apply_filters('fluent_community/all_space_courses_api_response', $data, $request->all());
455 599 }
456 600
457 601 }