diff --git a/mod/data/backup/moodle2/backup_data_activity_task.class.php b/mod/data/backup/moodle2/backup_data_activity_task.class.php index 94fa9e3f65e..a1de664a842 100644 --- a/mod/data/backup/moodle2/backup_data_activity_task.class.php +++ b/mod/data/backup/moodle2/backup_data_activity_task.class.php @@ -56,22 +56,55 @@ class backup_data_activity_task extends backup_activity_task { global $CFG; $base = preg_quote($CFG->wwwroot,"/"); + $baseunquoted = $CFG->wwwroot; - // Link to the list of datas - $search="/(".$base."\/mod\/data\/index.php\?id\=)([0-9]+)/"; - $content= preg_replace($search, '$@DATAINDEX*$2@$', $content); + // Link to the list of datas. + $search = '/(' . $base . '\/mod\/data\/index.php\?id\=)([0-9]+)/'; + $content = preg_replace($search, '$@DATAINDEX*$2@$', $content); - // Link to data view by moduleid - $search="/(".$base."\/mod\/data\/view.php\?id\=)([0-9]+)/"; - $content= preg_replace($search, '$@DATAVIEWBYID*$2@$', $content); + // Link to the list of datas, urlencoded. + $search = '/(' . urlencode($baseunquoted . '/mod/data/index.php?id=') . ')([0-9]+)/'; + $content = preg_replace($search, '$@DATAINDEXURLENCODED*$2@$', $content); - /// Link to database view by databaseid - $search="/(".$base."\/mod\/data\/view.php\?d\=)([0-9]+)/"; - $content= preg_replace($search,'$@DATAVIEWBYD*$2@$', $content); + // Link to data view by moduleid. + $search = '/(' . $base . '\/mod\/data\/view.php\?id\=)([0-9]+)/'; + $content = preg_replace($search, '$@DATAVIEWBYID*$2@$', $content); - /// Link to one "record" of the database - $search="/(".$base."\/mod\/data\/view.php\?d\=)([0-9]+)\&(amp;)rid\=([0-9]+)/"; - $content= preg_replace($search,'$@DATAVIEWRECORD*$2*$4@$', $content); + // Link to data view by moduleid, urlencoded. + $search = '/(' . urlencode($baseunquoted . '/mod/data/view.php?id=') . ')([0-9]+)/'; + $content = preg_replace($search, '$@DATAVIEWBYIDURLENCODED*$2@$', $content); + + // Link to one "record" of the database. + $search = '/(' . $base . '\/mod\/data\/view.php\?d\=)([0-9]+)\&(amp;)rid\=([0-9]+)/'; + $content = preg_replace($search, '$@DATAVIEWRECORD*$2*$4@$', $content); + + // Link to one "record" of the database, urlencoded. + $search = '/(' . urlencode($baseunquoted . '/mod/data/view.php?d=') . ')([0-9]+)%26rid%3D([0-9]+)/'; + $content = preg_replace($search, '$@DATAVIEWRECORDURLENCODED*$2*$3@$', $content); + + // Link to database view by databaseid. + $search = '/(' . $base . '\/mod\/data\/view.php\?d\=)([0-9]+)/'; + $content = preg_replace($search, '$@DATAVIEWBYD*$2@$', $content); + + // Link to database view by databaseid, urlencoded. + $search = '/(' . urlencode($baseunquoted . '/mod/data/view.php?d=') . ')([0-9]+)/'; + $content = preg_replace($search, '$@DATAVIEWBYDURLENCODED*$2@$', $content); + + // Link to the edit page. + $search = '/(' . $base . '\/mod\/data\/edit.php\?id\=)([0-9]+)/'; + $content = preg_replace($search, '$@DATAEDITBYID*$2@$', $content); + + // Link to the edit page, urlencoded. + $search = '/(' . urlencode($baseunquoted . '/mod/data/edit.php?id=') . ')([0-9]+)/'; + $content = preg_replace($search, '$@DATAEDITBYIDURLENCODED*$2@$', $content); + + // Link to the edit page by databaseid. + $search = '/(' . $base . '\/mod\/data\/edit.php\?d\=)([0-9]+)/'; + $content = preg_replace($search, '$@DATAEDITBYD*$2@$', $content); + + // Link to the edit page by databaseid, urlencoded. + $search = '/(' . urlencode($baseunquoted . '/mod/data/edit.php?d=') . ')([0-9]+)/'; + $content = preg_replace($search, '$@DATAEDITBYDURLENCODED*$2@$', $content); return $content; } diff --git a/mod/data/backup/moodle2/restore_data_activity_task.class.php b/mod/data/backup/moodle2/restore_data_activity_task.class.php index e9be75ac30b..588fd54b055 100644 --- a/mod/data/backup/moodle2/restore_data_activity_task.class.php +++ b/mod/data/backup/moodle2/restore_data_activity_task.class.php @@ -72,15 +72,27 @@ class restore_data_activity_task extends restore_activity_task { * to the activity to be executed by the link decoder */ public static function define_decode_rules() { - $rules = array(); + $rules = []; $rules[] = new restore_decode_rule('DATAVIEWBYID', '/mod/data/view.php?id=$1', 'course_module'); + $rules[] = new restore_decode_rule('DATAVIEWBYIDURLENCODED', '/mod/data/view.php?id=$1', 'course_module', true); $rules[] = new restore_decode_rule('DATAVIEWBYD', '/mod/data/view.php?d=$1', 'data'); + $rules[] = new restore_decode_rule('DATAVIEWBYDURLENCODED', '/mod/data/view.php?d=$1', 'data', true); $rules[] = new restore_decode_rule('DATAINDEX', '/mod/data/index.php?id=$1', 'course'); - $rules[] = new restore_decode_rule('DATAVIEWRECORD', '/mod/data/view.php?d=$1&rid=$2', array('data', 'data_record')); + $rules[] = new restore_decode_rule('DATAINDEXURLENCODED', '/mod/data/index.php?id=$1', 'course', true); + $rules[] = new restore_decode_rule('DATAVIEWRECORD', '/mod/data/view.php?d=$1&rid=$2', ['data', 'data_record']); + $rules[] = new restore_decode_rule( + 'DATAVIEWRECORDURLENCODED', + '/mod/data/view.php?d=$1&rid=$2', + ['data', 'data_record'], + true + ); + $rules[] = new restore_decode_rule('DATAEDITBYID', '/mod/data/edit.php?id=$1', 'course_module'); + $rules[] = new restore_decode_rule('DATAEDITBYIDURLENCODED', '/mod/data/edit.php?id=$1', 'course_module', true); + $rules[] = new restore_decode_rule('DATAEDITBYD', '/mod/data/edit.php?d=$1', 'data'); + $rules[] = new restore_decode_rule('DATAEDITBYDURLENCODED', '/mod/data/edit.php?d=$1', 'data', true); return $rules; - } /** diff --git a/mod/data/tests/backup/encode_links_test.php b/mod/data/tests/backup/encode_links_test.php new file mode 100644 index 00000000000..14d4a0a28aa --- /dev/null +++ b/mod/data/tests/backup/encode_links_test.php @@ -0,0 +1,87 @@ +. + +namespace mod_data\backup; + +/** + * Tests for Database + * + * @package mod_data + * @category test + * @copyright 2025 ISB Bayern + * @author Stefan Hanauska + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +final class encode_links_test extends \advanced_testcase { + /** + * Test that links are encoded correctly. + * + * @return void + * + * @covers \backup_data_activity_task::encode_content_links + * @covers \restore_data_activity_task::define_decode_rules + */ + public function test_encode_links(): void { + global $CFG, $DB; + $this->resetAfterTest(); + $this->setAdminUser(); + + // Make a test course. + $generator = $this->getDataGenerator(); + $course = $generator->create_course(); + $newcourse = $generator->create_course(); + $data = $this->getDataGenerator()->create_module('data', ['course' => $course->id]); + $datagenerator = $this->getDataGenerator()->get_plugin_generator('mod_data'); + $field = $datagenerator->create_field( + (object) ['name' => 'field', 'type' => 'text'], + $data + ); + + $entry = [$field->field->id => 'test']; + $datagenerator->create_entry($data, $entry); + + $data->intro = $CFG->wwwroot . '/mod/data/view.php?id=' . $data->cmid . '|'; + $data->intro .= urlencode($CFG->wwwroot . '/mod/data/view.php?id='. $data->cmid) . '|'; + $data->intro .= $CFG->wwwroot . '/mod/data/view.php?d=' . $data->id . '|'; + $data->intro .= urlencode($CFG->wwwroot . '/mod/data/view.php?d='. $data->id) . '|'; + $data->intro .= $CFG->wwwroot . '/mod/data/index.php?id=' . $data->course . '|'; + $data->intro .= urlencode($CFG->wwwroot . '/mod/data/index.php?id=' . $data->course) . '|'; + $data->intro .= $CFG->wwwroot . '/mod/data/edit.php?id=' . $data->cmid . '|'; + $data->intro .= urlencode($CFG->wwwroot . '/mod/data/edit.php?id='. $data->cmid) . '|'; + $data->intro .= $CFG->wwwroot . '/mod/data/edit.php?d=' . $data->id . '|'; + $data->intro .= urlencode($CFG->wwwroot . '/mod/data/edit.php?d=' . $data->id) . '|'; + + $DB->update_record('data', $data); + + // Duplicate the data module with the type. + $newcm = duplicate_module($course, get_fast_modinfo($course)->get_cm($data->cmid)); + + $newdata = $DB->get_record('data', ['id' => $newcm->instance]); + + $expected = $CFG->wwwroot . '/mod/data/view.php?id=' . $newcm->id . '|'; + $expected .= urlencode($CFG->wwwroot . '/mod/data/view.php?id=' . $newcm->id) . '|'; + $expected .= $CFG->wwwroot . '/mod/data/view.php?d=' . $newdata->id . '|'; + $expected .= urlencode($CFG->wwwroot . '/mod/data/view.php?d=' . $newdata->id) . '|'; + $expected .= $CFG->wwwroot . '/mod/data/index.php?id=' . $newcm->course . '|'; + $expected .= urlencode($CFG->wwwroot . '/mod/data/index.php?id=' . $newcm->course) . '|'; + $expected .= $CFG->wwwroot . '/mod/data/edit.php?id=' . $newcm->id . '|'; + $expected .= urlencode($CFG->wwwroot . '/mod/data/edit.php?id='. $newcm->id) . '|'; + $expected .= $CFG->wwwroot . '/mod/data/edit.php?d=' . $newdata->id . '|'; + $expected .= urlencode($CFG->wwwroot . '/mod/data/edit.php?d=' . $newdata->id) . '|'; + + $this->assertEquals($expected, $newdata->intro); + } +}