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 +58 -14 2.1.0 → 2.2.0 View file →
@@ -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();
@@ -237,14 +267,25 @@
237 267 ->whereIn('object_id', $boardIds)
238 268 ->exists();
239 269 }
240 270
271 + /**
272 + * Check WordPress or Boards admin access, caching by the resolved user ID.
273 + */
241 274 public static function isAdmin($userId = null, $useCache = true)
242 275 {
243 276
244 277 static $cache = [];
245 278
246 - 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])) {
247 288 return $cache[$userId];
248 289 }
249 290
250 291 /*
@@ -254,19 +295,8 @@
254 295 * if user is WordPress admin then we will allow him
255 296 * if user is FluentBoard admin then we will allow him
256 297 */
257 298
258 - if (!$userId) {
259 - $userId = get_current_user_id();
260 - if (!$userId) {
261 - return false;
262 - }
263 - }
264 -
265 - if (!$userId) {
266 - return false;
267 - }
268 -
269 299 if (user_can($userId, 'manage_options')) { // WordPress Administrator
270 300
271 301 $cache[$userId] = true;
272 302
@@ -413,8 +443,12 @@
413 443 // Deny access if the user is a viewer only and trying to modify data
414 444 return !($boardPermissions->settings['is_viewer_only'] ?? false);
415 445 }
416 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 + */
417 451 public static function userHasBoardCreationPermission($userId = null)
418 452 {
419 453 if (!$userId) {
420 454 $userId = get_current_user_id();
@@ -428,10 +462,20 @@
428 462 }
429 463
430 464 // Check if "allow members to create boards" setting is enabled
431 465 $generalSettings = fluent_boards_get_option('general_settings', []);
432 - if (!empty($generalSettings['allow_members_to_create_boards']) && $generalSettings['allow_members_to_create_boards'] !== 'false' && static::userHasAnyBoardAccess($userId)) {
433 - 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 + }
434 478 }
435 479
436 480 return apply_filters('fluent_boards/can_create_board', false, $userId);
437 481 }