From aba18628118e9bebc09c2b908d23f2f4af403b96 Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 29 Apr 2014 09:58:38 +1000 Subject: [PATCH] Fixes: U4-4754 Member and Media repositories need to generate preview xml when EnableGlobalPreviewStorage is true --- .../Configuration/UmbracoSettings.cs | 2 +- .../Models/ContentPreviewEntity.cs | 21 +++ .../Repositories/ContentPreviewRepository.cs | 109 +++++++++++++++ .../Repositories/ContentRepository.cs | 125 +----------------- .../Interfaces/IMediaRepository.cs | 7 + .../Interfaces/IMemberRepository.cs | 7 + .../Repositories/MediaRepository.cs | 14 +- .../Repositories/MemberRepository.cs | 12 ++ src/Umbraco.Core/Services/MediaService.cs | 27 ++++ src/Umbraco.Core/Services/MemberService.cs | 19 +++ src/Umbraco.Core/Umbraco.Core.csproj | 2 + src/umbraco.cms/businesslogic/media/Media.cs | 12 +- .../businesslogic/member/Member.cs | 10 -- 13 files changed, 222 insertions(+), 145 deletions(-) create mode 100644 src/Umbraco.Core/Models/ContentPreviewEntity.cs create mode 100644 src/Umbraco.Core/Persistence/Repositories/ContentPreviewRepository.cs diff --git a/src/Umbraco.Core/Configuration/UmbracoSettings.cs b/src/Umbraco.Core/Configuration/UmbracoSettings.cs index 9f6b19fc00..95e78c88a4 100644 --- a/src/Umbraco.Core/Configuration/UmbracoSettings.cs +++ b/src/Umbraco.Core/Configuration/UmbracoSettings.cs @@ -1083,7 +1083,7 @@ namespace Umbraco.Core.Configuration bool globalPreviewEnabled = false; string value = GetKey("/settings/content/GlobalPreviewStorageEnabled"); if (bool.TryParse(value, out globalPreviewEnabled)) - return !globalPreviewEnabled; + return globalPreviewEnabled; // Return default return false; } diff --git a/src/Umbraco.Core/Models/ContentPreviewEntity.cs b/src/Umbraco.Core/Models/ContentPreviewEntity.cs new file mode 100644 index 0000000000..e9688ff3d5 --- /dev/null +++ b/src/Umbraco.Core/Models/ContentPreviewEntity.cs @@ -0,0 +1,21 @@ +using System; +using System.Xml.Linq; + +namespace Umbraco.Core.Models +{ + /// + /// Used content repository in order to add an entity to the persisted collection to be saved + /// in a single transaction during saving an entity + /// + internal class ContentPreviewEntity : ContentXmlEntity + where TContent : IContentBase + { + public ContentPreviewEntity(bool previewExists, TContent content, Func xml) + : base(previewExists, content, xml) + { + Version = content.Version; + } + + public Guid Version { get; private set; } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentPreviewRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentPreviewRepository.cs new file mode 100644 index 0000000000..c749dc1204 --- /dev/null +++ b/src/Umbraco.Core/Persistence/Repositories/ContentPreviewRepository.cs @@ -0,0 +1,109 @@ +using System; +using System.Collections.Generic; +using System.Xml.Linq; +using Umbraco.Core.Models; +using Umbraco.Core.Models.Rdbms; +using Umbraco.Core.Persistence.Caching; +using Umbraco.Core.Persistence.Querying; +using Umbraco.Core.Persistence.UnitOfWork; + +namespace Umbraco.Core.Persistence.Repositories +{ + /// + /// Private class to handle preview insert/update based on standard principles and units of work with transactions + /// + internal class ContentPreviewRepository : PetaPocoRepositoryBase> + where TContent : IContentBase + { + public ContentPreviewRepository(IDatabaseUnitOfWork work, IRepositoryCacheProvider cache) + : base(work, cache) + { + } + + #region Not implemented (don't need to for the purposes of this repo) + protected override ContentPreviewEntity PerformGet(int id) + { + throw new NotImplementedException(); + } + + protected override IEnumerable> PerformGetAll(params int[] ids) + { + throw new NotImplementedException(); + } + + protected override IEnumerable> PerformGetByQuery(IQuery> query) + { + throw new NotImplementedException(); + } + + protected override Sql GetBaseQuery(bool isCount) + { + throw new NotImplementedException(); + } + + protected override string GetBaseWhereClause() + { + throw new NotImplementedException(); + } + + protected override IEnumerable GetDeleteClauses() + { + return new List(); + } + + protected override Guid NodeObjectTypeId + { + get { throw new NotImplementedException(); } + } + + protected override void PersistDeletedItem(ContentPreviewEntity entity) + { + throw new NotImplementedException(); + } + #endregion + + protected override void PersistNewItem(ContentPreviewEntity entity) + { + if (entity.Content.HasIdentity == false) + { + throw new InvalidOperationException("Cannot insert a preview for a content item that has no identity"); + } + + var previewPoco = new PreviewXmlDto + { + NodeId = entity.Id, + Timestamp = DateTime.Now, + VersionId = entity.Version, + Xml = entity.Xml.ToString(SaveOptions.None) + }; + + Database.Insert(previewPoco); + } + + protected override void PersistUpdatedItem(ContentPreviewEntity entity) + { + if (entity.Content.HasIdentity == false) + { + throw new InvalidOperationException("Cannot update a preview for a content item that has no identity"); + } + + var previewPoco = new PreviewXmlDto + { + NodeId = entity.Id, + Timestamp = DateTime.Now, + VersionId = entity.Version, + Xml = entity.Xml.ToString(SaveOptions.None) + }; + + Database.Update( + "SET xml = @Xml, timestamp = @Timestamp WHERE nodeId = @Id AND versionId = @Version", + new + { + Xml = previewPoco.Xml, + Timestamp = previewPoco.Timestamp, + Id = previewPoco.NodeId, + Version = previewPoco.VersionId + }); + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs index 9b2d728ab5..fc88ee5780 100644 --- a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs @@ -26,7 +26,7 @@ namespace Umbraco.Core.Persistence.Repositories private readonly IContentTypeRepository _contentTypeRepository; private readonly ITemplateRepository _templateRepository; private readonly CacheHelper _cacheHelper; - private readonly ContentPreviewRepository _contentPreviewRepository; + private readonly ContentPreviewRepository _contentPreviewRepository; private readonly ContentXmlRepository _contentXmlRepository; public ContentRepository(IDatabaseUnitOfWork work, IContentTypeRepository contentTypeRepository, ITemplateRepository templateRepository, CacheHelper cacheHelper) @@ -35,7 +35,7 @@ namespace Umbraco.Core.Persistence.Repositories _contentTypeRepository = contentTypeRepository; _templateRepository = templateRepository; _cacheHelper = cacheHelper; - _contentPreviewRepository = new ContentPreviewRepository(work, NullCacheProvider.Current); + _contentPreviewRepository = new ContentPreviewRepository(work, NullCacheProvider.Current); _contentXmlRepository = new ContentXmlRepository(work, NullCacheProvider.Current); EnsureUniqueNaming = true; @@ -47,7 +47,7 @@ namespace Umbraco.Core.Persistence.Repositories _contentTypeRepository = contentTypeRepository; _templateRepository = templateRepository; _cacheHelper = cacheHelper; - _contentPreviewRepository = new ContentPreviewRepository(work, NullCacheProvider.Current); + _contentPreviewRepository = new ContentPreviewRepository(work, NullCacheProvider.Current); _contentXmlRepository = new ContentXmlRepository(work, NullCacheProvider.Current); EnsureUniqueNaming = true; @@ -586,7 +586,7 @@ namespace Umbraco.Core.Persistence.Repositories Database.ExecuteScalar("SELECT COUNT(nodeId) FROM cmsPreviewXml WHERE nodeId = @Id AND versionId = @Version", new { Id = content.Id, Version = content.Version }) != 0; - _contentPreviewRepository.AddOrUpdate(new ContentPreviewEntity(previewExists, content, xml)); + _contentPreviewRepository.AddOrUpdate(new ContentPreviewEntity(previewExists, content, xml)); } #endregion @@ -650,122 +650,5 @@ namespace Umbraco.Core.Persistence.Repositories return currentName; } - #region Private classes - - /// - /// Used content repository in order to add an entity to the persisted collection to be saved - /// in a single transaction during saving an entity - /// - private class ContentPreviewEntity : ContentXmlEntity - { - public ContentPreviewEntity(bool previewExists, IContent content, Func xml) - : base(previewExists, content, xml) - { - Version = content.Version; - } - - public Guid Version { get; private set; } - } - - /// - /// Private class to handle preview insert/update based on standard principles and units of work with transactions - /// - private class ContentPreviewRepository : PetaPocoRepositoryBase - { - public ContentPreviewRepository(IDatabaseUnitOfWork work, IRepositoryCacheProvider cache) - : base(work, cache) - { - } - - #region Not implemented (don't need to for the purposes of this repo) - protected override ContentPreviewEntity PerformGet(int id) - { - throw new NotImplementedException(); - } - - protected override IEnumerable PerformGetAll(params int[] ids) - { - throw new NotImplementedException(); - } - - protected override IEnumerable PerformGetByQuery(IQuery query) - { - throw new NotImplementedException(); - } - - protected override Sql GetBaseQuery(bool isCount) - { - throw new NotImplementedException(); - } - - protected override string GetBaseWhereClause() - { - throw new NotImplementedException(); - } - - protected override IEnumerable GetDeleteClauses() - { - return new List(); - } - - protected override Guid NodeObjectTypeId - { - get { throw new NotImplementedException(); } - } - - protected override void PersistDeletedItem(ContentPreviewEntity entity) - { - throw new NotImplementedException(); - } - #endregion - - protected override void PersistNewItem(ContentPreviewEntity entity) - { - if (entity.Content.HasIdentity == false) - { - throw new InvalidOperationException("Cannot insert a preview for a content item that has no identity"); - } - - var previewPoco = new PreviewXmlDto - { - NodeId = entity.Id, - Timestamp = DateTime.Now, - VersionId = entity.Version, - Xml = entity.Xml.ToString(SaveOptions.None) - }; - - Database.Insert(previewPoco); - } - - protected override void PersistUpdatedItem(ContentPreviewEntity entity) - { - if (entity.Content.HasIdentity == false) - { - throw new InvalidOperationException("Cannot update a preview for a content item that has no identity"); - } - - var previewPoco = new PreviewXmlDto - { - NodeId = entity.Id, - Timestamp = DateTime.Now, - VersionId = entity.Version, - Xml = entity.Xml.ToString(SaveOptions.None) - }; - - Database.Update( - "SET xml = @Xml, timestamp = @Timestamp WHERE nodeId = @Id AND versionId = @Version", - new - { - Xml = previewPoco.Xml, - Timestamp = previewPoco.Timestamp, - Id = previewPoco.NodeId, - Version = previewPoco.VersionId - }); - } - } - - #endregion - - } } diff --git a/src/Umbraco.Core/Persistence/Repositories/Interfaces/IMediaRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IMediaRepository.cs index 7573bac60c..f5823303fd 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Interfaces/IMediaRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IMediaRepository.cs @@ -14,5 +14,12 @@ namespace Umbraco.Core.Persistence.Repositories /// void AddOrUpdateContentXml(IMedia content, Func xml); + /// + /// Used to add/update preview xml for the content item + /// + /// + /// + void AddOrUpdatePreviewXml(IMedia content, Func xml); + } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Repositories/Interfaces/IMemberRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IMemberRepository.cs index c9ac555ee9..5b9a963079 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Interfaces/IMemberRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IMemberRepository.cs @@ -62,5 +62,12 @@ namespace Umbraco.Core.Persistence.Repositories /// void AddOrUpdateContentXml(IMember content, Func xml); + /// + /// Used to add/update preview xml for the content item + /// + /// + /// + void AddOrUpdatePreviewXml(IMember content, Func xml); + } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs index 0464917d18..525ddaf835 100644 --- a/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs @@ -22,13 +22,14 @@ namespace Umbraco.Core.Persistence.Repositories { private readonly IMediaTypeRepository _mediaTypeRepository; private readonly ContentXmlRepository _contentXmlRepository; + private readonly ContentPreviewRepository _contentPreviewRepository; public MediaRepository(IDatabaseUnitOfWork work, IMediaTypeRepository mediaTypeRepository) : base(work) { _mediaTypeRepository = mediaTypeRepository; _contentXmlRepository = new ContentXmlRepository(work, NullCacheProvider.Current); - + _contentPreviewRepository = new ContentPreviewRepository(work, NullCacheProvider.Current); EnsureUniqueNaming = true; } @@ -37,7 +38,7 @@ namespace Umbraco.Core.Persistence.Repositories { _mediaTypeRepository = mediaTypeRepository; _contentXmlRepository = new ContentXmlRepository(work, NullCacheProvider.Current); - + _contentPreviewRepository = new ContentPreviewRepository(work, NullCacheProvider.Current); EnsureUniqueNaming = true; } @@ -185,6 +186,15 @@ namespace Umbraco.Core.Persistence.Repositories _contentXmlRepository.AddOrUpdate(new ContentXmlEntity(contentExists, content, xml)); } + public void AddOrUpdatePreviewXml(IMedia content, Func xml) + { + var previewExists = + Database.ExecuteScalar("SELECT COUNT(nodeId) FROM cmsPreviewXml WHERE nodeId = @Id AND versionId = @Version", + new { Id = content.Id, Version = content.Version }) != 0; + + _contentPreviewRepository.AddOrUpdate(new ContentPreviewEntity(previewExists, content, xml)); + } + protected override void PerformDeleteVersion(int id, Guid versionId) { Database.Delete("WHERE nodeId = @Id AND versionId = @VersionId", new { Id = id, VersionId = versionId }); diff --git a/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs index 95a2f88909..bcf6fd490e 100644 --- a/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs @@ -26,6 +26,7 @@ namespace Umbraco.Core.Persistence.Repositories private readonly IMemberTypeRepository _memberTypeRepository; private readonly IMemberGroupRepository _memberGroupRepository; private readonly ContentXmlRepository _contentXmlRepository; + private readonly ContentPreviewRepository _contentPreviewRepository; public MemberRepository(IDatabaseUnitOfWork work, IMemberTypeRepository memberTypeRepository, IMemberGroupRepository memberGroupRepository) : base(work) @@ -34,6 +35,7 @@ namespace Umbraco.Core.Persistence.Repositories _memberTypeRepository = memberTypeRepository; _memberGroupRepository = memberGroupRepository; _contentXmlRepository = new ContentXmlRepository(work, NullCacheProvider.Current); + _contentPreviewRepository = new ContentPreviewRepository(work, NullCacheProvider.Current); } public MemberRepository(IDatabaseUnitOfWork work, IRepositoryCacheProvider cache, IMemberTypeRepository memberTypeRepository, IMemberGroupRepository memberGroupRepository) @@ -43,6 +45,7 @@ namespace Umbraco.Core.Persistence.Repositories _memberTypeRepository = memberTypeRepository; _memberGroupRepository = memberGroupRepository; _contentXmlRepository = new ContentXmlRepository(work, NullCacheProvider.Current); + _contentPreviewRepository = new ContentPreviewRepository(work, NullCacheProvider.Current); } #region Overrides of RepositoryBase @@ -605,6 +608,15 @@ namespace Umbraco.Core.Persistence.Repositories _contentXmlRepository.AddOrUpdate(new ContentXmlEntity(contentExists, content, xml)); } + public void AddOrUpdatePreviewXml(IMember content, Func xml) + { + var previewExists = + Database.ExecuteScalar("SELECT COUNT(nodeId) FROM cmsPreviewXml WHERE nodeId = @Id AND versionId = @Version", + new { Id = content.Id, Version = content.Version }) != 0; + + _contentPreviewRepository.AddOrUpdate(new ContentPreviewEntity(previewExists, content, xml)); + } + private IMember BuildFromDto(List dtos) { if (dtos == null || dtos.Any() == false) diff --git a/src/Umbraco.Core/Services/MediaService.cs b/src/Umbraco.Core/Services/MediaService.cs index 28cbe7da1c..935d6ffb07 100644 --- a/src/Umbraco.Core/Services/MediaService.cs +++ b/src/Umbraco.Core/Services/MediaService.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Threading; using System.Xml.Linq; using Umbraco.Core.Auditing; +using Umbraco.Core.Configuration; using Umbraco.Core.Events; using Umbraco.Core.Models; using Umbraco.Core.Models.Rdbms; @@ -158,6 +159,11 @@ namespace Umbraco.Core.Services repository.AddOrUpdate(media); repository.AddOrUpdateContentXml(media, m => _entitySerializer.Serialize(this, _dataTypeService, m)); + // generate preview for blame history? + if (UmbracoSettings.EnableGlobalPreviewStorage) + { + repository.AddOrUpdatePreviewXml(media, m => _entitySerializer.Serialize(this, _dataTypeService, m)); + } uow.Commit(); } @@ -212,6 +218,12 @@ namespace Umbraco.Core.Services media.CreatorId = userId; repository.AddOrUpdate(media); repository.AddOrUpdateContentXml(media, m => _entitySerializer.Serialize(this, _dataTypeService, m)); + // generate preview for blame history? + if (UmbracoSettings.EnableGlobalPreviewStorage) + { + repository.AddOrUpdatePreviewXml(media, m => _entitySerializer.Serialize(this, _dataTypeService, m)); + } + uow.Commit(); } } @@ -808,6 +820,11 @@ namespace Umbraco.Core.Services media.CreatorId = userId; repository.AddOrUpdate(media); repository.AddOrUpdateContentXml(media, m => _entitySerializer.Serialize(this, _dataTypeService, m)); + // generate preview for blame history? + if (UmbracoSettings.EnableGlobalPreviewStorage) + { + repository.AddOrUpdatePreviewXml(media, m => _entitySerializer.Serialize(this, _dataTypeService, m)); + } uow.Commit(); } @@ -845,6 +862,11 @@ namespace Umbraco.Core.Services media.CreatorId = userId; repository.AddOrUpdate(media); repository.AddOrUpdateContentXml(media, m => _entitySerializer.Serialize(this, _dataTypeService, m)); + // generate preview for blame history? + if (UmbracoSettings.EnableGlobalPreviewStorage) + { + repository.AddOrUpdatePreviewXml(media, m => _entitySerializer.Serialize(this, _dataTypeService, m)); + } } //commit the whole lot in one go @@ -898,6 +920,11 @@ namespace Umbraco.Core.Services repository.AddOrUpdate(media); repository.AddOrUpdateContentXml(media, m => _entitySerializer.Serialize(this, _dataTypeService, m)); + // generate preview for blame history? + if (UmbracoSettings.EnableGlobalPreviewStorage) + { + repository.AddOrUpdatePreviewXml(media, m => _entitySerializer.Serialize(this, _dataTypeService, m)); + } } uow.Commit(); diff --git a/src/Umbraco.Core/Services/MemberService.cs b/src/Umbraco.Core/Services/MemberService.cs index d42ea973d0..3998ecc1ce 100644 --- a/src/Umbraco.Core/Services/MemberService.cs +++ b/src/Umbraco.Core/Services/MemberService.cs @@ -5,6 +5,7 @@ using System.Threading; using System.Web.Security; using System.Xml.Linq; using Umbraco.Core.Auditing; +using Umbraco.Core.Configuration; using Umbraco.Core.Events; using Umbraco.Core.Models; using Umbraco.Core.Models.EntityBase; @@ -20,6 +21,7 @@ using Umbraco.Core.Security; namespace Umbraco.Core.Services { + /// /// Represents the MemberService. /// @@ -742,6 +744,12 @@ namespace Umbraco.Core.Services repository.AddOrUpdate(member); //insert the xml repository.AddOrUpdateContentXml(member, m => _entitySerializer.Serialize(_dataTypeService, m)); + // generate preview for blame history? + if (UmbracoSettings.EnableGlobalPreviewStorage) + { + repository.AddOrUpdatePreviewXml(member, m => _entitySerializer.Serialize(_dataTypeService, m)); + } + uow.Commit(); } @@ -847,6 +855,12 @@ namespace Umbraco.Core.Services { repository.AddOrUpdate(entity); repository.AddOrUpdateContentXml(entity, m => _entitySerializer.Serialize(_dataTypeService, m)); + // generate preview for blame history? + if (UmbracoSettings.EnableGlobalPreviewStorage) + { + repository.AddOrUpdatePreviewXml(entity, m => _entitySerializer.Serialize(_dataTypeService, m)); + } + uow.Commit(); } @@ -872,6 +886,11 @@ namespace Umbraco.Core.Services { repository.AddOrUpdate(member); repository.AddOrUpdateContentXml(member, m => _entitySerializer.Serialize(_dataTypeService, m)); + // generate preview for blame history? + if (UmbracoSettings.EnableGlobalPreviewStorage) + { + repository.AddOrUpdatePreviewXml(member, m => _entitySerializer.Serialize(_dataTypeService, m)); + } } //commit the whole lot in one go diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 19077d15f6..7169cc09ae 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -190,6 +190,7 @@ + @@ -233,6 +234,7 @@ + diff --git a/src/umbraco.cms/businesslogic/media/Media.cs b/src/umbraco.cms/businesslogic/media/Media.cs index 6d8f8180a3..47533cc036 100644 --- a/src/umbraco.cms/businesslogic/media/Media.cs +++ b/src/umbraco.cms/businesslogic/media/Media.cs @@ -282,17 +282,7 @@ namespace umbraco.cms.businesslogic.media base.VersionDate = MediaItem.UpdateDate; base.Save(); - - XmlDocument xd = new XmlDocument(); - XmlGenerate(xd); - - // generate preview for blame history? - if (UmbracoSettings.EnableGlobalPreviewStorage) - { - // Version as new guid to ensure different versions are generated as media are not versioned currently! - SavePreviewXml(generateXmlWithoutSaving(xd), Guid.NewGuid()); - } - + FireAfterSave(e); } } diff --git a/src/umbraco.cms/businesslogic/member/Member.cs b/src/umbraco.cms/businesslogic/member/Member.cs index 8cd6675498..90fda80dd0 100644 --- a/src/umbraco.cms/businesslogic/member/Member.cs +++ b/src/umbraco.cms/businesslogic/member/Member.cs @@ -613,16 +613,6 @@ namespace umbraco.cms.businesslogic.member base.Save(); - XmlDocument xd = new XmlDocument(); - XmlGenerate(xd); - - // generate preview for blame history? - if (UmbracoSettings.EnableGlobalPreviewStorage) - { - // Version as new guid to ensure different versions are generated as media are not versioned currently! - SavePreviewXml(generateXmlWithoutSaving(xd), Guid.NewGuid()); - } - if (raiseEvents) { FireAfterSave(e);