diff --git a/config/vanilla/bootstrap.before.php b/config/vanilla/bootstrap.before.php
index 1030240..c97cc59 100644
--- a/config/vanilla/bootstrap.before.php
+++ b/config/vanilla/bootstrap.before.php
@@ -372,19 +372,24 @@ function checkGroupPermission($groupID,$permission = null, $fullMatch = true) {
}
}
-if(!function_exists('updateTopcoderRolePermissions')) {
+if(!function_exists('updateRolePermissions')) {
- function updateTopcoderRolePermissions($topcoderRoles) {
+ /**
+ * Update role permissions
+ * @param $roleType
+ * @param $roles
+ */
+ function updateRolePermissions($roleType, $roles) {
$RoleModel = new RoleModel();
$PermissionModel = new PermissionModel();
- // Configure default permission for Topcoder roles
- $allRoles = $RoleModel->getByType(RoleModel::TYPE_TOPCODER)->resultArray();
+ // Configure default permission for roles
+ $allRoles = $RoleModel->getByType($roleType)->resultArray();
foreach ($allRoles as $role) {
$allPermissions = $PermissionModel->getRolePermissions($role['RoleID']);
foreach ($allPermissions as $permission) {
$roleName = $role['Name'];
- if (array_key_exists($roleName, $topcoderRoles)) {
- $globalRolePermissions = $topcoderRoles[$roleName];
+ if (array_key_exists($roleName, $roles)) {
+ $globalRolePermissions = $roles[$roleName];
foreach ($globalRolePermissions as $key => $value) {
$permission[$key] = $globalRolePermissions[$key];
}
@@ -393,5 +398,4 @@ function updateTopcoderRolePermissions($topcoderRoles) {
}
}
}
-
}
diff --git a/config/vanilla/bootstrap.late.php b/config/vanilla/bootstrap.late.php
index e9dd08d..0460938 100644
--- a/config/vanilla/bootstrap.late.php
+++ b/config/vanilla/bootstrap.late.php
@@ -22,7 +22,11 @@
'Groups.EmailInvitations.Add',
'Groups.Group.Archive']);
- // TODO: need to be sure that all roles and permissions haven't be changed manually in prod/dev
- updateTopcoderRolePermissions(RoleModel::TOPCODER_ROLES);
- // updateTopcoderRolePermissions(RoleModel::TOPCODER_PROJECT_ROLES);
+ updateRolePermissions(RoleModel::TYPE_GUEST, RoleModel::VANILLA_GUEST_ROLES);
+
+ // TODO: Role permission might be configured manually in the env
+ // Before uncommenting the next lines:
+ // Check all roles in the env and update all role permissions in RoleModel
+ // updateRolePermissions(RoleModel::TYPE_TOPCODER, RoleModel::TOPCODER_ROLES);
+ // updateTopcoderRolePermissions(RoleModel::TYPE_TOPCODER,RoleModel::TOPCODER_PROJECT_ROLES);
}
diff --git a/config/vanilla/config.php b/config/vanilla/config.php
index 4bf87cd..370e1d2 100644
--- a/config/vanilla/config.php
+++ b/config/vanilla/config.php
@@ -157,4 +157,14 @@
$Configuration['Garden']['EmailTemplate']['Image']='';
// Email Logo size
$Configuration['Garden']['EmailTemplate']['ImageMaxWidth']='400';
-$Configuration['Garden']['EmailTemplate']['ImageMaxHeight']='300';
\ No newline at end of file
+$Configuration['Garden']['EmailTemplate']['ImageMaxHeight']='300';
+
+// Profile Configuration
+// Hide/Show the options in User Notification Preferences:
+// 'Email.WallComment' = 'Notify me when people write on my wall.'
+// 'Email.ActivityComment' = 'Notify me when people reply to my wall comments.'
+// 'Popup.WallComment' = 'Notify me when people write on my wall.'
+// 'Popup.ActivityComment' = 'Notify me when people reply to my wall comments.'
+// 'Email.ConversationMessage' = 'Notify me of private messages.'
+// 'Popup.ConversationMessage' = 'Notify me of private messages.'
+$Configuration['Garden']['Profile']['ShowActivities']=false;
diff --git a/vanilla/applications/conversations/settings/class.hooks.php b/vanilla/applications/conversations/settings/class.hooks.php
new file mode 100644
index 0000000..0138ed2
--- /dev/null
+++ b/vanilla/applications/conversations/settings/class.hooks.php
@@ -0,0 +1,215 @@
+rule(\Vanilla\Menu\CounterModel::class)
+ ->addCall('addProvider', [new Reference(ConversationCounterProvider::class)])
+ ;
+ }
+
+ /**
+ *
+ *
+ * @param DbaController $sender
+ */
+ public function dbaController_countJobs_handler($sender) {
+ $counts = [
+ 'Conversation' => ['CountMessages', 'CountParticipants', 'FirstMessageID', 'LastMessageID', 'DateUpdated', 'UpdateUserID']
+ ];
+
+ foreach ($counts as $table => $columns) {
+ foreach ($columns as $column) {
+ $name = "Recalculate $table.$column";
+ $url = "/dba/counts.json?".http_build_query(['table' => $table, 'column' => $column]);
+
+ $sender->Data['Jobs'][$name] = $url;
+ }
+ }
+ }
+
+ /**
+ * Remove data when deleting a user.
+ *
+ * @since 2.0.0
+ * @access public
+ */
+ public function userModel_beforeDeleteUser_handler($sender) {
+ $userID = val('UserID', $sender->EventArguments);
+ $options = val('Options', $sender->EventArguments, []);
+ $options = is_array($options) ? $options : [];
+
+ $deleteMethod = val('DeleteMethod', $options, 'delete');
+ if ($deleteMethod == 'delete') {
+ /** @var Gdn_SQLDriver $sql */
+ $sql = $sender->SQL;
+ $sql
+ ->from('UserConversation as uc')
+ ->join('Conversation as c', 'c.ConversationID = uc.ConversationID')
+ ->where(['c.InsertUserID' => $userID])
+ ->orWhere(['c.UpdateUserID' => $userID])
+ ->delete();
+ $sql
+ ->from('ConversationMessage as cm')
+ ->join('Conversation as c', 'c.ConversationID = cm.ConversationID')
+ ->where(['c.InsertUserID' => $userID])
+ ->orWhere(['c.UpdateUserID' => $userID])
+ ->delete();
+
+ $sender->SQL->delete('Conversation', ['InsertUserID' => $userID]);
+ $sender->SQL->delete('Conversation', ['UpdateUserID' => $userID]);
+ } elseif ($deleteMethod == 'wipe') {
+ $sender->SQL->update('ConversationMessage')
+ ->set('Body', t('The user and all related content has been deleted.'))
+ ->set('Format', 'Deleted')
+ ->where('InsertUserID', $userID)
+ ->put();
+ }
+ // Remove the user's profile information related to this application
+ $sender->SQL->update('User')
+ ->set('CountUnreadConversations', 0)
+ ->where('UserID', $userID)
+ ->put();
+ }
+
+ /**
+ * Add 'Inbox' to profile menu.
+ *
+ * @since 2.0.0
+ * @access public
+ */
+ public function profileController_addProfileTabs_handler($sender) {
+ if (Gdn::session()->isValid()) {
+ $inbox = t('Inbox');
+ $inboxHtml = sprite('SpInbox').' '.$inbox;
+ $inboxLink = '/messages/all';
+
+ if (Gdn::session()->UserID != $sender->User->UserID) {
+ // Accomodate admin access
+ if (c('Conversations.Moderation.Allow', false) && Gdn::session()->checkPermission('Conversations.Moderation.Manage')) {
+ $countUnread = $sender->User->CountUnreadConversations;
+ $inboxLink .= "?userid={$sender->User->UserID}";
+ } else {
+ return;
+ }
+ } else {
+ // Current user
+ $countUnread = Gdn::session()->User->CountUnreadConversations;
+ }
+
+ if (is_numeric($countUnread) && $countUnread > 0) {
+ $inboxHtml .= ' '.$countUnread.'';
+ }
+ $sender->addProfileTab($inbox, $inboxLink, 'Inbox', $inboxHtml);
+ }
+ }
+
+ /**
+ * Add "Message" option to profile options.
+ */
+ public function profileController_beforeProfileOptions_handler($sender, $args) {
+ if (!$sender->EditMode &&
+ Gdn::session()->UserID != $sender->User->UserID &&
+ Gdn::session()->checkPermission('Conversations.Conversations.Add')
+ ) {
+ $sender->EventArguments['MemberOptions'][] = [
+ 'Text' => sprite('SpMessage').' '.t('Message'),
+ 'Url' => '/messages/add/'.rawurlencode($sender->User->Name),
+ 'CssClass' => 'MessageUser'
+ ];
+ }
+ }
+
+
+ /**
+ * Additional options for the Preferences screen.
+ *
+ * @since 2.0.0
+ * @access public
+ */
+ public function profileController_afterPreferencesDefined_handler($sender) {
+ if (c('Garden.Profile.ShowActivities', true)) {
+ $sender->Preferences['Notifications']['Email.ConversationMessage'] = t('Notify me of private messages.');
+ $sender->Preferences['Notifications']['Popup.ConversationMessage'] = t('Notify me of private messages.');
+ }
+ }
+
+ /**
+ * Add 'Inbox' to global menu.
+ *
+ * @since 2.0.0
+ * @access public
+ */
+ public function base_render_before($sender) {
+ // Add the menu options for conversations
+ if ($sender->Menu && Gdn::session()->isValid()) {
+ $inbox = t('Inbox');
+ $countUnreadConversations = val('CountUnreadConversations', Gdn::session()->User);
+ if (is_numeric($countUnreadConversations) && $countUnreadConversations > 0) {
+ $inbox .= ' '.$countUnreadConversations.'';
+ }
+
+ $sender->Menu->addLink('Conversations', $inbox, '/messages/all', false, ['Standard' => true]);
+ }
+ }
+
+ /**
+ * Let us add Messages to the Inbox page.
+ */
+ public function base_afterGetLocationData_handler($sender, $args) {
+ $args['ControllerData']['Conversations/messages/inbox'] = t('Inbox Page');
+ }
+
+ /**
+ * Provide default permissions for roles, based on the value in their Type column.
+ *
+ * @param PermissionModel $sender Instance of permission model that fired the event
+ */
+ public function permissionModel_defaultPermissions_handler($sender) {
+ $sender->addDefault(
+ RoleModel::TYPE_MEMBER,
+ ['Conversations.Conversations.Add' => 1]
+ );
+ $sender->addDefault(
+ RoleModel::TYPE_MODERATOR,
+ ['Conversations.Conversations.Add' => 1]
+ );
+ $sender->addDefault(
+ RoleModel::TYPE_ADMINISTRATOR,
+ ['Conversations.Conversations.Add' => 1]
+ );
+ }
+
+ /**
+ * Database & config changes to be done upon enable.
+ *
+ * @since 2.0.0
+ * @access public
+ */
+ public function setup() {
+ $Database = Gdn::database();
+ $Config = Gdn::factory(Gdn::AliasConfig);
+ $Drop = false;
+ $Validation = new Gdn_Validation(); // This is going to be needed by structure.php to validate permission names
+ include(PATH_APPLICATIONS.DS.'conversations'.DS.'settings'.DS.'structure.php');
+ include(PATH_APPLICATIONS.DS.'conversations'.DS.'settings'.DS.'stub.php');
+ }
+}
diff --git a/vanilla/applications/dashboard/models/class.rolemodel.php b/vanilla/applications/dashboard/models/class.rolemodel.php
index 198e25e..d4e5e16 100644
--- a/vanilla/applications/dashboard/models/class.rolemodel.php
+++ b/vanilla/applications/dashboard/models/class.rolemodel.php
@@ -66,6 +66,7 @@ class RoleModel extends Gdn_Model {
'Groups.Category.Manage' => 1,
'Groups.Group.Delete' => 1,
'Groups.Group.Edit' => 1,
+ 'Groups.Group.Archive' => 1,
'Garden.Uploads.Add' => 1,
'Vanilla.Tagging.Add' => 1,
'Conversations.Moderation.Manage' => 1,
@@ -83,17 +84,82 @@ class RoleModel extends Gdn_Model {
'Vanilla.Comments.Edit' => 1,
'Vanilla.Comments.Delete' => 1,
'Plugins.Attachments.Upload.Allow' => 1,
- 'Groups.Group.Archive' => 1
+ ];
+
+ const GUEST_PERMISSIONS = [
+ 'Garden.Email.View' => 0,
+ 'Garden.Settings.Manage' => 0,
+ 'Garden.Settings.View' => 0,
+ 'Garden.SignIn.Allow' => 0,
+ 'Garden.Users.Add' => 0,
+ 'Garden.Users.Edit' => 0,
+ 'Garden.Users.Delete' => 0,
+ 'Garden.Users.Approve' => 0,
+ 'Garden.Activity.Delete' => 0,
+ 'Garden.Activity.View' => 0,
+ 'Garden.Profiles.View' => 0,
+ 'Garden.Profiles.Edit' => 0,
+ 'Garden.Curation.Manage' => 0,
+ 'Garden.Moderation.Manage' => 0,
+ 'Garden.PersonalInfo.View' => 0,
+ 'Garden.AdvancedNotifications.Allow' => 0,
+ 'Garden.Community.Manage' => 0,
+ 'Garden.Tokens.Add' => 0,
+ 'Groups.Group.Add' => 0,
+ 'Groups.Moderation.Manage' => 0,
+ 'Groups.EmailInvitations.Add' => 0,
+ 'Groups.Category.Manage' => 0,
+ 'Groups.Group.Delete' => 0,
+ 'Groups.Group.Edit' => 0,
+ 'Groups.Group.Archive' => 0,
+ 'Garden.Uploads.Add' => 0,
+ 'Vanilla.Tagging.Add' => 0,
+ 'Conversations.Moderation.Manage' => 0,
+ 'Conversations.Conversations.Add'=> 0,
+ 'Vanilla.Approval.Require' => 1, //
+ 'Vanilla.Comments.Me' => 0,
+ 'Vanilla.Discussions.View' => 0,
+ 'Vanilla.Discussions.Add' => 0,
+ 'Vanilla.Discussions.Edit' => 0,
+ 'Vanilla.Discussions.Announce' => 0,
+ 'Vanilla.Discussions.Sink' => 0,
+ 'Vanilla.Discussions.Close' => 0,
+ 'Vanilla.Discussions.Delete' => 0,
+ 'Vanilla.Comments.Add' => 0,
+ 'Vanilla.Comments.Edit' => 0,
+ 'Vanilla.Comments.Delete' => 0,
+ 'Plugins.Attachments.Upload.Allow' => 0
+ ];
+ const VANILLA_GUEST_ROLES = [
+ 'Guest' => self::GUEST_PERMISSIONS //The default Vanilla role for Guests
];
+
const TOPCODER_ROLES = [
'administrator' => self::ALL_VANILLA_PERMISSIONS,
- 'Connect Manager' => [],
+ 'Connect Manager' => [
+ 'Groups.Category.Manage' => 1,
+ ],
'Connect Account Manager' => [],
'Connect Copilot' => [
'Groups.Category.Manage' => 1,
'Groups.Moderation.Manage' => 1,
- 'Groups.EmailInvitations.Add' => 1
+ 'Groups.EmailInvitations.Add' => 1,
+ 'Groups.Category.Manage' => 1,
+ 'Groups.Moderation.Manage' => 1,
+ 'Groups.EmailInvitations.Add' => 1,
+ 'Garden.Uploads.Add' => 1,
+ 'Plugins.Attachments.Upload.Allow' => 1,
+ 'Vanilla.Discussions.View' => 1,
+ 'Vanilla.Discussions.Add' => 1,
+ 'Vanilla.Discussions.Edit' => 1,
+ 'Vanilla.Discussions.Announce' => 1,
+ 'Vanilla.Discussions.Sink' => 1,
+ 'Vanilla.Discussions.Close' => 0,
+ 'Vanilla.Discussions.Delete' => 1,
+ 'Vanilla.Comments.Add' => 1,
+ 'Vanilla.Comments.Edit' => 0,
+ 'Vanilla.Comments.Delete' => 1,
],
'Connect Admin' => self::ALL_VANILLA_PERMISSIONS,
'Connect Copilot Manager' => [
@@ -119,7 +185,16 @@ class RoleModel extends Gdn_Model {
'copilot' => [
'Groups.Category.Manage' => 1,
'Groups.Moderation.Manage' => 1,
- 'Groups.EmailInvitations.Add' => 1
+ 'Groups.EmailInvitations.Add' => 1,
+ 'Garden.Uploads.Add' => 1,
+ 'Plugins.Attachments.Upload.Allow' => 1,
+ 'Vanilla.Discussions.View' => 1,
+ 'Vanilla.Discussions.Add' => 1,
+ 'Vanilla.Discussions.Edit' => 1,
+ 'Vanilla.Discussions.Announce' => 1,
+ 'Vanilla.Discussions.Sink' => 0,
+ 'Vanilla.Discussions.Close' => 1,
+ 'Vanilla.Discussions.Delete' => 1,
],
'customer' => [],
'observer'=> [],