From c7a7368958df22a3eeeef04fc0e75fd1b3d45a14 Mon Sep 17 00:00:00 2001 From: Damyon Wiese Date: Tue, 10 Dec 2013 11:46:33 +0800 Subject: [PATCH] MDL-34432: Allow comment inline (stripping embedded images version) --- .../lang/en/assignfeedback_comments.php | 4 + mod/assign/feedback/comments/locallib.php | 103 +++++++++++++++++- mod/assign/feedback/comments/settings.php | 8 ++ mod/assign/feedback/comments/version.php | 2 +- mod/assign/tests/behat/comment_inline.feature | 50 +++++++++ mod/assign/tests/locallib_test.php | 71 ++++++++++++ 6 files changed, 233 insertions(+), 5 deletions(-) create mode 100644 mod/assign/tests/behat/comment_inline.feature diff --git a/mod/assign/feedback/comments/lang/en/assignfeedback_comments.php b/mod/assign/feedback/comments/lang/en/assignfeedback_comments.php index 1c327ecf12e..525eee68609 100644 --- a/mod/assign/feedback/comments/lang/en/assignfeedback_comments.php +++ b/mod/assign/feedback/comments/lang/en/assignfeedback_comments.php @@ -28,4 +28,8 @@ $string['default_help'] = 'If set, this feedback method will be enabled by defau $string['enabled'] = 'Feedback comments'; $string['enabled_help'] = 'If enabled, the marker can leave feedback comments for each submission. '; $string['pluginname'] = 'Feedback comments'; +$string['commentinline'] = 'Comment inline'; +$string['commentinline_help'] = 'If enabled, the submission text will be copied into the feedback comment field during grading, making it easier to comment inline (using a different colour, perhaps) or to edit the original text.'; +$string['commentinlinedefault'] = 'Comment inline by default'; +$string['commentinlinedefault_help'] = 'If set, this comment inline functionality will be enabled by default for all new assignments.'; diff --git a/mod/assign/feedback/comments/locallib.php b/mod/assign/feedback/comments/locallib.php index 7791c2d74ca..c46c1ab0f79 100644 --- a/mod/assign/feedback/comments/locallib.php +++ b/mod/assign/feedback/comments/locallib.php @@ -186,6 +186,87 @@ class assign_feedback_comments extends assign_feedback_plugin { } } + /** + * Save the settings for feedback comments plugin + * + * @param stdClass $data + * @return bool + */ + public function save_settings(stdClass $data) { + $this->set_config('commentinline', !empty($data->assignfeedback_comments_commentinline)); + return true; + } + + /** + * Get the default setting for feedback comments plugin + * + * @param MoodleQuickForm $mform The form to add elements to + * @return void + */ + public function get_settings(MoodleQuickForm $mform) { + $default = get_config('assignfeedback_comments', 'inline'); + $mform->addElement('selectyesno', + 'assignfeedback_comments_commentinline', + get_string('commentinline', 'assignfeedback_comments')); + $mform->addHelpButton('assignfeedback_comments_commentinline', 'commentinline', 'assignfeedback_comments'); + $mform->setDefault('assignfeedback_comments_commentinline', $default); + // Disable comment online if comment feedback plugin is disabled. + $mform->disabledIf('assignfeedback_comments_commentinline', 'assignfeedback_comments_enabled', 'notchecked'); + } + + /** + * A student submission may contain image tags that refer to images stored + * in the file area for the submission. We cannot allow these links to be copied to + * the feedback text fields, so we must strip them from the content. + * + * @param string $source The submission text + * @return string The stripped text + */ + protected function strip_moodle_content($source) { + $baseurl = '@@PLUGINFILE@@'; + // Looking for something like < .* "@@pluginfile@@.*" .* > + $pattern = '$<[^<>]+["\']' . $baseurl . '[^"\']*["\'][^<>]*>$'; + $stripped = preg_replace($pattern, '', $source); + // Use purify html to rebalence potentially mismatched tags and generally cleanup. + return purify_html($stripped); + } + + /** + * Convert the text from any submission plugin that has an editor field to + * a format suitable for inserting in the feedback text field. + * + * @param stdClass $submission + * @param stdClass $data - Form data to be filled with the converted submission text and format. + * @return boolean - True if feedback text was set. + */ + protected function convert_submission_text_to_feedback($submission, $data) { + $format = false; + $text = ''; + + foreach ($this->assignment->get_submission_plugins() as $plugin) { + $fields = $plugin->get_editor_fields(); + if ($plugin->is_enabled() && $plugin->is_visible() && !empty($fields)) { + foreach ($fields as $key => $description) { + $rawtext = $this->strip_moodle_content($plugin->get_editor_text($key, $submission->id)); + + $newformat = $plugin->get_editor_format($key, $submission->id); + + if ($format !== false && $newformat != $format) { + // There are 2 or more editor fields using different formats, set to plain as a fallback. + $format = FORMAT_PLAIN; + } else { + $format = $newformat; + } + $text .= $rawtext; + } + } + } + + $data->assignfeedbackcomments_editor['text'] = $text; + $data->assignfeedbackcomments_editor['format'] = $format; + return true; + } + /** * Get form elements for the grading page * @@ -194,12 +275,22 @@ class assign_feedback_comments extends assign_feedback_plugin { * @param stdClass $data * @return bool true if elements were added to the form */ - public function get_form_elements($grade, MoodleQuickForm $mform, stdClass $data) { + public function get_form_elements_for_user($grade, MoodleQuickForm $mform, stdClass $data, $userid) { + $commentinlinenabled = $this->get_config('commentinline'); + $submission = $this->assignment->get_user_submission($userid, false); + $feedbackcomments = false; + if ($grade) { $feedbackcomments = $this->get_feedback_comments($grade->id); - if ($feedbackcomments) { - $data->assignfeedbackcomments_editor['text'] = $feedbackcomments->commenttext; - $data->assignfeedbackcomments_editor['format'] = $feedbackcomments->commentformat; + } + + if ($feedbackcomments && !empty($feedbackcomments->commenttext)) { + $data->assignfeedbackcomments_editor['text'] = $feedbackcomments->commenttext; + $data->assignfeedbackcomments_editor['format'] = $feedbackcomments->commentformat; + } else { + // No feedback given yet - maybe we need to copy the text from the submission? + if (!empty($commentinlinenabled) && $submission) { + $this->convert_submission_text_to_feedback($submission, $data); } } @@ -296,6 +387,10 @@ class assign_feedback_comments extends assign_feedback_plugin { * @return bool was it a success? (false will trigger a rollback) */ public function upgrade_settings(context $oldcontext, stdClass $oldassignment, & $log) { + if ($oldassignment->assignmenttype == 'online') { + $this->set_config('commentinline', $oldassignment->var1); + return true; + } return true; } diff --git a/mod/assign/feedback/comments/settings.php b/mod/assign/feedback/comments/settings.php index f8d45ae927b..492a38d86f8 100644 --- a/mod/assign/feedback/comments/settings.php +++ b/mod/assign/feedback/comments/settings.php @@ -26,3 +26,11 @@ $settings->add(new admin_setting_configcheckbox('assignfeedback_comments/default new lang_string('default', 'assignfeedback_comments'), new lang_string('default_help', 'assignfeedback_comments'), 1)); +$setting = new admin_setting_configcheckbox('assignfeedback_comments/inline', + new lang_string('commentinlinedefault', 'assignfeedback_comments'), + new lang_string('commentinlinedefault_help', 'assignfeedback_comments'), 0); + +$setting->set_advanced_flag_options(admin_setting_flag::ENABLED, false); +$setting->set_locked_flag_options(admin_setting_flag::ENABLED, false); + +$settings->add($setting); diff --git a/mod/assign/feedback/comments/version.php b/mod/assign/feedback/comments/version.php index c4e5f210711..bae50966092 100644 --- a/mod/assign/feedback/comments/version.php +++ b/mod/assign/feedback/comments/version.php @@ -24,6 +24,6 @@ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2013110500; +$plugin->version = 2013121000; $plugin->requires = 2013110500; $plugin->component = 'assignfeedback_comments'; diff --git a/mod/assign/tests/behat/comment_inline.feature b/mod/assign/tests/behat/comment_inline.feature new file mode 100644 index 00000000000..0de4a80f82c --- /dev/null +++ b/mod/assign/tests/behat/comment_inline.feature @@ -0,0 +1,50 @@ +@mod @mod_assign +Feature: In an assignment, teachers can edit a students submission inline + In order to easily mark students assignments + As a teacher + I need to have a students submission text copied to the grading online form. + + @javascript + Scenario: Submit a text online and edit the submission + Given the following "courses" exists: + | fullname | shortname | category | groupmode | + | Course 1 | C1 | 0 | 1 | + And the following "users" exists: + | username | firstname | lastname | email | + | teacher1 | Teacher | 1 | teacher1@asd.com | + | student1 | Student | 1 | student1@asd.com | + And the following "course enrolments" exists: + | user | course | role | + | teacher1 | C1 | editingteacher | + | student1 | C1 | student | + And I log in as "teacher1" + And I follow "Course 1" + And I turn editing mode on + And I add a "Assignment" to section "1" and I fill the form with: + | Assignment name | Test assignment name | + | Description | Submit your online text | + | assignsubmission_onlinetext_enabled | 1 | + | assignsubmission_file_enabled | 0 | + | assignfeedback_comments_enabled | 1 | + | assignfeedback_comments_commentinline | 1 | + And I log out + And I log in as "student1" + And I follow "Course 1" + And I follow "Test assignment name" + And I press "Add submission" + And I fill the moodle form with: + | Online text | I'm the student first submission | + And I press "Save changes" + And I log out + When I log in as "teacher1" + And I follow "Course 1" + And I follow "Test assignment name" + And I follow "View/grade all submissions" + And I click on "Grade Student 1" "link" in the "Student 1" "table_row" + And I press "Save changes" + And I press "Continue" + And I log out + When I log in as "student1" + And I follow "Course 1" + And I follow "Test assignment name" + And I should see "I'm the student first submission" in the "Feedback comments" "table_row" diff --git a/mod/assign/tests/locallib_test.php b/mod/assign/tests/locallib_test.php index 0ab0abf882a..7efe35f50ef 100644 --- a/mod/assign/tests/locallib_test.php +++ b/mod/assign/tests/locallib_test.php @@ -1493,6 +1493,77 @@ class mod_assign_locallib_testcase extends mod_assign_base_testcase { $CFG->usecomments = $commentconfig; } + /** + * Testing for comment inline settings + */ + public function test_feedback_comment_commentinline() { + global $CFG; + + $sourcetext = "Hello! + +I'm writing to you from the Moodle Majlis in Muscat, Oman, where we just had several days of Moodle community goodness. + +URL outside a tag: https://moodle.org/logo/logo-240x60.gif +Plugin url outside a tag: @@PLUGINFILE@@/logo-240x60.gif + +External link 1:Moodle +External link 2:\"Moodle\" +Internal link 1:Moodle +Internal link 2:\"Moodle\" +Anchor link 1:Link text +Anchor link 2:Link text +"; + + // Note the internal images have been stripped and the html is purified (quotes fixed in this case). + $filteredtext = "Hello! + +I'm writing to you from the Moodle Majlis in Muscat, Oman, where we just had several days of Moodle community goodness. + +URL outside a tag: https://moodle.org/logo/logo-240x60.gif +Plugin url outside a tag: @@PLUGINFILE@@/logo-240x60.gif + +External link 1:\"Moodle\" +External link 2:\"Moodle\" +Internal link 1: +Internal link 2: +Anchor link 1:Link text +Anchor link 2:Link text +"; + + $this->setUser($this->editingteachers[0]); + $params = array('assignsubmission_onlinetext_enabled' => 1, + 'assignfeedback_comments_enabled' => 1, + 'assignfeedback_comments_commentinline' => 1); + $assign = $this->create_instance($params); + + $this->setUser($this->students[0]); + // Add a submission but don't submit now. + $submission = $assign->get_user_submission($this->students[0]->id, true); + $data = new stdClass(); + + // Test the internal link is stripped, but the external one is not. + $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(), + 'text'=>$sourcetext, + 'format'=>FORMAT_MOODLE); + + $plugin = $assign->get_submission_plugin_by_type('onlinetext'); + $plugin->save($submission, $data); + + $this->setUser($this->editingteachers[0]); + + $data = new stdClass(); + require_once($CFG->dirroot . '/mod/assign/gradeform.php'); + $pagination = array('userid'=>$this->students[0]->id, + 'rownum'=>0, + 'last'=>true, + 'useridlistid'=>time(), + 'attemptnumber'=>0); + $formparams = array($assign, $data, $pagination); + $mform = new mod_assign_grade_form(null, $formparams); + + $this->assertEquals($filteredtext, $data->assignfeedbackcomments_editor['text']); + } + /** * Testing for feedback comment plugin settings */