From f1ac41900c90df5bfd4e0915e6734d4fc14f3e88 Mon Sep 17 00:00:00 2001 From: Bogdanova Olga Date: Sun, 28 Feb 2021 17:27:36 +0300 Subject: [PATCH 1/5] Issues-445: stay on the same page after watch/unwatch --- controllers/class.groupcontroller.php | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/controllers/class.groupcontroller.php b/controllers/class.groupcontroller.php index f0c933c..095395f 100644 --- a/controllers/class.groupcontroller.php +++ b/controllers/class.groupcontroller.php @@ -493,7 +493,13 @@ public function watch($GroupID) { $this->setData('Group', $Group); if ($this->Form->authenticatedPostBack(true)) { $this->GroupModel->watchGroup($Group, Gdn::session()->UserID); - $this->setRedirectTo('group/' . $GroupID); + // Stay in the previous page + if(isset($_SERVER['HTTP_REFERER'])) { + $previous = $_SERVER['HTTP_REFERER']; + $this->setRedirectTo($previous); + } else { + $this->setRedirectTo('group/'.$GroupID); + } } $this->render(); } @@ -512,7 +518,13 @@ public function unwatch($GroupID) { $this->setData('Group', $Group); if ($this->Form->authenticatedPostBack(true)) { $this->GroupModel->unwatchGroup($Group, Gdn::session()->UserID); - $this->setRedirectTo('group/'.$GroupID); + // Stay in the previous page + if(isset($_SERVER['HTTP_REFERER'])) { + $previous = $_SERVER['HTTP_REFERER']; + $this->setRedirectTo($previous); + } else { + $this->setRedirectTo('group/'.$GroupID); + } } $this->render(); } From 033229f766f92518c028ee62a70b66167248d2dc Mon Sep 17 00:00:00 2001 From: Bogdanova Olga Date: Sun, 28 Feb 2021 21:40:27 +0300 Subject: [PATCH 2/5] Remove App Title from email subject --- models/class.groupmodel.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/models/class.groupmodel.php b/models/class.groupmodel.php index 3ff5a4a..9d12d0c 100644 --- a/models/class.groupmodel.php +++ b/models/class.groupmodel.php @@ -1764,16 +1764,15 @@ public function sendInviteEmail($GroupID, $userID) { $session = Gdn::session(); $sender = Gdn::userModel()->getID($session->UserID); $user = Gdn::userModel()->getID($userID); - $appTitle = Gdn::config('Garden.Title'); $email = new Gdn_Email(); - $email->subject('['.$appTitle.'] '.$sender->Name.' invited you to '.$Group->Name); + $email->subject($sender->Name.' invited you to '.$Group->Name); $email->to($user->Email); $greeting = 'Hello!'; $message = $greeting.'
'. 'You can accept or decline this invitation.'; $emailTemplate = $email->getEmailTemplate() - ->setTitle('['.$appTitle.'] '.$sender->Name.' invited you to '.$Group->Name) + ->setTitle($sender->Name.' invited you to '.$Group->Name) ->setMessage($message) ->setButton(externalUrl('/group/accept/'.$Group->GroupID.'?userID='.$userID), 'Accept' ); From 0517e726c9c3136293f5ea8385740781fb55fef6 Mon Sep 17 00:00:00 2001 From: Bogdanova Olga Date: Sun, 28 Feb 2021 22:08:15 +0300 Subject: [PATCH 3/5] Issues-430:fixed an accept link --- models/class.groupmodel.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/class.groupmodel.php b/models/class.groupmodel.php index 9d12d0c..dc0ef42 100644 --- a/models/class.groupmodel.php +++ b/models/class.groupmodel.php @@ -1774,7 +1774,7 @@ public function sendInviteEmail($GroupID, $userID) { $emailTemplate = $email->getEmailTemplate() ->setTitle($sender->Name.' invited you to '.$Group->Name) ->setMessage($message) - ->setButton(externalUrl('/group/accept/'.$Group->GroupID.'?userID='.$userID), 'Accept' ); + ->setButton(externalUrl('/group/accept/'.$Group->GroupID.'/'.$userID), 'Accept' ); $email->setEmailTemplate($emailTemplate); From b40e39fdc77b9c5912693795c7b6d5eb8d18915e Mon Sep 17 00:00:00 2001 From: Bogdanova Olga Date: Tue, 2 Mar 2021 00:03:16 +0300 Subject: [PATCH 4/5] Issues-449 --- controllers/class.groupcontroller.php | 66 +++++++- models/class.groupinvitationmodel.php | 211 ++++++++++++++++++++++++++ models/class.groupmodel.php | 59 +------ structure.php | 16 ++ views/group/accept.php | 8 + views/group/invitation_sent.php | 11 +- 6 files changed, 304 insertions(+), 67 deletions(-) create mode 100644 models/class.groupinvitationmodel.php create mode 100644 views/group/accept.php diff --git a/controllers/class.groupcontroller.php b/controllers/class.groupcontroller.php index 095395f..d37894d 100644 --- a/controllers/class.groupcontroller.php +++ b/controllers/class.groupcontroller.php @@ -3,9 +3,13 @@ * Group controller */ +use Garden\Schema\Validation; +use Garden\Schema\ValidationException; +use Garden\Web\Exception\ClientException; use Vanilla\Message; use Cocur\Slugify\Slugify; + /** * Handles accessing & displaying a single group via /group endpoint. */ @@ -405,9 +409,27 @@ public function invite($GroupID) { if(GroupModel::isMemberOfGroup($user->UserID, $GroupID)) { $this->Form->addError('User is a member of "'.$Group->Name.'".'); } else { - $this->GroupModel->invite($GroupID, $user->UserID); - $this->informMessage('Invitation was sent.'); - $this->render('invitation_sent'); + $groupInvitation['GroupID'] = $GroupID; + $groupInvitation['InviteeUserID'] = $user->UserID; + $groupInvitationModel = new GroupInvitationModel(); + $result = $groupInvitationModel->save($groupInvitation); + if($result) { + $this->informMessage('Invitation was sent.'); + } else { + $validationErrors = $groupInvitationModel->validationResults(); + $validation = new Validation(); + foreach ($validationErrors as $field => $errors) { + foreach ($errors as $error) { + $validation->addError( + $field, + $error + ); + } + } + $this->Form->addError($validation->getMessage()); + $this->render(); + } + } } catch (\Exception $e) { $this->Form->addError('Error' . $e->getMessage()); @@ -535,11 +557,41 @@ public function unwatch($GroupID) { * @param $UserID * @throws Gdn_UserException */ - public function accept($GroupID, $UserID) { - if(!GroupModel::isMemberOfGroup($UserID, $GroupID) ) { - $this->GroupModel->accept($GroupID, $UserID); + public function accept($token ='') { + + if (!Gdn::session()->isValid()) { + redirectTo(signInUrl()); } - redirectTo(GroupsPlugin::GROUP_ROUTE.$GroupID); + + $groupInvitationModel = new GroupInvitationModel(); + + $result = $groupInvitationModel->validateToken($token); + $validationErrors = $groupInvitationModel->Validation->results(); + if (count($validationErrors) > 0) { + $validation = new Validation(); + foreach ($validationErrors as $field => $errors) { + foreach ($errors as $error) { + $validation->addError( + $field, + $error + ); + } + } + if ($validation->getErrorCount() > 0) { + $this->setData('ErrorMessage', $validation->getMessage()); + $this->render(); + } + } else { + if(!GroupModel::isMemberOfGroup($result['InviteeUserID'], $result['GroupID']) ) { + $GroupModel = new GroupModel(); + $GroupModel->join($result['GroupID'],$result['InviteeUserID']); + } + $result['Status'] = 'accepted'; + $result['DateAccepted'] = Gdn_Format::toDateTime(); + $groupInvitationModel->save($result); + redirectTo(GroupsPlugin::GROUP_ROUTE.$result['GroupID']); + } + } diff --git a/models/class.groupinvitationmodel.php b/models/class.groupinvitationmodel.php new file mode 100644 index 0000000..4535df5 --- /dev/null +++ b/models/class.groupinvitationmodel.php @@ -0,0 +1,211 @@ +SQL->from('GroupInvitation gi') + ->join('Group g', 'gi.GroupID = g.GroupID') + ->join('User ibyu', 'gi.InvitedByUserID = ibyu.UserID') + ->join('User iu', 'gi.InviteeUserID = iu.UserID', 'left') + ->select('gi.*') + ->select('g.Name', '','GroupName') + ->select('iu.UserID', '', 'InviteeUserID') + ->select('iu.Email', '', 'InviteeEmail') + ->select('iu.Name', '', 'InviteeName') + ->select('ibyu.UserID', '', 'InvitedByUserID') + ->select('ibyu.Email', '', 'InvitedByEmail') + ->select('ibyu.Name', '', 'InvitedByName') + ->where('gi.GroupInvitationID', $groupInvitationID) + ->get(); + return $dataSet->firstRow(); + } + + + private function generateToken(){ + $strongResult = true; + // Returns the generated string of bytes on success, or false on failure + $randomString = openssl_random_pseudo_bytes(16, $strongResult); + if($randomString === false) { + throw new Exception('Couldn\'t generate a random string'); + } + + return bin2hex($randomString); + } + + /** + * + * + * @param array $formPostValues + * @param array|bool $settings + * @throws Exception + * @return bool|array + */ + public function save($formPostValues, $settings = false) { + $sendEmail = val('SendEmail', $settings, true); + $returnRow = val('ReturnRow', $settings, false); + $insert = $formPostValues['GroupInvitationID'] > 0? false: true; + + // Define the primary key in this model's table. + $this->defineSchema(); + + if($insert) { + $formPostValues['InvitedByUserID'] = Gdn::session()->UserID; + $formPostValues['Token'] = self::generateToken(); + + $expires = strtotime(c('Plugins.Groups.InviteExpiration', '+1 day')); + $formPostValues['DateExpires'] = Gdn_Format::toDateTime($expires); + $formPostValues['Status'] = 'pending'; + // Make sure required db fields are present. + $this->addInsertFields($formPostValues); + } else { + $this->addUpdateFields($formPostValues); + } + + if(!$insert) { + $invitationID = $this->update(['Status' => $formPostValues['Status'], 'DateAccepted' => $formPostValues['DateAccepted']], ['GroupInvitationID' => $formPostValues['GroupInvitationID']] ); + return $invitationID; + } + + // Validate the form posted values + if ($this->validate($formPostValues, $insert) === true) { + $groupModel = new GroupModel(); + // Make sure this user has permissions + $hasPermission = $groupModel->canInviteNewMember($formPostValues['GroupID']); + if (!$hasPermission) { + $this->Validation->addValidationResult('GroupID', 'You do not have permissions to invite new members.'); + return false; + } + + $now = Gdn_Format::toDateTime(); + $testData = $this->getWhere(['InviteeUserID' => $formPostValues['InviteeUserID'], 'GroupID' => $formPostValues['GroupID'], + 'Status' => 'pending', 'DateExpires >=' => $now])->result(DATASET_TYPE_ARRAY); + if (count($testData)> 0) { + // Check status + $this->Validation->addValidationResult('InviteeUserID', 'An invitation has already been sent to this user.'); + return false; + } + + // Call the base model for saving + $invitationID = parent::save($formPostValues); + + // And send the invitation email + if ($sendEmail) { + try { + $this->send($invitationID); + } catch (Exception $ex) { + $this->Validation->addValidationResult('Email', sprintf(t('Although the group invitation was created successfully, the email failed to send. The server reported the following error: %s'), strip_tags($ex->getMessage()))); + return false; + } + } + + if ($returnRow) { + return (array)$this->getByGroupInvitationID($invitationID); + } else { + return true; + } + } + return false; + } + + + + /** + * Send Group Invitation by Email + * + * @param $groupInvitationID + * @throws Exception + */ + public function send($groupInvitationID) { + $invitation = $this->getByGroupInvitationID($groupInvitationID); + $email = new Gdn_Email(); + $email->subject($invitation->InvitedByName.' invited you to '.$invitation->GroupName); + $email->to($invitation->InviteeEmail); + $greeting = 'Hello!'; + $message = $greeting.'
'. + 'You can accept or decline this invitation.'; + + $emailTemplate = $email->getEmailTemplate() + ->setTitle($invitation->InvitedByName.' invited you to '.$invitation->GroupName) + ->setMessage($message) + ->setButton(externalUrl('/group/accept/'.$invitation->Token), 'Accept' ); + $email->setEmailTemplate($emailTemplate); + + try { + $email->send(); + } catch (Exception $e) { + if (debug()) { + throw $e; + } + } + } + + /** + * Validate token + * @param $token + * @param bool $returnData + * @return array|bool|stdClass + */ + public function validateToken($token, $returnData = true){ + if(empty($token)){ + $this->Validation->addValidationResult('Token', 'Invalid token'); + return false; + } + $userID = Gdn::session()->UserID; + // One row only, token is unique + $testData = $this->getWhere(['Token' => $token])->firstRow(DATASET_TYPE_ARRAY); + if ($testData) { + if($testData['InviteeUserID'] != $userID) { + $this->Validation->addValidationResult('Token', 'Invalid token'); + return false; + } + $now = Gdn_Format::toDateTime(); + if($now > $testData['DateExpires']) { + $this->Validation->addValidationResult('Token', 'Your token has expired.'); + return false; + } + + if($returnData) { + return $testData; + } else { + return true; + } + + } else { + $this->Validation->addValidationResult('Token', 'Invalid token.'); + } + return false; + } + + /** + * {@inheritdoc} + */ + public function delete($where = [], $options = []) { + throw new Exception("Not supported"); + } + + /** + * {@inheritdoc} + */ + public function deleteID($id, $options = []) { + throw new Exception("Not supported"); + } +} \ No newline at end of file diff --git a/models/class.groupmodel.php b/models/class.groupmodel.php index dc0ef42..ca9e6c8 100644 --- a/models/class.groupmodel.php +++ b/models/class.groupmodel.php @@ -861,27 +861,6 @@ public function join($GroupID, $UserID, $watched = true, $followed = true ){ $discussionModel = new DiscussionModel(); $discussionModel->updateUserDiscussionCount($UserID, false); } - - /** - * Invite a new member - * @param $GroupID - * @param $UserID - * @return bool|Gdn_DataSet|object|string - */ - public function invite($GroupID, $UserID){ - $this->sendInviteEmail($GroupID, $UserID); - } - - /** - * Accept an invitation - * @param $GroupID - * @param $UserID - * @return bool|Gdn_DataSet|object|string - */ - public function accept($groupID, $userID){ - $this->join($groupID, $userID); - } - /** * Return true if user is a member of the group * @param $userID @@ -1503,6 +1482,10 @@ public function canManageMembers($group) { * */ public function canInviteNewMember($group) { + if(is_numeric($group) && $group > 0) { + $group = $this->getByGroupID($group); + } + if((int)$group->Archived === 1) { return false; } @@ -1753,40 +1736,6 @@ public function canDeleteDiscussion($discussion) { return false; } - /** - * Send invite email. - * - * @param int $userID - * @param string $password - */ - public function sendInviteEmail($GroupID, $userID) { - $Group = $this->getByGroupID($GroupID); - $session = Gdn::session(); - $sender = Gdn::userModel()->getID($session->UserID); - $user = Gdn::userModel()->getID($userID); - $email = new Gdn_Email(); - $email->subject($sender->Name.' invited you to '.$Group->Name); - $email->to($user->Email); - $greeting = 'Hello!'; - $message = $greeting.'
'. - 'You can accept or decline this invitation.'; - - $emailTemplate = $email->getEmailTemplate() - ->setTitle($sender->Name.' invited you to '.$Group->Name) - ->setMessage($message) - ->setButton(externalUrl('/group/accept/'.$Group->GroupID.'/'.$userID), 'Accept' ); - - $email->setEmailTemplate($emailTemplate); - - try { - $email->send(); - } catch (Exception $e) { - if (debug()) { - throw $e; - } - } - } - public function notifyNewGroup($groupID, $groupName) { $activityModel = Gdn::getContainer()->get(ActivityModel::class); $data = [ diff --git a/structure.php b/structure.php index a154de9..1dd4e1d 100644 --- a/structure.php +++ b/structure.php @@ -179,3 +179,19 @@ Gdn::structure()->table('Group') ->column('Archived', 'tinyint(1)', '0'); } + +// FIX: https://github.com/topcoder-platform/forums/issues/449 +if(!Gdn::structure()->tableExists('GroupInvitation')) { + // Group Invitation Table + Gdn::structure()->table('GroupInvitation') + ->primaryKey('GroupInvitationID') + ->column('GroupID', 'int', false, 'index') + ->column('Token', 'varchar(32)', false, 'unique') + ->column('InvitedByUserID', 'int', false, 'index') + ->column('InviteeUserID', 'int', false, 'index') + ->column('DateInserted', 'datetime', false, 'index') + ->column('Status', ['pending', 'accepted', 'declined', 'deleted']) + ->column('DateAccepted', 'datetime', true) + ->column('DateExpires', 'datetime') + ->set(false, false); +} \ No newline at end of file diff --git a/views/group/accept.php b/views/group/accept.php new file mode 100644 index 0000000..6c953fa --- /dev/null +++ b/views/group/accept.php @@ -0,0 +1,8 @@ + +

+data('ErrorMessage'); +?> +
  • '.$error.'
'; + ?> diff --git a/views/group/invitation_sent.php b/views/group/invitation_sent.php index af86296..c85884c 100644 --- a/views/group/invitation_sent.php +++ b/views/group/invitation_sent.php @@ -1,7 +1,8 @@

-
- Invitation was sent.
'; - ?> - \ No newline at end of file +data('ErrorMessage'); +?> +
  • '.$error.'
'; +?> From 9c4cd59c0e34abc35abc7a94ac96977b64a853d8 Mon Sep 17 00:00:00 2001 From: Bogdanova Olga Date: Tue, 2 Mar 2021 23:28:31 +0300 Subject: [PATCH 5/5] Issues-444: fixed announcements and reviewed group permissions --- class.groups.plugin.php | 15 -- controllers/class.groupcontroller.php | 129 +--------------- models/class.groupmodel.php | 213 +++++++++----------------- views/group/index.php | 4 +- 4 files changed, 78 insertions(+), 283 deletions(-) diff --git a/class.groups.plugin.php b/class.groups.plugin.php index 5716f22..9786bd6 100644 --- a/class.groups.plugin.php +++ b/class.groups.plugin.php @@ -272,18 +272,6 @@ public function discussionController_render_before($sender, $args) { } - public function base_BeforeCommentForm_handler($sender, $args) { - if($sender instanceof DiscussionController && $sender->Form->Action === '/post/comment/') { - $categoryID = $sender->data('Discussion.CategoryID'); - $groupID = $sender->data('Discussion.GroupID'); - $groupModel = new GroupModel(); - if(!$groupModel->canAddComment($categoryID, $groupID)) { - $cssClass = &$args['FormCssClass']; - $cssClass = 'hidden'; - } - } - } - /** * The '...' discussion dropdown options */ @@ -295,8 +283,6 @@ public function base_discussionOptionsDropdown_handler($sender, $args){ $data = $sender->Data; // $currentTopcoderProjectRoles = val('ChallengeCurrentUserProjectRoles', $data, []); $groupModel = new GroupModel(); - // $groupModel->setCurrentUserTopcoderProjectRoles($currentTopcoderProjectRoles); - $canView = $groupModel->canViewDiscussion($Discussion); $canEdit = $groupModel->canEditDiscussion($Discussion); $canDelete = $groupModel->canDeleteDiscussion($Discussion); $canDismiss = $groupModel->canDismissDiscussion($Discussion); @@ -343,7 +329,6 @@ public function base_discussionOptionsDropdown_handler($sender, $args){ } self::log('discussionController_discussionOptionsDropdown_handler', ['Discussion' => $Discussion->DiscussionID, - 'currentUserTopcoderProjectRoles' =>$currentTopcoderProjectRoles, 'canView' => $canView, 'canDelete' => $canDelete, 'canEdit' => $canEdit, 'canDismiss' => $canDismiss, 'canAnnounce' =>$canAnnounce, 'canSink' => $canSink, 'canMove' => $canMove, 'canReFetch' => $canRefetch ]); } diff --git a/controllers/class.groupcontroller.php b/controllers/class.groupcontroller.php index d37894d..17f3a37 100644 --- a/controllers/class.groupcontroller.php +++ b/controllers/class.groupcontroller.php @@ -112,6 +112,7 @@ public function index($GroupID = '') { } } + $this->setData('DefaultAnnouncementUrl', $defaultDiscussionUrl.'?announce=1'); $this->setData('DefaultDiscussionUrl', $defaultDiscussionUrl); // Find all discussions with content from after DateMarkedRead. @@ -732,134 +733,6 @@ public function discussions($GroupID='',$Page = false) { } - /** - * Create a new announcement - * @param string $GroupID - * @throws Gdn_UserException - */ - public function announcement($GroupID=''){ - - $Group = $this->findGroup($GroupID); - - if(!$this->GroupModel->canAddAnnouncement($Group)) { - throw permissionException(); - } - - $this->setData('Breadcrumbs', - [['Name' => t('Challenge Discussions'), 'Url' => GroupsPlugin::GROUPS_ROUTE], - ['Name' => $Group->Name, 'Url' => GroupsPlugin::GROUP_ROUTE.$Group->GroupID], ['Name' => t('New Announcement')]]); - $this->title('New Announcement'); - $this->setDiscussionData($Group, 2); - $this->View = 'discussion'; - $this->render(); - } - - /** - * Create a new discussion - * @param string $GroupID - * @throws Gdn_UserException - */ - public function discussion($GroupID=''){ - $Group = $this->findGroup($GroupID); - - if(!$this->GroupModel->canAddDiscussion($Group)) { - throw permissionException(); - } - - $this->setData('Breadcrumbs', [['Name' => t('Challenge Discussions'), 'Url' => GroupsPlugin::GROUPS_ROUTE], - ['Name' => $Group->Name, 'Url' => GroupsPlugin::GROUP_ROUTE.$Group->GroupID], ['Name' => t('New Discussion')]]); - $this->title('New Discussion'); - $this->setDiscussionData($Group, 1); - $this->View = 'discussion'; - $this->render(); - - } - - /** - * Create a discussion. - * @param int $categoryID Unique ID of the category to add the discussion to. - */ - public function setDiscussionData($Group,$Announce = '0') { - $categoryUrlCode =$Group->ChallengeID;//.'-questions'; - $useCategories = true; - - // Setup head - $this->addJsFile('jquery.autosize.min.js'); - $this->addJsFile('autosave.js'); - $this->addJsFile('post.js'); - - $session = Gdn::session(); - - Gdn_Theme::section('PostDiscussion'); - - // Set discussion, draft, and category data - $discussionID = isset($this->Discussion) ? $this->Discussion->DiscussionID : ''; - $draftID = isset($this->Draft) ? $this->Draft->DraftID : 0; - $category = false; - $categoryModel = new CategoryModel(); - $category = CategoryModel::categories($categoryUrlCode); - if ($category) { - $this->CategoryID = val('CategoryID', $category); - } - - if ($category) { - $this->Category = (object)$category; - $this->setData('Category', $category); - $this->Form->addHidden('CategoryID', $this->Category->CategoryID); - } - - $categoryData = $this->ShowCategorySelector ? CategoryModel::categories() : false; - if (!$useCategories || $this->ShowCategorySelector) { - // See if we should fill the CategoryID value. - $allowedCategories = CategoryModel::getByPermission( - 'Discussions.Add', - $this->Form->getValue('CategoryID', $this->CategoryID), - ['Archived' => 0, 'AllowDiscussions' => 1], - ['AllowedDiscussionTypes' => $this->Data['Type']] - ); - $allowedCategoriesCount = count($allowedCategories); - - if ($this->ShowCategorySelector && $allowedCategoriesCount === 1) { - $this->ShowCategorySelector = false; - } - - if (!$this->ShowCategorySelector && $allowedCategoriesCount) { - $allowedCategory = array_pop($allowedCategories); - $this->Form->addHidden('CategoryID', $allowedCategory['CategoryID']); - - if ($this->Form->isPostBack() && !$this->Form->getFormValue('CategoryID')) { - $this->Form->setFormValue('CategoryID', $allowedCategory['CategoryID']); - } - } - } - - // Set the model on the form - $DiscussionModel = new DiscussionModel(); - $this->Form->setModel($DiscussionModel); - $this->Form->addHidden('GroupID', $Group->GroupID); - $this->Form->Action = '/post/discussion'; - $this->Form->setFormValue('Announce', $Announce); - $this->setData('Group', $Group); - $this->setData('Announce', $Announce); - $this->setData('_AnnounceOptions', $this->announceOptions()); - - $this->fireEvent('BeforeDiscussionRender'); - - if ($this->CategoryID) { - $breadcrumbs = CategoryModel::getAncestors($this->CategoryID); - } else { - $breadcrumbs = []; - } - - $breadcrumbs[] = [ - 'Name' => $this->data('Title'), - 'Url' => val('AddUrl', val($this->data('Type'), DiscussionModel::discussionTypes()), '/post/discussion') - ]; - - $this->setData('Breadcrumbs', $breadcrumbs); - - } - /** * Join a group * @param $GroupID diff --git a/models/class.groupmodel.php b/models/class.groupmodel.php index ca9e6c8..518bd3e 100644 --- a/models/class.groupmodel.php +++ b/models/class.groupmodel.php @@ -1499,49 +1499,38 @@ public function canInviteNewMember($group) { } /** - * Check add group discusion permission + * Check add group discussion permission * */ public function canAddDiscussion($group) { if((int)$group->Archived === 1) { return false; } - $groupRole = self::getGroupRoleFor(Gdn::session()->UserID, $group->GroupID); - if($groupRole || Gdn::session()->UserID == $group->OwnerID) { - return true; + + $categoryIDs = $this->getAllGroupCategoryIDs($group->GroupID); + foreach($categoryIDs as $categoryID) { + if (CategoryModel::checkPermission($categoryID, ['Vanilla.Discussions.Add'])) { + return true; + } } + return false; } /** - * Check add group announcement permission + * Check add group announcement permission * */ - public function canAddAnnouncement($group) { + public function canAddNewAnnouncement($group) { if((int)$group->Archived === 1) { return false; } - $groupRole = self::getGroupRoleFor(Gdn::session()->UserID, $group->GroupID); - if($groupRole === GroupModel::ROLE_LEADER || Gdn::session()->UserID === $group->OwnerID - || $this->isProjectCopilot() || $this->isProjectManager()) { - return true; - } - return false; - } - - /** - * Check view group discusion permission - * - */ - public function canViewDiscussion($discussion) { - $groupID = $this->findGroupIDFromDiscussion($discussion); - if(!$groupID) { - return true; - } - $groupRole = self::getGroupRoleFor(Gdn::session()->UserID, $groupID); - if($groupRole || Gdn::session()->checkPermission(GroupsPlugin::GROUPS_MODERATION_MANAGE_PERMISSION)) { - return true; + $categoryIDs = $this->getAllGroupCategoryIDs($group->GroupID); + foreach($categoryIDs as $categoryID) { + if (CategoryModel::checkPermission($categoryID, ['Vanilla.Discussions.Announce', 'Vanilla.Discussions.Add'])) { + return true; + } } return false; } @@ -1553,17 +1542,11 @@ public function canViewDiscussion($discussion) { public function canEditDiscussion($discussion) { $canEditDiscussion = DiscussionModel::canEdit($discussion) ; $groupID= $this->findGroupIDFromDiscussion($discussion); - if(!$groupID) { - return $canEditDiscussion; - } - - $groupRole = self::getGroupRoleFor(Gdn::session()->UserID, $groupID); - - if(($groupRole && $discussion->InsertUserID == Gdn::session()->UserID) - || Gdn::session()->checkPermission(GroupsPlugin::GROUPS_MODERATION_MANAGE_PERMISSION)) { + if($groupID && Gdn::session()->checkPermission(GroupsPlugin::GROUPS_MODERATION_MANAGE_PERMISSION)) { return true; } - return false; + + return $canEditDiscussion; } /** @@ -1576,99 +1559,55 @@ public function canDismissDiscussion($discussion) { && !$discussion->Dismissed && Gdn::session()->isValid(); - $groupID= $this->findGroupIDFromDiscussion($discussion); - if(!$groupID ) { - return $canDismissDiscussion; - } - - if($canDismissDiscussion === false) { - return $canDismissDiscussion; - } - - $group = $this->getByGroupID($groupID); - $groupRole = self::getGroupRoleFor(Gdn::session()->UserID, $groupID); - if($groupRole === GroupModel::ROLE_LEADER || Gdn::session()->UserID === $group->OwnerID || - $this->isProjectCopilot() || $this->isProjectManager() || - Gdn::session()->checkPermission(GroupsPlugin::GROUPS_MODERATION_MANAGE_PERMISSION)) { - return true; + $groupID = $this->findGroupIDFromDiscussion($discussion); + if($groupID) { + $group = $this->getByGroupID($groupID); + $groupRole = self::getGroupRoleFor(Gdn::session()->UserID, $groupID); + if ($groupRole === GroupModel::ROLE_LEADER || Gdn::session()->UserID === $group->OwnerID || + Gdn::session()->checkPermission(GroupsPlugin::GROUPS_MODERATION_MANAGE_PERMISSION)) { + return true; + } } - return false; + return $canDismissDiscussion; } /** - * Check announce group discusion permission + * Check announce group discussion permission * */ public function canAnnounceDiscussion($discussion) { - $canAnnounceDiscussion = CategoryModel::checkPermission($discussion->CategoryID, 'Vanilla.Discussions.Announce', true); + $canAnnounceDiscussion = CategoryModel::checkPermission($discussion->CategoryID, 'Vanilla.Discussions.Announce'); $groupID = $this->findGroupIDFromDiscussion($discussion); - if(!$groupID ) { - return $canAnnounceDiscussion; - } - - if($canAnnounceDiscussion === false) { - return $canAnnounceDiscussion; - } - - $group = $this->getByGroupID($groupID); - $groupRole = self::getGroupRoleFor(Gdn::session()->UserID, $groupID); - if($groupRole === GroupModel::ROLE_LEADER || - Gdn::session()->UserID === $group->OwnerID || - $this->isProjectCopilot() || $this->isProjectManager() || - Gdn::session()->checkPermission(GroupsPlugin::GROUPS_MODERATION_MANAGE_PERMISSION)) { - return true; - } - return false; - } - - /** - * Check announce group discusion permission - * - */ - public function canAddComment($categoryID, $groupID) { - $canAddComment = CategoryModel::checkPermission($categoryID, 'Vanilla.Comments.Add', true); - if(!$groupID ) { - return $canAddComment; - } - - if($canAddComment === false) { - return $canAddComment; - } - - $group = $this->getByGroupID($groupID); - $groupRole = self::getGroupRoleFor(Gdn::session()->UserID, $groupID); - if($groupRole || Gdn::session()->UserID === $group->OwnerID - || Gdn::session()->checkPermission(GroupsPlugin::GROUPS_MODERATION_MANAGE_PERMISSION)) { - return true; + if($groupID) { + $group = $this->getByGroupID($groupID); + $groupRole = self::getGroupRoleFor(Gdn::session()->UserID, $groupID); + if ($groupRole === GroupModel::ROLE_LEADER || Gdn::session()->UserID === $group->OwnerID || + Gdn::session()->checkPermission(GroupsPlugin::GROUPS_MODERATION_MANAGE_PERMISSION)) { + return true; + } } - return false; + return $canAnnounceDiscussion; } /** - * Check sink group discusion permission + * Check sink group discussion permission * */ public function canSinkDiscussion($discussion) { - $canSinkDiscussion = CategoryModel::checkPermission($discussion->CategoryID, 'Vanilla.Discussions.Sink', true); + $canSinkDiscussion = CategoryModel::checkPermission($discussion->CategoryID, 'Vanilla.Discussions.Sink'); $groupID = $this->findGroupIDFromDiscussion($discussion); - if(!$groupID ) { - return $canSinkDiscussion; - } - - if($canSinkDiscussion === false) { - return $canSinkDiscussion; + if($groupID) { + $group = $this->getByGroupID($groupID); + $groupRole = self::getGroupRoleFor(Gdn::session()->UserID, $groupID); + if ($groupRole === GroupModel::ROLE_LEADER || + Gdn::session()->UserID === $group->OwnerID || + Gdn::session()->checkPermission(GroupsPlugin::GROUPS_MODERATION_MANAGE_PERMISSION)) { + return true; + } } - $group = $this->getByGroupID($groupID); - $groupRole = self::getGroupRoleFor(Gdn::session()->UserID, $groupID); - if($groupRole === GroupModel::ROLE_LEADER || - Gdn::session()->UserID === $group->OwnerID || - $this->isProjectCopilot() || $this->isProjectManager() || - Gdn::session()->checkPermission(GroupsPlugin::GROUPS_MODERATION_MANAGE_PERMISSION)) { - return true; - } - return false; + return $canSinkDiscussion; } /** @@ -1676,25 +1615,18 @@ public function canSinkDiscussion($discussion) { * */ public function canCloseDiscussion($discussion) { - $canCloseDiscussion = CategoryModel::checkPermission($discussion->CategoryID, 'Vanilla.Discussions.Close', true); + $canCloseDiscussion = CategoryModel::checkPermission($discussion->CategoryID, 'Vanilla.Discussions.Close'); $groupID = $this->findGroupIDFromDiscussion($discussion); - if(!$groupID ) { - return $canCloseDiscussion; - } - - if($canCloseDiscussion === false) { - return $canCloseDiscussion; - } - - $group = $this->getByGroupID($groupID); - $groupRole = self::getGroupRoleFor(Gdn::session()->UserID, $groupID); - if($groupRole === GroupModel::ROLE_LEADER || - Gdn::session()->UserID === $group->OwnerID || - $this->isProjectCopilot() || $this->isProjectManager() || - Gdn::session()->checkPermission(GroupsPlugin::GROUPS_MODERATION_MANAGE_PERMISSION)) { - return true; + if($groupID) { + $group = $this->getByGroupID($groupID); + $groupRole = self::getGroupRoleFor(Gdn::session()->UserID, $groupID); + if ($groupRole === GroupModel::ROLE_LEADER || + Gdn::session()->UserID === $group->OwnerID || + Gdn::session()->checkPermission(GroupsPlugin::GROUPS_MODERATION_MANAGE_PERMISSION)) { + return true; + } } - return false; + return $canCloseDiscussion; } /** @@ -1702,7 +1634,8 @@ public function canCloseDiscussion($discussion) { * */ public function canMoveDiscussion($discussion) { - if ($this->canEditDiscussion($discussion) && Gdn::session()->checkPermission('Garden.Moderation.Manage')) { + if ($this->canEditDiscussion($discussion) && + Gdn::session()->checkPermission('Garden.Moderation.Manage')) { return true; } @@ -1719,21 +1652,25 @@ public function canMoveDiscussion($discussion) { } public function canRefetchDiscussion($discussion) { - return $this->canEditDiscussion($discussion); + return $this->canEditDiscussion($discussion) && valr('Attributes.ForeignUrl', $discussion) ; } + /** + * Check delete discussion permission + * @param $discussion + * @return bool + */ public function canDeleteDiscussion($discussion) { - $canDeleteDiscussion = CategoryModel::checkPermission($discussion->CategoryID, 'Vanilla.Discussions.Delete', true); + $canDeleteDiscussion = CategoryModel::checkPermission($discussion->CategoryID, 'Vanilla.Discussions.Delete'); + /* $groupID = $this->findGroupIDFromDiscussion($discussion); - if(!$groupID) { - return $canDeleteDiscussion; - } - - $group = $this->getByGroupID($groupID); - if($canDeleteDiscussion && Gdn::session()->UserID == $group->OwnerID) { - return true; - } - return false; + if($groupID) { + $group = $this->getByGroupID($groupID); + if (Gdn::session()->UserID == $group->OwnerID) { + return true; + } + }*/ + return $canDeleteDiscussion ; } public function notifyNewGroup($groupID, $groupName) { diff --git a/views/group/index.php b/views/group/index.php index 88f1e61..a076ae9 100644 --- a/views/group/index.php +++ b/views/group/index.php @@ -29,8 +29,8 @@
canAddAnnouncement($Group)) { - echo anchor('New Announcement', $this->data('DefaultDiscussionUrl'), 'Button Primary', ''); + if($groupModel->canAddNewAnnouncement($Group)) { + echo anchor('New Announcement', $this->data('DefaultAnnouncementUrl'), 'Button Primary', ''); } ?>