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/SpaceController.php +81 -19 2.6.02.10.01 View file →
@@ -159,9 +159,10 @@
159 159 $q->where('user_id', get_current_user_id());
160 160 }])
161 161 ->where(function ($q) {
162 162 $q->whereHas('space_pivot', function ($q) {
163 - $q->where('user_id', get_current_user_id());
163 + $q->where('user_id', get_current_user_id())
164 + ->where('status', 'active');
164 165 })
165 166 ->orWhereIn('privacy', ['public', 'private']);
166 167 })
167 168 ->when($type == 'joined', function ($q) {
@@ -185,8 +186,10 @@
185 186
186 187 $memberCounts = $this->getActiveMemberCounts($spaces->pluck('id')->toArray());
187 188
188 189 foreach ($spaces as $space) {
190 + $space->description_rendered = wpautop($space->description);
191 +
189 192 $shouldHideMembersCount = Arr::get($space->settings, 'hide_members_count') == 'yes';
190 193 $canViewMembers = $currentUser && $space->verifyUserPermisson($currentUser, 'can_view_members', false);
191 194
192 195 if ($shouldHideMembersCount && !$canViewMembers) {
@@ -194,9 +197,8 @@
194 197 continue;
195 198 }
196 199
197 200 $space->members_count = (int)Arr::get($memberCounts, $space->id, 0);
198 - $space->description_rendered = wpautop($space->description);
199 201 }
200 202
201 203 $data = [
202 204 'spaces' => $spaces,
@@ -207,11 +209,23 @@
207 209 }
208 210
209 211 public function getAllSpaces(Request $request)
210 212 {
211 - $spaces = Space::paginate();
213 + $currentUser = $this->getUser();
212 214
213 - $currentUser = $this->getUser();
215 + $spacesQuery = Space::query();
216 +
217 + if (!($currentUser && $currentUser->isCommunityModerator())) {
218 + $spacesQuery->where(function ($q) {
219 + $q->whereHas('space_pivot', function ($q) {
220 + $q->where('user_id', get_current_user_id())
221 + ->where('status', 'active');
222 + })
223 + ->orWhereIn('privacy', ['public', 'private']);
224 + });
225 + }
226 + $spaces = $spacesQuery->paginate();
227 +
214 228 $memberCounts = $this->getActiveMemberCounts($spaces->pluck('id')->toArray());
215 229
216 230 foreach ($spaces as $space) {
217 231 $shouldHideMembersCount = Arr::get($space->settings, 'hide_members_count') == 'yes';
@@ -235,17 +249,18 @@
235 249
236 250 public function getBySlug(Request $request, $spaceSlug)
237 251 {
238 252 $user = $this->getUser();
239 - $space = Space::where('slug', $spaceSlug)
240 - ->firstOrFail();
253 + $space = Space::where('slug', $spaceSlug)->first();
241 254
242 255 $userId = $user ? $user->ID : null;
243 - if ($space->privacy == 'secret' && !$space->getMembership($userId) && !$space->isAdmin($userId, true)) {
256 +
257 + // A hidden secret space must be indistinguishable from a non-existent one, so its
258 + // existence cannot be enumerated by slug. Both return an identical 404.
259 + if (!$space || ($space->privacy == 'secret' && !$space->getMembership($userId) && !$space->isAdmin($userId, true))) {
244 260 return $this->sendError([
245 - 'message' => __('You are not allowed to view this space', 'fluent-community'),
246 - 'error_type' => 'restricted'
247 - ]);
261 + 'message' => __('Space not found', 'fluent-community')
262 + ], 404);
248 263 }
249 264
250 265 $space = $space->formatSpaceData($user);
251 266
@@ -372,8 +387,9 @@
372 387 }
373 388
374 389 public function getMembers(Request $request, $slug)
375 390 {
391 + /** @var Space $space */
376 392 $space = Space::where('slug', $slug)
377 393 ->firstOrFail();
378 394
379 395 $user = $this->getUser();
@@ -411,20 +427,37 @@
411 427 ], $pendingRequests, $request->all());
412 428 }
413 429 }
414 430
431 + $defaultDirections = [
432 + 'last_activity' => 'DESC',
433 + 'display_name' => 'ASC',
434 + 'created_at' => 'DESC',
435 + ];
436 +
437 + $sortBy = $request->getSafe('sort_by', 'sanitize_text_field', 'created_at');
438 + $sortColumn = in_array($sortBy, array_keys($defaultDirections), true) ? $sortBy : 'created_at';
439 + $sortDir = strtoupper($request->getSafe('sort_dir', 'sanitize_text_field', ''));
440 + $sortDirection = in_array($sortDir, ['ASC', 'DESC'], true) ? $sortDir : ($sortColumn === 'created_at' ? 'ASC' : $defaultDirections[$sortColumn]);
441 +
442 + $profileSort = $sortColumn !== 'created_at';
443 + $orderColumn = $profileSort ? 'fcom_xprofile.' . $sortColumn : 'fcom_space_user.created_at';
444 +
415 445 $spaceMembers = SpaceUserPivot::bySpace($space->id)
416 446 ->whereHas('xprofile', function ($q) use ($search) {
417 - return $q->searchBy($search)
418 - ->where('status', 'active');
447 + $q->searchBy($search)->where('status', 'active');
419 448 })
449 + ->where('fcom_space_user.status', 'active')
420 450 ->with(['xprofile' => function ($q) {
421 451 $q->select(ProfileHelper::getXProfilePublicFields());
422 452 }])
423 - ->where('status', 'active')
424 - ->orderBy('created_at', 'ASC')
453 + ->when($profileSort, function ($q) {
454 + $q->join('fcom_xprofile', 'fcom_xprofile.user_id', '=', 'fcom_space_user.user_id')
455 + ->select('fcom_space_user.*');
456 + })
457 + ->orderBy($orderColumn, $sortDirection)
425 458 ->paginate();
426 -
459 +
427 460 return apply_filters('fluent_community/space_members_api_response', [
428 461 'members' => $spaceMembers,
429 462 'pending_count' => $pendingCount
430 463 ], $spaceMembers, $request->all());
@@ -720,8 +753,12 @@
720 753 $userIds = $userQuery->get()
721 754 ->pluck('ID')
722 755 ->toArray();
723 756
757 + if ($userIds) {
758 + update_meta_cache('user', $userIds);
759 + }
760 +
724 761 $users = User::select($selects)
725 762 ->whereIn('ID', $userIds)
726 763 ->paginate(100);
727 764
@@ -815,13 +852,28 @@
815 852 'title' => 'required|unique:fcom_spaces,title',
816 853 'slug' => 'required|unique:fcom_spaces,slug'
817 854 ]);
818 855
856 + $title = sanitize_text_field(Arr::get($data, 'title', ''));
857 + $slug = sanitize_title(Arr::get($data, 'slug', ''));
858 + $desc = sanitize_textarea_field(Arr::get($data, 'description', ''));
819 859
860 + if (!$title) {
861 + return $this->sendError([
862 + 'message' => __('Please enter a valid group title.', 'fluent-community')
863 + ]);
864 + }
865 +
866 + if (!$slug) {
867 + return $this->sendError([
868 + 'message' => __('Please enter a valid group slug.', 'fluent-community')
869 + ]);
870 + }
871 +
820 872 $formattedData = [
821 - 'title' => sanitize_text_field($data['title']),
822 - 'slug' => sanitize_title($data['slug']),
823 - 'description' => sanitize_textarea_field($data['description']),
873 + 'title' => $title,
874 + 'slug' => $slug,
875 + 'description' => $desc,
824 876 'status' => 'active',
825 877 'type' => 'space_group',
826 878 'settings' => [
827 879 'always_show_spaces' => Arr::get($data, 'settings.always_show_spaces', 'yes'),
@@ -942,9 +994,19 @@
942 994 }
943 995
944 996 public function getLockScreenSettings(Request $request, $spaceSlug)
945 997 {
946 - $space = Space::where('slug', $spaceSlug)->firstOrFail();
998 + /** @var Space $space */
999 + $space = Space::where('slug', $spaceSlug)->first();
1000 +
1001 + $userId = $this->getUser() ? $this->getUser()->ID : null;
1002 +
1003 + if (!$space || ($space->privacy == 'secret' && !$space->getMembership($userId) && !$space->isAdmin($userId, true))) {
1004 + return $this->sendError([
1005 + 'message' => __('Space not found', 'fluent-community')
1006 + ], 404);
1007 + }
1008 +
947 1009 $lockscreen = $space->getLockscreen();
948 1010
949 1011 $lockscreen = apply_filters('fluent_community/get_lockscreen_settings', $lockscreen, $space);
950 1012