Skip to main content

Shahjahan JewelΒ I have been testing this over and over but yet no result.

The video plays fine, but the timed content refused to display

  • For example, less discussion space so the content isn't fragmented?
  • Onboarding?
  • Less effort on posts, more on courses?

Let's help each other.

Hello everyone. I'm planning to close a space but I don't want to loose all the content, I just want to merge it with another space.

Is it possibile to bulk move posts from a space to another?

Is there a limit on how many members you can have in a searchable community member/course directory?

Written 2026-09-18 against 2.10.01, remeasured the same evening against
2.11.0 on the staging site: all four guards and both routes are
unchanged, only the line numbers moved. Corrected after looking at the actual
screen: the save button is not rendered at all for a foreign profile – the
earlier draft claimed it was there and the click failed. That was inferred
from the controller instead of looked at, and it was wrong.
Earlier reports: upstream/2026-09-03-notification-row-and-license-message-en.md
(the empty co_comment row, shipped fixed as "Empty Notification Preference
Row When Push Is Unavailable"), upstream/2026-08-19-string-issues-en.md,
upstream/2026-08-26-profile-bio-placeholder-en.md.

Not a translation point this time. I run a FluentCommunity site and maintain the
German catalogues, and this is a permission asymmetry that leaves an admin with
an editable form and no way to commit it.

What happens

As a WordPress super admin, I open another member's notification preferences in
the portal. The page renders, the checkboxes carry that member's real values,
and I can change them. There is no save button. The edits go nowhere.

Why

Three places decide this, and they do not agree. Reading admits admins, editing
admits admins, saving does not – and saving is blocked twice over, once in the
UI and once in the controller.

The portal renders the save block only for the profile's owner. In
assets/app.js, the whole block hangs off isOwn, while the same component
loads the preferences for a super admin on purpose:

// the save block, rendered only when isOwn
i.isOwn ? (…, { onClick: i.saveSettings, … }, … "Save Changes" …) : _("", !0)

// isOwn compares the profile in the URL with the logged-in user
isOwn() { return this.username === this.auth.username }

// but loading explicitly admits super admins
mounted() { this.isOwn || this.hasPermission("super_admin") ? this.getPrefs() : … }

Nothing disables the checkboxes in between, so the form stays interactive for an
admin. It just has no way to submit.

And behind that, read and write hang off two different guards, only one of
which knows about admins:

// app/Http/Controllers/ProfileController.php:720
public function getNotificationPreferance(Request $request, $userName)
{
    ...
    $xProfile = $this->verifyAndGetProfile($userName);
// app/Http/Controllers/ProfileController.php:904
public function saveNotificationPreferance(Request $request, $userName)
{
    $xProfile = $this->verifyAndGetOwnProfile($userName);
// app/Http/Controllers/ProfileController.php:1000
private function verifyAndGetProfile($userName)
{
    $xProfile = XProfile::where('username', $userName)->firstOrFail();

    $currentUserId = get_current_user_id();
    if ($xProfile->user_id != $currentUserId && !Helper::isSuperAdmin($currentUserId)) {
        throw new \Exception('You are not allowed to update this profile');
    }

    return $xProfile;
}

// app/Http/Controllers/ProfileController.php:1012
private function verifyAndGetOwnProfile($userName)
{
    $xProfile = XProfile::where('username', $userName)->firstOrFail();

    if (!get_current_user_id() || $xProfile->user_id != get_current_user_id()) {
        throw new HttpException(403, esc_html__('You are not allowed to access these notification preferences.', 'fluent-community'));
    }

    return $xProfile;
}

Both endpoints sit on the same username-scoped route pair:

// app/Http/Routes/api.php:98-99
$router->get('/{username}/notification-preferences', 'ProfileController@getNotificationPreferance')->alphaNumDash('username');
$router->post('/{username}/notification-preferences', 'ProfileController@saveNotificationPreferance')->alphaNumDash('username');

So GET admits a super admin on any profile, POST admits nobody but the owner.
Worth noting: an admin never sees the 403 message, "You are not allowed to
access these notification preferences", because the UI hides the button before
any request goes out. The string is reachable through the API only. What the
admin sees instead is a form that silently keeps his edits and then drops them
on the next navigation.

Whichever way you decide this, the three should agree. Either the write path and
the save block admit admins, or the read path stops handing an admin an editable
form. What it should not do is all three at once: load the data, let him type,
and then quietly have nowhere to put it.

This looks like collateral from the hardening pass

Editing another member's preferences used to be a supported path. Your own
changelog fixed a bug in it:

= 2.7.0 (Date: Jul 8, 2026) =
- Fixed: Notification Settings Space Scope on Other Profiles

and in 2.3.0 there was a single guard, which let community moderators through:

// 2.3.0, app/Http/Controllers/ProfileController.php
if ($xProfile->user_id != get_current_user_id() && (!$currentUser || !$currentUser->isCommunityModerator())) {
    throw new \Exception('You are not allowed to update this profile');
}

I cannot pin the exact release that split the guards, since I only have 2.3.0
and the current sources to compare. Judging by the changelog, 2.9.0's "Security: Access
Control, Data Scoping and Input Sanitization Hardening" is the likely spot. If
that is right, the write path was tightened to owner-only and the read path kept
its admin branch, and the mismatch is an oversight rather than a decision.

Why an admin wants this

My members are not all comfortable in a portal. They phone or write to me: "I
get too much email from the community, please turn it off." Today I have three
options, and all three are bad. I can talk them through five checkboxes over the
phone, or ask them for their password, or write to the database behind your back.

The same case shows up for anyone running a community for a non-technical
audience: onboarding a new member with sensible defaults, quieting a member who
is about to unsubscribe from everything, or fixing a member who accidentally
turned off the digest and now believes the community is dead.

Suggestion

Two small changes, and they belong together – fixing only the controller would
leave the button hidden, fixing only the button would turn a silent loss into a
403.

In the portal, render the save block on the same condition that already
decides whether the preferences get loaded at all:

// instead of isOwn
isOwn || hasPermission('super_admin')

In the controller, give the write path the same admin branch the read path
already has:

private function verifyAndGetOwnProfile($userName)
{
    $xProfile = XProfile::where('username', $userName)->firstOrFail();

    $currentUserId = get_current_user_id();
    if (!$currentUserId || ($xProfile->user_id != $currentUserId && !Helper::isSuperAdmin($currentUserId))) {
        throw new HttpException(403, esc_html__('You are not allowed to access these notification preferences.', 'fluent-community'));
    }

    return $xProfile;
}

If you would rather keep owner-only as the default, a filter would be enough for
site owners like me:

$canManage = apply_filters(
    'fluent_community/can_manage_member_notification_prefs',
    Helper::isSuperAdmin($currentUserId),
    $xProfile->user_id,
    $currentUserId
);

Either way, please keep NotificationPref::updateUserPrefs() as the public
entry point it is today. That is the door I am using in the meantime: a small
admin-side plugin of my own reads with getUserPrefs(), writes with
updateUserPrefs(), and never touches fcom_notification_prefs directly. It
works, and it is a detour around your own API, which is why I would rather have
the route.

One note for whoever picks this up: since 2.9.0 the preferences live in their
own table with the channel as a column, and updateUserPrefs() also clears the
per-user cache (user_notification_pref_<id>). Any admin-side path that writes
rows directly would leave that cache stale, so the service really is the only
sane entry point.

Happy to send a PR for the guard, the button condition or the filter, whichever
you prefer.

Another big one. We just shipped 2.11 today and we upgraded the whole quiz module. More on that later.

Space Menu Manager

Until now the tabs at the top of a space came in a fixed order. You could add a few extra links and that was it. Now you own that menu. Open any space, go to Settings, there's a new Menu tab.

You can drag tabs into any order, rename them, add an emoji or SVG icon, and hide the ones you don't use. You can add your own tabs too, linking to any URL or to one of your space pages. And you can decide who sees each link: everyone, logged-in members, logged-out visitors, or members of specific spaces and courses.

Advanced Quiz Builder

This is the biggest quiz update since we launched courses.

Six new question types (Pro): True/False, Written Answer, Fill in the Blank, Ordering, Matching, and Image Matching. Everything is graded on the server, and the answers never reach the student's browser. Ordering and matching options are shuffled per student.

New one-by-one layout. One question per screen, progress bar, Previous/Next. Long quizzes stop feeling like a wall.

Per-question explanations. Students see "View Explanation" under each question after they submit. A score says how they did. An explanation says what to learn from it.

Plus shuffle settings for questions and answer options.

Also in this release

  • Students can restart a course. Admins can reset a student's progress too.
  • Works properly with the latest FluentAuth (magic links, 2FA on the portal login).
  • Fixed embedded videos getting blocked by Wordfence and similar WAF rules.
  • Fixed comment count drift after moderation.
  • Block editor and space page labels are now translatable.

Full details and screenshots here: https://fluentcommunity.co/blog/fluent-community-2-11/

If you're building something with the new quiz types or a custom space menu, post it here. I'd love to see it. Please let us know in the comments about this update and what we should ship next. More cooking!

Paul CΒ has been using FluentAuth since day one (v1.0). When 1.0 came out, he made a video about it, when almost nobody knew the plugin existed.

Now 3.0 is out, and he made another one. He goes through pretty much everything the plugin does. Passkeys, 2FA by role, brute-force limits, the security checklist, file monitoring, recovery tools, social login, the login page designer. All of it.

Please watch the video and explore all the cool features and yes, everything is 100% free and open

https://www.youtube.com/watch?v=Tt9LHwHySmA

Thanks, Paul, for supporting this plugin and using it. This means a lot.

PS: Another update is coming soon with some feedback and edge case fixes.

Hello team, I request that fluent community authentication forms open inside the community frame. They are isolated

I was under the impression that FluentCart was the natural integration to sell monthly recurring memberships to FluentCommunity, but it turns out that isn't the case as FluentCart doesn't offer the option to actually create an account (username/password) during the sales flow. So how is everyone doing this today? How are you onboarding new paid members?

Can't comment a post from the feed. It sends an error message. Can only comment in the spaces. Is that intended?

Error message when commenting from the feed