MDL-80746 core_course: fix initial_selector rendering

This change:
- Fixes naming of initials_selector class (making plural to match its
predecessor), and addresses relevant calling code.
- Adds an initials_dropdown_form renderable, templatable
- Removes superfluous course/classes/output/actionbar renderer
- Replaces the rendering logic inside initial_selector with calls to
render the new renderable
- Simplifies the initials_selector class, using instance vars instead of
passing args to helpers, removing unnecessary vars, etc.
This commit is contained in:
Jake Dallimore 2024-09-16 10:43:26 +08:00 committed by Mihail Geshoski
parent 67379e7607
commit 8d1cdf6f8e
10 changed files with 197 additions and 208 deletions

View File

@ -1,134 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_course\output\actionbar;
use core\output\comboboxsearch;
use stdClass;
/**
* Renderable class for the initial selector element in the action bar.
*
* @package core_course
* @copyright 2024 Kevin Percy <kevin.percy@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class initial_selector extends comboboxsearch {
/**
* The class constructor.
*
* @param stdClass $course The course object.
* @param string $targeturl The target URL to send the form to.
* @param string $firstinitial The selected first initial.
* @param string $lastinitial The selected last initial.
* @param string $firstinitialparam The parameter name for the first initial.
* @param string $lastinitialparam The parameter name for the last initial.
* @param array $additionalparams Any additional parameters required for the form submission URL.
*/
public function __construct(
stdClass $course,
string $targeturl,
string $firstinitial = '',
string $lastinitial = '',
string $firstinitialparam = 'sifirst',
string $lastinitialparam = 'silast',
array $additionalparams = []
) {
$initialselectorcontent = $this->initial_selector_output(
course: $course,
targeturl: $targeturl,
firstinitial: $firstinitial,
lastinitial: $lastinitial,
firstinitialparam: $firstinitialparam,
lastinitialparam: $lastinitialparam,
additionalparams: $additionalparams
);
$currentfilteroutput = $this->current_filter_output($firstinitial, $lastinitial);
parent::__construct(
false,
$currentfilteroutput !== '' ? $currentfilteroutput : get_string('filterbyname', 'course'),
$initialselectorcontent,
'initials-selector',
'initialswidget',
'initialsdropdown',
$currentfilteroutput !== '' ? get_string('name') : null,
true,
get_string('filterbyname', 'course'),
'nameinitials',
json_encode([
'first' => $firstinitial,
'last' => $lastinitial,
])
);
}
/**
* Method to generate the current filter information for the initial selector label.
*
* @param string $firstinitial The selected first initial.
* @param string $lastinitial The selected last initial.
* @return string
*/
public function current_filter_output(string $firstinitial, string $lastinitial): string {
if ($firstinitial !== '' && $lastinitial !== '') {
return get_string('filterbothactive', 'course', ['first' => $firstinitial, 'last' => $lastinitial]);
} else if ($firstinitial !== '') {
return get_string('filterfirstactive', 'course', ['first' => $firstinitial]);
} else if ($lastinitial !== '') {
return get_string('filterlastactive', 'course', ['last' => $lastinitial]);
}
return '';
}
/**
* Method to generate the output for the initial selector.
*
* @param stdClass $course The course object.
* @param string $targeturl The target URL to send the form to.
* @param string $firstinitial The selected first initial.
* @param string $lastinitial The selected last initial.
* @param string $firstinitialparam The parameter name for the first initial.
* @param string $lastinitialparam The parameter name for the last initial.
* @param array $additionalparams Any additional parameters required for the form submission URL.
* @return string
*/
public function initial_selector_output(
stdClass $course,
string $targeturl,
string $firstinitial = '',
string $lastinitial = '',
string $firstinitialparam = 'sifirst',
string $lastinitialparam = 'silast',
array $additionalparams = []
): string {
global $OUTPUT, $PAGE;
$renderer = $PAGE->get_renderer('core_user');
$initialsbar = $renderer->partial_user_search($targeturl, $firstinitial, $lastinitial, true);
$PAGE->requires->js_call_amd('core_course/actionbar/initials', 'init',
[$targeturl, $firstinitialparam, $lastinitialparam, $additionalparams]);
$formdata = (object) [
'courseid' => $course->id,
'initialsbars' => $initialsbar,
];
return $OUTPUT->render_from_template('core_course/initials_dropdown_form', $formdata);
}
}

View File

