diff --git a/src/Umbraco.Core/Persistence/Repositories/TemplateRepository.cs b/src/Umbraco.Core/Persistence/Repositories/TemplateRepository.cs index 53e9954fd0..e83ca6b40e 100644 --- a/src/Umbraco.Core/Persistence/Repositories/TemplateRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/TemplateRepository.cs @@ -295,34 +295,27 @@ namespace Umbraco.Core.Persistence.Repositories protected override void PersistDeletedItem(ITemplate entity) { + var deletes = GetDeleteClauses().ToArray(); - //TODO: This isn't the most ideal way to delete a template tree, because below it will actually end up - // recursing back to this method for each descendant and re-looking up the template list causing an extrac - // SQL call - not ideal but there shouldn't ever be a heaping list of descendant templates. - //The easiest way to overcome this is to expose the underlying cache upwards so that the repository has access - // to it, then in the PersistDeletedTemplate we wouldn't recurse the underlying function, we'd just call - // PersistDeletedItem with a Template object and clear it's cache. + var descendants = GetDescendants(entity.Id).ToList(); - var sql = GetBaseQuery(false).Where(dto => dto.ParentId > 0 || dto.NodeId == entity.Id); - - var dtos = Database.Fetch(sql); - - var self = dtos.Single(x => x.NodeId == entity.Id); - var allChildren = dtos.Except(new[] { self }); - var hierarchy = GenerateTemplateHierarchy(self, allChildren); - //remove ourselves - hierarchy.Remove(self); - //change the order so it goes bottom up! - hierarchy.Reverse(); + //change the order so it goes bottom up! (deepest level first) + descendants.Reverse(); //delete the hierarchy - foreach (var descendant in hierarchy) + foreach (var descendant in descendants) { - PersistDeletedTemplate(descendant); + foreach (var delete in deletes) + { + Database.Execute(delete, new { Id = GetEntityId(descendant) }); + } } //now we can delete this one - base.PersistDeletedItem(entity); + foreach (var delete in deletes) + { + Database.Execute(delete, new { Id = GetEntityId(entity) }); + } if (DetermineTemplateRenderingEngine(entity) == RenderingEngine.Mvc) { @@ -335,6 +328,12 @@ namespace Umbraco.Core.Persistence.Repositories _masterpagesFileSystem.DeleteFile(masterpageName); } + //It is important that we clear ALL template cache, this is because templates have a couple of readonly + // flags that will get cached which will become stale if other templates change: + // * MasterTemplateAlias + // * IsMasterTemplate + + RuntimeCache.ClearCacheObjectTypes(); } #endregion @@ -411,36 +410,7 @@ namespace Umbraco.Core.Persistence.Repositories return template; } - - - private void PersistDeletedTemplate(TemplateDto dto) - { - //we need to get the real template for this item unfortunately to remove it - var template = Get(dto.NodeId); - if (template != null) - { - //NOTE: We must cast here so that it goes to the outter method to - // ensure the cache is updated. - PersistDeletedItem((IEntity)template); - } - } - - /// - /// Returns a list of templates in order of descendants from the parent - /// - /// - /// - /// - private static List GenerateTemplateHierarchy(TemplateDto template, IEnumerable allChildTemplates) - { - var hierarchy = new List { template }; - foreach (var t in allChildTemplates.Where(x => x.NodeDto.ParentId == template.NodeId)) - { - hierarchy.AddRange(GenerateTemplateHierarchy(t, allChildTemplates)); - } - return hierarchy; - } - + private void PopulateViewTemplate(ITemplate template, string fileName) { string content; @@ -494,6 +464,8 @@ namespace Umbraco.Core.Persistence.Repositories } var dtos = Database.Fetch(sql).ToArray(); + if (dtos.Length == 0) return Enumerable.Empty(); + var axisDefos = GetAxisDefinitions(dtos).ToArray(); return dtos.Select(x => MapFromDto(x, axisDefos)); } @@ -511,6 +483,8 @@ namespace Umbraco.Core.Persistence.Repositories } var dtos = Database.Fetch(sql).ToArray(); + if (dtos.Length == 0) return Enumerable.Empty(); + var axisDefos = GetAxisDefinitions(dtos).ToArray(); return dtos.Select(x => MapFromDto(x, axisDefos)); } @@ -533,6 +507,8 @@ namespace Umbraco.Core.Persistence.Repositories } var dtos = Database.Fetch(sql).ToArray(); + if (dtos.Length == 0) return Enumerable.Empty(); + var axisDefos = GetAxisDefinitions(dtos).ToArray(); return dtos.Select(x => MapFromDto(x, axisDefos)); } @@ -556,7 +532,11 @@ namespace Umbraco.Core.Persistence.Repositories sql.Where(@"(umbracoNode." + SqlSyntax.GetQuotedColumnName("path") + @" LIKE @query)", new { query = path + ",%" }); } + sql.OrderBy("umbracoNode." + SqlSyntax.GetQuotedColumnName("level")); + var dtos = Database.Fetch(sql).ToArray(); + if (dtos.Length == 0) return Enumerable.Empty(); + var axisDefos = GetAxisDefinitions(dtos).ToArray(); return dtos.Select(x => MapFromDto(x, axisDefos)); @@ -577,7 +557,11 @@ namespace Umbraco.Core.Persistence.Repositories sql.Where(@"(umbracoNode." + SqlSyntax.GetQuotedColumnName("path") + @" LIKE @query)", new {query = path + ",%" }); } + sql.OrderBy("umbracoNode." + SqlSyntax.GetQuotedColumnName("level")); + var dtos = Database.Fetch(sql).ToArray(); + if (dtos.Length == 0) return Enumerable.Empty(); + var axisDefos = GetAxisDefinitions(dtos).ToArray(); return dtos.Select(x => MapFromDto(x, axisDefos)); } diff --git a/src/umbraco.cms/businesslogic/template/Template.cs b/src/umbraco.cms/businesslogic/template/Template.cs index ac9823d1cb..e78925bd60 100644 --- a/src/umbraco.cms/businesslogic/template/Template.cs +++ b/src/umbraco.cms/businesslogic/template/Template.cs @@ -256,6 +256,7 @@ namespace umbraco.cms.businesslogic.template foreach (var t in GetAllAsList().FindAll(t => t.MasterTemplate == Id)) { t.MasterTemplate = 0; + t.Save(); } } @@ -263,6 +264,9 @@ namespace umbraco.cms.businesslogic.template // remove from documents Document.RemoveTemplateFromDocument(this.Id); + + //save it + Save(); } public void RemoveFromDocumentTypes()