From 7f4abb48935f0529d8ca03ce3c8b9bdeb58f6884 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 24 Jul 2013 12:54:10 +1000 Subject: [PATCH] Fixed editContent.aspx to let the business logic handle the property validation when trying to publish and show the correct status message result (if it was not publishable). Adds the invalid properties collection to the PublishStatus so those can be shown too. --- src/Umbraco.Core/Models/ContentBase.cs | 13 ++- src/Umbraco.Core/Publishing/PublishStatus.cs | 7 +- src/Umbraco.Core/Services/ContentService.cs | 2 + src/Umbraco.Web.UI/umbraco/config/lang/en.xml | 2 +- .../umbraco/config/lang/en_us.xml | 2 +- .../WebServices/BulkPublishController.cs | 6 +- .../umbraco/dialogs/publish.aspx.cs | 1 + .../umbraco/editContent.aspx.cs | 101 ++++++++++-------- src/umbraco.cms/businesslogic/web/Document.cs | 26 +++-- 9 files changed, 102 insertions(+), 58 deletions(-) diff --git a/src/Umbraco.Core/Models/ContentBase.cs b/src/Umbraco.Core/Models/ContentBase.cs index 4c00831cae..6414ea2116 100644 --- a/src/Umbraco.Core/Models/ContentBase.cs +++ b/src/Umbraco.Core/Models/ContentBase.cs @@ -27,6 +27,7 @@ namespace Umbraco.Core.Models private bool _trashed; private int _contentTypeId; private PropertyCollection _properties; + private readonly List _lastInvalidProperties = new List(); /// /// Protected constructor for ContentBase (Base for Content and Media) @@ -421,7 +422,17 @@ namespace Umbraco.Core.Models /// True if content is valid otherwise false public virtual bool IsValid() { - return Properties.Any(property => !property.IsValid()) == false; + _lastInvalidProperties.Clear(); + _lastInvalidProperties.AddRange(Properties.Where(property => property.IsValid() == false)); + return _lastInvalidProperties.Any() == false; + } + + /// + /// Returns a collection of the result of the last validation process, this collection contains all invalid properties. + /// + internal IEnumerable LastInvalidProperties + { + get { return _lastInvalidProperties; } } public abstract void ChangeTrashedState(bool isTrashed, int parentId = -20); diff --git a/src/Umbraco.Core/Publishing/PublishStatus.cs b/src/Umbraco.Core/Publishing/PublishStatus.cs index 6bbaa59783..415b758965 100644 --- a/src/Umbraco.Core/Publishing/PublishStatus.cs +++ b/src/Umbraco.Core/Publishing/PublishStatus.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using Umbraco.Core.Models; namespace Umbraco.Core.Publishing @@ -10,6 +11,11 @@ namespace Umbraco.Core.Publishing public IContent ContentItem { get; private set; } public PublishStatusType StatusType { get; internal set; } + /// + /// Gets sets the invalid properties if the status failed due to validation. + /// + public IEnumerable InvalidProperties { get; set; } + public PublishStatus(IContent content, PublishStatusType statusType) { ContentItem = content; @@ -24,6 +30,5 @@ namespace Umbraco.Core.Publishing { } - } } \ No newline at end of file diff --git a/src/Umbraco.Core/Services/ContentService.cs b/src/Umbraco.Core/Services/ContentService.cs index ed47bc76d6..94aa0f9140 100644 --- a/src/Umbraco.Core/Services/ContentService.cs +++ b/src/Umbraco.Core/Services/ContentService.cs @@ -1552,6 +1552,8 @@ namespace Umbraco.Core.Services publishStatus.StatusType = CheckAndLogIsPublishable(content); //Content contains invalid property values and can therefore not be published - fire event? publishStatus.StatusType = CheckAndLogIsValid(content); + //set the invalid properties (if there are any) + publishStatus.InvalidProperties = ((ContentBase) content).LastInvalidProperties; //if we're still successful, then publish using the strategy if (publishStatus.StatusType == PublishStatusType.Success) diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml index 8923314534..b1eb029426 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml @@ -670,7 +670,7 @@ To manage your website, simply open the umbraco back office and start adding con 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 e56017416b..af7156b776 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml @@ -656,7 +656,7 @@ To manage your website, simply open the umbraco back office and start adding con diff --git a/src/Umbraco.Web/WebServices/BulkPublishController.cs b/src/Umbraco.Web/WebServices/BulkPublishController.cs index 74fdf75919..2c18a6df2c 100644 --- a/src/Umbraco.Web/WebServices/BulkPublishController.cs +++ b/src/Umbraco.Web/WebServices/BulkPublishController.cs @@ -93,7 +93,11 @@ namespace Umbraco.Web.WebServices string.Format("{0} ({1})", status.ContentItem.Name, status.ContentItem.Id), UmbracoUser); case PublishStatusType.FailedContentInvalid: return ui.Text("publish", "contentPublishedFailedInvalid", - string.Format("{0} ({1})", status.ContentItem.Name, status.ContentItem.Id), UmbracoUser); + new []{ + string.Format("{0} ({1})", status.ContentItem.Name, status.ContentItem.Id), + string.Join(",", status.InvalidProperties.Select(x => x.Alias)) + }, + UmbracoUser); default: return status.StatusType.ToString(); } diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/publish.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/publish.aspx.cs index dfb7507073..255c61cbe8 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/publish.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/publish.aspx.cs @@ -14,6 +14,7 @@ namespace umbraco.dialogs /// /// Summary description for publish. /// + [Obsolete("This is no longer used whatsoever and will be removed from the codebase")] public partial class publish : UmbracoEnsuredPage { protected Literal total; diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs index 5cbd2b87ef..ab8579db27 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs @@ -4,6 +4,7 @@ using System.Web.UI.WebControls; using Umbraco.Core.Models; using Umbraco.Core.Persistence.Caching; using Umbraco.Core.IO; +using Umbraco.Core.Publishing; using Umbraco.Core.Services; using umbraco.BusinessLogic.Actions; using umbraco.uicontrols.DatePicker; @@ -290,65 +291,73 @@ namespace umbraco.cms.presentation { //update UI and set document properties PerformSaveLogic(); + + //the business logic here will check to see if the doc can actually be published and will return the + // appropriate result so we can display the correct error messages (or success). + var savePublishResult = _document.SaveAndPublishWithResult(UmbracoUser); - //the page is not valid, we'll still need to save the document and persist it - if (!Page.IsValid) - { - ClientTools.ShowSpeechBubble( - speechBubbleIcon.save, ui.Text("speechBubbles", "editContentSavedHeader", null), - ui.Text("speechBubbles", "editContentSavedText", null)); - _document.Save(); - return; - } + ShowMessageForStatus(savePublishResult.Result); - //If the document is at a level deeper than the root but it's ancestor's path is not published, - //it means that we cannot actually publish this document because one of it's parent's is not published. - //So, we still need to save the document but we'll show a different notification. - if (_document.Level > 1 && !Services.ContentService.IsPublishable(_document.Content)) + if (savePublishResult.Success) { - ClientTools.ShowSpeechBubble( - speechBubbleIcon.warning, ui.Text("publish"), - ui.Text("speechBubbles", "editContentPublishedFailedByParent")); - _document.Save(); - return; - } - - if (_document.SaveAndPublish(UmbracoUser)) - { - //library.UpdateDocumentCache(_document.Id); - - ClientTools.ShowSpeechBubble(speechBubbleIcon.save, ui.Text("speechBubbles", "editContentPublishedHeader", null), ui.Text("speechBubbles", "editContentPublishedText", null)); - _littPublishStatus.Text = string.Format("{0}: {1}
", ui.Text("content", "lastPublished", UmbracoUser), _document.VersionDate.ToString()); if (UmbracoUser.GetPermissions(_document.Path).IndexOf("U") > -1) + { _unPublish.Visible = true; + } _documentHasPublishedVersion = _document.Content.HasPublishedVersion(); - - //if (previouslyPublished == false) - //{ - // var descendants = ((ContentService)ApplicationContext.Current.Services.ContentService) - // .GetPublishedDescendants(_document.Content).ToList(); - - // if (descendants.Any()) - // { - // foreach (var descendant in descendants) - // { - // library.UpdateDocumentCache(descendant.Id); - // } - // library.RefreshContent(); - // } - //} } - else - { - ClientTools.ShowSpeechBubble(speechBubbleIcon.warning, ui.Text("publish"), ui.Text("speechBubbles", "contentPublishedFailedByEvent")); - } - + ClientTools.SyncTree(_document.Path, true); } + private void ShowMessageForStatus(PublishStatus status) + { + switch (status.StatusType) + { + case PublishStatusType.Success: + case PublishStatusType.SuccessAlreadyPublished: + ClientTools.ShowSpeechBubble( + speechBubbleIcon.save, + ui.Text("speechBubbles", "editContentPublishedHeader", UmbracoUser), + ui.Text("speechBubbles", "editContentPublishedText", UmbracoUser)); + break; + case PublishStatusType.FailedPathNotPublished: + ClientTools.ShowSpeechBubble( + speechBubbleIcon.warning, + ui.Text("publish"), + ui.Text("publish", "contentPublishedFailedByParent", + string.Format("{0} ({1})", status.ContentItem.Name, status.ContentItem.Id), + UmbracoUser).Trim()); + break; + case PublishStatusType.FailedCancelledByEvent: + ClientTools.ShowSpeechBubble( + speechBubbleIcon.warning, + ui.Text("publish"), + ui.Text("speechBubbles", "contentPublishedFailedByEvent")); + break; + case PublishStatusType.FailedHasExpired: + case PublishStatusType.FailedAwaitingRelease: + case PublishStatusType.FailedIsTrashed: + case PublishStatusType.FailedContentInvalid: + ClientTools.ShowSpeechBubble( + speechBubbleIcon.warning, + ui.Text("publish"), + ui.Text("publish", "contentPublishedFailedInvalid", + new[] + { + string.Format("{0} ({1})", status.ContentItem.Name, status.ContentItem.Id), + string.Join(",", status.InvalidProperties.Select(x => x.Alias)) + }, + UmbracoUser).Trim()); + break; + default: + throw new IndexOutOfRangeException(); + } + } + protected void UnPublishDo(object sender, EventArgs e) { _document.UnPublish(); diff --git a/src/umbraco.cms/businesslogic/web/Document.cs b/src/umbraco.cms/businesslogic/web/Document.cs index 2df9e19f37..724ca09b34 100644 --- a/src/umbraco.cms/businesslogic/web/Document.cs +++ b/src/umbraco.cms/businesslogic/web/Document.cs @@ -1027,11 +1027,12 @@ namespace umbraco.cms.businesslogic.web } /// - /// Saves and publishes a document + /// Do not use! only used internally in order to get the published status until we upgrade everything to use the new API /// - /// The usercontext under which the action are performed + /// /// - public bool SaveAndPublish(User u) + [Obsolete("Do not use! only used internally in order to get the published status until we upgrade everything to use the new API")] + internal Attempt SaveAndPublishWithResult(User u) { foreach (var property in GenericProperties) { @@ -1065,13 +1066,24 @@ namespace umbraco.cms.businesslogic.web //Now we need to fire the After publish event FireAfterPublish(publishArgs); - return result.Success; + return result; } - - return false; + + return Attempt.False; } - return false; + return Attempt.False; + } + + /// + /// Saves and publishes a document + /// + /// The usercontext under which the action are performed + /// + public bool SaveAndPublish(User u) + { + var result = SaveAndPublishWithResult(u); + return result.Success; } [Obsolete("Obsolete, Use Umbraco.Core.Services.ContentService.HasPublishedVersion()", false)]