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 f0c933c..17f3a37 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.
*/
@@ -108,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.
@@ -405,9 +410,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());
@@ -493,7 +516,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 +541,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();
}
@@ -523,11 +558,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());
+ }
+
+ $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']);
}
- redirectTo(GroupsPlugin::GROUP_ROUTE.$GroupID);
+
}
@@ -668,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.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 3ff5a4a..518bd3e 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;
}
@@ -1516,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;
}
@@ -1570,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;
}
/**
@@ -1593,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;
}
/**
@@ -1693,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;
}
/**
@@ -1719,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;
}
@@ -1736,56 +1652,25 @@ public function canMoveDiscussion($discussion) {
}
public function canRefetchDiscussion($discussion) {
- return $this->canEditDiscussion($discussion);
- }
-
- public function canDeleteDiscussion($discussion) {
- $canDeleteDiscussion = CategoryModel::checkPermission($discussion->CategoryID, 'Vanilla.Discussions.Delete', true);
- $groupID = $this->findGroupIDFromDiscussion($discussion);
- if(!$groupID) {
- return $canDeleteDiscussion;
- }
-
- $group = $this->getByGroupID($groupID);
- if($canDeleteDiscussion && Gdn::session()->UserID == $group->OwnerID) {
- return true;
- }
- return false;
+ return $this->canEditDiscussion($discussion) && valr('Attributes.ForeignUrl', $discussion) ;
}
/**
- * Send invite email.
- *
- * @param int $userID
- * @param string $password
+ * Check delete discussion permission
+ * @param $discussion
+ * @return bool
*/
- public function sendInviteEmail($GroupID, $userID) {
- $Group = $this->getByGroupID($GroupID);
- $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->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)
- ->setMessage($message)
- ->setButton(externalUrl('/group/accept/'.$Group->GroupID.'?userID='.$userID), 'Accept' );
-
- $email->setEmailTemplate($emailTemplate);
-
- try {
- $email->send();
- } catch (Exception $e) {
- if (debug()) {
- throw $e;
+ public function canDeleteDiscussion($discussion) {
+ $canDeleteDiscussion = CategoryModel::checkPermission($discussion->CategoryID, 'Vanilla.Discussions.Delete');
+ /*
+ $groupID = $this->findGroupIDFromDiscussion($discussion);
+ if($groupID) {
+ $group = $this->getByGroupID($groupID);
+ if (Gdn::session()->UserID == $group->OwnerID) {
+ return true;
}
- }
+ }*/
+ return $canDeleteDiscussion ;
}
public function notifyNewGroup($groupID, $groupName) {
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 @@
+
+