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 +181 -18 1.20 → 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
@@ -139,15 +139,17 @@
139 139 return false;
140 140 }
141 141 }
142 142
143 + // if boardId is not provided then we will return false
144 + if (!$boardId) {
145 + return false;
146 + }
147 +
143 148 if (static::isAdmin($userId)) {
144 149 return true; // if task some admin we will allow him.
145 150 }
146 151
147 - if (!$boardId) {
148 - return false;
149 - }
150 152
151 153 /* now, if user is board admin or board member then will allow him */
152 154 return Relation::where('object_id', $boardId)
153 155 ->where('foreign_id', $userId)
@@ -154,8 +156,38 @@
154 156 ->where('object_type', Constant::OBJECT_TYPE_BOARD_USER)
155 157 ->exists();
156 158 }
157 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 +
158 190 public static function isFluentBoardsAdmin($userId = null): bool
159 191 {
160 192 if (!$userId) {
161 193 $userId = get_current_user_id();
@@ -198,14 +230,62 @@
198 230
199 231 return true;
200 232 }
201 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 + */
202 274 public static function isAdmin($userId = null, $useCache = true)
203 275 {
204 276
205 277 static $cache = [];
206 278
207 - 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])) {
208 288 return $cache[$userId];
209 289 }
210 290
211 291 /*
@@ -215,19 +295,8 @@
215 295 * if user is WordPress admin then we will allow him
216 296 * if user is FluentBoard admin then we will allow him
217 297 */
218 298
219 - if (!$userId) {
220 - $userId = get_current_user_id();
221 - if (!$userId) {
222 - return false;
223 - }
224 - }
225 -
226 - if (!$userId) {
227 - return false;
228 - }
229 -
230 299 if (user_can($userId, 'manage_options')) { // WordPress Administrator
231 300
232 301 $cache[$userId] = true;
233 302
@@ -244,9 +313,9 @@
244 313 }
245 314
246 315 /**
247 316 * Get array of board Ids for logged-in user
248 - * @param null $userId
317 + * @param int $userId
249 318 * @return array
250 319 */
251 320 public static function getBoardIdsForUser($userId = null, $boardId = null)
252 321 {
@@ -305,9 +374,9 @@
305 374 {
306 375 return !!is_user_logged_in();
307 376 }
308 377
309 - public static function getAll_WP_Admins($searchquery = '')
378 + public static function getAll_WP_Admins($searchquery = '', $number = null)
310 379 {
311 380 $args = array(
312 381 'role' => '',
313 382 'capability' => 'manage_options',
@@ -313,7 +382,101 @@
313 382 'capability' => 'manage_options',
314 383 'search' => '*' . $searchquery . '*',
315 384 );
316 385
386 + // Optionally bound the result set (e.g. for selector popovers) so an
387 + // empty search can't serialize every admin-capable user on large sites.
388 + if ($number !== null) {
389 + $args['number'] = (int) $number;
390 + }
391 +
317 392 return get_users($args);
393 + }
394 +
395 + public static function isWPAdmin($userId = null)
396 + {
397 + if (!$userId) {
398 + $userId = get_current_user_id();
399 + if (!$userId) {
400 + return false;
401 + }
402 + }
403 +
404 + return user_can($userId, 'manage_options');
405 + }
406 +
407 + public static function userHasBoardPermission($boardId, $requestMethod, $userId = null)
408 + {
409 + // Get the current user if no user ID is provided
410 + if (!$userId) {
411 + $userId = get_current_user_id();
412 + if (!$userId) {
413 + return false; // Return false if no user is logged in
414 + }
415 + }
416 +
417 + // Ensure the board ID is valid
418 + if (!$boardId) {
419 + return false; // Return false if no board ID is provided
420 + }
421 +
422 + // Admins have full permissions, allow access immediately
423 + if (static::isAdmin($userId)) {
424 + return true;
425 + }
426 +
427 + // Fetch user permissions for the given board
428 + $boardPermissions = Relation::where('object_id', $boardId)
429 + ->where('foreign_id', $userId)
430 + ->where('object_type', Constant::OBJECT_TYPE_BOARD_USER)
431 + ->first();
432 +
433 + // If no permissions are found, deny access
434 + if (!$boardPermissions) {
435 + return false;
436 + }
437 +
438 + // Allow read-only access for GET requests
439 + if ($requestMethod === 'GET') {
440 + return true;
441 + }
442 +
443 + // Deny access if the user is a viewer only and trying to modify data
444 + return !($boardPermissions->settings['is_viewer_only'] ?? false);
445 + }
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 + */
451 + public static function userHasBoardCreationPermission($userId = null)
452 + {
453 + if (!$userId) {
454 + $userId = get_current_user_id();
455 + if (!$userId) {
456 + return false;
457 + }
458 + }
459 +
460 + if (static::isAdmin($userId)) {
461 + return apply_filters('fluent_boards/can_create_board', true, $userId);
462 + }
463 +
464 + // Check if "allow members to create boards" setting is enabled
465 + $generalSettings = fluent_boards_get_option('general_settings', []);
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 + }
478 + }
479 +
480 + return apply_filters('fluent_boards/can_create_board', false, $userId);
318 481 }
319 482 }