From c64883907019ba75198d51e61c4dc37ff75dfeef Mon Sep 17 00:00:00 2001 From: Jake Dallimore Date: Mon, 16 Sep 2024 15:18:50 +0800 Subject: [PATCH] MDL-80746 core_course: fix group_selector rendering This change: - Fixes the group_selector constructor, removing the unnecessarily deprecated param (this code is main-only, so no need to deprecate) and fixes all calling code. - moves the button and content into separate named_templatable renderables, cleaning up the group_selector code so that it only needs to make a single call to render and doesn't concern itself with contexts of other renderables. --- .../output/actionbar/group_selector.php | 56 +++++---------- .../actionbar/group_selector_button.php | 69 +++++++++++++++++++ .../group_selector_dropdown_form.php | 56 +++++++++++++++ .../grader/classes/output/action_bar.php | 2 +- .../singleview/classes/report/singleview.php | 3 +- .../report/user/classes/output/action_bar.php | 2 +- .../comboboxsearch/group_selector.mustache | 6 +- .../classes/output/grading_actionmenu.php | 2 +- 8 files changed, 151 insertions(+), 45 deletions(-) create mode 100644 course/classes/output/actionbar/group_selector_button.php create mode 100644 course/classes/output/actionbar/group_selector_dropdown_form.php diff --git a/course/classes/output/actionbar/group_selector.php b/course/classes/output/actionbar/group_selector.php index 26793a9d6da..df0b35697ce 100644 --- a/course/classes/output/actionbar/group_selector.php +++ b/course/classes/output/actionbar/group_selector.php @@ -28,28 +28,26 @@ use stdClass; */ class group_selector extends comboboxsearch { - /** - * @var stdClass The context object. - */ - private stdClass $context; + /** @var int|bool the active group, false if groups not used. */ + private int|bool $activegroup; /** * The class constructor. * - * @param null|stdClass $course This parameter has been deprecated since Moodle 4.5 and should not be used anymore. * @param stdClass $context The context object. */ - public function __construct(?stdClass $course, stdClass $context) { - if ($course !== null) { - debugging( - 'The course argument has been deprecated. Please remove it from your group_selector class instances.', - DEBUG_DEVELOPER, - ); - } - $this->context = $context; + public function __construct(private stdClass $context) { + $this->activegroup = $this->get_active_group(); + $this->label = $this->get_label(); + + // The second and third arguments (buttoncontent and dropdowncontent) need to be rendered here, since the comboboxsearch + // template expects HTML in its respective context properties. Ideally, children of comboboxsearch would leverage Mustache's + // blocks pragma, meaning a child template could extend the comboboxsearch, allowing rendering of the child component, + // instead of needing to inject the child's content HTML as part of rendering the comboboxsearch parent, as is the case + // here. Achieving this, however, requires a refactor of comboboxsearch. For now, this must be pre-rendered and injected. 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()); + 'groupsearchwidget', 'groupsearchdropdown overflow-auto', null, true, $this->label, 'group', + $this->activegroup); } /** @@ -58,23 +56,10 @@ class group_selector extends comboboxsearch { * @return string HTML fragment */ private function get_button_content(): string { - global $OUTPUT; + global $PAGE; + $groupsselectorbutton = new group_selector_button($this->context, $this->activegroup, $this->label); - $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->get_course_context()]); - } else if ($activegroup === 0) { - $buttondata['selectedgroup'] = get_string('allparticipants'); - } - - return $OUTPUT->render_from_template('core_group/comboboxsearch/group_selector', $buttondata); + return $PAGE->get_renderer('core', 'course')->render($groupsselectorbutton); } /** @@ -83,13 +68,10 @@ class group_selector extends comboboxsearch { * @return string HTML fragment */ private function get_dropdown_content(): string { - global $OUTPUT; + global $PAGE; + $groupsdropdownform = new group_selector_dropdown_form($this->context); - return $OUTPUT->render_from_template('core_group/comboboxsearch/searchbody', [ - 'courseid' => $this->context->get_course_context()->instanceid, - 'currentvalue' => optional_param('groupsearchvalue', '', PARAM_NOTAGS), - 'instance' => rand(), - ]); + return $PAGE->get_renderer('core', 'course')->render($groupsdropdownform); } /** diff --git a/course/classes/output/actionbar/group_selector_button.php b/course/classes/output/actionbar/group_selector_button.php new file mode 100644 index 00000000000..8da3f99eee9 --- /dev/null +++ b/course/classes/output/actionbar/group_selector_button.php @@ -0,0 +1,69 @@ +. + +namespace core_course\output\actionbar; + +use context; +use core\output\named_templatable; +use core\output\renderable; +use core\output\renderer_base; + +/** + * Renderable class for the group selection button state. + * + * This form is the button state for the group_selector renderable, which itself is an extension of the comboboxsearch component. + * {@see group_selector}. + * + * @package core_course + * @copyright 2024 Jake Dallimore + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class group_selector_button implements renderable, named_templatable { + + /** + * The class constructor. + * + * @param context $context The context instance. + * @param int|bool $activegroup The active group, or false if groups not used. + * @param string $label the label string. + */ + public function __construct( + protected context $context, + protected int|bool $activegroup, + protected string $label + ) { + } + + public function export_for_template(renderer_base $output) { + $context = [ + 'label' => $this->label, + 'group' => $this->activegroup, + ]; + + if ($this->activegroup) { + $group = groups_get_group($this->activegroup); + $context['selectedgroup'] = format_string($group->name, true, ['context' => $this->context->get_course_context()]); + } else if ($this->activegroup === 0) { + $context['selectedgroup'] = get_string('allparticipants'); + } + + return $context; + } + + public function get_template_name(renderer_base $renderer): string { + return 'core_group/comboboxsearch/group_selector'; + } +} diff --git a/course/classes/output/actionbar/group_selector_dropdown_form.php b/course/classes/output/actionbar/group_selector_dropdown_form.php new file mode 100644 index 00000000000..8a98f6a6608 --- /dev/null +++ b/course/classes/output/actionbar/group_selector_dropdown_form.php @@ -0,0 +1,56 @@ +. + +namespace core_course\output\actionbar; + +use core\output\named_templatable; +use core\output\renderable; +use core\output\renderer_base; + +/** + * Renderable class for the group selection dropdown form. + * + * This form is the content for the group_selector renderable, which itself is an extension of the comboboxsearch component. + * {@see group_selector}. + * + * @package core_course + * @copyright 2024 Jake Dallimore + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class group_selector_dropdown_form implements renderable, named_templatable { + + /** + * The class constructor. + * + * @param \context $context The context instance. + */ + public function __construct( + protected \context $context + ) { + } + + public function export_for_template(renderer_base $output) { + return [ + 'courseid' => $this->context->get_course_context()->instanceid, + 'currentvalue' => optional_param('groupsearchvalue', '', PARAM_NOTAGS), + 'instance' => rand(), + ]; + } + + public function get_template_name(renderer_base $renderer): string { + return 'core_group/comboboxsearch/searchbody'; + } +} diff --git a/grade/report/grader/classes/output/action_bar.php b/grade/report/grader/classes/output/action_bar.php index 65cfd8b0c9b..82c82662c43 100644 --- a/grade/report/grader/classes/output/action_bar.php +++ b/grade/report/grader/classes/output/action_bar.php @@ -106,7 +106,7 @@ class action_bar extends \core_grades\output\action_bar { if ($course->groupmode) { $data['groupselector'] = $actionbarrenderer->render( - new \core_course\output\actionbar\group_selector(null, $this->context)); + new \core_course\output\actionbar\group_selector($this->context)); } $resetlink = new moodle_url('/grade/report/grader/index.php', ['id' => $courseid]); diff --git a/grade/report/singleview/classes/report/singleview.php b/grade/report/singleview/classes/report/singleview.php index 90b9cd8616b..843d3fc8535 100644 --- a/grade/report/singleview/classes/report/singleview.php +++ b/grade/report/singleview/classes/report/singleview.php @@ -146,8 +146,7 @@ class singleview extends grade_report { protected static function groups_course_menu(stdClass $course) { global $PAGE; - $renderer = $PAGE->get_renderer('core', 'course'); - return $renderer->render(new \core_course\output\actionbar\group_selector(null, $PAGE->context)); + return $PAGE->get_renderer('core', 'course')->render(new \core_course\output\actionbar\group_selector($PAGE->context)); } /** diff --git a/grade/report/user/classes/output/action_bar.php b/grade/report/user/classes/output/action_bar.php index 47063a9c3fa..bf88fec851c 100644 --- a/grade/report/user/classes/output/action_bar.php +++ b/grade/report/user/classes/output/action_bar.php @@ -94,7 +94,7 @@ class action_bar extends \core_grades\output\action_bar { $userreportrenderer = $PAGE->get_renderer('gradereport_user'); $course = get_course($courseid); if ($course->groupmode) { - $groupselector = new \core_course\output\actionbar\group_selector(null, $this->context); + $groupselector = new \core_course\output\actionbar\group_selector($this->context); $data['groupselector'] = $PAGE->get_renderer('core_course')->render($groupselector); } $data['userselector'] = [ diff --git a/group/templates/comboboxsearch/group_selector.mustache b/group/templates/comboboxsearch/group_selector.mustache index 9d0c02be7ab..13b07f59da5 100644 --- a/group/templates/comboboxsearch/group_selector.mustache +++ b/group/templates/comboboxsearch/group_selector.mustache @@ -34,10 +34,10 @@
- - + + {{selectedgroup}}
diff --git a/mod/assign/classes/output/grading_actionmenu.php b/mod/assign/classes/output/grading_actionmenu.php index 7fb898c5cc8..557a49287a4 100644 --- a/mod/assign/classes/output/grading_actionmenu.php +++ b/mod/assign/classes/output/grading_actionmenu.php @@ -136,7 +136,7 @@ class grading_actionmenu implements templatable, renderable { if (groups_get_activity_groupmode($cm, $course)) { $data['groupselector'] = $actionbarrenderer->render( - new \core_course\output\actionbar\group_selector(null, $PAGE->context)); + new \core_course\output\actionbar\group_selector($PAGE->context)); } if ($extrafiltersdropdown = $this->get_extra_filters_dropdown()) {