Commit 431e5b6d authored by Dan Poltawski's avatar Dan Poltawski
Browse files

Merge branch 'wip-MDL-50851-backupfix' of https://github.com/marinaglancy/moodle

parents 4bc9112b 71da0356
......@@ -369,15 +369,17 @@ class core_tag_area {
$cleanupcollections = $DB->get_fieldset_sql($sql, $params);
// Find all tags that are related to the tags being moved and make sure they are present in the target tagcoll.
$sql = "SELECT DISTINCT r.name, r.rawname, r.description, r.descriptionformat, ".
" r.userid, r.tagtype, r.flag ".
// This query is a little complicated because Oracle does not allow to run SELECT DISTINCT on CLOB fields.
$sql = "SELECT name, rawname, description, descriptionformat, userid, tagtype, flag ".
"FROM {tag} WHERE id IN ".
"(SELECT r.id ".
"FROM {tag_instance} ti ". // Instances that need moving.
"JOIN {tag} t ON t.id = ti.tagid AND t.tagcollid <> :tagcollid1 ". // Tags that need moving.
"JOIN {tag_instance} tr ON tr.itemtype = 'tag' and tr.component = 'core' AND tr.itemid = t.id ".
"JOIN {tag} r ON r.id = tr.tagid ". // Tags related to the tags that need moving.
"LEFT JOIN {tag} re ON re.name = r.name AND re.tagcollid = :tagcollid2 ". // Existing tags in the target tagcoll with the same name as related tags.
"WHERE ti.itemtype = :itemtype2 AND ti.component = :component2 ".
" AND re.id IS NULL"; // We need related tags that ARE NOT present in the target tagcoll.
" AND re.id IS NULL)"; // We need related tags that ARE NOT present in the target tagcoll.
$result = $DB->get_records_sql($sql, $params);
foreach ($result as $tag) {
$tag->tagcollid = $tagcollid;
......@@ -410,14 +412,21 @@ class core_tag_area {
LEFT JOIN {tag} tt ON tt.name = t.name AND tt.tagcollid = :tagcollid2
WHERE ti.itemtype = :itemtype2 AND ti.component = :component2
AND tt.id IS NULL)";
$todelete = array();
$movedtags = array(); // Keep track of moved tags so we don't hit DB index violation.
$result = $DB->get_records_sql($sql, $params);
foreach ($result as $tag) {
$originaltagid = $tag->id;
unset($tag->id);
$tag->tagcollid = $tagcollid;
$tag->id = $DB->insert_record('tag', $tag);
\core\event\tag_created::create_from_tag($tag);
if (array_key_exists($tag->name, $movedtags)) {
// Case of corrupted data when the same tag was in several collections.
$tag->id = $movedtags[$tag->name];
} else {
// Copy the tag into the new collection.
unset($tag->id);
$tag->tagcollid = $tagcollid;
$tag->id = $DB->insert_record('tag', $tag);
\core\event\tag_created::create_from_tag($tag);
$movedtags[$tag->name] = $tag->id;
}
$DB->execute("UPDATE {tag_instance} SET tagid = ? WHERE tagid = ? AND itemtype = ? AND component = ?",
array($tag->id, $originaltagid, $itemtype, $component));
}
......
......@@ -813,6 +813,39 @@ class core_tag_taglib_testcase extends advanced_testcase {
$this->assertEquals('Tag2, Tag4', join(', ', $related21));
}
public function test_move_tags_corrupted() {
global $DB;
list($collid1, $collid2, $user1, $user2, $blogpost) = $this->prepare_move_tags();
$collid3 = core_tag_collection::create(array('name' => 'weirdcoll'))->id;
// We already have Tag1 in coll1, now let's create it in coll3.
$extratag1 = $this->getDataGenerator()->create_tag(array('rawname' => 'Tag1',
'tagcollid' => $collid3, 'tagtype' => 'official'));
// Artificially add 'Tag1' from coll3 to user2.
$DB->insert_record('tag_instance', array('tagid' => $extratag1->id, 'itemtype' => 'user',
'component' => 'core', 'itemid' => $user2->id, 'ordering' => 3));
// Now we have corrupted data: both users are tagged with 'Tag1', however these are two tags in different collections.
$user1tags = array_values(core_tag_tag::get_item_tags('core', 'user', $user1->id));
$user2tags = array_values(core_tag_tag::get_item_tags('core', 'user', $user2->id));
$this->assertEquals('Tag1', $user1tags[0]->rawname);
$this->assertEquals('Tag1', $user2tags[2]->rawname);
$this->assertNotEquals($user1tags[0]->tagcollid, $user2tags[2]->tagcollid);
// Move user interests tag area into coll2.
$tagarea = $DB->get_record('tag_area', array('itemtype' => 'user', 'component' => 'core'));
core_tag_area::update($tagarea, array('tagcollid' => $collid2));
// Now all tags are correctly moved to the new collection and both tags 'Tag1' were merged.
$user1tags = array_values(core_tag_tag::get_item_tags('core', 'user', $user1->id));
$user2tags = array_values(core_tag_tag::get_item_tags('core', 'user', $user2->id));
$this->assertEquals('Tag1', $user1tags[0]->rawname);
$this->assertEquals('Tag1', $user2tags[2]->rawname);
$this->assertEquals($collid2, $user1tags[0]->tagcollid);
$this->assertEquals($collid2, $user2tags[2]->tagcollid);
}
public function test_normalize() {
$tagset = array('Cat', ' Dog ', '<Mouse', '<>', 'mouse', 'Dog');
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment