diff --git a/src/Umbraco.Core/Models/Rdbms/UserGroupDto.cs b/src/Umbraco.Core/Models/Rdbms/UserGroupDto.cs
index fdad78bfcd..f6bb09066d 100644
--- a/src/Umbraco.Core/Models/Rdbms/UserGroupDto.cs
+++ b/src/Umbraco.Core/Models/Rdbms/UserGroupDto.cs
@@ -51,10 +51,12 @@ namespace Umbraco.Core.Models.Rdbms
[Column("startContentId")]
[NullSetting(NullSetting = NullSettings.Null)]
+ [ForeignKey(typeof(NodeDto), Name = "FK_startContentId_umbracoNode_id")]
public int? StartContentId { get; set; }
[Column("startMediaId")]
[NullSetting(NullSetting = NullSettings.Null)]
+ [ForeignKey(typeof(NodeDto), Name = "FK_startMediaId_umbracoNode_id")]
public int? StartMediaId { get; set; }
[ResultColumn]
diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenSevenZero/AddUserGroupTables.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenSevenZero/AddUserGroupTables.cs
index d1cf0a40d9..36c45615a3 100644
--- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenSevenZero/AddUserGroupTables.cs
+++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenSevenZero/AddUserGroupTables.cs
@@ -28,6 +28,45 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenSevenZe
DeleteOldTables(tables, constraints);
SetDefaultIcons();
}
+ else
+ {
+ //if we aren't adding the tables, make sure that the umbracoUserGroup table has the correct FKs - these
+ //were added after the beta release so we need to do some cleanup
+ //if the FK doesn't exist
+ if (constraints.Any(x => x.Item1.InvariantEquals("umbracoUserGroup")
+ && x.Item2.InvariantEquals("startContentId")
+ && x.Item3.InvariantEquals("FK_startContentId_umbracoNode_id")) == false)
+ {
+ //before we add any foreign key we need to make sure there's no stale data in there which would have happened in the beta
+ //release if a start node was assigned and then that start node was deleted.
+ Execute.Sql(@"UPDATE umbracoUserGroup SET startContentId = NULL WHERE startContentId NOT IN (SELECT id FROM umbracoNode)");
+
+ Create.ForeignKey("FK_startContentId_umbracoNode_id")
+ .FromTable("umbracoUserGroup")
+ .ForeignColumn("startContentId")
+ .ToTable("umbracoNode")
+ .PrimaryColumn("id")
+ .OnDelete(Rule.None)
+ .OnUpdate(Rule.None);
+ }
+
+ if (constraints.Any(x => x.Item1.InvariantEquals("umbracoUserGroup")
+ && x.Item2.InvariantEquals("startMediaId")
+ && x.Item3.InvariantEquals("FK_startMediaId_umbracoNode_id")) == false)
+ {
+ //before we add any foreign key we need to make sure there's no stale data in there which would have happened in the beta
+ //release if a start node was assigned and then that start node was deleted.
+ Execute.Sql(@"UPDATE umbracoUserGroup SET startMediaId = NULL WHERE startMediaId NOT IN (SELECT id FROM umbracoNode)");
+
+ Create.ForeignKey("FK_startMediaId_umbracoNode_id")
+ .FromTable("umbracoUserGroup")
+ .ForeignColumn("startMediaId")
+ .ToTable("umbracoNode")
+ .PrimaryColumn("id")
+ .OnDelete(Rule.None)
+ .OnUpdate(Rule.None);
+ }
+ }
}
private void SetDefaultIcons()
diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs
index addd0bc925..daa8140670 100644
--- a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs
@@ -183,6 +183,8 @@ namespace Umbraco.Core.Persistence.Repositories
"DELETE FROM cmsTask WHERE nodeId = @Id",
"DELETE FROM umbracoUser2NodeNotify WHERE nodeId = @Id",
"DELETE FROM umbracoUserGroup2NodePermission WHERE nodeId = @Id",
+ "DELETE FROM umbracoUserStartNode WHERE startNode = @Id",
+ "UPDATE umbracoUserGroup SET startContentId = NULL WHERE startContentId = @Id",
"DELETE FROM umbracoRelation WHERE parentId = @Id",
"DELETE FROM umbracoRelation WHERE childId = @Id",
"DELETE FROM cmsTagRelationship WHERE nodeId = @Id",
@@ -194,7 +196,7 @@ namespace Umbraco.Core.Persistence.Repositories
"DELETE FROM cmsContentXml WHERE nodeId = @Id",
"DELETE FROM cmsContent WHERE nodeId = @Id",
"DELETE FROM umbracoAccess WHERE nodeId = @Id",
- "DELETE FROM umbracoNode WHERE id = @Id"
+ "DELETE FROM umbracoNode WHERE id = @Id"
};
return list;
}
diff --git a/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs
index ee413c2a59..be96d80f5a 100644
--- a/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs
@@ -118,6 +118,8 @@ namespace Umbraco.Core.Persistence.Repositories
"DELETE FROM cmsTask WHERE nodeId = @Id",
"DELETE FROM umbracoUser2NodeNotify WHERE nodeId = @Id",
"DELETE FROM umbracoUserGroup2NodePermission WHERE nodeId = @Id",
+ "DELETE FROM umbracoUserStartNode WHERE startNode = @Id",
+ "UPDATE umbracoUserGroup SET startMediaId = NULL WHERE startMediaId = @Id",
"DELETE FROM umbracoRelation WHERE parentId = @Id",
"DELETE FROM umbracoRelation WHERE childId = @Id",
"DELETE FROM cmsTagRelationship WHERE nodeId = @Id",
diff --git a/src/Umbraco.Core/Persistence/Repositories/RecycleBinRepository.cs b/src/Umbraco.Core/Persistence/Repositories/RecycleBinRepository.cs
index efb7487fdf..efb93bcff3 100644
--- a/src/Umbraco.Core/Persistence/Repositories/RecycleBinRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/RecycleBinRepository.cs
@@ -53,7 +53,10 @@ namespace Umbraco.Core.Persistence.Repositories
@"DELETE FROM umbracoRedirectUrl WHERE umbracoRedirectUrl.id IN(
SELECT TB1.id FROM umbracoRedirectUrl as TB1
INNER JOIN umbracoNode as TB2 ON TB1.contentKey = TB2.uniqueId
- WHERE TB2.trashed = '1' AND TB2.nodeObjectType = @NodeObjectType)",
+ WHERE TB2.trashed = '1' AND TB2.nodeObjectType = @NodeObjectType)",
+ FormatDeleteStatement("umbracoUserStartNode", "startNode"),
+ FormatUpdateStatement("umbracoUserGroup", "startContentId"),
+ FormatUpdateStatement("umbracoUserGroup", "startMediaId"),
FormatDeleteStatement("umbracoRelation", "parentId"),
FormatDeleteStatement("umbracoRelation", "childId"),
FormatDeleteStatement("cmsTagRelationship", "nodeId"),
@@ -108,6 +111,21 @@ namespace Umbraco.Core.Persistence.Repositories
tableName, keyName);
}
+ ///
+ /// An update statement that will update a value to NULL in the table specified where its PK (keyName) is found in the
+ /// list of umbracoNode.id that have trashed flag set
+ ///
+ ///
+ ///
+ ///
+ private string FormatUpdateStatement(string tableName, string keyName)
+ {
+ return
+ string.Format(
+ "UPDATE {0} SET {0}.{1} = NULL WHERE {0}.{1} IN (SELECT id FROM umbracoNode WHERE trashed = '1' AND nodeObjectType = @NodeObjectType)",
+ tableName, keyName);
+ }
+
///
/// Gets a list of files, which are referenced on items in the Recycle Bin.
/// The list is generated by the convention that a file is referenced by
diff --git a/src/Umbraco.Tests/Services/ContentServiceTests.cs b/src/Umbraco.Tests/Services/ContentServiceTests.cs
index 5a2b9f23e7..c9daeb0022 100644
--- a/src/Umbraco.Tests/Services/ContentServiceTests.cs
+++ b/src/Umbraco.Tests/Services/ContentServiceTests.cs
@@ -1583,6 +1583,14 @@ namespace Umbraco.Tests.Services
ServiceContext.ContentService.Save(content2, 0);
Assert.IsTrue(ServiceContext.ContentService.PublishWithStatus(content2, 0).Success);
+ var editorGroup = ServiceContext.UserService.GetUserGroupByAlias("editor");
+ editorGroup.StartContentId = content1.Id;
+ ServiceContext.UserService.Save(editorGroup);
+
+ var admin = ServiceContext.UserService.GetUserById(0);
+ admin.StartContentIds = new[] {content1.Id};
+ ServiceContext.UserService.Save(admin);
+
ServiceContext.RelationService.Save(new RelationType(Constants.ObjectTypes.DocumentGuid, Constants.ObjectTypes.DocumentGuid, "test"));
Assert.IsNotNull(ServiceContext.RelationService.Relate(content1, content2, "test"));
@@ -1608,6 +1616,7 @@ namespace Umbraco.Tests.Services
}).Success);
// Act
+ ServiceContext.ContentService.MoveToRecycleBin(content1);
ServiceContext.ContentService.EmptyRecycleBin();
var contents = ServiceContext.ContentService.GetContentInRecycleBin();