Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions config/vanilla/bootstrap.before.php
Original file line number Diff line number Diff line change
Expand Up @@ -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];
}
Expand All @@ -393,5 +398,4 @@ function updateTopcoderRolePermissions($topcoderRoles) {
}
}
}

}
10 changes: 7 additions & 3 deletions config/vanilla/bootstrap.late.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
12 changes: 11 additions & 1 deletion config/vanilla/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -157,4 +157,14 @@
$Configuration['Garden']['EmailTemplate']['Image']='';
// Email Logo size
$Configuration['Garden']['EmailTemplate']['ImageMaxWidth']='400';
$Configuration['Garden']['EmailTemplate']['ImageMaxHeight']='300';
$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;
215 changes: 215 additions & 0 deletions vanilla/applications/conversations/settings/class.hooks.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
<?php
/**
* Hooks for Conversations.
*
* @copyright 2009-2019 Vanilla Forums Inc.
* @license GPL-2.0-only
* @package Conversations
* @since 2.0
*/

use Garden\Container\Container;
use Garden\Container\Reference;

/**
* Handles hooks into Dashboard and Vanilla.
*/
class ConversationsHooks implements Gdn_IPlugin {
/**
* Handle the container init event to register things with the container.
*
* @param Container $dic
*/
public function container_init(Container $dic) {
$dic->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 .= ' <span class="Aside"><span class="Count">'.$countUnread.'</span></span>';
}
$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 .= ' <span class="Alert">'.$countUnreadConversations.'</span>';
}

$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');
}
}
83 changes: 79 additions & 4 deletions vanilla/applications/dashboard/models/class.rolemodel.php
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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' => [
Expand All @@ -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'=> [],
Expand Down