MDL-82393 course: Refactor the renderable class for the group selector

The group selector renderable class should extend the comboboxsearch
renderable class to eliminate the need for initializing the
comboboxsearch object within the export_for_template() method and to
prevent duplicating the get_template() method.
This commit is contained in:
Mihail Geshoski
2024-08-07 17:27:41 +08:00
parent 19786070c7
commit 02755c4f95
@@ -17,10 +17,7 @@
namespace core_course\output\actionbar;
use core\output\comboboxsearch;
use renderable;
use renderer_base;
use stdClass;
use templatable;
/**
* Renderable class for the group selector element in the action bar.
@@ -29,7 +26,7 @@ use templatable;
* @copyright 2024 Shamim Rezaie <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class group_selector implements renderable, templatable {
class group_selector extends comboboxsearch {
/**
* @var stdClass The course object.
@@ -50,97 +47,106 @@ class group_selector implements renderable, templatable {
public function __construct(stdClass $course, stdClass $context) {
$this->course = $course;
$this->context = $context;
parent::__construct(false, $this->get_button_content(), $this->get_dropdown_content(), 'group-search',
'groupsearchwidget', 'groupsearchdropdown overflow-auto', null, true, $this->get_label(), 'group',
$this->get_active_group());
}
/**
* Export the data for the mustache template.
* Returns the output for the button (trigger) element of the group selector.
*
* @param renderer_base $output The renderer that will be used to render the output.
* @return array
* @return string HTML fragment
*/
public function export_for_template(renderer_base $output) {
global $USER, $OUTPUT;
private function get_button_content(): string {
global $OUTPUT;
$course = $this->course;
// Based on the current context level, retrieve the correct group mode and grouping ID.
// Also, specify whether only groups with the participation field set to true should be returned.
if ($this->context->contextlevel === CONTEXT_MODULE) { // Module context.
$cm = get_coursemodule_from_id(false, $this->context->instanceid);
$groupmode = groups_get_activity_groupmode($cm);
$groupingid = $cm->groupingid;
$participationonly = true;
} else { // Course context.
$groupmode = $course->groupmode;
$groupingid = $course->defaultgroupingid;
$participationonly = false;
}
$sbody = $OUTPUT->render_from_template('core_group/comboboxsearch/searchbody', [
'courseid' => $course->id,
'cmid' => $this->context->contextlevel === CONTEXT_MODULE ? $this->context->instanceid : null,
'currentvalue' => optional_param('groupsearchvalue', '', PARAM_NOTAGS),
'instance' => rand(),
]);
$label = $groupmode == VISIBLEGROUPS ? get_string('selectgroupsvisible') : get_string('selectgroupsseparate');
$buttondata = ['label' => $label];
if ($groupmode == VISIBLEGROUPS || has_capability('moodle/site:accessallgroups', $this->context)) {
$allowedgroups = groups_get_all_groups(
courseid: $course->id,
userid: 0,
groupingid: $groupingid,
participationonly: $participationonly
);
} else {
$allowedgroups = groups_get_all_groups(
courseid: $course->id,
userid: $USER->id,
groupingid: $groupingid,
participationonly: $participationonly
);
}
if ($this->context->contextlevel === CONTEXT_MODULE) {
$cm = get_coursemodule_from_id(false, $this->context->instanceid);
$activegroup = groups_get_activity_group($cm, true, $allowedgroups);
} else {
$activegroup = groups_get_course_group($course, true, $allowedgroups);
}
$buttondata['group'] = $activegroup;
$activegroup = $this->get_active_group();
$buttondata = [
'label' => $this->get_label(),
'group' => $activegroup,
];
if ($activegroup) {
$group = groups_get_group($activegroup);
$buttondata['selectedgroup'] = format_string($group->name, true, ['context' => $this->context]);
$buttondata['selectedgroup'] = format_string($group->name, true,
['context' => \context_course::instance($this->course->id)]);
} else if ($activegroup === 0) {
$buttondata['selectedgroup'] = get_string('allparticipants');
}
$groupdropdown = new comboboxsearch(
false,
$OUTPUT->render_from_template('core_group/comboboxsearch/group_selector', $buttondata),
$sbody,
'group-search',
'groupsearchwidget',
'groupsearchdropdown overflow-auto',
null,
true,
$label,
'group',
$activegroup
);
return $groupdropdown->export_for_template($OUTPUT);
return $OUTPUT->render_from_template('core_group/comboboxsearch/group_selector', $buttondata);
}
/**
* Returns the template for the group selector.
* Returns the output of the content rendered within the dropdown (search body area) of the group selector.
*
* @return string HTML fragment
*/
private function get_dropdown_content(): string {
global $OUTPUT;
return $OUTPUT->render_from_template('core_group/comboboxsearch/searchbody', [
'courseid' => $this->course->id,
'currentvalue' => optional_param('groupsearchvalue', '', PARAM_NOTAGS),
'instance' => rand(),
]);
}
/**
* Returns the label text for the group selector based on specified group mode.
*
* @return string
*/
public function get_template(): string {
return 'core/comboboxsearch';
private function get_label(): string {
return $this->get_group_mode() === VISIBLEGROUPS ? get_string('selectgroupsvisible') :
get_string('selectgroupsseparate');
}
/**
* Returns the active group based on the context level.
*
* @return int|bool The active group (false if groups not used, int if groups used)
*/
private function get_active_group(): int|bool {
global $USER;
$canaccessallgroups = has_capability('moodle/site:accessallgroups', $this->context);
$userid = $this->get_group_mode() == VISIBLEGROUPS || $canaccessallgroups ? 0 : $USER->id;
// Based on the current context level, retrieve the correct grouping ID and specify whether only groups with the
// participation field set to true should be returned.
if ($this->context->contextlevel === CONTEXT_MODULE) {
$cm = get_coursemodule_from_id(false, $this->context->instanceid);
$groupingid = $cm->groupingid;
$participationonly = true;
} else {
$cm = null;
$groupingid = $this->course->defaultgroupingid;
$participationonly = false;
}
$allowedgroups = groups_get_all_groups(
courseid: $this->course->id,
userid: $userid,
groupingid: $groupingid,
participationonly: $participationonly
);
if ($cm) {
return groups_get_activity_group($cm, true, $allowedgroups);
}
return groups_get_course_group($this->course, true, $allowedgroups);
}
/**
* Returns the group mode based on the context level.
*
* @return int The group mode
*/
private function get_group_mode(): int {
if ($this->context->contextlevel == CONTEXT_MODULE) {
$cm = get_coursemodule_from_id(false, $this->context->instanceid);
return groups_get_activity_groupmode($cm);
}
return $this->course->groupmode;
}
}