Merge branch 'MDL-61063-master' of https://github.com/sammarshallou/moodle
authorEloy Lafuente (stronk7) <stronk7@moodle.org>
Mon, 15 Jan 2018 21:02:08 +0000 (22:02 +0100)
committerEloy Lafuente (stronk7) <stronk7@moodle.org>
Mon, 15 Jan 2018 21:02:08 +0000 (22:02 +0100)
37 files changed:
calendar/classes/local/event/container.php
completion/classes/edit_base_form.php
course/moodleform_mod.php
enrol/manual/amd/build/quickenrolment.min.js
enrol/manual/amd/src/quickenrolment.js
lang/en/deprecated.txt
lang/en/error.php
lang/en/moodle.php
lang/en/table.php
lang/en/tag.php
lib/grouplib.php
mod/assign/feedback/editpdf/yui/build/moodle-assignfeedback_editpdf-editor/moodle-assignfeedback_editpdf-editor-debug.js
mod/assign/feedback/editpdf/yui/build/moodle-assignfeedback_editpdf-editor/moodle-assignfeedback_editpdf-editor-min.js
mod/assign/feedback/editpdf/yui/build/moodle-assignfeedback_editpdf-editor/moodle-assignfeedback_editpdf-editor.js
mod/assign/feedback/editpdf/yui/src/editor/js/quickcommentlist.js
mod/feedback/lang/en/deprecated.txt
mod/feedback/lang/en/feedback.php
mod/forum/lang/en/deprecated.txt [deleted file]
mod/forum/lang/en/forum.php
mod/forum/lib.php
mod/lesson/lang/en/deprecated.txt [deleted file]
mod/lesson/lang/en/lesson.php
mod/quiz/tests/behat/manually_mark_question.feature
mod/quiz/tests/fixtures/moodle_logo.jpg [new file with mode: 0644]
mod/workshop/form/accumulative/lang/en/deprecated.txt [deleted file]
mod/workshop/form/accumulative/lang/en/workshopform_accumulative.php
mod/workshop/form/comments/lang/en/deprecated.txt [deleted file]
mod/workshop/form/comments/lang/en/workshopform_comments.php
mod/workshop/form/numerrors/lang/en/deprecated.txt [deleted file]
mod/workshop/form/numerrors/lang/en/workshopform_numerrors.php
mod/workshop/lang/en/deprecated.txt
mod/workshop/lang/en/workshop.php
question/behaviour/behaviourbase.php
question/behaviour/rendererbase.php
question/engine/lib.php
question/engine/questionattempt.php
question/type/essay/renderer.php

