From 3041fe6faa8ad26a090c73e312c103588cd3322c Mon Sep 17 00:00:00 2001 From: Ryan Wyllie Date: Wed, 2 May 2018 12:08:58 +0800 Subject: [PATCH] MDL-62285 privacy: use context id when generating context path moodle_content_writer::get_context_path() now includes the context id in the path to ensure that it will always generate unique paths even when the context names are not unique. --- .../local/request/moodle_content_writer.php | 4 +- privacy/tests/moodle_content_writer_test.php | 56 +++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/privacy/classes/local/request/moodle_content_writer.php b/privacy/classes/local/request/moodle_content_writer.php index de607ccdf82..b83ee9a5097 100644 --- a/privacy/classes/local/request/moodle_content_writer.php +++ b/privacy/classes/local/request/moodle_content_writer.php @@ -244,7 +244,9 @@ class moodle_content_writer implements content_writer { $path = []; $contexts = array_reverse($this->context->get_parent_contexts(true)); foreach ($contexts as $context) { - $path[] = clean_param($context->get_context_name(), PARAM_FILE); + $name = $context->get_context_name(); + $id = $context->id; + $path[] = clean_param("{$name} {$id}", PARAM_FILE); } return $path; diff --git a/privacy/tests/moodle_content_writer_test.php b/privacy/tests/moodle_content_writer_test.php index b683348186f..7b49ef9dc45 100644 --- a/privacy/tests/moodle_content_writer_test.php +++ b/privacy/tests/moodle_content_writer_test.php @@ -677,6 +677,62 @@ class moodle_content_writer_test extends advanced_testcase { $this->assertEquals($desc, $data->description); } + /** + * Writing user preferences for two different blocks with the same name and + * same parent context should generate two different context paths and export + * files. + */ + public function test_export_user_preference_context_block_multiple_instances() { + $this->resetAfterTest(); + + $generator = $this->getDataGenerator(); + $course = $generator->create_course(); + $coursecontext = context_course::instance($course->id); + $block1 = $generator->create_block('online_users', ['parentcontextid' => $coursecontext->id]); + $block2 = $generator->create_block('online_users', ['parentcontextid' => $coursecontext->id]); + $block1context = context_block::instance($block1->id); + $block2context = context_block::instance($block2->id); + $component = 'block'; + $desc = 'test preference'; + $block1key = 'block1key'; + $block1value = 'block1value'; + $block2key = 'block2key'; + $block2value = 'block2value'; + $writer = $this->get_writer_instance(); + + // Confirm that we have two different block contexts with the same name + // and the same parent context id. + $this->assertNotEquals($block1context->id, $block2context->id); + $this->assertEquals($block1context->get_context_name(), $block2context->get_context_name()); + $this->assertEquals($block1context->get_parent_context()->id, $block2context->get_parent_context()->id); + + $retrieveexport = function($context) use ($writer, $component) { + $fileroot = $this->fetch_exported_content($writer); + + $contextpath = $this->get_context_path($context, [get_string('userpreferences')], "{$component}.json"); + $this->assertTrue($fileroot->hasChild($contextpath)); + + $json = $fileroot->getChild($contextpath)->getContent(); + return json_decode($json); + }; + + $writer->set_context($block1context) + ->export_user_preference($component, $block1key, $block1value, $desc); + $writer->set_context($block2context) + ->export_user_preference($component, $block2key, $block2value, $desc); + + $block1export = $retrieveexport($block1context); + $block2export = $retrieveexport($block2context); + + // Confirm that the exports didn't write to the same file. + $this->assertTrue(isset($block1export->$block1key)); + $this->assertTrue(isset($block2export->$block2key)); + $this->assertFalse(isset($block1export->$block2key)); + $this->assertFalse(isset($block2export->$block1key)); + $this->assertEquals($block1value, $block1export->$block1key->value); + $this->assertEquals($block2value, $block2export->$block2key->value); + } + /** * User preferences can be exported against the system. *