diff --git a/src/Umbraco.Core/Models/ContentExtensions.cs b/src/Umbraco.Core/Models/ContentExtensions.cs index 2c4b1006c3..10151455e7 100644 --- a/src/Umbraco.Core/Models/ContentExtensions.cs +++ b/src/Umbraco.Core/Models/ContentExtensions.cs @@ -370,6 +370,18 @@ namespace Umbraco.Core.Models } } + /// + /// Checks whether an item has any published versions + /// + /// + /// True if the content has any published versiom otherwise False + public static bool HasPublishedVersion(this IContent content) + { + if (content.HasIdentity == false) + return false; + + return ApplicationContext.Current.Services.ContentService.HasPublishedVersion(content.Id); + } /// /// Creates the xml representation for the object diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs index f7f67a85ab..6417c48b2f 100644 --- a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs @@ -298,7 +298,7 @@ namespace Umbraco.Core.Persistence.Repositories } //If Published state has changed then previous versions should have their publish state reset - if (((ICanBeDirty)entity).IsPropertyDirty("Published")) + if (((ICanBeDirty)entity).IsPropertyDirty("Published") && entity.Published) { var publishedDocs = Database.Fetch("WHERE nodeId = @Id AND published = @IsPublished", new { Id = entity.Id, IsPublished = true }); foreach (var doc in publishedDocs) diff --git a/src/Umbraco.Core/Services/ContentService.cs b/src/Umbraco.Core/Services/ContentService.cs index 8f2c76f582..768bd63857 100644 --- a/src/Umbraco.Core/Services/ContentService.cs +++ b/src/Umbraco.Core/Services/ContentService.cs @@ -1,5 +1,4 @@ using System; -using System.Collections; using System.Collections.Generic; using System.Linq; using System.Web; @@ -573,7 +572,7 @@ namespace Umbraco.Core.Services return false; //Check if parent is published (although not if its a root node) - if parent isn't published this Content cannot be published - if (content.ParentId != -1 && content.ParentId != -20 && IsPublishable(content) == false) + if (content.ParentId != -1 && content.ParentId != -20 && IsPublishable(content) == false) { LogHelper.Info( string.Format( @@ -608,31 +607,30 @@ namespace Umbraco.Core.Services { var xml = content.ToXml(); var poco = new ContentXmlDto { NodeId = content.Id, Xml = xml.ToString(SaveOptions.None) }; - var exists = - uow.Database.FirstOrDefault("WHERE nodeId = @Id", new { Id = content.Id }) != - null; + var exists = uow.Database.FirstOrDefault("WHERE nodeId = @Id", new {Id = content.Id}) != null; int result = exists ? uow.Database.Update(poco) : Convert.ToInt32(uow.Database.Insert(poco)); } } + Saved.RaiseEvent(new SaveEventArgs(content, false), this); + //Save xml to db and call following method to fire event through PublishingStrategy to update cache if (omitCacheRefresh == false) _publishingStrategy.PublishingFinalized(content); + + //We need to check if children and their publish state to ensure that we republish content that was previously published + if (HasChildren(content.Id)) + { + var children = GetChildrenDeep(content.Id); + var shouldBeRepublished = children.Where(child => HasPublishedVersion(child.Id)); - Saved.RaiseEvent(new SaveEventArgs(content, false), this); - if (HasChildren(content.Id)) - { - var children = GetChildrenDeep(content.Id); - var shouldBeRepublished = children.Where(child => HasPublishedVersion(child.Id)); + if (omitCacheRefresh == false) + _publishingStrategy.PublishingFinalized(shouldBeRepublished, false); + } - if (omitCacheRefresh == false) - _publishingStrategy.PublishingFinalized(shouldBeRepublished, false); - } - - - Audit.Add(AuditTypes.Publish, "Save and Publish performed by user", userId == -1 ? 0 : userId, content.Id); + Audit.Add(AuditTypes.Publish, "Save and Publish performed by user", userId == -1 ? 0 : userId, content.Id); return published; } @@ -688,7 +686,6 @@ namespace Umbraco.Core.Services { foreach (var content in contents) { - SetWriter(content, userId); //Only change the publish state if the "previous" version was actually published @@ -1102,7 +1099,6 @@ namespace Umbraco.Core.Services /// The newly created object public IContent Rollback(int id, Guid versionId, int userId = -1) { - var content = GetByVersion(versionId); if (RollingBack.IsRaisedEventCancelled(new RollbackEventArgs(content), this)) @@ -1149,7 +1145,7 @@ namespace Umbraco.Core.Services /// /// Id of the parent to retrieve children from /// A list of valid that can be published - private List GetChildrenDeep(int parentId) + private IEnumerable GetChildrenDeep(int parentId) { var list = new List(); var children = GetChildren(parentId); diff --git a/src/Umbraco.Tests/Persistence/Querying/ContentRepositorySqlClausesTest.cs b/src/Umbraco.Tests/Persistence/Querying/ContentRepositorySqlClausesTest.cs index f5a7cf11ca..37a57a6bf6 100644 --- a/src/Umbraco.Tests/Persistence/Querying/ContentRepositorySqlClausesTest.cs +++ b/src/Umbraco.Tests/Persistence/Querying/ContentRepositorySqlClausesTest.cs @@ -20,7 +20,7 @@ namespace Umbraco.Tests.Persistence.Querying .InnerJoin("[cmsContentVersion]").On("[cmsDocument].[versionId] = [cmsContentVersion].[VersionId]") .InnerJoin("[cmsContent]").On("[cmsContentVersion].[ContentId] = [cmsContent].[nodeId]") .InnerJoin("[umbracoNode]").On("[cmsContent].[nodeId] = [umbracoNode].[id]") - .Where("nodeObjectType='c66ba18e-eaf3-4cff-8a22-41b16d66a972'"); + .Where("nodeObjectType = 'c66ba18e-eaf3-4cff-8a22-41b16d66a972'"); var sql = new Sql(); sql.Select("*") @@ -49,8 +49,8 @@ namespace Umbraco.Tests.Persistence.Querying .InnerJoin("[cmsContentVersion]").On("[cmsDocument].[versionId] = [cmsContentVersion].[VersionId]") .InnerJoin("[cmsContent]").On("[cmsContentVersion].[ContentId] = [cmsContent].[nodeId]") .InnerJoin("[umbracoNode]").On("[cmsContent].[nodeId] = [umbracoNode].[id]") - .Where("nodeObjectType='c66ba18e-eaf3-4cff-8a22-41b16d66a972'") - .Where("id=1050"); + .Where("nodeObjectType = 'c66ba18e-eaf3-4cff-8a22-41b16d66a972'") + .Where("id = 1050"); var sql = new Sql(); sql.Select("*") @@ -81,9 +81,9 @@ namespace Umbraco.Tests.Persistence.Querying .InnerJoin("[cmsContentVersion]").On("[cmsDocument].[versionId] = [cmsContentVersion].[VersionId]") .InnerJoin("[cmsContent]").On("[cmsContentVersion].[ContentId] = [cmsContent].[nodeId]") .InnerJoin("[umbracoNode]").On("[cmsContent].[nodeId] = [umbracoNode].[id]") - .Where("nodeObjectType='c66ba18e-eaf3-4cff-8a22-41b16d66a972'") - .Where("id=1050") - .Where("VersionId='2b543516-a944-4ee6-88c6-8813da7aaa07'") + .Where("nodeObjectType = 'c66ba18e-eaf3-4cff-8a22-41b16d66a972'") + .Where("id = 1050") + .Where("VersionId = '2b543516-a944-4ee6-88c6-8813da7aaa07'") .OrderBy("[cmsContentVersion].[VersionDate] DESC"); var sql = new Sql(); diff --git a/src/Umbraco.Tests/Persistence/Querying/ContentTypeRepositorySqlClausesTest.cs b/src/Umbraco.Tests/Persistence/Querying/ContentTypeRepositorySqlClausesTest.cs index d9fca798e7..6a72713323 100644 --- a/src/Umbraco.Tests/Persistence/Querying/ContentTypeRepositorySqlClausesTest.cs +++ b/src/Umbraco.Tests/Persistence/Querying/ContentTypeRepositorySqlClausesTest.cs @@ -21,8 +21,8 @@ namespace Umbraco.Tests.Persistence.Querying .On("[cmsContentType].[nodeId] = [cmsDocumentType].[contentTypeNodeId]") .InnerJoin("[umbracoNode]") .On("[cmsContentType].[nodeId] = [umbracoNode].[id]") - .Where("nodeObjectType='a2cb7800-f571-4787-9638-bc48539a0efb'") - .Where("IsDefault='True'"); + .Where("nodeObjectType = 'a2cb7800-f571-4787-9638-bc48539a0efb'") + .Where("IsDefault = 'True'"); var sql = new Sql(); sql.Select("*") @@ -51,9 +51,9 @@ namespace Umbraco.Tests.Persistence.Querying .On("[cmsContentType].[nodeId] = [cmsDocumentType].[contentTypeNodeId]") .InnerJoin("[umbracoNode]") .On("[cmsContentType].[nodeId] = [umbracoNode].[id]") - .Where("nodeObjectType='a2cb7800-f571-4787-9638-bc48539a0efb'") - .Where("IsDefault='True'") - .Where("id=1050"); + .Where("nodeObjectType = 'a2cb7800-f571-4787-9638-bc48539a0efb'") + .Where("IsDefault = 'True'") + .Where("id = 1050"); var sql = new Sql(); sql.Select("*") diff --git a/src/Umbraco.Tests/Persistence/Querying/PetaPocoSqlTests.cs b/src/Umbraco.Tests/Persistence/Querying/PetaPocoSqlTests.cs index 0e57c019bb..8037e347aa 100644 --- a/src/Umbraco.Tests/Persistence/Querying/PetaPocoSqlTests.cs +++ b/src/Umbraco.Tests/Persistence/Querying/PetaPocoSqlTests.cs @@ -74,7 +74,7 @@ namespace Umbraco.Tests.Persistence.Querying public void Can_Use_Where_Predicate() { var expected = new Sql(); - expected.Select("*").From("[cmsContent]").Where("nodeId=1045"); + expected.Select("*").From("[cmsContent]").Where("nodeId = 1045"); var sql = new Sql(); sql.Select("*").From().Where(x => x.NodeId == 1045); @@ -90,8 +90,8 @@ namespace Umbraco.Tests.Persistence.Querying var expected = new Sql(); expected.Select("*") .From("[cmsContent]") - .Where("nodeId=1045") - .Where("contentType=1050"); + .Where("nodeId = 1045") + .Where("contentType = 1050"); var sql = new Sql(); sql.Select("*") diff --git a/src/Umbraco.Tests/Persistence/Querying/QueryBuilderTests.cs b/src/Umbraco.Tests/Persistence/Querying/QueryBuilderTests.cs index 2fc46144c1..46bc9099ac 100644 --- a/src/Umbraco.Tests/Persistence/Querying/QueryBuilderTests.cs +++ b/src/Umbraco.Tests/Persistence/Querying/QueryBuilderTests.cs @@ -48,7 +48,7 @@ namespace Umbraco.Tests.Persistence.Querying var result = translator.Translate(); var strResult = result.SQL; - string expectedResult = "SELECT *\nFROM umbracoNode\nWHERE ([umbracoNode].[parentID]=-1)"; + string expectedResult = "SELECT *\nFROM umbracoNode\nWHERE ([umbracoNode].[parentID] = -1)"; // Assert Assert.That(strResult, Is.Not.Empty); @@ -71,7 +71,7 @@ namespace Umbraco.Tests.Persistence.Querying var result = translator.Translate(); var strResult = result.SQL; - string expectedResult = "SELECT *\nFROM umbracoNode\nWHERE ([cmsContentType].[alias]='umbTextpage')"; + string expectedResult = "SELECT *\nFROM umbracoNode\nWHERE ([cmsContentType].[alias] = 'umbTextpage')"; // Assert Assert.That(strResult, Is.Not.Empty); diff --git a/src/Umbraco.Tests/Services/ContentServiceTests.cs b/src/Umbraco.Tests/Services/ContentServiceTests.cs index 10362f51a4..49e29d2324 100644 --- a/src/Umbraco.Tests/Services/ContentServiceTests.cs +++ b/src/Umbraco.Tests/Services/ContentServiceTests.cs @@ -308,7 +308,15 @@ namespace Umbraco.Tests.Services Assert.That(content.Published, Is.False); } - [Test] + /// + /// This test is ignored because the way children are handled when + /// parent is unpublished is treated differently now then from when this test + /// was written. + /// The correct case is now that Root is UnPublished removing the children + /// from cache, but still having them "Published" in the "background". + /// Once the Parent is Published the Children should re-appear as published. + /// + [Test, NUnit.Framework.Ignore] public void Can_UnPublish_Root_Content_And_Verify_Children_Is_UnPublished() { // Arrange @@ -727,6 +735,7 @@ namespace Umbraco.Tests.Services Assert.That(hasPublishedVersion, Is.True); } + private IEnumerable CreateContentHierarchy() { var contentType = ServiceContext.ContentTypeService.GetContentType("umbTextpage"); var root = ServiceContext.ContentService.GetById(1046);