@ -0,0 +1,70 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_course\output\actionbar;
use core\output\renderable;
use core\output\renderer_base;
use stdClass;
use templatable;
/**
* Renderable class for the initial_dropdown_form.
*
* This form is the content for the initials_selector renderable, which itself is an extension of the comboboxsearch component.
* {@see initials_selector}.
*
* @package core_course
* @copyright 2024 Jake Dallimore <jrhdallimore@gmail.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class initials_dropdown_form implements renderable, templatable {
/**
* The class constructor.
*
* @param stdClass $course The course object.
* @param string $targeturl The target URL to send the form to.
* @param string $firstinitial The selected first initial.
* @param string $lastinitial The selected last initial.
* @param string $firstinitialparam The parameter name for the first initial.
* @param string $lastinitialparam The parameter name for the last initial.
* @param array $additionalparams Any additional parameters required for the form submission URL.
*/
public function __construct(
protected stdClass $course,
protected string $targeturl,
protected string $firstinitial = '',
protected string $lastinitial = '',
protected string $firstinitialparam = 'sifirst',
protected string $lastinitialparam = 'silast',
protected array $additionalparams = []
) {
}
public function export_for_template(renderer_base $output) {
global $PAGE;
$PAGE->requires->js_call_amd('core_course/actionbar/initials', 'init',
[$this->targeturl, $this->firstinitialparam, $this->lastinitialparam, $this->additionalparams]);
$renderer = $PAGE->get_renderer('core_user');
return (object) [
'courseid' => $this->course->id,
'initialsbars' => $renderer->partial_user_search($this->targeturl, $this->firstinitial, $this->lastinitial, true),
];
}
}

View File

@ -0,0 +1,111 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_course\output\actionbar;
use core\output\comboboxsearch;
use stdClass;
/**
* Renderable class for the initial selector element in the action bar.
*
* @package core_course
* @copyright 2024 Kevin Percy <kevin.percy@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class initials_selector extends comboboxsearch {
/**
* The class constructor.
*
* @param stdClass $course The course object.
* @param string $targeturl The target URL to send the form to.
* @param string $firstinitial The selected first initial.
* @param string $lastinitial The selected last initial.
* @param string $firstinitialparam The parameter name for the first initial.
* @param string $lastinitialparam The parameter name for the last initial.
* @param array $additionalparams Any additional parameters required for the form submission URL.
*/
public function __construct(
protected stdClass $course,
protected string $targeturl,
protected string $firstinitial = '',
protected string $lastinitial = '',
protected string $firstinitialparam = 'sifirst',
protected string $lastinitialparam = 'silast',
protected array $additionalparams = []
) {
// 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.
$filterstatestring = $this->get_current_filter_state_string();
parent::__construct(
false,
$filterstatestring !== '' ? $filterstatestring : get_string('filterbyname', 'course'),
$this->render_initials_dropdown_form(),
'initials-selector',
'initialswidget',
'initialsdropdown',
$filterstatestring !== '' ? get_string('name') : null,
true,
get_string('filterbyname', 'course'),
'nameinitials',
json_encode([
'first' => $firstinitial,
'last' => $lastinitial,
])
);
}
/**
* Method to generate the current filter string for the initial selector label.
*
* @return string the HTML string representing the current initials filter state. E.g. "First (A)", or empty if none selected.
*/
private function get_current_filter_state_string(): string {
if ($this->firstinitial !== '' && $this->lastinitial !== '') {
return get_string('filterbothactive', 'course', ['first' => $this->firstinitial, 'last' => $this->lastinitial]);
} else if ($this->firstinitial !== '') {
return get_string('filterfirstactive', 'course', ['first' => $this->firstinitial]);
} else if ($this->lastinitial !== '') {
return get_string('filterlastactive', 'course', ['last' => $this->lastinitial]);
}
return '';
}
/**
* Method to generate the output for the initial selector.
*
* @return string the rendered HTML content.
*/
private function render_initials_dropdown_form(): string {
global $PAGE;
$initialsdropdownform = new initials_dropdown_form(
$this->course,
$this->targeturl,
$this->firstinitial,
$this->lastinitial,
$this->firstinitialparam,
$this->lastinitialparam,
$this->additionalparams
);
return $PAGE->get_renderer('core', 'course')->render($initialsdropdownform);
}
}

View File

