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/SettingController.php +90 -139 2.6.02.10.01 View file →
@@ -5,8 +5,9 @@
5 5 use FluentCommunity\App\Functions\Utility;
6 6 use FluentCommunity\App\Models\Space;
7 7 use FluentCommunity\App\Models\SpaceGroup;
8 8 use FluentCommunity\App\Services\Helper;
9 +use FluentCommunity\App\Services\OnboardingService;
9 10 use FluentCommunity\Framework\Http\Request\Request;
10 11 use FluentCommunity\Framework\Support\Arr;
11 12 use FluentCommunity\Framework\Support\Sanitizer;
12 13 use FluentCommunity\Modules\Course\Model\Course;
@@ -14,12 +15,19 @@
14 15 class SettingController extends Controller
15 16 {
16 17 public function getFeatures()
17 18 {
19 + $features = Utility::getFeaturesConfig();
20 +
21 + if (!empty($features['giphy_api_key'])) {
22 + $features['giphy_api_key'] = 'FCOM_ENCRYPTED_DATA_KEY';
23 + }
24 +
18 25 $data = [
19 - 'features' => Utility::getFeaturesConfig(),
26 + 'features' => $features,
20 27 'addOns' => $this->getAddons()
21 28 ];
29 +
22 30 return apply_filters('fluent_community/features_api_response', $data, $this->request->all());
23 31 }
24 32
25 33 public function setFeatures(Request $request)
@@ -40,12 +48,17 @@
40 48 'user_badge' => 'sanitize_text_field',
41 49 'has_crm_sync' => 'sanitize_text_field',
42 50 'followers_module' => 'sanitize_text_field',
43 51 'custom_profile_fields' => 'sanitize_text_field',
52 + 'pwa_module' => 'sanitize_text_field',
44 53 ]);
45 54
46 55 $prevConfig = Utility::getFeaturesConfig();
47 56
57 + if (Arr::get($data, 'giphy_api_key') === 'FCOM_ENCRYPTED_DATA_KEY') {
58 + $data['giphy_api_key'] = Arr::get($prevConfig, 'giphy_api_key', '');
59 + }
60 +
48 61 $data = wp_parse_args($data, $prevConfig);
49 62
50 63 Utility::updateOption('fluent_community_features', $data);
51 64
@@ -177,8 +190,17 @@
177 190 'settings_url' => Helper::baseUrl('chat'),
178 191 'action_text' => $this->isPluginInstalled('fluent-messaging/fluent-messaging.php') ? __('Active FluentCommunity Chat', 'fluent-community') : __('Install FluentCommunity Chat', 'fluent-community'),
179 192 'description' => __('FluentCommunity Chat is a real-time chat plugin for WordPress. It allows you to create a chat room for your community members.', 'fluent-community')
180 193 ],
194 + 'fluent-notify' => [
195 + 'is_repo' => false,
196 + 'title' => __('FluentNotify', 'fluent-community'),
197 + 'logo' => Helper::assetUrl('images/brands/fluent-notify.svg'),
198 + 'is_installed' => defined('FLUENT_NOTIFY_PLUGIN_VERSION'),
199 + 'learn_more_url' => 'https://fluentnotify.com',
200 + 'action_text' => $this->isPluginInstalled('fluent-notify/fluent-notify.php') ? __('Active FluentNotify', 'fluent-community') : __('Install FluentNotify', 'fluent-community'),
201 + 'description' => __('Send browser push notifications to your community members for comments, replies and mentions.', 'fluent-community')
202 + ],
181 203 'fluent-player' => [
182 204 'is_repo' => false,
183 205 'title' => __('FluentPlayer', 'fluent-community'),
184 206 'logo' => Helper::assetUrl('images/brands/fluent-player.svg'),
@@ -261,24 +283,49 @@
261 283 }
262 284
263 285 public function installPlugin(Request $request)
264 286 {
265 - if (!current_user_can('install_plugins')) {
266 - return $this->sendError([
267 - 'message' => __('You do not have permission to install plugins', 'fluent-community')
268 - ]);
269 - }
270 -
271 287 $pluginSlug = $request->get('plugin');
272 288
273 289 $addons = $this->getAddons();
274 290
275 291 if (!isset($addons[$pluginSlug])) {
276 - return $this->sendError(__('Invalid Plugin', 'fluent-community'));
292 + return $this->sendError(['message' => __('Invalid Plugin', 'fluent-community')]);
277 293 }
278 294
279 295 $details = $addons[$pluginSlug];
280 296
297 + $pluginFile = $pluginSlug . '/' . $pluginSlug . '.php';
298 +
299 + // Already on disk but deactivated: that is an activation, so it answers to
300 + // activate_plugins and needs no download.
301 + if (!$details['is_repo'] && $this->isPluginInstalled($pluginFile)) {
302 + if (!current_user_can('activate_plugins')) {
303 + return $this->sendError(['message' => __('You do not have permission to activate plugins', 'fluent-community')]);
304 + }
305 +
306 + require_once ABSPATH . 'wp-admin/includes/plugin.php';
307 +
308 + if (!is_plugin_active($pluginFile)) {
309 + $activated = activate_plugin($pluginFile);
310 +
311 + if (is_wp_error($activated)) {
312 + return $this->sendError(['message' => wp_kses_post($activated->get_error_message())]);
313 + }
314 + }
315 +
316 + return [
317 + 'message' => __('Plugin has been activated Successfully', 'fluent-community'),
318 + 'is_installed' => true
319 + ];
320 + }
321 +
322 + if (!current_user_can('install_plugins')) {
323 + return $this->sendError([
324 + 'message' => __('You do not have permission to install plugins', 'fluent-community')
325 + ]);
326 + }
327 +
281 328 if ($details['is_repo']) {
282 329 $plugin = [
283 330 'name' => $details['title'],
284 331 'repo-slug' => $pluginSlug,
@@ -283,23 +330,42 @@
283 330 'name' => $details['title'],
284 331 'repo-slug' => $pluginSlug,
285 332 'file' => $pluginSlug . '.php',
286 333 ];
287 - $this->backgroundInstaller($plugin, $pluginSlug);
334 + try {
335 + OnboardingService::backgroundInstaller($plugin);
336 + } catch (\Exception $e) {
337 + return $this->sendError(['message' => $e->getMessage()]);
338 + }
288 339 } else {
340 + $installHook = '';
341 +
289 342 if ($pluginSlug == 'fluent-messaging') {
290 343 if (!defined('FLUENT_COMMUNITY_PRO')) {
291 - return $this->sendError(__('FluentMessaging is a Pro Plugin. Please install FluentCommunity Pro first.', 'fluent-community'));
344 + return $this->sendError(['message' => __('FluentMessaging is a Pro Plugin. Please install FluentCommunity Pro first.', 'fluent-community')]);
292 345 }
293 - do_action('fluent_community/install_messaging_plugin');
346 + $installHook = 'fluent_community/install_messaging_plugin';
294 347 } else if ($pluginSlug == 'fluent-player') {
295 348
296 349 if (!defined('FLUENT_COMMUNITY_PRO')) {
297 - return $this->sendError(__('FluentPlayer is required pro version of FluentCommunity. Please install FluentCommunity Pro first.', 'fluent-community'));
350 + return $this->sendError(['message' => __('FluentPlayer requires the pro version of FluentCommunity. Please install FluentCommunity Pro first.', 'fluent-community')]);
298 351 }
299 352
300 - do_action('fluent_community/install_fluent_player_plugin');
353 + $installHook = 'fluent_community/install_fluent_player_plugin';
354 + } else if ($pluginSlug == 'fluent-notify') {
355 + $installHook = 'fluent_community/install_fluent_notify_plugin';
301 356 }
357 +
358 + if (!$installHook || !has_action($installHook)) {
359 + return $this->sendError(['message' => __('This plugin can not be installed from here. Please install it manually.', 'fluent-community')]);
360 + }
361 +
362 + try {
363 + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound -- every assigned value is a literal fluent_community/ prefixed hook, guarded above
364 + do_action($installHook);
365 + } catch (\Exception $e) {
366 + return $this->sendError(['message' => $e->getMessage()]);
367 + }
302 368 }
303 369
304 370 return [
305 371 'message' => __('Plugin has been installed Successfully', 'fluent-community'),
@@ -306,129 +372,8 @@
306 372 'is_installed' => true
307 373 ];
308 374 }
309 375
310 - private function backgroundInstaller($plugin_to_install, $plugin_id)
311 - {
312 - if (!empty($plugin_to_install['repo-slug'])) {
313 - require_once ABSPATH . 'wp-admin/includes/file.php';
314 - require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
315 - require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
316 - require_once ABSPATH . 'wp-admin/includes/plugin.php';
317 -
318 - WP_Filesystem();
319 -
320 - $skin = new \Automatic_Upgrader_Skin();
321 - $upgrader = new \WP_Upgrader($skin);
322 - $installed_plugins = array_reduce(array_keys(\get_plugins()), array($this, 'associate_plugin_file'),
323 - array());
324 - $plugin_slug = $plugin_to_install['repo-slug'];
325 - $plugin_file = isset($plugin_to_install['file']) ? $plugin_to_install['file'] : $plugin_slug . '.php';
326 - $installed = false;
327 - $activate = false;
328 -
329 - // See if the plugin is installed already.
330 - if (isset($installed_plugins[$plugin_file])) {
331 - $installed = true;
332 - $activate = !is_plugin_active($installed_plugins[$plugin_file]);
333 - }
334 -
335 - // Install this thing!
336 - if (!$installed) {
337 - // Suppress feedback.
338 - ob_start();
339 -
340 - try {
341 - $plugin_information = plugins_api(
342 - 'plugin_information',
343 - array(
344 - 'slug' => $plugin_slug,
345 - 'fields' => array(
346 - 'short_description' => false,
347 - 'sections' => false,
348 - 'requires' => false,
349 - 'rating' => false,
350 - 'ratings' => false,
351 - 'downloaded' => false,
352 - 'last_updated' => false,
353 - 'added' => false,
354 - 'tags' => false,
355 - 'homepage' => false,
356 - 'donate_link' => false,
357 - 'author_profile' => false,
358 - 'author' => false,
359 - ),
360 - )
361 - );
362 -
363 - if (is_wp_error($plugin_information)) {
364 - throw new \Exception($plugin_information->get_error_message());
365 - }
366 -
367 - $package = $plugin_information->download_link;
368 - $download = $upgrader->download_package($package);
369 -
370 - if (is_wp_error($download)) {
371 - throw new \Exception($download->get_error_message());
372 - }
373 -
374 - $working_dir = $upgrader->unpack_package($download, true);
375 -
376 - if (is_wp_error($working_dir)) {
377 - throw new \Exception($working_dir->get_error_message());
378 - }
379 -
380 - $result = $upgrader->install_package(
381 - array(
382 - 'source' => $working_dir,
383 - 'destination' => WP_PLUGIN_DIR,
384 - 'clear_destination' => false,
385 - 'abort_if_destination_exists' => false,
386 - 'clear_working' => true,
387 - 'hook_extra' => array(
388 - 'type' => 'plugin',
389 - 'action' => 'install',
390 - ),
391 - )
392 - );
393 -
394 - if (is_wp_error($result)) {
395 - throw new \Exception($result->get_error_message());
396 - }
397 -
398 - $activate = true;
399 - } catch (\Exception $e) {
400 - }
401 -
402 - // Discard feedback.
403 - ob_end_clean();
404 - }
405 -
406 - wp_clean_plugins_cache();
407 -
408 - // Activate this thing.
409 - if ($activate) {
410 - try {
411 - $result = activate_plugin($installed ? $installed_plugins[$plugin_file] : $plugin_slug . '/' . $plugin_file);
412 -
413 - if (is_wp_error($result)) {
414 - throw new \Exception($result->get_error_message());
415 - }
416 - } catch (\Exception $e) {
417 - throw new \Exception(esc_html($e->getMessage()));
418 - }
419 - }
420 - }
421 - }
422 -
423 - private function associate_plugin_file($plugins, $key)
424 - {
425 - $path = explode('/', $key);
426 - $filename = end($path);
427 - $plugins[$filename] = $key;
428 - return $plugins;
429 - }
430 -
431 376 public function getCustomizationSettings(Request $request)
432 377 {
433 378 $data = [
434 379 'settings' => Utility::getCustomizationSettings()
@@ -441,14 +386,16 @@
441 386 {
442 387 $settings = $request->get('settings', []);
443 388
444 389 $yesNoFields = [
445 - 'dark_mode', 'fixed_page_header', 'show_powered_by', 'show_post_modal', 'feed_link_on_sidebar', 'fixed_sidebar', 'icon_on_header_menu', 'disable_feed_layout', 'collapse_sidebar_groups', 'hide_header_on_scroll'
390 + 'dark_mode', 'fixed_page_header', 'show_powered_by', 'show_post_modal', 'feed_link_on_sidebar', 'fixed_sidebar', 'icon_on_header_menu', 'disable_feed_layout', 'collapse_sidebar_groups', 'hide_header_on_scroll', 'enable_sidebar_toggle'
446 391 ];
447 392
448 393 foreach ($settings as $key => $value) {
449 394 if (in_array($key, $yesNoFields)) {
450 395 $settings[$key] = $value == 'yes' ? 'yes' : 'no';
396 + } else if ($key == 'default_theme_mode') {
397 + $settings[$key] = in_array($value, ['light', 'dark', 'system'], true) ? $value : 'light';
451 398 } else if ($key == 'affiliate_id') {
452 399 $settings[$key] = (int)$value;
453 400 if (!$settings[$key]) {
454 401 $settings[$key] = '';
@@ -457,8 +404,12 @@
457 404 $settings[$key] = sanitize_text_field($value);
458 405 }
459 406 }
460 407
408 + if (isset($settings['dark_mode']) && $settings['dark_mode'] !== 'yes') {
409 + $settings['default_theme_mode'] = 'light';
410 + }
411 +
461 412 Utility::updateCustomizationSettings($settings);
462 413
463 414 return [
464 415 'message' => __('Customization settings have been saved successfully.', 'fluent-community')
@@ -541,8 +492,12 @@
541 492 ->get();
542 493
543 494 $formattedSpaceGroups = [];
544 495 foreach ($spaceGroups as $spaceGroup) {
496 + if ($spaceGroup->spaces->isEmpty()) {
497 + continue;
498 + }
499 +
545 500 $spaces = $spaceGroup->spaces->map(function ($space) {
546 501 return [
547 502 'id' => $space->id,
548 503 'title' => $space->title,
@@ -551,12 +506,8 @@
551 506 'icon' => $space->getIconMark(),
552 507 'type' => $space->type,
553 508 ];
554 509 });
555 -
556 - if (!$spaces) {
557 - continue;
558 - }
559 510
560 511 $formattedSpaceGroups[] = [
561 512 'id' => $spaceGroup->id,
562 513 'title' => $spaceGroup->title,