From 21778d8d168815cd0a6b962371216bde2ce92dfe Mon Sep 17 00:00:00 2001 From: Dan Marsden Date: Fri, 1 May 2020 20:32:09 +1200 Subject: [PATCH] MDL-32226 mod_quiz: Add Plagiarism hooks to quiz and essay question. --- mod/quiz/lib.php | 1 + mod/quiz/report/attemptsreport_table.php | 12 ++++++++- mod/quiz/report/default.php | 6 ++++- plagiarism/upgrade.txt | 7 +++++ question/type/essay/renderer.php | 34 +++++++++++++++++++++--- 5 files changed, 54 insertions(+), 6 deletions(-) diff --git a/mod/quiz/lib.php b/mod/quiz/lib.php index be87ab21c26..f73d07d9c6c 100644 --- a/mod/quiz/lib.php +++ b/mod/quiz/lib.php @@ -1669,6 +1669,7 @@ function quiz_supports($feature) { case FEATURE_SHOW_DESCRIPTION: return true; case FEATURE_CONTROLS_GRADE_VISIBILITY: return true; case FEATURE_USES_QUESTIONS: return true; + case FEATURE_PLAGIARISM: return true; default: return null; } diff --git a/mod/quiz/report/attemptsreport_table.php b/mod/quiz/report/attemptsreport_table.php index 9f681b718e8..3e123b5d934 100644 --- a/mod/quiz/report/attemptsreport_table.php +++ b/mod/quiz/report/attemptsreport_table.php @@ -246,7 +246,7 @@ abstract class quiz_attempts_report_table extends table_sql { * @param int $slot the number used to identify this question within this usage. */ public function make_review_link($data, $attempt, $slot) { - global $OUTPUT; + global $OUTPUT, $CFG; $flag = ''; if ($this->is_flagged($attempt->usageid, $slot)) { @@ -273,6 +273,16 @@ abstract class quiz_attempts_report_table extends table_sql { array('height' => 450, 'width' => 650)), array('title' => get_string('reviewresponse', 'quiz'))); + if (!empty($CFG->enableplagiarism)) { + require_once($CFG->libdir . '/plagiarismlib.php'); + $output .= plagiarism_get_links([ + 'context' => $this->context->id, + 'component' => 'qtype_'.$this->questions[$slot]->qtype, + 'cmid' => $this->context->instanceid, + 'area' => $attempt->usageid, + 'itemid' => $slot, + 'userid' => $attempt->userid]); + } return $output; } diff --git a/mod/quiz/report/default.php b/mod/quiz/report/default.php index d783cf7311a..55ce4356f88 100644 --- a/mod/quiz/report/default.php +++ b/mod/quiz/report/default.php @@ -61,7 +61,7 @@ abstract class quiz_default_report { * @param string $reportmode the report name. */ public function print_header_and_tabs($cm, $course, $quiz, $reportmode = 'overview') { - global $PAGE, $OUTPUT; + global $PAGE, $OUTPUT, $CFG; // Print the page header. $PAGE->set_title($quiz->name); @@ -69,6 +69,10 @@ abstract class quiz_default_report { echo $OUTPUT->header(); $context = context_module::instance($cm->id); echo $OUTPUT->heading(format_string($quiz->name, true, array('context' => $context))); + if (!empty($CFG->enableplagiarism)) { + require_once($CFG->libdir . '/plagiarismlib.php'); + echo plagiarism_update_status($course, $cm); + } } /** diff --git a/plagiarism/upgrade.txt b/plagiarism/upgrade.txt index 1a664b82479..f726421053d 100644 --- a/plagiarism/upgrade.txt +++ b/plagiarism/upgrade.txt @@ -1,5 +1,12 @@ This files describes API changes for code that uses the plagiarism API. +=== 3.11 === +* Support for Essay question type in Quiz has now been implemented, allowing plagiarism plugins to display information + on the quiz overview report and when viewing an essay question response. + To implement support, plugins should add a listener to the \mod_quiz\event\attempt_submitted event to send the data + to the plagiarism api using the essay question response summary (plain text response from the user). + The function plagiarism_get_links should only be called to render the results. + === 3.9 === * The method get_form_elements_module has been deprecated. Please use {plugin name}_coursemodule_edit_post_actions() instead. diff --git a/question/type/essay/renderer.php b/question/type/essay/renderer.php index 91b07de9733..bdb900e81f5 100644 --- a/question/type/essay/renderer.php +++ b/question/type/essay/renderer.php @@ -36,7 +36,7 @@ defined('MOODLE_INTERNAL') || die(); class qtype_essay_renderer extends qtype_renderer { public function formulation_and_controls(question_attempt $qa, question_display_options $options) { - + global $CFG; $question = $qa->get_question(); $responseoutput = $question->get_format_renderer($this->page); @@ -57,6 +57,17 @@ class qtype_essay_renderer extends qtype_renderer { $step, $question->responsefieldlines, $options->context); $answer .= html_writer::nonempty_tag('p', $question->get_word_count_message_for_review($step->get_qt_data())); + if (!empty($CFG->enableplagiarism)) { + require_once($CFG->libdir . '/plagiarismlib.php'); + + $answer .= plagiarism_get_links([ + 'context' => $options->context->id, + 'component' => $qa->get_question()->qtype->plugin_name(), + 'area' => $qa->get_usage_id(), + 'itemid' => $qa->get_slot(), + 'userid' => $step->get_user_id(), + 'content' => $qa->get_response_summary()]); + } } $files = ''; @@ -94,13 +105,28 @@ class qtype_essay_renderer extends qtype_renderer { * not be displayed. Used to get the context. */ public function files_read_only(question_attempt $qa, question_display_options $options) { + global $CFG; $files = $qa->get_last_qt_files('attachments', $options->context->id); $output = array(); + $step = $qa->get_last_step_with_qt_var('attachments'); + foreach ($files as $file) { - $output[] = html_writer::tag('p', html_writer::link($qa->get_response_file_url($file), - $this->output->pix_icon(file_file_icon($file), get_mimetype_description($file), - 'moodle', array('class' => 'icon')) . ' ' . s($file->get_filename()))); + $out = html_writer::link($qa->get_response_file_url($file), + $this->output->pix_icon(file_file_icon($file), get_mimetype_description($file), + 'moodle', array('class' => 'icon')) . ' ' . s($file->get_filename())); + if (!empty($CFG->enableplagiarism)) { + require_once($CFG->libdir . '/plagiarismlib.php'); + + $out .= plagiarism_get_links([ + 'context' => $options->context->id, + 'component' => $qa->get_question()->qtype->plugin_name(), + 'area' => $qa->get_usage_id(), + 'itemid' => $qa->get_slot(), + 'userid' => $step->get_user_id(), + 'file' => $file]); + } + $output[] = html_writer::tag('p', $out); } return implode($output); }