Commit 15c5fdff authored by Richard Mansfield's avatar Richard Mansfield
Browse files

Add groups with hidden membership (bug #845287)

Site & institutional admins & staff can check a 'hide membership'
checkbox on the edit group page.  Non-members cannot access the
membership lists of these groups, and when they view the group,
both the members block and members tab are hidden.  Site admins
and staff can still access the members page directly.

Also filters the my friends block by changing that block to use
group_get_user_groups rather than group_get_associated_groups.

See http://mahara.org/interaction/forum/topic.php?id=2229



Change-Id: Iaa907484c5d395cdf3869565fcf1c47c2faec733
Signed-off-by: default avatarRichard Mansfield <richard.mansfield@catalyst.net.nz>
parent 01d515c3
......@@ -52,6 +52,7 @@ $ALLOWEDKEYS = array(
'submitpages',
'editroles',
'hidden',
'hidemembers',
);
if ($USER->get('admin')) {
$ALLOWEDKEYS[] = 'usersautoadded';
......
......@@ -51,6 +51,10 @@ class PluginBlocktypeGroupMembers extends SystemBlocktype {
return array('grouphomepage');
}
public static function hide_title_on_empty_content() {
return true;
}
public static function render_instance (BlockInstance $instance, $editing = false) {
global $USER;
......@@ -61,6 +65,16 @@ class PluginBlocktypeGroupMembers extends SystemBlocktype {
$numtoshow = isset($configdata['numtoshow']) ? $configdata['numtoshow'] : $rows * $columns;
$groupid = $instance->get_view()->get('group');
// If the group has hidden membership, display nothing to non-members
$usergroups = $USER->get('grouproles');
if (!isset($usergroups[$groupid])) {
$group = defined('GROUP') && $groupid == GROUP ? group_current_group() : get_record('group', 'id', $groupid);
if ($group->hidemembers) {
return '';
}
}
require_once('searchlib.php');
$groupmembers = get_group_user_search_results($groupid, '', 0, $numtoshow, '', $order);
......
......@@ -58,12 +58,12 @@ class PluginBlocktypeMyGroups extends SystemBlocktype {
$smarty = smarty_core();
require_once('group.php');
// Group stuff
$results = group_get_associated_groups($userid, 'member');
$usergroups = group_get_user_groups($userid);
foreach ($results['groups'] as $group) {
foreach ($usergroups as $group) {
$group->roledisplay = get_string($group->role, 'grouptype.'.$group->grouptype);
}
$smarty->assign('USERGROUPS',$results['groups']);
$smarty->assign('USERGROUPS', $usergroups);
return $smarty->fetch('blocktype:mygroups:mygroups.tpl');
}
......
......@@ -69,6 +69,7 @@ else {
'submittableto' => 0,
'editroles' => 'all',
'hidden' => 0,
'hidemembers' => 0,
);
}
......@@ -243,12 +244,22 @@ if ($cancreatecontrolled) {
'description' => get_string('hiddengroupdescription', 'group'),
'defaultvalue' => $group_data->hidden,
);
$elements['hidemembers'] = array(
'type' => 'checkbox',
'title' => get_string('hidemembers', 'group'),
'description' => get_string('hidemembersdescription', 'group'),
'defaultvalue' => $group_data->hidemembers,
);
}
else {
$form['elements']['hidden'] = array(
'type' => 'hidden',
'value' => $group_data->hidden,
);
$form['elements']['hidemembers'] = array(
'type' => 'hidden',
'value' => $group_data->hidemembers,
);
}
$elements['general'] = array(
......@@ -337,6 +348,7 @@ function editgroup_submit(Pieform $form, $values) {
'submittableto' => intval($values['submittableto']),
'editroles' => $values['editroles'],
'hidden' => intval($values['hidden']),
'hidemembers' => intval($values['hidemembers']),
);
db_begin();
......
......@@ -45,6 +45,10 @@ define('TITLE', $group->name . ' - ' . get_string('Members', 'group'));
$role = group_user_access($group->id);
if ($group->hidemembers && !$role && !$USER->get('admin') && !$USER->get('staff')) {
throw new AccessDeniedException();
}
if (!empty($membershiptype) && $role != 'admin') {
throw new AccessDeniedException();
}
......
......@@ -43,10 +43,16 @@ if (!is_logged_in() && !$group->public) {
throw new AccessDeniedException(get_string('accessdenied', 'error'));
}
$role = group_user_access($group->id);
if ($group->hidemembers && !$role && !$USER->get('admin') && !$USER->get('staff')) {
json_reply('local', get_string('accessdenied', 'error'));
}
$membershiptype = param_variable('membershiptype', '');
if (!empty($membershiptype)) {
if (group_user_access($id) != 'admin') {
if ($role != 'admin') {
json_reply('local', get_string('accessdenied', 'error'));
}
}
......
......@@ -98,6 +98,8 @@ $string['viewnotify'] = 'Shared page notifications';
$string['viewnotifydescription'] = 'If checked, a notification will be sent to every group member whenever a member shares one of their pages with the group. Enabling this setting in very large groups can produce a lot of notifications.';
$string['hiddengroup'] = 'Hidden group';
$string['hiddengroupdescription'] = 'Do not list this group on the Find Groups page.';
$string['hidemembers'] = 'Hide membership';
$string['hidemembersdescription'] = 'Hide the group\'s membership listing from non-members.';
$string['editgroupmembership'] = 'Edit group membership';
$string['editmembershipforuser'] = 'Edit membership for %s';
......
......@@ -345,6 +345,7 @@
<FIELD NAME="submittableto" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" />
<FIELD NAME="editroles" TYPE="char" LENGTH="20" NOTNULL="true" ENUM="true" ENUMVALUES="'all', 'notmember', 'admin'" DEFAULT="all" />
<FIELD NAME="hidden" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" />
<FIELD NAME="hidemembers" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" />
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id" />
......
......@@ -2715,6 +2715,11 @@ function xmldb_core_upgrade($oldversion=0) {
$field = new XMLDBField('hidden');
$field->setAttributes(XMLDB_TYPE_INTEGER, 1, null, XMLDB_NOTNULL, null, null, null, 0);
add_field($table, $field);
// Setting to hide group members
$field = new XMLDBField('hidemembers');
$field->setAttributes(XMLDB_TYPE_INTEGER, 1, null, XMLDB_NOTNULL, null, null, null, 0);
add_field($table, $field);
}
return $status;
......
......@@ -157,6 +157,10 @@ function group_user_can_edit_views($group, $userid=null) {
function group_role_can_edit_views($group, $role) {
if (empty($role)) {
return false;
}
if ($role == 'admin') {
return true;
}
......@@ -275,6 +279,7 @@ function group_create($data) {
$data['public'] = (isset($data['public'])) ? intval($data['public']) : 0;
$data['hidden'] = (isset($data['hidden'])) ? intval($data['hidden']) : 0;
$data['hidemembers'] = (isset($data['hidemembers'])) ? intval($data['hidemembers']) : 0;
$data['usersautoadded'] = (isset($data['usersautoadded'])) ? intval($data['usersautoadded']) : 0;
$data['quota'] = get_config_plugin('artefact', 'file', 'defaultgroupquota');
......@@ -350,6 +355,7 @@ function group_create($data) {
'submittableto' => intval($data['submittableto']),
'editroles' => $data['editroles'],
'hidden' => $data['hidden'],
'hidemembers' => $data['hidemembers'],
),
'id',
true
......@@ -456,7 +462,7 @@ function group_update($new, $create=false) {
unset($new->institution);
unset($new->shortname);
foreach (array('id', 'grouptype', 'public', 'request', 'submittableto', 'editroles', 'hidden') as $f) {
foreach (array('id', 'grouptype', 'public', 'request', 'submittableto', 'editroles', 'hidden', 'hidemembers') as $f) {
if (!isset($new->$f)) {
$new->$f = $old->$f;
}
......@@ -1446,6 +1452,9 @@ function group_get_menu_tabs() {
if (!$group) {
return null;
}
$role = group_user_access($group->id);
$menu = array(
'info' => array(
'path' => 'groups/info',
......@@ -1453,14 +1462,18 @@ function group_get_menu_tabs() {
'title' => get_string('About', 'group'),
'weight' => 20
),
'members' => array(
);
if ($role || !$group->hidemembers) {
$menu['members'] = array(
'path' => 'groups/members',
'url' => 'group/members.php?id='.$group->id,
'title' => get_string('Members', 'group'),
'weight' => 30
),
);
if ($group->public || group_user_access($group->id)) {
);
}
if ($group->public || $role) {
$menu['forums'] = array( // @todo: get this from a function in the interaction plugin (or better, make forums an artefact plugin)
'path' => 'groups/forums',
'url' => 'interaction/forum/index.php?group='.$group->id,
......@@ -1475,7 +1488,7 @@ function group_get_menu_tabs() {
'weight' => 50,
);
if (group_user_can_edit_views($group)) {
if (group_role_can_edit_views($group, $role)) {
$menu['share'] = array(
'path' => 'groups/share',
'url' => 'group/shareviews.php?group='.$group->id,
......@@ -1484,7 +1497,7 @@ function group_get_menu_tabs() {
);
}
if (group_user_access($group->id)) {
if ($role) {
safe_require('grouptype', $group->grouptype);
$artefactplugins = call_static_method('GroupType' . $group->grouptype, 'get_group_artefact_plugins');
if ($plugins = get_records_array('artefact_installed', 'active', 1)) {
......@@ -1731,35 +1744,42 @@ function group_get_associated_groups($userid, $filter='all', $limit=20, $offset=
function group_get_user_groups($userid=null, $roles=null) {
global $USER;
static $usergroups = array();
$loggedinid = $USER->get('id');
if (is_null($userid)) {
global $USER;
$userid = $USER->get('id');
$userid = $loggedinid;
}
if (!isset($usergroups[$userid])) {
$groups = get_records_sql_array("
SELECT g.id, g.name, gm.role, g.jointype, g.request, g.grouptype, gtr.see_submitted_views, g.category
SELECT g.id, g.name, gm.role, g.jointype, g.request, g.grouptype, gtr.see_submitted_views, g.category,
g.hidemembers, gm1.role AS loggedinrole
FROM {group} g
JOIN {group_member} gm ON (gm.group = g.id)
JOIN {grouptype_roles} gtr ON (g.grouptype = gtr.grouptype AND gm.role = gtr.role)
JOIN {group_member} gm ON gm.group = g.id
JOIN {grouptype_roles} gtr ON g.grouptype = gtr.grouptype AND gm.role = gtr.role
LEFT OUTER JOIN {group_member} gm1 ON gm1.group = gm.group AND gm1.member = ?
WHERE gm.member = ?
AND g.deleted = 0
ORDER BY g.name, gm.role = 'admin' DESC, gm.role, g.id",
array($userid)
array($loggedinid, $userid)
);
$usergroups[$userid] = $groups ? $groups : array();
}
if (empty($roles)) {
if (empty($roles) && $userid == $loggedinid) {
return $usergroups[$userid];
}
$filtered = array();
foreach ($usergroups[$userid] as $g) {
if (in_array($g->role, $roles)) {
$goodrole = empty($roles) || in_array($g->role, $roles);
$visible = !$g->hidemembers || $g->loggedinrole || $USER->get('admin') || $USER->get('staff');
if ($goodrole && $visible) {
$filtered[] = $g;
}
}
......
......@@ -300,7 +300,16 @@ class PluginSearchInternal extends PluginSearch {
private static function prepare_search_user_options($options) {
global $USER;
if (isset($options['group'])) {
$options['group'] = intval($options['group']);
// This option should only be used by group admins, so just ensure that the caller is
// using it correctly.
$roles = $USER->get('grouproles');
if ($USER->get('admin') || $USER->get('staff')
|| (isset($roles[$options['group']]) && $roles[$options['group']] == 'admin')) {
$options['group'] = intval($options['group']);
}
else {
unset($options['group']);
}
}
if (isset($options['includeadmins'])) {
$options['includeadmins'] = (bool)$options['includeadmins'];
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment