PluginProbe
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration / 2.2.0
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration v2.2.0
2.2.0 2.1.0 2.0.15 2.0.12 2.0.10 2.0.4 2.0.1 2.0.0 1.95.3 1.95.2 1.95 1.91.6 trunk 1.11 1.12 1.13 1.20 1.21 1.22 1.23 1.30 1.31 1.32 1.35 1.40 All 43 releases
← All changes | app/Services/PermissionManager.php +97 -16 2.0.4 → 2.2.0 View file →
@@ -106,9 +106,9 @@
106 106 if (!$boardUser) {
107 107 return false;
108 108 }
109 109
110 - return (bool)$boardUser->settings ? $boardUser->settings['is_admin'] : null;
110 + return (bool)($boardUser->settings[Constant::IS_BOARD_ADMIN] ?? false);
111 111
112 112 }
113 113
114 114 public static function userHasAnyBoardAccess($userId = null): bool
@@ -156,8 +156,38 @@
156 156 ->where('object_type', Constant::OBJECT_TYPE_BOARD_USER)
157 157 ->exists();
158 158 }
159 159
160 + /** Filter existing users by board membership or global admin access using bulk lookups. */
161 + public static function getUserIdsWithBoardAccess($boardId, array $userIds): array
162 + {
163 + $boardId = absint($boardId);
164 + $userIds = array_values(array_unique(array_filter(array_map('absint', $userIds))));
165 + if (!$boardId || !$userIds) {
166 + return [];
167 + }
168 +
169 + $memberIds = Relation::where('object_id', $boardId)
170 + ->where('object_type', Constant::OBJECT_TYPE_BOARD_USER)
171 + ->whereIn('foreign_id', $userIds)
172 + ->pluck('foreign_id')->toArray();
173 + $adminIds = Meta::where('object_type', Constant::FLUENT_BOARD_ADMIN)
174 + ->whereIn('object_id', $userIds)
175 + ->pluck('object_id')->toArray();
176 + $allowedIds = array_fill_keys(array_merge($memberIds, $adminIds), true);
177 +
178 + // Loading full users primes their metadata together before capability checks.
179 + $users = get_users(['include' => $userIds, 'fields' => 'all']);
180 + $accessibleIds = [];
181 + foreach ($users as $user) {
182 + if (isset($allowedIds[$user->ID]) || user_can($user, 'manage_options')) {
183 + $accessibleIds[] = (int) $user->ID;
184 + }
185 + }
186 +
187 + return array_values(array_intersect($userIds, $accessibleIds));
188 + }
189 +
160 190 public static function isFluentBoardsAdmin($userId = null): bool
161 191 {
162 192 if (!$userId) {
163 193 $userId = get_current_user_id();
@@ -200,14 +230,62 @@
200 230
201 231 return true;
202 232 }
203 233
234 + public static function userCanAccessMemberProfile($targetUserId, $userId = null): bool
235 + {
236 + $targetUserId = intval($targetUserId);
237 +
238 + if (!$userId) {
239 + $userId = get_current_user_id();
240 + }
241 +
242 + $userId = intval($userId);
243 +
244 + if (!$targetUserId || !$userId) {
245 + return false;
246 + }
247 +
248 + if ($userId === $targetUserId || static::isAdmin($userId)) {
249 + return true;
250 + }
251 +
252 + if (!static::isFluentBoardsUser($targetUserId)) {
253 + return false;
254 + }
255 +
256 + $boardIds = Relation::where('foreign_id', $userId)
257 + ->where('object_type', Constant::OBJECT_TYPE_BOARD_USER)
258 + ->pluck('object_id')
259 + ->toArray();
260 +
261 + if (empty($boardIds)) {
262 + return false;
263 + }
264 +
265 + return Relation::where('foreign_id', $targetUserId)
266 + ->where('object_type', Constant::OBJECT_TYPE_BOARD_USER)
267 + ->whereIn('object_id', $boardIds)
268 + ->exists();
269 + }
270 +
271 + /**
272 + * Check WordPress or Boards admin access, caching by the resolved user ID.
273 + */
204 274 public static function isAdmin($userId = null, $useCache = true)
205 275 {
206 276
207 277 static $cache = [];
208 278
209 - if (isset($cache[$userId]) && $useCache) {
279 + if (!$userId) {
280 + $userId = get_current_user_id();
281 + }
282 +
283 + if (!$userId) {
284 + return false;
285 + }
286 +
287 + if ($useCache && isset($cache[$userId])) {
210 288 return $cache[$userId];
211 289 }
212 290
213 291 /*
@@ -217,19 +295,8 @@
217 295 * if user is WordPress admin then we will allow him
218 296 * if user is FluentBoard admin then we will allow him
219 297 */
220 298
221 - if (!$userId) {
222 - $userId = get_current_user_id();
223 - if (!$userId) {
224 - return false;
225 - }
226 - }
227 -
228 - if (!$userId) {
229 - return false;
230 - }
231 -
232 299 if (user_can($userId, 'manage_options')) { // WordPress Administrator
233 300
234 301 $cache[$userId] = true;
235 302
@@ -352,9 +419,9 @@
352 419 return false; // Return false if no board ID is provided
353 420 }
354 421
355 422 // Admins have full permissions, allow access immediately
356 - if (static::isAdmin()) {
423 + if (static::isAdmin($userId)) {
357 424 return true;
358 425 }
359 426
360 427 // Fetch user permissions for the given board
@@ -376,8 +443,12 @@
376 443 // Deny access if the user is a viewer only and trying to modify data
377 444 return !($boardPermissions->settings['is_viewer_only'] ?? false);
378 445 }
379 446
447 + /**
448 + * Allow admins, or members with a non-viewer membership when creation is enabled.
449 + * The final filter remains available for site-specific permission overrides.
450 + */
380 451 public static function userHasBoardCreationPermission($userId = null)
381 452 {
382 453 if (!$userId) {
383 454 $userId = get_current_user_id();
@@ -391,10 +462,20 @@
391 462 }
392 463
393 464 // Check if "allow members to create boards" setting is enabled
394 465 $generalSettings = fluent_boards_get_option('general_settings', []);
395 - if (!empty($generalSettings['allow_members_to_create_boards']) && $generalSettings['allow_members_to_create_boards'] !== 'false' && static::userHasAnyBoardAccess($userId)) {
396 - return apply_filters('fluent_boards/can_create_board', true, $userId);
466 + if (!empty($generalSettings['allow_members_to_create_boards']) && $generalSettings['allow_members_to_create_boards'] !== 'false') {
467 + $memberships = Relation::where('foreign_id', $userId)
468 + ->where('object_type', Constant::OBJECT_TYPE_BOARD_USER)
469 + ->whereNotNull('object_id')
470 + ->get(['settings']);
471 +
472 + // Roles are per board: a viewer elsewhere may still be a member or manager here.
473 + foreach ($memberships as $membership) {
474 + if (!($membership->settings['is_viewer_only'] ?? false)) {
475 + return apply_filters('fluent_boards/can_create_board', true, $userId);
476 + }
477 + }
397 478 }
398 479
399 480 return apply_filters('fluent_boards/can_create_board', false, $userId);
400 481 }