Skip to content

Commit

Permalink
MDL-62285 privacy: use context id when generating context path
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
ryanwyllie committed May 2, 2018
1 parent 446d848 commit 3041fe6
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 1 deletion.
4 changes: 3 additions & 1 deletion privacy/classes/local/request/moodle_content_writer.php
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,9 @@ protected function get_context_path() : Array {
$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;
Expand Down
56 changes: 56 additions & 0 deletions privacy/tests/moodle_content_writer_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,62 @@ public function test_export_user_preference_context_block($component, $key, $val
$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.
*
Expand Down

0 comments on commit 3041fe6

Please sign in to comment.