MDL-74610 quiz: refactor rendering of '6.00 out of 10.00' into a helper

This commit is contained in:
Tim Hunt
2024-04-09 14:59:45 +01:00
parent 81495189fc
commit ba40067746
5 changed files with 132 additions and 23 deletions
@@ -19,6 +19,7 @@ namespace mod_quiz\output;
use action_link;
use core\output\named_templatable;
use html_writer;
use mod_quiz\output\grades\grade_out_of;
use mod_quiz\quiz_attempt;
use moodle_url;
use mod_quiz\question\display_options;
@@ -178,29 +179,14 @@ class attempt_summary_information implements renderable, named_templatable {
} else {
// Show raw marks only if they are different from the grade (like on the view page).
if ($quiz->grade != $quiz->sumgrades) {
$a = new stdClass();
$a->grade = quiz_format_grade($quiz, $attempt->sumgrades);
$a->maxgrade = quiz_format_grade($quiz, $quiz->sumgrades);
$summary->add_item('marks', get_string('marks', 'quiz'),
get_string('outofshort', 'quiz', $a));
new grade_out_of($quiz, $attempt->sumgrades, $quiz->sumgrades, grade_out_of::SHORT));
}
// Now the scaled grade.
$a = new stdClass();
$a->grade = html_writer::tag('b', quiz_format_grade($quiz, $grade));
$a->maxgrade = quiz_format_grade($quiz, $quiz->grade);
if ($quiz->grade != 100) {
// Show the percentage using the configured number of decimal places,
// but without trailing zeroes.
$a->percent = html_writer::tag('b', format_float(
$attempt->sumgrades * 100 / $quiz->sumgrades,
$quiz->decimalpoints, true, true));
$formattedgrade = get_string('outofpercent', 'quiz', $a);
} else {
$formattedgrade = get_string('outof', 'quiz', $a);
}
$summary->add_item('grade', get_string('gradenoun'),
$formattedgrade);
new grade_out_of($quiz, $grade, $quiz->grade,
$quiz->grade == 100 ? grade_out_of::NORMAL : grade_out_of::WITH_PERCENT));
}
}
@@ -243,7 +229,7 @@ class attempt_summary_information implements renderable, named_templatable {
return $templatecontext;
}
public function get_template_name(\renderer_base $renderer): string {
public function get_template_name(renderer_base $renderer): string {
// Only reason we are forced to implement this is that we want the quiz renderer
// passed to export_for_template, not a core_renderer.
return 'mod_quiz/attempt_summary_information';
@@ -0,0 +1,108 @@
<?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 mod_quiz\output\grades;
use html_writer;
use renderable;
use stdClass;
/**
* Represents a grade out of a give total, that wants to be output in a particular way.
*
* @package mod_quiz
* @category output
* @copyright 2024 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class grade_out_of implements renderable {
/** @var string Indicates we want a short rendering. Also the lang string used. */
const SHORT = 'outofshort';
/** @var string Indicates we want the default rendering. Also the lang string used. */
const NORMAL = 'outof';
/** @var string like normal, but with the percent equivalent in brackets. Also the lang string used */
const WITH_PERCENT = 'outofpercent';
/**
* Constructor.
*
* @param stdClass $quiz Quiz settings.
* @param float $grade the mark to show.
* @param float $maxgrade the total to show it out of.
* @param string $style which format to use, grade_out_of::NORMAL, ::SHORT or ::WITH_PERCENT.
*/
public function __construct(
/** @var stdClass Quiz settings (so we can access the settings like decimal places). */
public readonly stdClass $quiz,
/** @var float the grade to show. */
public float $grade,
/** @var float the total the grade is out of. */
public float $maxgrade,
/** @var string The display style, one of the consts above. */
public readonly string $style = self::NORMAL,
) {
}
/**
* Get the lang string to use to display the grade in the requested style.
*
* @return string lang string key from the mod_quiz lang pack.
*/
public function get_string_key(): string {
return $this->style;
}
/**
* Get the formatted values to be inserted into the {@see get_string_key()} string placeholders.
*
* Values are not styled. To apply the recommended styling, call {@see style_formatted_values()}
*
* @return stdClass to be passed as the third argument to get_string().
*/
public function get_formatted_values(): stdClass {
$a = new stdClass();
$a->grade = quiz_format_grade($this->quiz, $this->grade);
$a->maxgrade = quiz_format_grade($this->quiz, $this->maxgrade);
if ($this->style === self::WITH_PERCENT) {
$a->percent = format_float($this->grade * 100 / $this->maxgrade,
$this->quiz->decimalpoints, true, true);
}
return $a;
}
/**
* Apply the normal styling to the values returned by {@see get_formatted_values()}.
*
* @param stdClass $a formatted values, as returned by get_formatted_values.
* @return stdClass same structure, with some values wrapped in &lt;b> tags.
*/
public function style_formatted_values(stdClass $a): stdClass {
if ($this->style !== self::SHORT) {
$a->grade = html_writer::tag('b', $a->grade);
}
if ($this->style === self::WITH_PERCENT) {
$a->percent = html_writer::tag('b', $a->percent);
}
return $a;
}
}
+15
View File
@@ -25,6 +25,7 @@ use html_table_cell;
use html_writer;
use mod_quiz\access_manager;
use mod_quiz\form\preflight_check_form;
use mod_quiz\output\grades\grade_out_of;
use mod_quiz\question\display_options;
use mod_quiz\quiz_attempt;
use moodle_url;
@@ -465,6 +466,20 @@ class renderer extends plugin_renderer_base {
return implode(', ', $attemptlinks);
}
/**
* Render a {@see grade_out_of}.
*
* Most of the logic is in methods of the grade_out_of class. However,
* having this renderer method allows themes to override the default rendering.
*
* @param grade_out_of $grade
* @return string HTML to output.
*/
protected function render_grade_out_of(grade_out_of $grade): string {
return get_string($grade->get_string_key(), 'quiz',
$grade->style_formatted_values($grade->get_formatted_values()));
}
/**
* Render the 'start attempt' page.
*
+3 -4
View File
@@ -22,6 +22,7 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
use mod_quiz\output\grades\grade_out_of;
require_once("../../config.php");
require_once("locallib.php");
@@ -161,10 +162,8 @@ foreach ($quizzes as $quiz) {
$feedback = '';
if ($quiz->grade && array_key_exists($quiz->id, $grades)) {
if ($alloptions->marks >= question_display_options::MARK_AND_MAX) {
$a = new stdClass();
$a->grade = quiz_format_grade($quiz, $grades[$quiz->id]);
$a->maxgrade = quiz_format_grade($quiz, $quiz->grade);
$grade = get_string('outofshort', 'quiz', $a);
$grade = $OUTPUT->render(new grade_out_of(
$grades[$quiz->id], $quiz->grade, $quiz->sumgrades, style: grade_out_of::SHORT));
}
if ($alloptions->overallfeedback) {
$feedback = quiz_feedback_for_grade($grades[$quiz->id], $quiz, $context);
+1
View File
@@ -28,6 +28,7 @@ This file describes API changes in the quiz code.
- override_manager::delete_override_by_id
- override_manager::delete_overrides
- override_manager::delete_all_overrides
* There is a new renderable grade_out_of to help with display a nicely formatted "42.00 out of 100.00" with a few variants.
=== 4.3 ===