diff --git a/lib/tests/weblib_test.php b/lib/tests/weblib_test.php
index 87185348148..1cdd34b6db0 100644
--- a/lib/tests/weblib_test.php
+++ b/lib/tests/weblib_test.php
@@ -492,4 +492,43 @@ class core_weblib_testcase extends advanced_testcase {
$this->assertEquals(DEBUG_NONE, $CFG->debug);
$this->assertFalse($CFG->debugdeveloper);
}
+
+ public function test_strip_pluginfile_content() {
+ $source = <<
+External link 2:
+Internal link 1:
+Internal link 2:
+Anchor link 1:Link text
+Anchor link 2:Link text
+Anchor + ext. img:
+Ext. anchor + img:
+SOURCE;
+ $expected = <<
+External link 2:
+Internal link 1:
+Internal link 2:
+Anchor link 1:Link text
+Anchor link 2:Link text
+Anchor + ext. img:
+Ext. anchor + img:
+EXPECTED;
+ $this->assertSame($expected, strip_pluginfile_content($source));
+ }
+
}
diff --git a/lib/weblib.php b/lib/weblib.php
index 680d091de78..ef395228b57 100644
--- a/lib/weblib.php
+++ b/lib/weblib.php
@@ -1523,6 +1523,25 @@ function format_module_intro($module, $activity, $cmid, $filter=true) {
return trim(format_text($intro, $activity->introformat, $options, null));
}
+/**
+ * Removes the usage of Moodle files from a text.
+ *
+ * In some rare cases we need to re-use a text that already has embedded links
+ * to some files hosted within Moodle. But the new area in which we will push
+ * this content does not support files... therefore we need to remove those files.
+ *
+ * @param string $source The text
+ * @return string The stripped text
+ */
+function strip_pluginfile_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);
+}
+
/**
* Legacy function, used for cleaning of old forum and glossary text only.
*
diff --git a/mod/assign/feedback/comments/locallib.php b/mod/assign/feedback/comments/locallib.php
index 1f043cb5a5a..96dde23d982 100644
--- a/mod/assign/feedback/comments/locallib.php
+++ b/mod/assign/feedback/comments/locallib.php
@@ -214,23 +214,6 @@ class assign_feedback_comments extends assign_feedback_plugin {
$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.
@@ -247,7 +230,7 @@ class assign_feedback_comments extends assign_feedback_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));
+ $rawtext = strip_pluginfile_content($plugin->get_editor_text($key, $submission->id));
$newformat = $plugin->get_editor_format($key, $submission->id);
diff --git a/mod/assign/locallib.php b/mod/assign/locallib.php
index 71ce279329e..2d5acfdfe37 100644
--- a/mod/assign/locallib.php
+++ b/mod/assign/locallib.php
@@ -831,30 +831,37 @@ class assign {
$event = new stdClass();
$params = array('modulename'=>'assign', 'instance'=>$instance->id);
- $event->id = $DB->get_field('event',
- 'id',
- $params);
+ $event->id = $DB->get_field('event', 'id', $params);
+ $event->name = $instance->name;
+ $event->timestart = $instance->duedate;
+
+ // Convert the links to pluginfile. It is a bit hacky but at this stage the files
+ // might not have been saved in the module area yet.
+ $intro = $instance->intro;
+ if ($draftid = file_get_submitted_draft_itemid('introeditor')) {
+ $intro = file_rewrite_urls_to_pluginfile($intro, $draftid);
+ }
+
+ // We need to remove the links to files as the calendar is not ready
+ // to support module events with file areas.
+ $intro = strip_pluginfile_content($intro);
+ $event->description = array(
+ 'text' => $intro,
+ 'format' => $instance->introformat
+ );
if ($event->id) {
- $event->name = $instance->name;
- $event->description = format_module_intro('assign', $instance, $coursemoduleid);
- $event->timestart = $instance->duedate;
-
$calendarevent = calendar_event::load($event->id);
$calendarevent->update($event);
} else {
- $event = new stdClass();
- $event->name = $instance->name;
- $event->description = format_module_intro('assign', $instance, $coursemoduleid);
+ unset($event->id);
$event->courseid = $instance->course;
$event->groupid = 0;
$event->userid = 0;
$event->modulename = 'assign';
$event->instance = $instance->id;
$event->eventtype = 'due';
- $event->timestart = $instance->duedate;
$event->timeduration = 0;
-
calendar_event::create($event);
}
} else {
diff --git a/mod/assign/tests/locallib_test.php b/mod/assign/tests/locallib_test.php
index 0e703ae6237..77c08975afe 100644
--- a/mod/assign/tests/locallib_test.php
+++ b/mod/assign/tests/locallib_test.php
@@ -296,15 +296,45 @@ class mod_assign_locallib_testcase extends mod_assign_base_testcase {
public function test_update_calendar() {
global $DB;
- $now = time();
$this->setUser($this->editingteachers[0]);
- $assign = $this->create_instance(array('duedate'=>$now));
+ $userctx = context_user::instance($this->editingteachers[0]->id)->id;
+
+ // Hack to pretend that there was an editor involved. We need both $_POST and $_REQUEST, and a sesskey.
+ $draftid = file_get_unused_draft_itemid();
+ $_REQUEST['introeditor'] = $draftid;
+ $_POST['introeditor'] = $draftid;
+ $_POST['sesskey'] = sesskey();
+
+ // Write links to a draft area.
+ $fakearealink1 = file_rewrite_pluginfile_urls('link', 'draftfile.php', $userctx,
+ 'user', 'draft', $draftid);
+ $fakearealink2 = file_rewrite_pluginfile_urls('new', 'draftfile.php', $userctx,
+ 'user', 'draft', $draftid);
+
+ // Create a new assignment with links to a draft area.
+ $now = time();
+ $assign = $this->create_instance(array(
+ 'duedate' => $now,
+ 'intro' => $fakearealink1,
+ 'introformat' => FORMAT_HTML
+ ));
// See if there is an event in the calendar.
$params = array('modulename'=>'assign', 'instance'=>$assign->get_instance()->id);
- $id = $DB->get_field('event', 'id', $params);
+ $event = $DB->get_record('event', $params);
+ $this->assertNotEmpty($event);
+ $this->assertSame('link', $event->description); // The pluginfile links are removed.
- $this->assertEquals(false, empty($id));
+ // Make sure the same works when updating the assignment.
+ $instance = $assign->get_instance();
+ $instance->instance = $instance->id;
+ $instance->intro = $fakearealink2;
+ $instance->introformat = FORMAT_HTML;
+ $assign->update_instance($instance);
+ $params = array('modulename' => 'assign', 'instance' => $assign->get_instance()->id);
+ $event = $DB->get_record('event', $params);
+ $this->assertNotEmpty($event);
+ $this->assertSame('new', $event->description); // The pluginfile links are removed.
}
public function test_update_instance() {