MDL-34432: Allow comment inline (stripping embedded images version)
authorDamyon Wiese <damyon@moodle.com>
Tue, 10 Dec 2013 03:46:33 +0000 (11:46 +0800)
committerDamyon Wiese <damyon@moodle.com>
Mon, 16 Dec 2013 02:38:23 +0000 (10:38 +0800)
mod/assign/feedback/comments/lang/en/assignfeedback_comments.php
mod/assign/feedback/comments/locallib.php
mod/assign/feedback/comments/settings.php
mod/assign/feedback/comments/version.php
mod/assign/tests/behat/comment_inline.feature [new file with mode: 0644]
mod/assign/tests/locallib_test.php

index 1c327ec..525eee6 100644 (file)
@@ -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.';
 
index 7791c2d..c46c1ab 100644 (file)
@@ -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;
     }
 
index f8d45ae..492a38d 100644 (file)
@@ -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);
index c4e5f21..bae5096 100644 (file)
@@ -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 (file)
index 0000000..0de4a80
--- /dev/null
@@ -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"
index 0ab0abf..7efe35f 100644 (file)
@@ -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:<img src='https://moodle.org/logo/logo-240x60.gif' alt='Moodle'/>
+External link 2:<img alt=\"Moodle\" src=\"https://moodle.org/logo/logo-240x60.gif\"/>
+Internal link 1:<img src='@@PLUGINFILE@@/logo-240x60.gif' alt='Moodle'/>
+Internal link 2:<img alt=\"Moodle\" src=\"@@PLUGINFILE@@logo-240x60.gif\"/>
+Anchor link 1:<a href=\"@@PLUGINFILE@@logo-240x60.gif\" alt=\"bananas\">Link text</a>
+Anchor link 2:<a title=\"bananas\" href=\"../logo-240x60.gif\">Link text</a>
+";
+
+        // 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:<img src=\"https://moodle.org/logo/logo-240x60.gif\" alt=\"Moodle\" />
+External link 2:<img alt=\"Moodle\" src=\"https://moodle.org/logo/logo-240x60.gif\" />
+Internal link 1:
+Internal link 2:
+Anchor link 1:Link text
+Anchor link 2:<a title=\"bananas\" href=\"../logo-240x60.gif\">Link text</a>
+";
+
+        $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
      */