MDL-66767 forumreport_summary: Control groups filter content
Control the groups filter options based on forum groups mode and groups visible to the user viewing the report.
This commit is contained in:
@@ -93,35 +93,42 @@ class filters implements renderable, templatable {
|
||||
* @return void.
|
||||
*/
|
||||
protected function prepare_groups_data(array $groupsdata): void {
|
||||
global $DB, $USER;
|
||||
|
||||
$groupmode = groups_get_activity_groupmode($this->cm);
|
||||
$context = \context_module::instance($this->cm->id);
|
||||
$aag = has_capability('moodle/site:accessallgroups', $context);
|
||||
$groupsavailable = [];
|
||||
$groupsselected = [];
|
||||
|
||||
// Only fetch groups user has access to.
|
||||
$groups = groups_get_activity_allowed_groups($this->cm);
|
||||
// If no groups mode enabled, nothing to prepare.
|
||||
if (!in_array($groupmode, [VISIBLEGROUPS, SEPARATEGROUPS])) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Include a 'no groups' option if groups exist.
|
||||
if (!empty($groups)) {
|
||||
if ($groupmode == VISIBLEGROUPS || $aag) {
|
||||
// Any groups, and no groups.
|
||||
$allowedgroupsobj = groups_get_all_groups($this->cm->course, 0, $this->cm->groupingid);
|
||||
$nogroups = new stdClass();
|
||||
$nogroups->id = -1;
|
||||
$nogroups->name = get_string('groupsnone');
|
||||
array_push($groups, $nogroups);
|
||||
$allowedgroupsobj[] = $nogroups;
|
||||
} else {
|
||||
// Only assigned groups.
|
||||
$allowedgroupsobj = groups_get_all_groups($this->cm->course, $USER->id, $this->cm->groupingid);
|
||||
}
|
||||
|
||||
foreach ($groups as $group) {
|
||||
foreach ($allowedgroupsobj as $group) {
|
||||
$groupsavailable[$group->id] = $group->name;
|
||||
|
||||
// Select provided groups if they are available.
|
||||
if (in_array($group->id, $groupsdata)) {
|
||||
$groupsselected[] = $group->id;
|
||||
}
|
||||
}
|
||||
|
||||
// Set valid groups selected.
|
||||
$groupsselected = array_intersect($groupsdata, array_keys($groupsavailable));
|
||||
|
||||
// Overwrite groups properties.
|
||||
$this->groupsavailable = $groupsavailable;
|
||||
$this->groupsselected = $groupsselected;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Export data for use as the context of a mustache template.
|
||||
*
|
||||
|
||||
@@ -313,20 +313,23 @@ class summary_table extends table_sql {
|
||||
// Filter data to only include content within specified groups (and/or no groups).
|
||||
// Additionally, only display users who can post within the selected option(s).
|
||||
|
||||
// Skip adding filter if not applied, or all options are selected.
|
||||
if ($this->is_filtered_by_groups($values)) {
|
||||
// Only filter by groups the user has access to.
|
||||
$groups = $this->get_filter_groups($values);
|
||||
|
||||
// Skip adding filter if not applied, or all valid options are selected.
|
||||
if (!empty($groups)) {
|
||||
// Posts within selected groups and/or not in any groups (group ID -1) are included.
|
||||
// No user filtering as anyone enrolled can potentially post to unrestricted discussions.
|
||||
if (array_search(-1, $values, true) !== false) {
|
||||
list($groupidin, $groupidparams) = $DB->get_in_or_equal($values, SQL_PARAMS_NAMED, 'groupid');
|
||||
if (array_search(-1, $groups) !== false) {
|
||||
list($groupidin, $groupidparams) = $DB->get_in_or_equal($groups, SQL_PARAMS_NAMED);
|
||||
|
||||
$this->sql->filterwhere .= " AND d.groupid {$groupidin}";
|
||||
$this->sql->params += $groupidparams;
|
||||
|
||||
} else if (!empty($values)) {
|
||||
} else {
|
||||
// Only posts and users within selected groups are included.
|
||||
list($groupusersin, $groupusersparams) = $DB->get_in_or_equal($values, SQL_PARAMS_NAMED, 'groupusers');
|
||||
list($groupidin, $groupidparams) = $DB->get_in_or_equal($values, SQL_PARAMS_NAMED, 'groupid');
|
||||
list($groupusersin, $groupusersparams) = $DB->get_in_or_equal($groups, SQL_PARAMS_NAMED);
|
||||
list($groupidin, $groupidparams) = $DB->get_in_or_equal($groups, SQL_PARAMS_NAMED);
|
||||
|
||||
// No joins required (handled by where to prevent data duplication).
|
||||
$this->sql->filterwhere .= "
|
||||
@@ -607,25 +610,57 @@ class summary_table extends table_sql {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the groups filter will be applied by checking whether the number of groups selected
|
||||
* matches the total number of options available (all groups plus no groups option).
|
||||
* Get the final list of groups to filter by, based on the groups submitted,
|
||||
* and those the user has access to.
|
||||
*
|
||||
* @param array $groups The group IDs selected.
|
||||
* @return bool
|
||||
*
|
||||
* @param array $groups The group IDs submitted.
|
||||
* @return array Group objects of groups to use in groups filter.
|
||||
* If no filtering required (all groups selected), returns [].
|
||||
*/
|
||||
protected function is_filtered_by_groups(array $groups): bool {
|
||||
static $groupsavailablecount = null;
|
||||
protected function get_filter_groups(array $groups): array {
|
||||
global $USER;
|
||||
|
||||
if (empty($groups)) {
|
||||
return false;
|
||||
$groupmode = groups_get_activity_groupmode($this->cm);
|
||||
$aag = has_capability('moodle/site:accessallgroups', $this->context);
|
||||
$allowedgroups = [];
|
||||
$filtergroups = [];
|
||||
|
||||
// Filtering only valid if a forum groups mode is enabled.
|
||||
if (in_array($groupmode, [VISIBLEGROUPS, SEPARATEGROUPS])) {
|
||||
$allgroupsobj = groups_get_all_groups($this->cm->course, 0, $this->cm->groupingid);
|
||||
$allgroups = [];
|
||||
|
||||
foreach ($allgroupsobj as $group) {
|
||||
$allgroups[] = $group->id;
|
||||
}
|
||||
|
||||
if ($groupmode == VISIBLEGROUPS || $aag) {
|
||||
$nogroups = new \stdClass();
|
||||
$nogroups->id = -1;
|
||||
$nogroups->name = get_string('groupsnone');
|
||||
|
||||
// Any groups and no groups.
|
||||
$allowedgroupsobj = $allgroupsobj + [$nogroups];
|
||||
} else {
|
||||
// Only assigned groups.
|
||||
$allowedgroupsobj = groups_get_all_groups($this->cm->course, $USER->id, $this->cm->groupingid);
|
||||
}
|
||||
|
||||
foreach ($allowedgroupsobj as $group) {
|
||||
$allowedgroups[] = $group->id;
|
||||
}
|
||||
|
||||
// If not all groups in course are selected, filter by allowed groups submitted.
|
||||
if (!empty($groups) && !empty(array_diff($allowedgroups, $groups))) {
|
||||
$filtergroups = array_intersect($groups, $allowedgroups);
|
||||
} else if (!empty(array_diff($allgroups, $allowedgroups))) {
|
||||
// If user's 'all groups' is a subset of the course groups, filter by all groups available to them.
|
||||
$filtergroups = $allowedgroups;
|
||||
}
|
||||
}
|
||||
|
||||
// Find total number of options available (groups plus 'no groups'), if not already fetched.
|
||||
if (is_null($groupsavailablecount)) {
|
||||
$groupsavailablecount = 1 + count(groups_get_activity_allowed_groups($this->cm));
|
||||
}
|
||||
|
||||
return (count($groups) < $groupsavailablecount);
|
||||
return $filtergroups;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user