Skip to content

Commit f1ad2bd

Browse files
authored
Merge pull request #343 from topcoder-platform/issues-311_2
Issues-342, Issues-301, get a list of category view permissions for any user
2 parents 4d3aa4f + 23bcb43 commit f1ad2bd

File tree

7 files changed

+959
-19
lines changed

7 files changed

+959
-19
lines changed

config/vanilla/bootstrap.before.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -364,17 +364,18 @@ function watchButton($categoryID) {
364364

365365
if (!function_exists('checkGroupPermission')) {
366366
/**
367-
* Check group permission for the current user
367+
* Check group permission for an user
368+
* @param $userID
368369
* @param $groupID
369-
* @param null $category
370+
* @param null $categoryID
370371
* @param null $permissionCategoryID
371372
* @param null $permission null - any permission for a group
372373
* @param bool $fullMatch
373374
* @return bool return true if user has a permission
374375
*/
375-
function checkGroupPermission($groupID, $category = null , $permissionCategoryID = null , $permission = null, $fullMatch = true) {
376+
function checkGroupPermission($userID,$groupID, $categoryID = null , $permissionCategoryID = null , $permission = null, $fullMatch = true) {
376377
$groupModel = new GroupModel();
377-
return $groupModel->checkPermission(Gdn::session()->UserID,$groupID, $category,$permissionCategoryID , $permission, $fullMatch);
378+
return $groupModel->checkPermission($userID,$groupID, $categoryID,$permissionCategoryID , $permission, $fullMatch);
378379
}
379380
}
380381

vanilla/applications/dashboard/models/class.permissionmodel.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1477,4 +1477,23 @@ public function getNamespaces() {
14771477
}
14781478

14791479

1480+
// Original: checkPermission from package/library/core/class.session.php works only with signed-in user
1481+
// In REST API, we need to check permissions for any user, not only current user
1482+
public static function checkPermission($allUserPermissions, $permission, $fullMatch = true, $junctionTable = '', $junctionID = '') {
1483+
if ($junctionID === 'any' || $junctionID === '' || empty($junctionTable) ||
1484+
c("Garden.Permissions.Disabled.{$junctionTable}")) {
1485+
$junctionID = null;
1486+
}
1487+
1488+
if (is_array($permission)) {
1489+
if ($fullMatch) {
1490+
return $allUserPermissions->hasAll($permission, $junctionID);
1491+
} else {
1492+
return $allUserPermissions->hasAny($permission, $junctionID);
1493+
}
1494+
} else {
1495+
return $allUserPermissions->has($permission, $junctionID);
1496+
}
1497+
}
1498+
14801499
}

vanilla/applications/vanilla/models/class.categorymodel.php

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -889,9 +889,16 @@ public static function filterCategoryPermissions($categoryIDs) {
889889
* @param int|array|object $category The category to check.
890890
* @param string|array $permission The permission(s) to check.
891891
* @param bool $fullMatch Whether or not the permission has to be a full match.
892+
* @param null $userID if userID is not set then the current user is used by default
892893
* @return bool Returns **true** if the current user has the permission or **false** otherwise.
893894
*/
894-
public static function checkPermission($category, $permission, $fullMatch = true) {
895+
public static function checkPermission($category, $permission, $fullMatch = true, $userID = null) {
896+
if(!$userID) {
897+
$userID = Gdn::session()->UserID;
898+
$userPermissions = Gdn::session()->getPermissions();
899+
} else {
900+
$userPermissions = Gdn::userModel()->getPermissions($userID);
901+
}
895902
if (is_numeric($category)) {
896903
$category = static::categories($category);
897904
}
@@ -906,10 +913,10 @@ public static function checkPermission($category, $permission, $fullMatch = true
906913
}
907914

908915
if($groupID && $groupID > 0) {
909-
$result = checkGroupPermission($groupID, $category, $permissionCategoryID, $permission, $fullMatch);
916+
$result = checkGroupPermission($userID, $groupID, $categoryID, $permissionCategoryID, $permission, $fullMatch);
910917
} else {
911-
$result = Gdn::session()->checkPermission($permission, $fullMatch, 'Category', $permissionCategoryID)
912-
|| Gdn::session()->checkPermission($permission, $fullMatch, 'Category', $categoryID);
918+
$result = PermissionModel::checkPermission($userPermissions,$permission, $fullMatch, 'Category', $permissionCategoryID)
919+
|| PermissionModel::checkPermission($userPermissions,$permission, $fullMatch, 'Category', $categoryID);
913920
}
914921

915922
return $result;

vanilla/applications/vanilla/models/class.discussionmodel.php

Lines changed: 75 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2575,7 +2575,7 @@ public function incrementNewDiscussion($discussion) {
25752575

25762576
/**
25772577
* Update a user's discussion count.
2578-
*
2578+
* FIX: https://github.com/topcoder-platform/forums/issues/301
25792579
* @param int $userID The user to calculate.
25802580
* @param bool $inc Whether to increment of recalculate from scratch.
25812581
*/
@@ -2596,16 +2596,85 @@ public function updateUserDiscussionCount($userID, $inc = false) {
25962596
}
25972597
}
25982598

2599-
$countDiscussions = $this->SQL
2600-
->select('DiscussionID', 'count', 'CountDiscussions')
2601-
->from('Discussion')
2602-
->where('InsertUserID', $userID)
2603-
->get()->value('CountDiscussions', 0);
2599+
// FIX: https://github.com/topcoder-platform/forums/issues/301
2600+
$discussionModel = new DiscussionModel();
2601+
$countDiscussions = $discussionModel->getMyDiscussionsCount($userID);
26042602

26052603
// Save the count to the user table
26062604
Gdn::userModel()->setField($userID, 'CountDiscussions', $countDiscussions);
26072605
}
26082606

2607+
// FIX: https://github.com/topcoder-platform/forums/issues/301
2608+
// Get all Category View Permissions for an user. This method works for any UserID.
2609+
// We can't use some Vanilla methods due to they are implemented for signed-in user only.
2610+
// return array|true arrays of CategoryIDs. or true if user has access to all categories
2611+
private function getCategoryPermissions($userID, $escape = false) {
2612+
$user = Gdn::userModel()->getID($userID);
2613+
$isAdmin = val('Admin', $user, false);
2614+
if ($isAdmin) {
2615+
$categoryPermissions = true;
2616+
} elseif (c('Garden.Permissions.Disabled.Category')) {
2617+
$categoryPermissions = true;
2618+
} else {
2619+
// Get Current Tree from cache
2620+
$categories = CategoryModel::categories();
2621+
2622+
// Clone it to avoid changing category tree for current user
2623+
$iDs = array_column($categories, 'CategoryID');
2624+
2625+
$categoryPermissions = [];
2626+
// Add User permissions.
2627+
foreach ($iDs as $cID) {
2628+
$hasViewPermission = CategoryModel::checkPermission($cID, 'Vanilla.Discussions.View', true, $userID);
2629+
if ($hasViewPermission) {
2630+
$categoryPermissions[] = ($escape ? '@' : '') . $cID;
2631+
}
2632+
}
2633+
2634+
// Check to see if the user has permission to all categories. This is for speed.
2635+
$categoryCount = count($categories);
2636+
if (count($categoryPermissions) == $categoryCount) {
2637+
$categoryPermissions = true;
2638+
}
2639+
}
2640+
return $categoryPermissions;
2641+
}
2642+
2643+
/**
2644+
* Calculate count of discussions (respecting user category (group) permissions).
2645+
* @param $userID
2646+
* @return array|int|mixed|string|null
2647+
*/
2648+
public function getMyDiscussionsCount($userID) {
2649+
// Get permissions.
2650+
$perms = $this->getCategoryPermissions($userID);
2651+
2652+
// No permissions
2653+
if (!$perms) {
2654+
return 0;
2655+
}
2656+
2657+
// We have permission to everything.
2658+
if ($perms === true) {
2659+
//default query
2660+
return Gdn::sql()
2661+
->select('DiscussionID', 'count', 'CountDiscussions')
2662+
->from('Discussion')
2663+
->where('InsertUserID', $userID)
2664+
->get()->value('CountDiscussions', 0);
2665+
}
2666+
2667+
return Gdn::sql()
2668+
->select('d.DiscussionID', 'count', 'CountDiscussions')
2669+
->from('Discussion d')
2670+
->join('Category c', 'd.CategoryID = c.CategoryID')
2671+
->where('c.CategoryID', $perms)
2672+
->where('d.InsertUserID', $userID)
2673+
->get()
2674+
->firstRow()
2675+
->CountDiscussions;
2676+
}
2677+
26092678
/**
26102679
* Update and get bookmark count for the specified user.
26112680
*

vanilla/applications/vanilla/views/categories/helper_functions.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
<?php if (!defined('APPLICATION')) exit();
1+
<?php use Vanilla\Formatting\DateTimeFormatter;
2+
3+
if (!defined('APPLICATION')) exit();
24

35
if (!function_exists('CategoryHeading')):
46

@@ -121,8 +123,9 @@ function mostRecentString($row) {
121123

122124
$r .= '<span class="MostRecentOn">';
123125
$r .= t('on').' ';
126+
$dateFormatted = Gdn::getContainer()->get(DateTimeFormatter::class)->formatDate($lastDate, false, DateTimeFormatter::FORCE_FULL_FORMAT);
124127
$r .= anchor(
125-
Gdn_Format::date( $lastDate, 'html'),
128+
$dateFormatted,
126129
$row['LastUrl'],
127130
'CommentDate');
128131
$r .= '</span>';

vanilla/applications/vanilla/views/discussions/helper_functions.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
<?php if (!defined('APPLICATION')) exit();
1+
<?php use Vanilla\Formatting\DateTimeFormatter;
2+
3+
if (!defined('APPLICATION')) exit();
24

35
if (!function_exists('AdminCheck')) {
46
/**
@@ -204,11 +206,13 @@ function writeDiscussion($discussion, $sender, $session) {
204206
$sender->fireEvent('AfterCountMeta');
205207

206208
if ($discussion->LastDiscussionCommentsUserID != '') {
209+
$dateFormatted = Gdn::getContainer()->get(DateTimeFormatter::class)->formatDate($lastDate, false, DateTimeFormatter::FORCE_FULL_FORMAT);
207210
echo ' <span class="MItem LastCommentBy">'.sprintf(t('Most recent by %1$s'), userAnchor($last)).'</span> ';
208-
echo ' <span class="MItem LastCommentDate">'.Gdn_Format::date($lastDate, 'html').'</span>';
211+
echo ' <span class="MItem LastCommentDate">'.$dateFormatted.'</span>';
209212
} else {
213+
$dateFormatted = Gdn::getContainer()->get(DateTimeFormatter::class)->formatDate($discussion->FirstDate, false, DateTimeFormatter::FORCE_FULL_FORMAT);
210214
echo ' <span class="MItem LastCommentBy">'.sprintf(t('Started by %1$s'), userAnchor($first)).'</span> ';
211-
echo ' <span class="MItem LastCommentDate">'.Gdn_Format::date($discussion->FirstDate, 'html');
215+
echo ' <span class="MItem LastCommentDate">'.$dateFormatted;
212216
if ($source = val('Source', $discussion)) {
213217
echo ' '.sprintf(t('via %s'), t($source.' Source', $source));
214218
}

0 commit comments

Comments
 (0)