From a6b56db2f542a3a9e971f5798cc9fe879d31e211 Mon Sep 17 00:00:00 2001 From: Jordan Lane Date: Thu, 29 Oct 2015 15:16:44 +0000 Subject: [PATCH 1/7] Fixes an issue with the contentService.RePublishAll() where it wouldn't publish an old published version if the newest version of the content wasn't published i.e had a scheduled date set because this would create a new version with status not published --- .../Repositories/ContentRepository.cs | 30 +++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs index 60d7d8e7ef..2eab12a6a0 100644 --- a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs @@ -234,7 +234,7 @@ namespace Umbraco.Core.Persistence.Repositories var processed = 0; do { - var descendants = GetPagedResultsByQuery(query, pageIndex, pageSize, out total, "Path", Direction.Ascending); + var descendants = GetPagedResultsByQueryNoFilter(query, pageIndex, pageSize, out total, "Path", Direction.Ascending); var xmlItems = (from descendant in descendants let xml = serializer(descendant) @@ -728,7 +728,7 @@ namespace Umbraco.Core.Persistence.Repositories /// /// public void AddOrUpdateContentXml(IContent content, Func xml) - { + { _contentXmlRepository.AddOrUpdate(new ContentXmlEntity(content, xml)); } @@ -787,6 +787,26 @@ namespace Umbraco.Core.Persistence.Repositories } + /// + /// Gets paged content results + /// + /// Query to excute + /// Page number + /// Page size + /// Total records query would return without paging + /// Field to order by + /// Direction to order by + /// An Enumerable list of objects + public IEnumerable GetPagedResultsByQueryNoFilter(IQuery query, long pageIndex, int pageSize, out long totalRecords, + string orderBy, Direction orderDirection) + { + + return GetPagedResultsByQuery(query, pageIndex, pageSize, out totalRecords, + new Tuple("cmsDocument", "nodeId"), + ProcessQuery, orderBy, orderDirection); + + } + #endregion #region IRecycleBinRepository members @@ -826,11 +846,11 @@ namespace Umbraco.Core.Persistence.Repositories var contentTypes = _contentTypeRepository.GetAll(dtos.Select(x => x.ContentVersionDto.ContentDto.ContentTypeId).ToArray()) .ToArray(); - + var ids = dtos .Where(dto => dto.TemplateId.HasValue && dto.TemplateId.Value > 0) .Select(x => x.TemplateId.Value).ToArray(); - + //NOTE: This should be ok for an SQL 'IN' statement, there shouldn't be an insane amount of content types var templates = ids.Length == 0 ? Enumerable.Empty() : _templateRepository.GetAll(ids).ToArray(); @@ -972,4 +992,4 @@ namespace Umbraco.Core.Persistence.Repositories _contentXmlRepository.Dispose(); } } -} +} \ No newline at end of file From 1e4c9c2505c155e72b8c74215487db1e3a6684c7 Mon Sep 17 00:00:00 2001 From: Jordan Lane Date: Thu, 29 Oct 2015 15:20:35 +0000 Subject: [PATCH 2/7] Set the publish status of new content version to saved if validation of publication fails e.g. a release date of the future or past unpublish date --- src/Umbraco.Core/Services/ContentService.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Umbraco.Core/Services/ContentService.cs b/src/Umbraco.Core/Services/ContentService.cs index da25bd0938..6819ce2859 100644 --- a/src/Umbraco.Core/Services/ContentService.cs +++ b/src/Umbraco.Core/Services/ContentService.cs @@ -1966,6 +1966,10 @@ namespace Umbraco.Core.Services var uow = UowProvider.GetUnitOfWork(); using (var repository = RepositoryFactory.CreateContentRepository(uow)) { + if (published == false) + { + content.ChangePublishedState(PublishedState.Saved); + } //Since this is the Save and Publish method, the content should be saved even though the publish fails or isn't allowed if (content.HasIdentity == false) { From c5cf1fa6b2d3930bc4ee818124feaac217936c71 Mon Sep 17 00:00:00 2001 From: Jordan Lane Date: Thu, 29 Oct 2015 15:21:15 +0000 Subject: [PATCH 3/7] Checks if content has expired or is awaiting release before publishing --- src/Umbraco.Core/Services/ContentService.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/Umbraco.Core/Services/ContentService.cs b/src/Umbraco.Core/Services/ContentService.cs index 6819ce2859..68038fe9c0 100644 --- a/src/Umbraco.Core/Services/ContentService.cs +++ b/src/Umbraco.Core/Services/ContentService.cs @@ -2112,6 +2112,22 @@ namespace Umbraco.Core.Services content.Name, content.Id)); return PublishStatusType.FailedPathNotPublished; } + else if (content.ExpireDate.HasValue && content.ExpireDate.Value > DateTime.MinValue && DateTime.Now > content.ExpireDate.Value) + { + Logger.Info( + string.Format( + "Content '{0}' with Id '{1}' has expired and could not be published.", + content.Name, content.Id)); + return PublishStatusType.FailedHasExpired; + } + else if (content.ReleaseDate.HasValue && content.ReleaseDate.Value > DateTime.MinValue && content.ReleaseDate.Value > DateTime.Now) + { + Logger.Info( + string.Format( + "Content '{0}' with Id '{1}' is awaiting release and could not be published.", + content.Name, content.Id)); + return PublishStatusType.FailedAwaitingRelease; + } return PublishStatusType.Success; } From 8e6bac534a9042828c0331cd49b6419a5f521fe4 Mon Sep 17 00:00:00 2001 From: Jordan Lane Date: Thu, 29 Oct 2015 15:23:40 +0000 Subject: [PATCH 4/7] Fix a bug where PublishStatusType would fallback to FailedContentInvalid (and break) if it was expired or trashed and add error message for FailedHasExpired TODO: Add error message to other languages --- src/Umbraco.Web.UI/umbraco/config/lang/en.xml | 3 +++ src/Umbraco.Web/Editors/ContentController.cs | 10 +++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml index 8f493d2582..90c9e0c605 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml @@ -689,6 +689,9 @@ To manage your website, simply open the Umbraco back office and start adding con %0% could not be published because the item is scheduled for release. ]]> + diff --git a/src/Umbraco.Web/Editors/ContentController.cs b/src/Umbraco.Web/Editors/ContentController.cs index 1b6fbfa3cb..9e63a45353 100644 --- a/src/Umbraco.Web/Editors/ContentController.cs +++ b/src/Umbraco.Web/Editors/ContentController.cs @@ -659,9 +659,17 @@ namespace Umbraco.Web.Editors new[] {string.Format("{0} ({1})", status.ContentItem.Name, status.ContentItem.Id)}).Trim()); break; case PublishStatusType.FailedHasExpired: - //TODO: We should add proper error messaging for this! + display.AddWarningNotification( + Services.TextService.Localize("publish"), + Services.TextService.Localize("publish/contentPublishedFailedExpired", + new[] + { + string.Format("{0} ({1})", status.ContentItem.Name, status.ContentItem.Id), + }).Trim()); + break; case PublishStatusType.FailedIsTrashed: //TODO: We should add proper error messaging for this! + break; case PublishStatusType.FailedContentInvalid: display.AddWarningNotification( Services.TextService.Localize("publish"), From d6a49f275f8a7442d2f3826e624976146ab3eb51 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 13 Jan 2016 10:29:26 +0100 Subject: [PATCH 5/7] adds test that fails - need to fix it now --- .../Repositories/ContentRepositoryTest.cs | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/src/Umbraco.Tests/Persistence/Repositories/ContentRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/ContentRepositoryTest.cs index 146ec49a50..d3ff6307cf 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/ContentRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/ContentRepositoryTest.cs @@ -57,6 +57,58 @@ namespace Umbraco.Tests.Persistence.Repositories return repository; } + [Test] + public void Rebuild_Xml_Structures_With_Non_Latest_Version() + { + var provider = new PetaPocoUnitOfWorkProvider(Logger); + var unitOfWork = provider.GetUnitOfWork(); + ContentTypeRepository contentTypeRepository; + using (var repository = CreateRepository(unitOfWork, out contentTypeRepository)) + { + var contentType1 = MockedContentTypes.CreateSimpleContentType("Textpage1", "Textpage1"); + contentTypeRepository.AddOrUpdate(contentType1); + + var allCreated = new List(); + + //create 100 non published + for (var i = 0; i < 100; i++) + { + var c1 = MockedContent.CreateSimpleContent(contentType1); + repository.AddOrUpdate(c1); + allCreated.Add(c1); + } + //create 100 published + for (var i = 0; i < 100; i++) + { + var c1 = MockedContent.CreateSimpleContent(contentType1); + c1.ChangePublishedState(PublishedState.Published); + repository.AddOrUpdate(c1); + allCreated.Add(c1); + } + unitOfWork.Commit(); + + //now create some versions of this content - this shouldn't affect the xml structures saved + for (int i = 0; i < allCreated.Count; i++) + { + allCreated[i].Name = "blah" + i; + //IMPORTANT testing note here: We need to changed the published state here so that + // it doesn't automatically think this is simply publishing again - this forces the latest + // version to be Saved and not published + allCreated[i].ChangePublishedState(PublishedState.Saved); + repository.AddOrUpdate(allCreated[i]); + } + unitOfWork.Commit(); + + //delete all xml + unitOfWork.Database.Execute("DELETE FROM cmsContentXml"); + Assert.AreEqual(0, unitOfWork.Database.ExecuteScalar("SELECT COUNT(*) FROM cmsContentXml")); + + repository.RebuildXmlStructures(media => new XElement("test"), 10); + + Assert.AreEqual(100, unitOfWork.Database.ExecuteScalar("SELECT COUNT(*) FROM cmsContentXml")); + } + } + [Test] public void Rebuild_All_Xml_Structures() { From 68ddea2776d8219ed7a233c2581edcf72b01bf38 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 13 Jan 2016 12:33:57 +0100 Subject: [PATCH 6/7] refactors a bit of code from the PR, adds more translations to the other english file. --- .../Repositories/ContentRepository.cs | 31 ++++++------------- .../umbraco/config/lang/en_us.xml | 3 ++ 2 files changed, 12 insertions(+), 22 deletions(-) diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs index 2eab12a6a0..85491b9f36 100644 --- a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs @@ -234,8 +234,15 @@ namespace Umbraco.Core.Persistence.Repositories var processed = 0; do { - var descendants = GetPagedResultsByQueryNoFilter(query, pageIndex, pageSize, out total, "Path", Direction.Ascending); - + //NOTE: This is an important call, we cannot simply make a call to: + // GetPagedResultsByQuery(query, pageIndex, pageSize, out total, "Path", Direction.Ascending); + // because that method is used to query 'latest' content items where in this case we don't necessarily + // want latest content items because a pulished content item might not actually be the latest. + // see: http://issues.umbraco.org/issue/U4-6322 & http://issues.umbraco.org/issue/U4-5982 + var descendants = GetPagedResultsByQuery(query, pageIndex, pageSize, out total, + new Tuple("cmsDocument", "nodeId"), + ProcessQuery, "Path", Direction.Ascending); + var xmlItems = (from descendant in descendants let xml = serializer(descendant) select new ContentXmlDto { NodeId = descendant.Id, Xml = xml.ToDataString() }).ToArray(); @@ -787,26 +794,6 @@ namespace Umbraco.Core.Persistence.Repositories } - /// - /// Gets paged content results - /// - /// Query to excute - /// Page number - /// Page size - /// Total records query would return without paging - /// Field to order by - /// Direction to order by - /// An Enumerable list of objects - public IEnumerable GetPagedResultsByQueryNoFilter(IQuery query, long pageIndex, int pageSize, out long totalRecords, - string orderBy, Direction orderDirection) - { - - return GetPagedResultsByQuery(query, pageIndex, pageSize, out totalRecords, - new Tuple("cmsDocument", "nodeId"), - ProcessQuery, orderBy, orderDirection); - - } - #endregion #region IRecycleBinRepository members diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml index 2a86fa458b..c7480ac22a 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml @@ -696,6 +696,9 @@ To manage your website, simply open the Umbraco back office and start adding con %0% could not be published because the item is scheduled for release. ]]> + From 5b9cbae860609eb4ea7d5bc9338003aa5351c2f5 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 13 Jan 2016 17:17:39 +0100 Subject: [PATCH 7/7] Fixes: U4-7712 fcnMode = Single by default --- src/Umbraco.Web.UI/web.Template.Debug.config | 2 +- src/Umbraco.Web.UI/web.Template.config | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI/web.Template.Debug.config b/src/Umbraco.Web.UI/web.Template.Debug.config index dfbf72173e..3a6633ebab 100644 --- a/src/Umbraco.Web.UI/web.Template.Debug.config +++ b/src/Umbraco.Web.UI/web.Template.Debug.config @@ -89,7 +89,7 @@ - + diff --git a/src/Umbraco.Web.UI/web.Template.config b/src/Umbraco.Web.UI/web.Template.config index 62e3a00457..17e2dbf755 100644 --- a/src/Umbraco.Web.UI/web.Template.config +++ b/src/Umbraco.Web.UI/web.Template.config @@ -79,7 +79,7 @@ - +