index 398304e..597eb70 100644 (file)
@@ -151,11 +151,16 @@ class container {
                     // 2) Only process modules for courses a user has the capability to view OR they are enrolled in.
                     // 3) Only process modules for courses that are visible OR if the course is not visible, the user
                     //    has the capability to view hidden courses.
+                    if (!$cm->uservisible) {
+                        return true;
+                    }
+
                     $coursecontext = \context_course::instance($dbrow->courseid);
-                    $canseecourse = has_capability('moodle/course:view', $coursecontext) || is_enrolled($coursecontext);
-                    $canseecourse = $canseecourse &&
-                        ($cm->get_course()->visible || has_capability('moodle/course:viewhiddencourses', $coursecontext));
-                    if (!$cm->uservisible || !$canseecourse) {
+                    if (!$cm->get_course()->visible && !has_capability('moodle/course:viewhiddencourses', $coursecontext)) {
+                        return true;
+                    }
+
+                    if (!has_capability('moodle/course:view', $coursecontext) && !is_enrolled($coursecontext)) {
                         return true;
                     }
 
index 676d712..505c789 100644 (file)
@@ -220,7 +220,7 @@ abstract class core_completion_edit_base_form extends moodleform {
         }
 
         // Completion expected at particular date? (For progress tracking).
-        $mform->addElement('date_selector', 'completionexpected',
+        $mform->addElement('date_time_selector', 'completionexpected',
             get_string('completionexpected', 'completion'), ['optional' => true]);
         $mform->addHelpButton('completionexpected', 'completionexpected', 'completion');
         $mform->disabledIf('completionexpected', 'completion', 'eq', COMPLETION_TRACKING_NONE);
index 06cc2b1..024f159 100644 (file)
@@ -710,7 +710,8 @@ abstract class moodleform_mod extends moodleform {
             }
 
             // Completion expected at particular date? (For progress tracking)
-            $mform->addElement('date_selector', 'completionexpected', get_string('completionexpected', 'completion'), array('optional'=>true));
+            $mform->addElement('date_time_selector', 'completionexpected', get_string('completionexpected', 'completion'),
+                    array('optional' => true));
             $mform->addHelpButton('completionexpected', 'completionexpected', 'completion');
             $mform->disabledIf('completionexpected', 'completion', 'eq', COMPLETION_TRACKING_NONE);
         }
index 427c130..0e86534 100644 (file)
Binary files a/enrol/manual/amd/build/quickenrolment.min.js and b/enrol/manual/amd/build/quickenrolment.min.js differ
index 6f359b3..980581a 100644 (file)
@@ -137,7 +137,7 @@ define(['core/templates',
         // This hidden fields are added automatically by mforms and when it reaches the AJAX we get an error.
         var hidden = form.find(SELECTORS.UNWANTEDHIDDENFIELDS);
         hidden.each(function() {
-            this.remove();
+            $(this).remove();
         });
 
         var formData = form.serialize();
index c7b2559..06ce696 100644 (file)
@@ -5,24 +5,8 @@ myfilesmanage,core
 mypreferences,core_grades
 myprofile,core
 viewallmyentries,core_blog
-taggedwith,core_tag
-officialtag,core_tag
-otags,core_tag
-othertags,core_tag
-tagtype,core_tag
-manageofficialtags,core_tag
-settypeofficial,core_tag
-filetoolarge,core
-maxbytesforfile,core
 modchooserenable,core
 modchooserdisable,core
-maxbytes,core_error
-downloadcsv,core_table
-downloadexcel,core_table
-downloadods,core_table
-downloadoptions,core_table
-downloadtsv,core_table
-downloadxhtml,core_table
 invalidpersistent,core_competency
 revealpassword,core_form
 mediasettings,core_media
index 55786b4..492de6f 100644 (file)
@@ -593,5 +593,3 @@ $string['alreadyloggedin'] = 'You are already logged in as {$a}, you need to log
 $string['youcannotdeletecategory'] = 'You cannot delete category \'{$a}\' because you can neither delete the contents, nor move them elsewhere.';
 $string['protected_cc_not_supported'] = 'Protected cartridges not supported.';
 
-// Deprecated since Moodle 3.1.
-$string['maxbytes'] = 'The file is larger than the maximum size allowed.';
index 7df89eb..80b20b6 100644 (file)
@@ -2150,10 +2150,6 @@ $string['yourwordforx'] = 'Your word for \'{$a}\'';
 $string['zippingbackup'] = 'Zipping backup';
 $string['deprecatedeventname'] = '{$a} (no longer in use)';
 
-// Deprecated since Moodle 3.1.
-$string['filetoolarge'] = 'is too large to upload';
-$string['maxbytesforfile'] = 'The file {$a} is larger than the maximum size allowed.';
-
 // Deprecated since Moodle 3.2.
 $string['modchooserenable'] = 'Activity chooser on';
 $string['modchooserdisable'] = 'Activity chooser off';
index 8ab01a3..78020e0 100644 (file)
 
 $string['downloadas'] = 'Download table data as';
 
-// Deprecated since Moodle 3.1.
-$string['downloadcsv'] = 'Comma separated values text file';
-$string['downloadexcel'] = 'Excel spreadsheet';
-$string['downloadods'] = 'OpenDocument spreadsheet';
-$string['downloadoptions'] = 'Select download options';
-$string['downloadtsv'] = 'Tab separated values text file';
-$string['downloadxhtml'] = 'Unpaged XHTML document';
index 83d3b5f..fea1031 100644 (file)
@@ -148,12 +148,3 @@ $string['page-tag-index'] = 'Single tag page';
 $string['page-tag-search'] = 'Tag search page';
 $string['page-tag-manage'] = 'Manage tags page';
 
-// Deprecated since 3.1 .
-
-$string['manageofficialtags'] = 'Manage official tags';
-$string['officialtag'] = 'Official';
-$string['otags'] = 'Official tags';
-$string['othertags'] = 'Other tags';
-$string['settypeofficial'] = 'Make official';
-$string['taggedwith'] = 'tagged with "{$a}"';
-$string['tagtype'] = 'Tag type';
index 2f36760..469a012 100644 (file)
@@ -165,7 +165,8 @@ function groups_get_grouping_by_idnumber($courseid, $idnumber) {
  * @param int $groupid ID of the group.
  * @param string $fields (default is all fields)
  * @param int $strictness (IGNORE_MISSING - default)
- * @return stdGlass group object
+ * @return bool|stdClass group object or false if not found
+ * @throws dml_exception
  */
 function groups_get_group($groupid, $fields='*', $strictness=IGNORE_MISSING) {
     global $DB;
index 3dd767e..56f1f76 100644 (file)
Binary files a/mod/assign/feedback/editpdf/yui/build/moodle-assignfeedback_editpdf-editor/moodle-assignfeedback_editpdf-editor-debug.js and b/mod/assign/feedback/editpdf/yui/build/moodle-assignfeedback_editpdf-editor/moodle-assignfeedback_editpdf-editor-debug.js differ
index 36fcb5c..0111190 100644 (file)
Binary files a/mod/assign/feedback/editpdf/yui/build/moodle-assignfeedback_editpdf-editor/moodle-assignfeedback_editpdf-editor-min.js and b/mod/assign/feedback/editpdf/yui/build/moodle-assignfeedback_editpdf-editor/moodle-assignfeedback_editpdf-editor-min.js differ
index 3dd767e..56f1f76 100644 (file)
Binary files a/mod/assign/feedback/editpdf/yui/build/moodle-assignfeedback_editpdf-editor/moodle-assignfeedback_editpdf-editor.js and b/mod/assign/feedback/editpdf/yui/build/moodle-assignfeedback_editpdf-editor/moodle-assignfeedback_editpdf-editor.js differ
index a3689b4..c960ec2 100644 (file)
@@ -86,6 +86,9 @@ var QUICKCOMMENTLIST = function(editor) {
                                                                                      jsondata.width,
                                                                                      jsondata.colour);
                             this.comments.push(quickcomment);
+                            this.comments.sort(function(a, b) {
+                                return a.rawtext.localeCompare(b.rawtext);
+                            });
                         }
                     } catch (e) {
                         return new M.core.exception(e);
@@ -182,6 +185,10 @@ var QUICKCOMMENTLIST = function(editor) {
                                                                                              comment.colour);
                                 this.comments.push(quickcomment);
                             }, this);
+
+                            this.comments.sort(function(a, b) {
+                                return a.rawtext.localeCompare(b.rawtext);
+                            });
                         }
                     } catch (e) {
                         return new M.core.exception(e);
index 176f304..fe76fa7 100644 (file)
@@ -1,28 +1,2 @@
-cancel_moving,mod_feedback
-cannotunmap,mod_feedback
-cannotmapfeedback,mod_feedback
-line_values,mod_feedback
-mapcourses_help,mod_feedback
-max_args_exceeded,mod_feedback
-movedown_item,mod_feedback
-move_here,mod_feedback
-moveup_item,mod_feedback
-notavailable,mod_feedback
-parameters_missing,mod_feedback
-picture,mod_feedback
-picture_file_list,mod_feedback
-picture_values,mod_feedback
-preview,mod_feedback
-preview_help,mod_feedback
-radiorated,mod_feedback
-radiobutton,mod_feedback
-radiobutton_rated,mod_feedback
-relateditemsdeleted,mod_feedback
-separator_decimal,mod_feedback
-separator_thousand,mod_feedback
-saving_failed_because_missing_or_false_values,mod_feedback
 start,mod_feedback
-stop,mod_feedback
-switch_group,mod_feedback
-viewcompleted,mod_feedback
-viewcompleted_help,mod_feedback
+stop,mod_feedback
\ No newline at end of file
index 73eb880..a0ee5f1 100644 (file)
@@ -275,35 +275,6 @@ $string['use_one_line_for_each_value'] = 'Use one line for each answer!';
 $string['use_this_template'] = 'Use this template';
 $string['using_templates'] = 'Use a template';
 $string['vertical'] = 'vertical';
-// Deprecated since Moodle 3.1.
-$string['cannotmapfeedback'] = 'Database problem, unable to map feedback to course';
-$string['line_values'] = 'Rating';
-$string['mapcourses_help'] = 'Once you have selected the relevant course(s) from your search,
-you can associate them with this feedback using map course(s). Multiple courses may be selected by holding down the Apple or Ctrl key whilst clicking on the course names. A course may be disassociated from a feedback at any time.';
-$string['max_args_exceeded'] = 'Max 6 arguments can be handled, too many arguments for';
-$string['cancel_moving'] = 'Cancel moving';
-$string['movedown_item'] = 'Move this question down';
-$string['move_here'] = 'Move here';
-$string['moveup_item'] = 'Move this question up';
-$string['notavailable'] = 'this feedback is not available';
-$string['saving_failed_because_missing_or_false_values'] = 'Saving failed because missing or false values';
-$string['cannotunmap'] = 'Database problem, unable to unmap';
-$string['viewcompleted'] = 'completed feedbacks';
-$string['viewcompleted_help'] = 'You may view completed feedback forms, searchable by course and/or by question.
-Feedback responses may be exported to Excel.';
-$string['parameters_missing'] = 'Parameters missing from';
-$string['picture'] = 'Picture';
-$string['picture_file_list'] = 'List of pictures';
-$string['picture_values'] = 'Choose one or more<br />picture files from the list:';
-$string['preview'] = 'Preview';
-$string['preview_help'] = 'In the preview you can change the order of questions.';
-$string['switch_group'] = 'Switch group';
-$string['separator_decimal'] = '.';
-$string['separator_thousand'] = ',';
-$string['relateditemsdeleted'] = 'All responses for this question will also be deleted.';
-$string['radiorated'] = 'Radiobutton (rated)';
-$string['radiobutton'] = 'Multiple choice - single answer allowed (radio buttons)';
-$string['radiobutton_rated'] = 'Radiobutton (rated)';
 // Deprecated since Moodle 3.2.
 $string['start'] = 'Start';
 $string['stop'] = 'End';
diff --git a/mod/forum/lang/en/deprecated.txt b/mod/forum/lang/en/deprecated.txt
deleted file mode 100644 (file)
index caf084c..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-postmailinfo,mod_forum
-emaildigestupdated,mod_forum
-emaildigestupdated_default,mod_forum
-emaildigest_0,mod_forum
-emaildigest_1,mod_forum
-emaildigest_2,mod_forum
index 9ee8be1..abb8410 100644 (file)
@@ -555,13 +555,3 @@ $string['warnformorepost'] = 'Warning! There is more than one discussion in this
 $string['yournewquestion'] = 'Your new question';
 $string['yournewtopic'] = 'Your new discussion topic';
 $string['yourreply'] = 'Your reply';
-
-// Deprecated since Moodle 3.1.
-$string['postmailinfo'] = 'This is a copy of a message posted on the {$a} website.
-
-To reply click on this link:';
-$string['emaildigestupdated'] = 'The e-mail digest option was changed to \'{$a->maildigesttitle}\' for the forum \'{$a->forum}\'. {$a->maildigestdescription}';
-$string['emaildigestupdated_default'] = 'Your default profile setting of \'{$a->maildigesttitle}\' was used for the forum \'{$a->forum}\'. {$a->maildigestdescription}.';
-$string['emaildigest_0'] = 'You will receive one e-mail per forum post.';
-$string['emaildigest_1'] = 'You will receive one digest e-mail per day containing the complete contents of each forum post.';
-$string['emaildigest_2'] = 'You will receive one digest e-mail per day containing the subject of each forum post.';
index eb1aa4e..43f5ca4 100644 (file)
@@ -3516,10 +3516,11 @@ function forum_print_post($post, $discussion, $forum, &$cm, $course, $ownpost=fa
         }
         if (!empty($discussion->unread) && $discussion->unread !== '-') {
             $replystring .= ' <span class="sep">/</span> <span class="unread">';
+            $unreadlink = new moodle_url($discussionlink, null, 'unread');
             if ($discussion->unread == 1) {
-                $replystring .= get_string('unreadpostsone', 'forum');
+                $replystring .= html_writer::link($unreadlink, get_string('unreadpostsone', 'forum'));
             } else {
-                $replystring .= get_string('unreadpostsnumber', 'forum', $discussion->unread);
+                $replystring .= html_writer::link($unreadlink, get_string('unreadpostsnumber', 'forum', $discussion->unread));
             }
             $replystring .= '</span>';
         }
diff --git a/mod/lesson/lang/en/deprecated.txt b/mod/lesson/lang/en/deprecated.txt
deleted file mode 100644 (file)
index 7521da8..0000000
+++ /dev/null
@@ -1 +0,0 @@
-configactionaftercorrectanswer,mod_lesson
\ No newline at end of file
index a5cd95f..52cf786 100644 (file)
@@ -547,5 +547,3 @@ $string['yourcurrentgradeis'] = 'Your current grade is {$a}';
 $string['yourcurrentgradeisoutof'] = 'Your current grade is {$a->grade} out of {$a->total}';
 $string['youshouldview'] = 'You should answer at least: {$a}';
 
-// Deprecated since Moodle 3.1.
-$string['configactionaftercorrectanswer'] = 'The default action to take after a correct answer';
index 72c2c39..f465f19 100644 (file)
@@ -36,15 +36,15 @@ Feature: Teachers can override the grade for any question
     And I press "Submit all and finish"
     And I click on "Submit all and finish" "button" in the "Confirmation" "dialogue"
     And I log out
-    And I log in as "teacher1"
+
+  @javascript @_switch_window @_bug_phantomjs
+  Scenario: Validating the marking of an essay question attempt.
+    When I log in as "teacher1"
     And I am on "Course 1" course homepage
     And I follow "Quiz 1"
     And I follow "Attempts: 1"
     And I follow "Review attempt"
-
-  @javascript @_switch_window @_bug_phantomjs
-  Scenario: Validating the marking of an essay question attempt.
-    When I follow "Make comment or override mark"
+    And I follow "Make comment or override mark"
     And I switch to "commentquestion" window
     And I set the field "Mark" to "25"
     And I press "Save"
@@ -57,3 +57,35 @@ Feature: Teachers can override the grade for any question
     And I should see "Complete" in the "Manually graded 10 with comment: " "table_row"
     # This time is same as time the window is open. So wait for it to close before proceeding.
     And I wait "2" seconds
+
+  @javascript @_switch_window @_file_upload @_bug_phantomjs
+  Scenario: Comment on a response to an essay question attempt.
+    When I log in as "teacher1"
+    And I follow "Manage private files"
+    And I upload "mod/quiz/tests/fixtures/moodle_logo.jpg" file to "Files" filemanager
+    And I click on "Save changes" "button"
+    And I am on "Course 1" course homepage
+    And I follow "Quiz 1"
+    And I follow "Attempts: 1"
+    And I follow "Review attempt"
+    And I follow "Make comment or override mark"
+    And I switch to "commentquestion" window
+    And I set the field "Comment" to "Administrator's comment"
+    # Atto needs focus to add image, select empty p tag to do so.
+    And I select the text in the "Comment" Atto editor
+    And I click on "Image" "button" in the "[data-fieldtype=editor]" "css_element"
+    And I click on "Browse repositories..." "button"
+    And I click on "Private files" "link" in the ".fp-repo-area" "css_element"
+    And I click on "moodle_logo.jpg" "link"
+    And I click on "Select this file" "button"
+    And I set the field "Describe this image for someone who cannot see it" to "It's the logo"
+    And I click on "Save image" "button"
+    # Editor is not inserting the html for the image correctly
+    # when running under behat so line below manually inserts it.
+    And I set the field "Comment" to "<img src=\"@@PLUGINFILE@@/moodle_logo.jpg\" alt=\"It's the logo\" width=\"48\" height=\"48\" class=\"img-responsive atto_image_button_text-bottom\"><!-- File hash: a8e3ffba4ab315b3fb9187ebbf122fe9 -->"
+    And I press "Save" and switch to main window
+    And I switch to the main window
+    And I should see "It's the logo" in the "3" "table_row"
+    And "//*[contains(@class, 'comment')]//img[contains(@src, 'moodle_logo.jpg')]" "xpath_element" should exist
+    # This time is same as time the window is open. So wait for it to close before proceeding.
+    And I wait "2" seconds
diff --git a/mod/quiz/tests/fixtures/moodle_logo.jpg b/mod/quiz/tests/fixtures/moodle_logo.jpg
new file mode 100644 (file)
index 0000000..f2d5365
Binary files /dev/null and b/mod/quiz/tests/fixtures/moodle_logo.jpg differ
diff --git a/mod/workshop/form/accumulative/lang/en/deprecated.txt b/mod/workshop/form/accumulative/lang/en/deprecated.txt
deleted file mode 100644 (file)
index a7d55aa..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-dimensioncomment,workshopform_accumulative
-dimensiongrade,workshopform_accumulative
index 31ab57f..43567c4 100644 (file)
@@ -48,6 +48,3 @@ $string['scalename5'] = 'Excellent/Very poor (5 point)';
 $string['scalename6'] = 'Excellent/Very poor (7 point)';
 $string['verypoor'] = 'Very poor';
 
-// Deprecated since Moodle 3.1.
-$string['dimensioncomment'] = 'Comment';
-$string['dimensiongrade'] = 'Grade';
diff --git a/mod/workshop/form/comments/lang/en/deprecated.txt b/mod/workshop/form/comments/lang/en/deprecated.txt
deleted file mode 100644 (file)
index a680205..0000000
+++ /dev/null
@@ -1 +0,0 @@
-dimensioncomment,workshopform_comments
index fb11fbe..7677acd 100644 (file)
@@ -29,5 +29,3 @@ $string['dimensiondescription'] = 'Description';
 $string['dimensionnumber'] = 'Aspect {$a}';
 $string['pluginname'] = 'Comments';
 
-// Deprecated since Moodle 3.1.
-$string['dimensioncomment'] = 'Comment';
diff --git a/mod/workshop/form/numerrors/lang/en/deprecated.txt b/mod/workshop/form/numerrors/lang/en/deprecated.txt
deleted file mode 100644 (file)
index c078309..0000000
+++ /dev/null
@@ -1 +0,0 @@
-dimensioncomment,workshopform_numerrors
index 55fd534..307cfed 100644 (file)
@@ -41,5 +41,3 @@ $string['mapgrade'] = 'Grade for submission';
 $string['percents'] = '{$a} %';
 $string['pluginname'] = 'Number of errors';
 
-// Deprecated since Moodle 3.1.
-$string['dimensioncomment'] = 'Comment';
index dc549a1..0be98a2 100644 (file)
@@ -1,3 +1,2 @@
 err_unknownfileextension,mod_workshop
 err_wrongfileextension,mod_workshop
-yourassessment,mod_workshop
index b09bb2a..a7b383f 100644 (file)
@@ -371,9 +371,6 @@ $string['yourassessmentfor'] = 'Your assessment for {$a}';
 $string['yourgrades'] = 'Your grades';
 $string['yoursubmission'] = 'Your submission';
 
-// Deprecated since Moodle 3.1.
-$string['yourassessment'] = 'Your assessment';
-
 // Deprecated since Moodle 3.4.
 $string['err_unknownfileextension'] = 'Unknown file extension: {$a}';
 $string['err_wrongfileextension'] = 'Some files ({$a->wrongfiles}) cannot be uploaded. Only file types {$a->whitelist} are allowed.';
index 6558785..3b9943f 100644 (file)
@@ -124,6 +124,17 @@ abstract class question_behaviour {
      */
     public function check_file_access($options, $component, $filearea, $args, $forcedownload) {
         $this->adjust_display_options($options);
+
+        if ($component == 'question' && $filearea == 'response_bf_comment') {
+            foreach ($this->qa->get_step_iterator() as $attemptstep) {
+                if ($attemptstep->get_id() == $args[0]) {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+
         return $this->question->check_file_access($this->qa, $options, $component,
                 $filearea, $args, $forcedownload);
     }
@@ -202,7 +213,7 @@ abstract class question_behaviour {
             return array();
         }
 
-        $vars = array('comment' => PARAM_RAW, 'commentformat' => PARAM_INT);
+        $vars = array('comment' => question_attempt::PARAM_RAW_FILES, 'commentformat' => PARAM_INT);
         if ($this->qa->get_max_mark()) {
             $vars['mark'] = PARAM_RAW_TRIMMED;
             $vars['maxmark'] = PARAM_FLOAT;
@@ -507,15 +518,20 @@ abstract class question_behaviour {
      * @param $comment the comment text to format. If omitted,
      *      $this->qa->get_manual_comment() is used.
      * @param $commentformat the format of the comment, one of the FORMAT_... constants.
+     * @param $context the quiz context.
      * @return string the comment, ready to be output.
      */
-    public function format_comment($comment = null, $commentformat = null) {
+    public function format_comment($comment = null, $commentformat = null, $context = null) {
         $formatoptions = new stdClass();
         $formatoptions->noclean = true;
         $formatoptions->para = false;
 
         if (is_null($comment)) {
-            list($comment, $commentformat) = $this->qa->get_manual_comment();
+            list($comment, $commentformat, $commentstep) = $this->qa->get_manual_comment();
+        }
+
+        if ($context !== null) {
+            $comment = $this->qa->rewrite_response_pluginfile_urls($comment, $context->id, 'bf_comment', $commentstep);
         }
 
         return format_text($comment, $commentformat, $formatoptions);
@@ -528,8 +544,9 @@ abstract class question_behaviour {
     protected function summarise_manual_comment($step) {
         $a = new stdClass();
         if ($step->has_behaviour_var('comment')) {
-            $a->comment = shorten_text(html_to_text($this->format_comment(
-                    $step->get_behaviour_var('comment')), 0, false), 200);
+            list($comment, $commentformat, $commentstep) = $this->qa->get_manual_comment();
+            $comment = question_utils::to_plain_text($comment, $commentformat);
+            $a->comment = shorten_text($comment, 200);
         } else {
             $a->comment = '';
         }
index b474887..c791866 100644 (file)
@@ -69,9 +69,14 @@ abstract class qbehaviour_renderer extends plugin_renderer_base {
     }
 
     public function manual_comment_fields(question_attempt $qa, question_display_options $options) {
+        global $CFG;
+
+        require_once($CFG->dirroot.'/lib/filelib.php');
+        require_once($CFG->dirroot.'/repository/lib.php');
+
         $inputname = $qa->get_behaviour_field_name('comment');
         $id = $inputname . '_id';
-        list($commenttext, $commentformat) = $qa->get_current_manual_comment();
+        list($commenttext, $commentformat, $commentstep) = $qa->get_current_manual_comment();
 
         $editor = editors_get_preferred_editor($commentformat);
         $strformats = format_text_menu();
@@ -80,12 +85,27 @@ abstract class qbehaviour_renderer extends plugin_renderer_base {
             $formats[$fid] = $strformats[$fid];
         }
 
+        $draftitemareainputname = $qa->get_behaviour_field_name('comment:itemid');
+        $draftitemid = optional_param($draftitemareainputname, false, PARAM_INT);
+
+        if (!$draftitemid && $commentstep === null) {
+            $commenttext = '';
+            $draftitemid = file_get_unused_draft_itemid();
+        } else if (!$draftitemid) {
+            list($draftitemid, $commenttext) = $commentstep->prepare_response_files_draft_itemid_with_text(
+                    'bf_comment', $options->context->id, $commenttext);
+        }
+
         $editor->set_text($commenttext);
-        $editor->use_editor($id, array('context' => $options->context));
+        $editor->use_editor($id, question_utils::get_editor_options($options->context),
+                question_utils::get_filepicker_options($options->context, $draftitemid));
 
         $commenteditor = html_writer::tag('div', html_writer::tag('textarea', s($commenttext),
                 array('id' => $id, 'name' => $inputname, 'rows' => 10, 'cols' => 60)));
 
+        $attributes = ['type'  => 'hidden', 'name'  => $draftitemareainputname, 'value' => $draftitemid];
+        $commenteditor .= html_writer::empty_tag('input', $attributes);
+
         $editorformat = '';
         if (count($formats) == 1) {
             reset($formats);
@@ -105,7 +125,7 @@ abstract class qbehaviour_renderer extends plugin_renderer_base {
         $comment = html_writer::tag('div', html_writer::tag('div',
                 html_writer::tag('label', get_string('comment', 'question'),
                 array('for' => $id)), array('class' => 'fitemtitle')) .
-                html_writer::tag('div', $commenteditor, array('class' => 'felement fhtmleditor')),
+                html_writer::tag('div', $commenteditor, array('class' => 'felement fhtmleditor', 'data-fieldtype' => "editor")),
                 array('class' => 'fitem'));
         $comment .= $editorformat;
 
@@ -168,7 +188,7 @@ abstract class qbehaviour_renderer extends plugin_renderer_base {
     public function manual_comment_view(question_attempt $qa, question_display_options $options) {
         $output = '';
         if ($qa->has_manual_comment()) {
-            $output .= get_string('commentx', 'question', $qa->get_behaviour()->format_comment());
+            $output .= get_string('commentx', 'question', $qa->get_behaviour()->format_comment(null, null, $options->context));
         }
         if ($options->manualcommentlink) {
             $url = new moodle_url($options->manualcommentlink, array('slot' => $qa->get_slot()));
index 1889378..b65ce4b 100644 (file)
@@ -954,6 +954,65 @@ abstract class question_utils {
         $text = str_replace('@@PLUGINFILE@@/', 'http://example.com/', $text);
         return html_to_text(format_text($text, $format, $options), 0, false);
     }
+
+    /**
+     * Get the options required to configure the filepicker for one of the editor
+     * toolbar buttons.
+     * @param mixed $acceptedtypes array of types of '*'.
+     * @param int $draftitemid the draft area item id.
+     * @param object $context the context.
+     * @return object the required options.
+     */
+    protected static function specific_filepicker_options($acceptedtypes, $draftitemid, $context) {
+        $filepickeroptions = new stdClass();
+        $filepickeroptions->accepted_types = $acceptedtypes;
+        $filepickeroptions->return_types = FILE_INTERNAL | FILE_EXTERNAL;
+        $filepickeroptions->context = $context;
+        $filepickeroptions->env = 'filepicker';
+
+        $options = initialise_filepicker($filepickeroptions);
+        $options->context = $context;
+        $options->client_id = uniqid();
+        $options->env = 'editor';
+        $options->itemid = $draftitemid;
+
+        return $options;
+    }
+
+    /**
+     * Get filepicker options for question related text areas.
+     * @param object $context the context.
+     * @param int $draftitemid the draft area item id.
+     * @return array An array of options
+     */
+    public static function get_filepicker_options($context, $draftitemid) {
+        return [
+                'image' => self::specific_filepicker_options(['image'], $draftitemid, $context),
+                'media' => self::specific_filepicker_options(['video', 'audio'], $draftitemid, $context),
+                'link'  => self::specific_filepicker_options('*', $draftitemid, $context),
+            ];
+    }
+
+    /**
+     * Get editor options for question related text areas.
+     * @param object $context the context.
+     * @return array An array of options
+     */
+    public static function get_editor_options($context) {
+        global $CFG;
+
+        $editoroptions = [
+                'subdirs'  => 0,
+                'context'  => $context,
+                'maxfiles' => EDITOR_UNLIMITED_FILES,
+                'maxbytes' => $CFG->maxbytes,
+                'noclean' => 0,
+                'trusttext' => 0,
+                'autosave' => false
+        ];
+
+        return $editoroptions;
+    }
 }
 
 
index d295170..5473535 100644 (file)
@@ -1107,8 +1107,10 @@ class question_attempt {
             return null;
         }
 
-        return new question_file_saver($draftitemid, 'question', 'response_' .
-                str_replace($this->get_field_prefix(), '', $name), $text);
+        $filearea = str_replace($this->get_field_prefix(), '', $name);
+        $filearea = str_replace('-', 'bf_', $filearea);
+        $filearea = 'response_' . $filearea;
+        return new question_file_saver($draftitemid, 'question', $filearea, $text);
     }
 
     /**
@@ -1164,6 +1166,8 @@ class question_attempt {
                 $this->behaviour->get_expected_data(), $postdata, '-');
 
         $expected = $this->behaviour->get_expected_qt_data();
+        $this->check_qt_var_name_restrictions($expected);
+
         if ($expected === self::USE_RAW_DATA) {
             $submitteddata += $this->get_all_submitted_qt_vars($postdata);
         } else {
@@ -1172,6 +1176,23 @@ class question_attempt {
         return $submitteddata;
     }
 
+    /**
+     * Ensure that no reserved prefixes are being used by installed
+     * question types.
+     * @param array $expected An array of question type variables
+     */
+    protected function check_qt_var_name_restrictions($expected) {
+        global $CFG;
+
+        if ($CFG->debugdeveloper) {
+            foreach ($expected as $key => $value) {
+                if (strpos($key, 'bf_') !== false) {
+                    debugging('The bf_ prefix is reserved and cannot be used by question types', DEBUG_DEVELOPER);
+                }
+            }
+        }
+    }
+
     /**
      * Get a set of response data for this question attempt that would get the
      * best possible mark. If it is not possible to compute a correct
@@ -1370,16 +1391,17 @@ class question_attempt {
 
     /**
      * @return array(string, int) the most recent manual comment that was added
-     * to this question, and the FORMAT_... it is.
+     * to this question, the FORMAT_... it is and the step itself.
      */
     public function get_manual_comment() {
         foreach ($this->get_reverse_step_iterator() as $step) {
             if ($step->has_behaviour_var('comment')) {
                 return array($step->get_behaviour_var('comment'),
-                        $step->get_behaviour_var('commentformat'));
+                        $step->get_behaviour_var('commentformat'),
+                        $step);
             }
         }
-        return array(null, null);
+        return array(null, null, null);
     }
 
     /**
@@ -1399,7 +1421,7 @@ class question_attempt {
             if ($commentformat === null) {
                 $commentformat = FORMAT_HTML;
             }
-            return array($comment, $commentformat);
+            return array($comment, $commentformat, null);
         }
     }
 
index a6352ef..9b04c49 100644 (file)
@@ -358,28 +358,28 @@ class qtype_essay_format_editorfilepicker_renderer extends qtype_essay_format_ed
                 $name, $context->id, $step->get_qt_var($name));
     }
 
+    /**
+     * Get editor options for question response text area.
+     * @param object $context the context the attempt belongs to.
+     * @return array options for the editor.
+     */
     protected function get_editor_options($context) {
-        // Disable the text-editor autosave because quiz has it's own auto save function.
-        return array(
-            'subdirs' => 0,
-            'maxbytes' => 0,
-            'maxfiles' => -1,
-            'context' => $context,
-            'noclean' => 0,
-            'trusttext'=> 0,
-            'autosave' => false
-        );
+        return question_utils::get_editor_options($context);
     }
 
     /**
      * Get the options required to configure the filepicker for one of the editor
      * toolbar buttons.
+     * @deprecated since 3.5
      * @param mixed $acceptedtypes array of types of '*'.
      * @param int $draftitemid the draft area item id.
      * @param object $context the context.
      * @return object the required options.
      */
     protected function specific_filepicker_options($acceptedtypes, $draftitemid, $context) {
+        debugging('qtype_essay_format_editorfilepicker_renderer::specific_filepicker_options() is deprecated, ' .
+            'use question_utils::specific_filepicker_options() instead.', DEBUG_DEVELOPER);
+
         $filepickeroptions = new stdClass();
         $filepickeroptions->accepted_types = $acceptedtypes;
         $filepickeroptions->return_types = FILE_INTERNAL | FILE_EXTERNAL;
@@ -395,17 +395,13 @@ class qtype_essay_format_editorfilepicker_renderer extends qtype_essay_format_ed
         return $options;
     }
 
+    /**
+     * @param object $context the context the attempt belongs to.
+     * @param int $draftitemid draft item id.
+     * @return array filepicker options for the editor.
+     */
     protected function get_filepicker_options($context, $draftitemid) {
-        global $CFG;
-
-        return array(
-            'image' => $this->specific_filepicker_options(array('image'),
-                            $draftitemid, $context),
-            'media' => $this->specific_filepicker_options(array('video', 'audio'),
-                            $draftitemid, $context),
-            'link'  => $this->specific_filepicker_options('*',
-                            $draftitemid, $context),
-        );
+        return question_utils::get_filepicker_options($context, $draftitemid);
     }
 
     protected function filepicker_html($inputname, $draftitemid) {