From 61afe225bee0ec2c1d1ea1bf51a1a6a52e8d9167 Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Sun, 11 Nov 2012 19:02:45 -0100 Subject: [PATCH] Adding Template to ContentType and Content objects and updating repositories accordingly. Removing templates from the mocks for the time being. --- src/Umbraco.Core/Models/Content.cs | 24 +++++++----- src/Umbraco.Core/Models/ContentType.cs | 26 +++++++++---- src/Umbraco.Core/Models/IContent.cs | 7 ++-- src/Umbraco.Core/Models/IContentType.cs | 8 ++-- .../Factories/ContentTypeFactory.cs | 11 +++++- .../Repositories/ContentRepository.cs | 16 ++++++-- .../Repositories/ContentTypeRepository.cs | 37 +++++++++++++++---- .../Repositories/TemplateRepository.cs | 2 + .../TestHelpers/Entities/MockedContent.cs | 8 ++-- .../Entities/MockedContentTypes.cs | 6 --- src/Umbraco.Web/ContentExtensions.cs | 2 +- 11 files changed, 98 insertions(+), 49 deletions(-) diff --git a/src/Umbraco.Core/Models/Content.cs b/src/Umbraco.Core/Models/Content.cs index cd3cd80e09..012170cda8 100644 --- a/src/Umbraco.Core/Models/Content.cs +++ b/src/Umbraco.Core/Models/Content.cs @@ -13,7 +13,7 @@ namespace Umbraco.Core.Models public class Content : ContentBase, IContent { private IContentType _contentType; - private string _template; + private ITemplate _template; private bool _published; private string _language; private DateTime? _releaseDate; @@ -41,8 +41,8 @@ namespace Umbraco.Core.Models _contentType = contentType; } - - private static readonly PropertyInfo TemplateSelector = ExpressionHelper.GetPropertyInfo(x => x.Template); + + private static readonly PropertyInfo TemplateSelector = ExpressionHelper.GetPropertyInfo(x => x.Template); private static readonly PropertyInfo PublishedSelector = ExpressionHelper.GetPropertyInfo(x => x.Published); private static readonly PropertyInfo LanguageSelector = ExpressionHelper.GetPropertyInfo(x => x.Language); private static readonly PropertyInfo ReleaseDateSelector = ExpressionHelper.GetPropertyInfo(x => x.ReleaseDate); @@ -50,16 +50,19 @@ namespace Umbraco.Core.Models private static readonly PropertyInfo WriterSelector = ExpressionHelper.GetPropertyInfo(x => x.WriterId); /// - /// Path to the template used by this Content - /// This is used to override the default one from the ContentType + /// Gets or sets the template used by the Content. + /// This is used to override the default one from the ContentType. /// - /// If no template is explicitly set on the Content object, the Default template from the ContentType will be returned + /// + /// If no template is explicitly set on the Content object, + /// the Default template from the ContentType will be returned. + /// [DataMember] - public virtual string Template + public virtual ITemplate Template { get { - if (string.IsNullOrEmpty(_template) || _template == null) + if (_template == null) return _contentType.DefaultTemplate; return _template; @@ -111,8 +114,11 @@ namespace Umbraco.Core.Models } /// - /// Language of the data contained within this Content object + /// Language of the data contained within this Content object. /// + /// + /// Left internal until multilingual support is implemented. + /// [DataMember] internal string Language { diff --git a/src/Umbraco.Core/Models/ContentType.cs b/src/Umbraco.Core/Models/ContentType.cs index 5207cf585d..5afdb5f3b9 100644 --- a/src/Umbraco.Core/Models/ContentType.cs +++ b/src/Umbraco.Core/Models/ContentType.cs @@ -13,22 +13,31 @@ namespace Umbraco.Core.Models [DataContract(IsReference = true)] public class ContentType : ContentTypeCompositionBase, IContentType { - private string _defaultTemplate; - private IEnumerable _allowedTemplates; + private int _defaultTemplate; + private IEnumerable _allowedTemplates; public ContentType(int parentId) : base(parentId) { - _allowedTemplates = new List(); + _allowedTemplates = new List(); } - private static readonly PropertyInfo DefaultTemplateSelector = ExpressionHelper.GetPropertyInfo(x => x.DefaultTemplate); - private static readonly PropertyInfo AllowedTemplatesSelector = ExpressionHelper.GetPropertyInfo>(x => x.AllowedTemplates); + private static readonly PropertyInfo DefaultTemplateSelector = ExpressionHelper.GetPropertyInfo(x => x.DefaultTemplateId); + private static readonly PropertyInfo AllowedTemplatesSelector = ExpressionHelper.GetPropertyInfo>(x => x.AllowedTemplates); /// /// Gets or sets the alias of the default Template. /// [DataMember] - public string DefaultTemplate//NOTE Use internal extension method to get Id of the Template + public ITemplate DefaultTemplate + { + get { return AllowedTemplates.FirstOrDefault(x => x.Id == DefaultTemplateId); } + } + + /// + /// Internal property to store the Id of the default template + /// + [DataMember] + internal int DefaultTemplateId { get { return _defaultTemplate; } set @@ -39,9 +48,10 @@ namespace Umbraco.Core.Models } /// - /// Gets or sets a list of aliases for allowed Templates + /// Gets or Sets a list of Templates which are allowed for the ContentType /// - public IEnumerable AllowedTemplates//NOTE Use internal extension method to get Ids of the Templates + [DataMember] + public IEnumerable AllowedTemplates { get { return _allowedTemplates; } set diff --git a/src/Umbraco.Core/Models/IContent.cs b/src/Umbraco.Core/Models/IContent.cs index f7a7be72ad..e60c4f5c83 100644 --- a/src/Umbraco.Core/Models/IContent.cs +++ b/src/Umbraco.Core/Models/IContent.cs @@ -1,5 +1,4 @@ using System; -using Umbraco.Core.Models.Membership; namespace Umbraco.Core.Models { @@ -9,10 +8,10 @@ namespace Umbraco.Core.Models public interface IContent : IContentBase { /// - /// Alias of the template used by the Content - /// This is used to override the default one from the ContentType + /// Gets or sets the template used by the Content. + /// This is used to override the default one from the ContentType. /// - string Template { get; set; } + ITemplate Template { get; set; } /// /// Boolean indicating whether the Content is Published or not diff --git a/src/Umbraco.Core/Models/IContentType.cs b/src/Umbraco.Core/Models/IContentType.cs index 3d9282278d..1600a92ee3 100644 --- a/src/Umbraco.Core/Models/IContentType.cs +++ b/src/Umbraco.Core/Models/IContentType.cs @@ -8,13 +8,13 @@ namespace Umbraco.Core.Models public interface IContentType : IContentTypeComposition { /// - /// Gets or Sets the path to the default Template of the ContentType + /// Gets the default Template of the ContentType /// - string DefaultTemplate { get; set; } + ITemplate DefaultTemplate { get; } /// - /// Gets or Sets a list of Template names/paths which are allowed for the ContentType + /// Gets or Sets a list of Templates which are allowed for the ContentType /// - IEnumerable AllowedTemplates { get; set; } + IEnumerable AllowedTemplates { get; set; } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Factories/ContentTypeFactory.cs b/src/Umbraco.Core/Persistence/Factories/ContentTypeFactory.cs index 87dfae4653..5a83fe0cee 100644 --- a/src/Umbraco.Core/Persistence/Factories/ContentTypeFactory.cs +++ b/src/Umbraco.Core/Persistence/Factories/ContentTypeFactory.cs @@ -38,7 +38,8 @@ namespace Umbraco.Core.Persistence.Factories CreatorId = dto.ContentTypeDto.NodeDto.UserId.Value, AllowedAsRoot = dto.ContentTypeDto.AllowAtRoot, IsContainer = dto.ContentTypeDto.IsContainer, - Trashed = dto.ContentTypeDto.NodeDto.Trashed + Trashed = dto.ContentTypeDto.NodeDto.Trashed, + DefaultTemplateId = dto.TemplateNodeId }; return contentType; } @@ -47,7 +48,13 @@ namespace Umbraco.Core.Persistence.Factories { var documentTypeDto = new DocumentTypeDto {ContentTypeDto = BuildContentTypeDto(entity), ContentTypeNodeId = entity.Id}; - //NOTE TemplateId and IsDefault currently not added + + var contentType = entity as ContentType; + if(contentType != null) + { + documentTypeDto.TemplateNodeId = contentType.DefaultTemplateId; + documentTypeDto.IsDefault = true; + } return documentTypeDto; } diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs index fe297e1306..7762237e89 100644 --- a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs @@ -18,17 +18,20 @@ namespace Umbraco.Core.Persistence.Repositories internal class ContentRepository : PetaPocoRepositoryBase, IContentRepository { private readonly IContentTypeRepository _contentTypeRepository; + private readonly ITemplateRepository _templateRepository; - public ContentRepository(IUnitOfWork work, IContentTypeRepository contentTypeRepository) + public ContentRepository(IUnitOfWork work, IContentTypeRepository contentTypeRepository, ITemplateRepository templateRepository) : base(work) { _contentTypeRepository = contentTypeRepository; + _templateRepository = templateRepository; } - public ContentRepository(IUnitOfWork work, IRepositoryCacheProvider cache, IContentTypeRepository contentTypeRepository) + public ContentRepository(IUnitOfWork work, IRepositoryCacheProvider cache, IContentTypeRepository contentTypeRepository, ITemplateRepository templateRepository) : base(work, cache) { _contentTypeRepository = contentTypeRepository; + _templateRepository = templateRepository; } #region Overrides of RepositoryBase @@ -44,11 +47,18 @@ namespace Umbraco.Core.Persistence.Repositories if (dto == null) return null; + //Get the ContentType that this Content is based on var contentType = _contentTypeRepository.Get(dto.ContentVersionDto.ContentDto.ContentTypeId); var factory = new ContentFactory(contentType, NodeObjectTypeId, id); var content = factory.BuildEntity(dto); - + + //Check if template id is set on DocumentDto, and get ITemplate if it is. + if (dto.TemplateId.HasValue) + { + content.Template = _templateRepository.Get(dto.TemplateId.Value); + } + content.Properties = GetPropertyCollection(id, dto.ContentVersionDto.VersionId, contentType); ((ICanBeDirty)content).ResetDirtyProperties(); diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentTypeRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentTypeRepository.cs index 7e48e9abdd..d8eb643055 100644 --- a/src/Umbraco.Core/Persistence/Repositories/ContentTypeRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/ContentTypeRepository.cs @@ -16,14 +16,18 @@ namespace Umbraco.Core.Persistence.Repositories /// internal class ContentTypeRepository : ContentTypeBaseRepository, IContentTypeRepository { - public ContentTypeRepository(IUnitOfWork work) + private readonly ITemplateRepository _templateRepository; + + public ContentTypeRepository(IUnitOfWork work, ITemplateRepository templateRepository) : base(work) { + _templateRepository = templateRepository; } - public ContentTypeRepository(IUnitOfWork work, IRepositoryCacheProvider cache) + public ContentTypeRepository(IUnitOfWork work, IRepositoryCacheProvider cache, ITemplateRepository templateRepository) : base(work, cache) { + _templateRepository = templateRepository; } #region Overrides of RepositoryBase @@ -33,7 +37,6 @@ namespace Umbraco.Core.Persistence.Repositories var contentTypeSql = GetBaseQuery(false); contentTypeSql.Where(GetBaseWhereClause(), new { Id = id }); - //TODO Test with multiple templates for a single DocType as that would cause problems for the query below var dto = Database.Query(contentTypeSql).FirstOrDefault(); if (dto == null) @@ -45,6 +48,13 @@ namespace Umbraco.Core.Persistence.Repositories contentType.AllowedContentTypes = GetAllowedContentTypeIds(id); contentType.PropertyGroups = GetPropertyGroupCollection(id); + var templates = Database.Fetch("WHERE contentTypeNodeId = @Id", new { Id = id }); + if(templates.Any()) + { + contentType.AllowedTemplates = + templates.Select(template => _templateRepository.Get(template.TemplateNodeId)); + } + var list = Database.Fetch("WHERE childContentTypeId = @Id", new { Id = id}); foreach (var contentTypeDto in list) { @@ -115,6 +125,7 @@ namespace Umbraco.Core.Persistence.Repositories sql.RightJoin("cmsContentType ON ([cmsContentType].[nodeId] = [cmsDocumentType].[contentTypeNodeId])"); sql.InnerJoin("umbracoNode ON ([cmsContentType].[nodeId] = [umbracoNode].[id])"); sql.Where("[umbracoNode].[nodeObjectType] = @NodeObjectType", new { NodeObjectType = NodeObjectTypeId }); + sql.Where("[cmsDocumentType].[IsDefault] = @IsDefault", new { IsDefault = true }); return sql; } @@ -159,12 +170,16 @@ namespace Umbraco.Core.Persistence.Repositories var dto = factory.BuildDto(entity); PersistNewBaseContentType(dto.ContentTypeDto, entity); - //Inserts data into the cmsDocumentType table - currently only the ContentTypeNodeId is added/updated + //Inserts data into the cmsDocumentType table dto.ContentTypeNodeId = entity.Id; Database.Insert(dto); - //TODO Insert new DocumentType entries - NOTE only seems relevant as long as Templates resides in the DB? - //TODO Insert allowed Templates + //Insert allowed Templates not including the default one, as that has already been inserted + foreach (var template in entity.AllowedTemplates.Where(x => x.Id != dto.TemplateNodeId)) + { + Database.Insert(new DocumentTypeDto + {ContentTypeNodeId = entity.Id, TemplateNodeId = template.Id, IsDefault = false}); + } ((ICanBeDirty)entity).ResetDirtyProperties(); } @@ -180,9 +195,15 @@ namespace Umbraco.Core.Persistence.Repositories PersistUpdatedBaseContentType(dto.ContentTypeDto, entity); //Look up DocumentType entries for updating - this could possibly be a "remove all, insert all"-approach + Database.Delete("WHERE contentTypeNodeId = @Id", new { Id = entity.Id}); - //TODO Update new DocumentType entries - NOTE only seems relevant as long as Templates resides in the DB? - //TODO Update allowed Templates + Database.Insert(dto); + + //Insert allowed Templates not including the default one, as that has already been inserted + foreach (var template in entity.AllowedTemplates.Where(x => x.Id != dto.TemplateNodeId)) + { + Database.Insert(new DocumentTypeDto { ContentTypeNodeId = entity.Id, TemplateNodeId = template.Id, IsDefault = false }); + } ((ICanBeDirty)entity).ResetDirtyProperties(); } diff --git a/src/Umbraco.Core/Persistence/Repositories/TemplateRepository.cs b/src/Umbraco.Core/Persistence/Repositories/TemplateRepository.cs index 7090921ae5..42a51585f1 100644 --- a/src/Umbraco.Core/Persistence/Repositories/TemplateRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/TemplateRepository.cs @@ -135,8 +135,10 @@ namespace Umbraco.Core.Persistence.Repositories protected override IEnumerable GetDeleteClauses() { + //TODO check for references in DocumentDto and remove value (nullable) var list = new List { + string.Format("DELETE FROM cmsDocumentType WHERE templateNodeId = @Id"), string.Format("DELETE FROM cmsTemplate WHERE nodeId = @Id"), string.Format("DELETE FROM umbracoNode WHERE id = @Id") }; diff --git a/src/Umbraco.Tests/TestHelpers/Entities/MockedContent.cs b/src/Umbraco.Tests/TestHelpers/Entities/MockedContent.cs index 9970f60d6c..7ced5269a3 100644 --- a/src/Umbraco.Tests/TestHelpers/Entities/MockedContent.cs +++ b/src/Umbraco.Tests/TestHelpers/Entities/MockedContent.cs @@ -8,7 +8,7 @@ namespace Umbraco.Tests.TestHelpers.Entities { public static Content CreateSimpleContent(IContentType contentType) { - var content = new Content(-1, contentType) { Name = "Home", Language = "en-US", Level = 1, ParentId = -1, SortOrder = 1, Template = "~/masterpages/umbTextPage.master", CreatorId = 0, WriterId = 0 }; + var content = new Content(-1, contentType) { Name = "Home", Language = "en-US", Level = 1, ParentId = -1, SortOrder = 1, CreatorId = 0, WriterId = 0 }; object obj = new { @@ -24,7 +24,7 @@ namespace Umbraco.Tests.TestHelpers.Entities public static Content CreateSimpleContent(IContentType contentType, string name, int parentId) { - var content = new Content(parentId, contentType) { Name = name, Language = "en-US", ParentId = parentId, Template = "~/masterpages/umbTextPage.master", CreatorId = 0, WriterId = 0 }; + var content = new Content(parentId, contentType) { Name = name, Language = "en-US", ParentId = parentId, CreatorId = 0, WriterId = 0 }; object obj = new { @@ -40,7 +40,7 @@ namespace Umbraco.Tests.TestHelpers.Entities public static Content CreateTextpageContent(IContentType contentType, string name, int parentId) { - var content = new Content(parentId, contentType) { Name = name, Language = "en-US", ParentId = parentId, Template = "~/masterpages/umbTextPage.master", CreatorId = 0, WriterId = 0}; + var content = new Content(parentId, contentType) { Name = name, Language = "en-US", ParentId = parentId, CreatorId = 0, WriterId = 0}; object obj = new { @@ -62,7 +62,7 @@ namespace Umbraco.Tests.TestHelpers.Entities for (int i = 0; i < amount; i++) { var name = "Textpage No-" + i; - var content = new Content(parentId, contentType) { Name = name, Language = "en-US", ParentId = parentId, Template = "~/masterpages/umbTextPage.master", CreatorId = 0, WriterId = 0 }; + var content = new Content(parentId, contentType) { Name = name, Language = "en-US", ParentId = parentId, CreatorId = 0, WriterId = 0 }; object obj = new { diff --git a/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs b/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs index 43f07a9171..735491513d 100644 --- a/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs +++ b/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs @@ -17,7 +17,6 @@ namespace Umbraco.Tests.TestHelpers.Entities Thumbnail = "doc.png", SortOrder = 1, CreatorId = 0, - DefaultTemplate = "~/masterpages/umbTextPage.master", Trashed = false }; @@ -46,7 +45,6 @@ namespace Umbraco.Tests.TestHelpers.Entities Thumbnail = "doc.png", SortOrder = 1, CreatorId = 0, - DefaultTemplate = "", Trashed = false }; @@ -70,7 +68,6 @@ namespace Umbraco.Tests.TestHelpers.Entities Thumbnail = "doc.png", SortOrder = 1, CreatorId = 0, - DefaultTemplate = "~/masterpages/umbSimplePage.master", Trashed = false }; @@ -95,7 +92,6 @@ namespace Umbraco.Tests.TestHelpers.Entities Thumbnail = "doc2.png", SortOrder = 1, CreatorId = 0, - DefaultTemplate = "~/masterpages/umbSimplePage.master", Trashed = false }; @@ -120,7 +116,6 @@ namespace Umbraco.Tests.TestHelpers.Entities Thumbnail = "doc2.png", SortOrder = 1, CreatorId = 0, - DefaultTemplate = "~/masterpages/umbSimplePage.master", Trashed = false }; @@ -145,7 +140,6 @@ namespace Umbraco.Tests.TestHelpers.Entities Thumbnail = "doc3.png", SortOrder = 1, CreatorId = 0, - DefaultTemplate = "~/masterpages/umbSimplePage.master", Trashed = false }; diff --git a/src/Umbraco.Web/ContentExtensions.cs b/src/Umbraco.Web/ContentExtensions.cs index a65412cf42..cc14dcb7d6 100644 --- a/src/Umbraco.Web/ContentExtensions.cs +++ b/src/Umbraco.Web/ContentExtensions.cs @@ -30,7 +30,7 @@ namespace Umbraco.Web new XAttribute("writerID", content.WriterId), new XAttribute("creatorID", content.CreatorId), new XAttribute("nodeType", content.ContentType.Id), - new XAttribute("template", content.Template ?? string.Empty),//Template name versus Id - note that the template name/alias isn't saved in the db. + new XAttribute("template", content.Template.Id.ToString()), new XAttribute("sortOrder", content.SortOrder), new XAttribute("createDate", content.CreateDate), new XAttribute("updateDate", content.UpdateDate),