@ -1,60 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_course\output\actionbar;
/**
* Renderer class for the action bar.
*
* @package core_course
* @copyright 2024 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class renderer extends \plugin_renderer_base {
/**
* Renders the user selector trigger element in the action bar.
*
* @param user_selector $userselector The user selector object.
* @return string The HTML output.
*/
public function render_user_selector(user_selector $userselector): string {
$data = $userselector->export_for_template($this);
return parent::render_from_template($userselector->get_template(), $data);
}
/**
* Renders the group selector trigger element in the action bar.
*
* @param group_selector $groupselector The group selector object.
* @return string The HTML output.
*/
protected function render_group_selector(group_selector $groupselector) {
$data = $groupselector->export_for_template($this);
return parent::render_from_template($groupselector->get_template(), $data);
}
/**
* Renders the initial selector trigger element in the action bar.
*
* @param initial_selector $initialselector The initial selector object.
* @return string The HTML output.
*/
protected function render_initial_selector(initial_selector $initialselector): string {
$data = $initialselector->export_for_template($this);
return parent::render_from_template($initialselector->get_template(), $data);
}
}

View File

@ -17,6 +17,7 @@
namespace gradereport_grader\output;
use core\output\comboboxsearch;
use core_course\output\actionbar\initials_selector;
use core_grades\output\general_action_bar;
use moodle_url;
@ -94,7 +95,7 @@ class action_bar extends \core_grades\output\action_bar {
}
$actionbarrenderer = $PAGE->get_renderer('core_course', 'actionbar');
$initialselector = new \core_course\output\actionbar\initial_selector(
$initialselector = new initials_selector(
course: $course,
targeturl: '/grade/report/grader/index.php',
firstinitial: $firstnameinitial,

View File

@ -146,7 +146,7 @@ class singleview extends grade_report {
protected static function groups_course_menu(stdClass $course) {
global $PAGE;
$renderer = $PAGE->get_renderer('core_course', 'actionbar');
$renderer = $PAGE->get_renderer('core', 'course');
return $renderer->render(new \core_course\output\actionbar\group_selector(null, $PAGE->context));
}

View File

@ -45,7 +45,7 @@ class gradereport_singleview_renderer extends plugin_renderer_base {
* @return string The raw HTML to render.
*/
public function users_selector(object $course, ?int $userid = null, ?int $groupid = null): string {
$actionbarrenderer = $this->page->get_renderer('core_course', 'actionbar');
$courserenderer = $this->page->get_renderer('core', 'course');
$resetlink = new moodle_url('/grade/report/singleview/index.php', ['id' => $course->id, 'group' => $groupid ?? 0]);
$usersearch = '';
@ -54,7 +54,7 @@ class gradereport_singleview_renderer extends plugin_renderer_base {
$usersearch = fullname($user);
}
return $actionbarrenderer->render(
return $courserenderer->render(
new \core_course\output\actionbar\user_selector(
course: $course,
resetlink: $resetlink,

View File

@ -95,7 +95,7 @@ class action_bar extends \core_grades\output\action_bar {
$course = get_course($courseid);
if ($course->groupmode) {
$groupselector = new \core_course\output\actionbar\group_selector(null, $this->context);
$data['groupselector'] = $PAGE->get_renderer('core_course', 'actionbar')->render($groupselector);
$data['groupselector'] = $PAGE->get_renderer('core_course')->render($groupselector);
}
$data['userselector'] = [
'courseid' => $courseid,

View File

@ -93,18 +93,19 @@ class gradereport_user_renderer extends plugin_renderer_base {
* @throws coding_exception
*/
public function users_selector(object $course, ?int $userid = null, ?int $groupid = null, string $usersearch = ''): string {
$actionbarrenderer = $this->page->get_renderer('core_course', 'actionbar');
$courserenderer = $this->page->get_renderer('core', 'course');
$resetlink = new moodle_url('/grade/report/user/index.php', ['id' => $course->id, 'group' => 0]);
$baseurl = new moodle_url('/grade/report/user/index.php', ['id' => $course->id]);
$this->page->requires->js_call_amd('gradereport_user/user', 'init', [$baseurl->out(false)]);
$userselector = new \core_course\output\actionbar\user_selector(
course: $course,
resetlink: $resetlink,
userid: $userid,
groupid: $groupid,
usersearch: $usersearch
return $courserenderer->render(
new \core_course\output\actionbar\user_selector(
course: $course,
resetlink: $resetlink,
userid: $userid,
groupid: $groupid,
usersearch: $usersearch
)
);
return $actionbarrenderer->render($userselector);
}
/**

View File

@ -122,7 +122,7 @@ class grading_actionmenu implements templatable, renderable {
$additionalparams['search'] = $usersearch;
}
$initialselector = new \core_course\output\actionbar\initial_selector(
$initialselector = new \core_course\output\actionbar\initials_selector(
course: $course,
targeturl: 'mod/assign/view.php',
firstinitial: $this->userinitials['firstname'] ?? '',