From 8b0a933d215331c871e58cf2810d3ab12bbb63d3 Mon Sep 17 00:00:00 2001 From: Huong Nguyen Date: Mon, 6 Aug 2018 11:43:44 +0700 Subject: [PATCH] MDL-40695 Quiz: Move manual grading report display to renderer --- mod/quiz/report/grading/renderer.php | 197 +++++++++++++++++++++++++ mod/quiz/report/grading/report.php | 205 ++++++++++++++------------- 2 files changed, 306 insertions(+), 96 deletions(-) create mode 100755 mod/quiz/report/grading/renderer.php diff --git a/mod/quiz/report/grading/renderer.php b/mod/quiz/report/grading/renderer.php new file mode 100755 index 00000000000..69dbd2cea8f --- /dev/null +++ b/mod/quiz/report/grading/renderer.php @@ -0,0 +1,197 @@ +. + +/** + * Defines the renderer for the quiz_grading module. + * + * @package quiz_grading + * @copyright 2018 Huong Nguyen + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +/** + * The renderer for the quiz_grading module. + * + * @copyright 2018 Huong Nguyen + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class quiz_grading_renderer extends plugin_renderer_base { + + /** + * Render no question notification. + * + * @param object $quiz The quiz settings. + * @param object $cm The course-module for this quiz. + * @param object $context The quiz context. + * @return string The HTML for the no questions message. + */ + public function render_quiz_no_question_notification($quiz, $cm, $context) { + return quiz_no_questions_message($quiz, $cm, $context); + } + + /** + * Render no question need to grade notification. + * + * @throws coding_exception + */ + public function render_quiz_no_grade_question_notification() { + return $this->notification(get_string('nothingfound', 'quiz_grading')); + } + + /** + * Render index display. + * + * @param string $linktext The text of the link. + * @param moodle_url $listquestionurl Url of the page that list all questions. + * @return string The HTML for the display heading. + * @throws coding_exception + */ + public function render_display_index_heading($linktext, $listquestionurl) { + $output = ''; + + $output .= $this->heading(get_string('questionsthatneedgrading', 'quiz_grading'), 3); + $output .= html_writer::tag('p', html_writer::link($listquestionurl, $linktext), ['class' => 'toggleincludeauto']); + + return $output; + } + + /** + * Render questions list table. + * + * @param bool $includeauto True to show automatically graded questions. + * @param array $data List of questions. + * @param array $header List of table headers. + * @return string The HTML for the question table. + * @throws coding_exception + */ + public function render_questions_table($includeauto, $data, $header) { + if (empty($data)) { + return $this->render_quiz_no_grade_question_notification(); + } + $output = ''; + + $table = new html_table(); + $table->class = 'generaltable'; + $table->id = 'questionstograde'; + $table->head = $header; + $table->data = $data; + + $output .= html_writer::table($table); + + return $output; + } + + /** + * Render grade link for question. + * + * @param object $counts + * @param string $type Type of grade. + * @param string $gradestring Lang string. + * @param moodle_url $gradequestionurl Url to grade question. + * @return string The HTML for the question grade link. + * @throws coding_exception + */ + public function render_grade_link($counts, $type, $gradestring, $gradequestionurl) { + $output = ''; + if ($counts->$type > 0) { + $output .= ' ' . html_writer::link( + $gradequestionurl, + get_string($gradestring, 'quiz_grading'), + ['class' => 'gradetheselink']); + } + return $output; + } + + /** + * Render grading page. + * + * @param object $questioninfo Information of a question. + * @param moodle_url $listquestionsurl Url of the page that list all questions. + * @param quiz_grading_settings_form $filterform Question filter form. + * @param object $paginginfo Pagination information. + * @param object $pagingbar Pagination bar information. + * @param moodle_url $formaction Form submit url. + * @param array $hiddeninputs List of hidden input fields. + * @param string $gradequestioncontent HTML string of question content. + * @return string The HTML for the grading interface. + * @throws coding_exception + * @throws moodle_exception + */ + public function render_grading_interface($questioninfo, $listquestionsurl, $filterform, $paginginfo, $pagingbar, $formaction, + $hiddeninputs, $gradequestioncontent) { + $output = ''; + + $output .= question_engine::initialise_js(); + + $output .= $this->heading(get_string('gradingquestionx', 'quiz_grading', $questioninfo), 3); + + $output .= html_writer::tag('p', html_writer::link($listquestionsurl, + get_string('backtothelistofquestions', 'quiz_grading')), + ['class' => 'mdl-align']); + + $output .= $filterform->render(); + + $output .= $this->heading(get_string('gradingattemptsxtoyofz', 'quiz_grading', $paginginfo), 3); + + if ($pagingbar->count > $pagingbar->pagesize && $pagingbar->order != 'random') { + $output .= $this->paging_bar($pagingbar->count, $pagingbar->page, $pagingbar->pagesize, $pagingbar->pagingurl); + } + + $output .= html_writer::start_tag('form', [ + 'method' => 'post', + 'action' => $formaction, + 'class' => 'mform', + 'id' => 'manualgradingform' + ]); + $output .= html_writer::start_tag('div'); + $output .= html_writer::input_hidden_params(new moodle_url('', $hiddeninputs)); + + $output .= $gradequestioncontent; + + $output .= html_writer::tag('div', html_writer::empty_tag('input', [ + 'type' => 'submit', + 'class' => 'btn btn-primary', + 'value' => get_string('saveandnext', 'quiz_grading') + ]), ['class' => 'mdl-align']); + $output .= html_writer::end_tag('div') . html_writer::end_tag('form'); + + return $output; + } + + /** + * Render grade question content. + * + * @param question_usage_by_activity $questionusage The question usage that need to grade. + * @param int $slot the number used to identify this question within this usage. + * @param question_display_options $displayoptions the display options to use. + * @param int $questionnumber the number of the question to check. + * @param string $heading the question heading text. + * @return string The HTML for the question display. + */ + public function render_grade_question($questionusage, $slot, $displayoptions, $questionnumber, $heading) { + $output = ''; + + if ($heading) { + $output .= $this->heading($heading, 4); + } + + $output .= $questionusage->render_question($slot, $displayoptions, $questionnumber); + + return $output; + } +} diff --git a/mod/quiz/report/grading/report.php b/mod/quiz/report/grading/report.php index ecb0355e547..c4e843fb7cf 100644 --- a/mod/quiz/report/grading/report.php +++ b/mod/quiz/report/grading/report.php @@ -48,6 +48,9 @@ class quiz_grading_report extends quiz_default_report { protected $quiz; protected $context; + /** @var renderer_base Renderer of Quiz Grading. */ + private $renderer; + public function display($quiz, $cm, $course) { $this->quiz = $quiz; @@ -143,13 +146,13 @@ class quiz_grading_report extends quiz_default_report { // What sort of page to display? if (!$hasquestions) { - echo quiz_no_questions_message($quiz, $cm, $this->context); + echo $this->renderer->render_quiz_no_question_notification($quiz, $cm, $this->context); } else if (!$slot) { - $this->display_index($includeauto); + echo $this->display_index($includeauto); } else { - $this->display_grading_interface($slot, $questionid, $grade, + echo $this->display_grading_interface($slot, $questionid, $grade, $pagesize, $page, $shownames, $showidnumbers, $order, $counts); } return true; @@ -257,34 +260,40 @@ class quiz_grading_report extends quiz_default_report { protected function format_count_for_table($counts, $type, $gradestring) { $result = $counts->$type; if ($counts->$type > 0) { - $result .= ' ' . html_writer::link($this->grade_question_url( - $counts->slot, $counts->questionid, $type), - get_string($gradestring, 'quiz_grading'), - array('class' => 'gradetheselink')); + $gradeurl = $this->grade_question_url($counts->slot, $counts->questionid, $type); + $result .= $this->renderer->render_grade_link($counts, $type, $gradestring, $gradeurl); } return $result; } protected function display_index($includeauto) { - global $OUTPUT, $PAGE; + global $PAGE; + $output = ''; if ($groupmode = groups_get_activity_groupmode($this->cm)) { // Groups is being used. groups_print_activity_menu($this->cm, $this->list_questions_url()); } - - echo $OUTPUT->heading(get_string('questionsthatneedgrading', 'quiz_grading'), 3); + $statecounts = $this->get_question_state_summary(array_keys($this->questions)); if ($includeauto) { $linktext = get_string('hideautomaticallygraded', 'quiz_grading'); } else { $linktext = get_string('alsoshowautomaticallygraded', 'quiz_grading'); } - echo html_writer::tag('p', html_writer::link($this->list_questions_url(!$includeauto), - $linktext), array('class' => 'toggleincludeauto')); - - $statecounts = $this->get_question_state_summary(array_keys($this->questions)); - + $output .= $this->renderer->render_display_index_heading($linktext, $this->list_questions_url(!$includeauto)); $data = array(); + $header = []; + + $header[] = get_string('qno', 'quiz_grading'); + $header[] = get_string('qtypeveryshort', 'question'); + $header[] = get_string('questionname', 'quiz_grading'); + $header[] = get_string('tograde', 'quiz_grading'); + $header[] = get_string('alreadygraded', 'quiz_grading'); + if ($includeauto) { + $header[] = get_string('automaticallygraded', 'quiz_grading'); + } + $header[] = get_string('total', 'quiz_grading'); + foreach ($statecounts as $counts) { if ($counts->all == 0) { continue; @@ -313,33 +322,13 @@ class quiz_grading_report extends quiz_default_report { $data[] = $row; } - - if (empty($data)) { - echo $OUTPUT->notification(get_string('nothingfound', 'quiz_grading')); - return; - } - - $table = new html_table(); - $table->class = 'generaltable'; - $table->id = 'questionstograde'; - - $table->head[] = get_string('qno', 'quiz_grading'); - $table->head[] = get_string('qtypeveryshort', 'question'); - $table->head[] = get_string('questionname', 'quiz_grading'); - $table->head[] = get_string('tograde', 'quiz_grading'); - $table->head[] = get_string('alreadygraded', 'quiz_grading'); - if ($includeauto) { - $table->head[] = get_string('automaticallygraded', 'quiz_grading'); - } - $table->head[] = get_string('total', 'quiz_grading'); - - $table->data = $data; - echo html_writer::table($table); + $output .= $this->renderer->render_questions_table($includeauto, $data, $header); + return $output; } protected function display_grading_interface($slot, $questionid, $grade, $pagesize, $page, $shownames, $showidnumbers, $order, $counts) { - global $OUTPUT; + $output = ''; if ($pagesize * $page >= $counts->$grade) { $page = 0; @@ -369,41 +358,19 @@ class quiz_grading_report extends quiz_default_report { $settings->order = $order; $mform->set_data($settings); - // Print the heading and form. - echo question_engine::initialise_js(); - - $a = new stdClass(); - $a->number = $this->questions[$slot]->number; - $a->questionname = format_string($counts->name); - echo $OUTPUT->heading(get_string('gradingquestionx', 'quiz_grading', $a), 3); - echo html_writer::tag('p', html_writer::link($this->list_questions_url(), - get_string('backtothelistofquestions', 'quiz_grading')), - array('class' => 'mdl-align')); - - $mform->display(); + // Question info. + $questioninfo = new stdClass(); + $questioninfo->number = $this->questions[$slot]->number; + $questioninfo->questionname = format_string($counts->name); // Paging info. - $a = new stdClass(); - $a->from = $page * $pagesize + 1; - $a->to = min(($page + 1) * $pagesize, $count); - $a->of = $count; - echo $OUTPUT->heading(get_string('gradingattemptsxtoyofz', 'quiz_grading', $a), 3); - - if ($count > $pagesize && $order != 'random') { - echo $OUTPUT->paging_bar($count, $page, $pagesize, - $this->grade_question_url($slot, $questionid, $grade, false)); - } - - // Display the form with one section for each attempt. - $sesskey = sesskey(); + $paginginfo = new stdClass(); + $paginginfo->from = $page * $pagesize + 1; + $paginginfo->to = min(($page + 1) * $pagesize, $count); + $paginginfo->of = $count; $qubaidlist = implode(',', $qubaids); - echo html_writer::start_tag('form', array('method' => 'post', - 'action' => $this->grade_question_url($slot, $questionid, $grade, $page), - 'class' => 'mform', 'id' => 'manualgradingform')) . - html_writer::start_tag('div') . - html_writer::input_hidden_params(new moodle_url('', array( - 'qubaids' => $qubaidlist, 'slots' => $slot, 'sesskey' => $sesskey))); + $gradequestioncontent = ''; foreach ($qubaids as $qubaid) { $attempt = $attempts[$qubaid]; $quba = question_engine::load_questions_usage_by_activity($qubaid); @@ -413,37 +380,40 @@ class quiz_grading_report extends quiz_default_report { $displayoptions->history = question_display_options::HIDDEN; $displayoptions->manualcomment = question_display_options::EDITABLE; - $heading = $this->get_question_heading($attempt, $shownames, $showidnumbers); - if ($heading) { - echo $OUTPUT->heading($heading, 4); - } - echo $quba->render_question($slot, $displayoptions, $this->questions[$slot]->number); + $gradequestioncontent .= $this->renderer->render_grade_question( + $quba, + $slot, + $displayoptions, + $this->questions[$slot]->number, + $this->get_question_heading($attempt, $shownames, $showidnumbers) + ); } - echo html_writer::tag('div', html_writer::empty_tag('input', array( - 'type' => 'submit', 'class' => 'btn btn-primary', 'value' => get_string('saveandnext', 'quiz_grading'))), - array('class' => 'mdl-align')) . - html_writer::end_tag('div') . html_writer::end_tag('form'); - } + $pagingbar = new stdClass(); + $pagingbar->count = $count; + $pagingbar->page = $page; + $pagingbar->pagesize = $pagesize; + $pagingbar->pagesize = $pagesize; + $pagingbar->order = $order; + $pagingbar->pagingurl = $this->grade_question_url($slot, $questionid, $grade, false); - protected function get_question_heading($attempt, $shownames, $showidnumbers) { - $a = new stdClass(); - $a->attempt = $attempt->attempt; - $a->fullname = fullname($attempt); - $a->idnumber = $attempt->idnumber; + $hiddeninputs = [ + 'qubaids' => $qubaidlist, + 'slots' => $slot, + 'sesskey' => sesskey() + ]; - $showidnumbers &= !empty($attempt->idnumber); - - if ($shownames && $showidnumbers) { - return get_string('gradingattemptwithidnumber', 'quiz_grading', $a); - } else if ($shownames) { - return get_string('gradingattempt', 'quiz_grading', $a); - } else if ($showidnumbers) { - $a->fullname = $attempt->idnumber; - return get_string('gradingattempt', 'quiz_grading', $a); - } else { - return ''; - } + $output .= $this->renderer->render_grading_interface( + $questioninfo, + $this->list_questions_url(), + $mform, + $paginginfo, + $pagingbar, + $this->grade_question_url($slot, $questionid, $grade, $page), + $hiddeninputs, + $gradequestioncontent + ); + return $output; } protected function validate_submitted_marks() { @@ -587,4 +557,47 @@ class quiz_grading_report extends quiz_default_report { return $dm->load_questions_usages_where_question_in_state($qubaids, $summarystate, $slot, $questionid, $orderby, $params, $limitfrom, $pagesize); } + + /** + * Initialise some parts of $PAGE and start output. + * + * @param object $cm the course_module information. + * @param object $course the course settings. + * @param object $quiz the quiz settings. + * @param string $reportmode the report name. + */ + public function print_header_and_tabs($cm, $course, $quiz, $reportmode = 'overview') { + global $PAGE; + $this->renderer = $PAGE->get_renderer('quiz_grading'); + parent::print_header_and_tabs($cm, $course, $quiz, $reportmode); + } + + /** + * Get question heading. + * + * @param object $attempt an instance of quiz_attempt. + * @param bool $shownames True to show the question name. + * @param bool $showidnumbers True to show the question id number. + * @return string The string text for the question heading. + * @throws coding_exception + */ + protected function get_question_heading($attempt, $shownames, $showidnumbers) { + $a = new stdClass(); + $a->attempt = $attempt->attempt; + $a->fullname = fullname($attempt); + $a->idnumber = $attempt->idnumber; + + $showidnumbers = $showidnumbers && !empty($attempt->idnumber); + + if ($shownames && $showidnumbers) { + return get_string('gradingattemptwithidnumber', 'quiz_grading', $a); + } else if ($shownames) { + return get_string('gradingattempt', 'quiz_grading', $a); + } else if ($showidnumbers) { + $a->fullname = $attempt->idnumber; + return get_string('gradingattempt', 'quiz_grading', $a); + } else { + return ''; + } + } }