diff --git a/src/Umbraco.Core/Configuration/GlobalSettings.cs b/src/Umbraco.Core/Configuration/GlobalSettings.cs index 7e6e2d53b5..c10b14ffcb 100644 --- a/src/Umbraco.Core/Configuration/GlobalSettings.cs +++ b/src/Umbraco.Core/Configuration/GlobalSettings.cs @@ -532,6 +532,16 @@ namespace Umbraco.Core.Configuration return context.Request.Path.ToLower().IndexOf(SystemDirectories.Umbraco.ToLower() + "/liveediting.aspx") > -1; } + public static bool RequestIsInUmbracoApplication(HttpContextBase context) + { + return context.Request.Path.ToLower().IndexOf(IOHelper.ResolveUrl(SystemDirectories.Umbraco).ToLower()) > -1; + } + + public static bool RequestIsLiveEditRedirector(HttpContextBase context) + { + return context.Request.Path.ToLower().IndexOf(SystemDirectories.Umbraco.ToLower() + "/liveediting.aspx") > -1; + } + /// /// Gets a value indicating whether umbraco should force a secure (https) connection to the backoffice. /// diff --git a/src/Umbraco.Core/Models/Content.cs b/src/Umbraco.Core/Models/Content.cs index 631f88075e..2e99396707 100644 --- a/src/Umbraco.Core/Models/Content.cs +++ b/src/Umbraco.Core/Models/Content.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.Serialization; diff --git a/src/Umbraco.Core/Models/ContentBase.cs b/src/Umbraco.Core/Models/ContentBase.cs index 6def10748f..3ddf71308e 100644 --- a/src/Umbraco.Core/Models/ContentBase.cs +++ b/src/Umbraco.Core/Models/ContentBase.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Collections.Specialized; +using System.Diagnostics; using System.Globalization; using System.Linq; using System.Reflection; @@ -13,6 +14,7 @@ namespace Umbraco.Core.Models /// /// Represents an abstract class for base Content properties and methods /// + [DebuggerDisplay("Id: {Id}, Name: {Name}, ContentType: {ContentTypeBase.Alias}")] public abstract class ContentBase : Entity, IContentBase { protected IContentTypeComposition ContentTypeBase; diff --git a/src/Umbraco.Core/Models/EntityBase/Entity.cs b/src/Umbraco.Core/Models/EntityBase/Entity.cs index 6c081ea0b4..95be4851e7 100644 --- a/src/Umbraco.Core/Models/EntityBase/Entity.cs +++ b/src/Umbraco.Core/Models/EntityBase/Entity.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.ComponentModel; +using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.Serialization; @@ -12,6 +13,7 @@ namespace Umbraco.Core.Models.EntityBase /// [Serializable] [DataContract(IsReference = true)] + [DebuggerDisplay("Id: {Id}")] public abstract class Entity : IEntity, ICanBeDirty { private bool _hasIdentity; diff --git a/src/Umbraco.Core/Models/IContent.cs b/src/Umbraco.Core/Models/IContent.cs index 230b6693e5..7926c595b0 100644 --- a/src/Umbraco.Core/Models/IContent.cs +++ b/src/Umbraco.Core/Models/IContent.cs @@ -1,10 +1,11 @@ using System; +using System.Diagnostics; namespace Umbraco.Core.Models { /// /// Defines a Content object - /// + /// public interface IContent : IContentBase { /// diff --git a/src/Umbraco.Core/Publishing/BasePublishingStrategy.cs b/src/Umbraco.Core/Publishing/BasePublishingStrategy.cs index d126140c04..9ce2032b57 100644 --- a/src/Umbraco.Core/Publishing/BasePublishingStrategy.cs +++ b/src/Umbraco.Core/Publishing/BasePublishingStrategy.cs @@ -8,6 +8,24 @@ namespace Umbraco.Core.Publishing /// public abstract class BasePublishingStrategy : IPublishingStrategy { + + protected internal abstract Attempt PublishInternal(IContent content, int userId); + + /// + /// Publishes a list of content items + /// + /// + /// + /// + /// By default this is set to true which means that it will publish any content item in the list that is completely unpublished and + /// not visible on the front-end. If set to false, this will only publish content that is live on the front-end but has new versions + /// that have yet to be published. + /// + /// + protected internal abstract IEnumerable> PublishWithChildrenInternal(IEnumerable content, int userId, bool includeUnpublishedDocuments = true); + + protected internal abstract IEnumerable> UnPublishInternal(IEnumerable content, int userId); + public abstract bool Publish(IContent content, int userId); public abstract bool PublishWithChildren(IEnumerable content, int userId); public abstract bool UnPublish(IContent content, int userId); diff --git a/src/Umbraco.Core/Publishing/PublishStatus.cs b/src/Umbraco.Core/Publishing/PublishStatus.cs new file mode 100644 index 0000000000..e406c3fff5 --- /dev/null +++ b/src/Umbraco.Core/Publishing/PublishStatus.cs @@ -0,0 +1,29 @@ +using Umbraco.Core.Models; + +namespace Umbraco.Core.Publishing +{ + /// + /// The result of publishing a content item + /// + public class PublishStatus + { + public IContent ContentItem { get; private set; } + public PublishStatusType StatusType { get; private set; } + + public PublishStatus(IContent content, PublishStatusType statusType) + { + ContentItem = content; + StatusType = statusType; + } + + /// + /// Creates a successful publish status + /// + public PublishStatus(IContent content) + : this(content, PublishStatusType.Success) + { + } + + + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Publishing/PublishStatusType.cs b/src/Umbraco.Core/Publishing/PublishStatusType.cs new file mode 100644 index 0000000000..59d063f41d --- /dev/null +++ b/src/Umbraco.Core/Publishing/PublishStatusType.cs @@ -0,0 +1,40 @@ +namespace Umbraco.Core.Publishing +{ + /// + /// A status type of the result of publishing a content item + /// + public enum PublishStatusType + { + /// + /// The publishing was successful. + /// + Success, + + /// + /// The content item was scheduled to be un-published and it has expired so we cannot force it to be + /// published again as part of a bulk publish operation. + /// + FailedHasExpired, + + /// + /// The content item is scheduled to be released in the future and therefore we cannot force it to + /// be published during a bulk publish operation. + /// + FailedAwaitingRelease, + + /// + /// The content item is in the trash, it cannot be published + /// + FailedIsTrashed, + + /// + /// The publish action has been cancelled by an event handler + /// + FailedCancelledByEvent, + + /// + /// The content item contains invalid data (has not passed validation requirements) + /// + FailedContentInvalid + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Publishing/PublishingStrategy.cs b/src/Umbraco.Core/Publishing/PublishingStrategy.cs index 17a80be37b..8dfd36b8f6 100644 --- a/src/Umbraco.Core/Publishing/PublishingStrategy.cs +++ b/src/Umbraco.Core/Publishing/PublishingStrategy.cs @@ -4,6 +4,7 @@ using System.Linq; using Umbraco.Core.Events; using Umbraco.Core.Logging; using Umbraco.Core.Models; +using Umbraco.Core; namespace Umbraco.Core.Publishing { @@ -12,8 +13,46 @@ namespace Umbraco.Core.Publishing /// public class PublishingStrategy : BasePublishingStrategy { - public PublishingStrategy() + + protected internal override Attempt PublishInternal(IContent content, int userId) { + if (Publishing.IsRaisedEventCancelled(new PublishEventArgs(content), this)) + return new Attempt(false, new PublishStatus(content, PublishStatusType.FailedCancelledByEvent)); + + //Check if the Content is Expired to verify that it can in fact be published + if (content.Status == ContentStatus.Expired) + { + LogHelper.Info( + string.Format("Content '{0}' with Id '{1}' has expired and could not be published.", + content.Name, content.Id)); + return new Attempt(false, new PublishStatus(content, PublishStatusType.FailedHasExpired)); + } + + //Check if the Content is Awaiting Release to verify that it can in fact be published + if (content.Status == ContentStatus.AwaitingRelease) + { + LogHelper.Info( + string.Format("Content '{0}' with Id '{1}' is awaiting release and could not be published.", + content.Name, content.Id)); + return new Attempt(false, new PublishStatus(content, PublishStatusType.FailedAwaitingRelease)); + } + + //Check if the Content is Trashed to verify that it can in fact be published + if (content.Status == ContentStatus.Trashed) + { + LogHelper.Info( + string.Format("Content '{0}' with Id '{1}' is trashed and could not be published.", + content.Name, content.Id)); + return new Attempt(false, new PublishStatus(content, PublishStatusType.FailedIsTrashed)); + } + + content.ChangePublishedState(PublishedState.Published); + + LogHelper.Info( + string.Format("Content '{0}' with Id '{1}' has been published.", + content.Name, content.Id)); + + return new Attempt(true, new PublishStatus(content)); } /// @@ -24,43 +63,79 @@ namespace Umbraco.Core.Publishing /// True if the publish operation was successfull and not cancelled, otherwise false public override bool Publish(IContent content, int userId) { - if (Publishing.IsRaisedEventCancelled(new PublishEventArgs(content), this)) - return false; + return PublishInternal(content, userId).Success; + } - //Check if the Content is Expired to verify that it can in fact be published - if (content.Status == ContentStatus.Expired) + /// + /// Publishes a list of content items + /// + /// + /// + /// + /// By default this is set to true which means that it will publish any content item in the list that is completely unpublished and + /// not visible on the front-end. If set to false, this will only publish content that is live on the front-end but has new versions + /// that have yet to be published. + /// + /// + protected internal override IEnumerable> PublishWithChildrenInternal(IEnumerable content, int userId, bool includeUnpublishedDocuments = true) + { + var statuses = new List>(); + + /* Only update content thats not already been published - we want to loop through + * all unpublished content to write skipped content (expired and awaiting release) to log. + */ + foreach (var item in content.Where(x => x.Published == false)) { + //Check if this item has never been published + if (!includeUnpublishedDocuments && !item.HasPublishedVersion()) + { + //this item does not have a published version and the flag is set to not include them + continue; + } + + //Fire Publishing event + if (Publishing.IsRaisedEventCancelled(new PublishEventArgs(item), this)) + + //Check if the Content is Expired to verify that it can in fact be published + if (item.Status == ContentStatus.Expired) + { + LogHelper.Info( + string.Format("Content '{0}' with Id '{1}' has expired and could not be published.", + item.Name, item.Id)); + statuses.Add(new Attempt(false, new PublishStatus(item, PublishStatusType.FailedHasExpired))); + continue; + } + + //Check if the Content is Awaiting Release to verify that it can in fact be published + if (item.Status == ContentStatus.AwaitingRelease) + { + LogHelper.Info( + string.Format("Content '{0}' with Id '{1}' is awaiting release and could not be published.", + item.Name, item.Id)); + statuses.Add(new Attempt(false, new PublishStatus(item, PublishStatusType.FailedAwaitingRelease))); + continue; + } + + //Check if the Content is Trashed to verify that it can in fact be published + if (item.Status == ContentStatus.Trashed) + { + LogHelper.Info( + string.Format("Content '{0}' with Id '{1}' is trashed and could not be published.", + item.Name, item.Id)); + statuses.Add(new Attempt(false, new PublishStatus(item, PublishStatusType.FailedIsTrashed))); + continue; + } + + item.ChangePublishedState(PublishedState.Published); + LogHelper.Info( - string.Format("Content '{0}' with Id '{1}' has expired and could not be published.", - content.Name, content.Id)); - return false; + string.Format("Content '{0}' with Id '{1}' has been published.", + item.Name, item.Id)); + + statuses.Add(new Attempt(true, new PublishStatus(item))); } - //Check if the Content is Awaiting Release to verify that it can in fact be published - if (content.Status == ContentStatus.AwaitingRelease) - { - LogHelper.Info( - string.Format("Content '{0}' with Id '{1}' is awaiting release and could not be published.", - content.Name, content.Id)); - return false; - } - - //Check if the Content is Trashed to verify that it can in fact be published - if (content.Status == ContentStatus.Trashed) - { - LogHelper.Info( - string.Format("Content '{0}' with Id '{1}' is trashed and could not be published.", - content.Name, content.Id)); - return false; - } - - content.ChangePublishedState(PublishedState.Published); - - LogHelper.Info( - string.Format("Content '{0}' with Id '{1}' has been published.", - content.Name, content.Id)); - - return true; + return statuses; } /// @@ -71,48 +146,14 @@ namespace Umbraco.Core.Publishing /// True if the publish operation was successfull and not cancelled, otherwise false public override bool PublishWithChildren(IEnumerable content, int userId) { - /* Only update content thats not already been published - we want to loop through - * all unpublished content to write skipped content (expired and awaiting release) to log. - */ - foreach (var item in content.Where(x => x.Published == false)) - { - //Fire Publishing event - if (Publishing.IsRaisedEventCancelled(new PublishEventArgs(item), this)) - - //Check if the Content is Expired to verify that it can in fact be published - if (item.Status == ContentStatus.Expired) - { - LogHelper.Info( - string.Format("Content '{0}' with Id '{1}' has expired and could not be published.", - item.Name, item.Id)); - continue; - } - - //Check if the Content is Awaiting Release to verify that it can in fact be published - if (item.Status == ContentStatus.AwaitingRelease) - { - LogHelper.Info( - string.Format("Content '{0}' with Id '{1}' is awaiting release and could not be published.", - item.Name, item.Id)); - continue; - } - - //Check if the Content is Trashed to verify that it can in fact be published - if (item.Status == ContentStatus.Trashed) - { - LogHelper.Info( - string.Format("Content '{0}' with Id '{1}' is trashed and could not be published.", - item.Name, item.Id)); - continue; - } - - item.ChangePublishedState(PublishedState.Published); - - LogHelper.Info( - string.Format("Content '{0}' with Id '{1}' has been published.", - item.Name, item.Id)); - } - + var result = PublishWithChildrenInternal(content, userId); + + //NOTE: This previously always returned true so I've left it that way. It returned true because (from Morten)... + // ... if one item couldn't be published it wouldn't be correct to return false. + // in retrospect it should have returned a list of with Ids and Publish Status + // come to think of it ... the cache would still be updated for a failed item or at least tried updated. + // It would call the Published event for the entire list, but if the Published property isn't set to True it + // wouldn't actually update the cache for that item. But not really ideal nevertheless... return true; } @@ -147,20 +188,19 @@ namespace Umbraco.Core.Publishing return true; } - /// - /// Unpublishes a list of Content - /// - /// An enumerable list of - /// Id of the User issueing the unpublish operation - /// True if the unpublish operation was successfull and not cancelled, otherwise false - public override bool UnPublish(IEnumerable content, int userId) + protected internal override IEnumerable> UnPublishInternal(IEnumerable content, int userId) { + var result = new List>(); + //Only update content thats already been published foreach (var item in content.Where(x => x.Published == true)) { //Fire UnPublishing event if (UnPublishing.IsRaisedEventCancelled(new PublishEventArgs(item), this)) - return false; + { + result.Add(new Attempt(false, new PublishStatus(item, PublishStatusType.FailedCancelledByEvent))); + continue; + } //If Content has a release date set to before now, it should be removed so it doesn't interrupt an unpublish //Otherwise it would remain released == published @@ -178,8 +218,29 @@ namespace Umbraco.Core.Publishing LogHelper.Info( string.Format("Content '{0}' with Id '{1}' has been unpublished.", item.Name, item.Id)); + + result.Add(new Attempt(true, new PublishStatus(item))); } + return result; + } + + /// + /// Unpublishes a list of Content + /// + /// An enumerable list of + /// Id of the User issueing the unpublish operation + /// True if the unpublish operation was successfull and not cancelled, otherwise false + public override bool UnPublish(IEnumerable content, int userId) + { + var result = UnPublishInternal(content, userId); + + //NOTE: This previously always returned true so I've left it that way. It returned true because (from Morten)... + // ... if one item couldn't be published it wouldn't be correct to return false. + // in retrospect it should have returned a list of with Ids and Publish Status + // come to think of it ... the cache would still be updated for a failed item or at least tried updated. + // It would call the Published event for the entire list, but if the Published property isn't set to True it + // wouldn't actually update the cache for that item. But not really ideal nevertheless... return true; } diff --git a/src/Umbraco.Core/Services/ContentService.cs b/src/Umbraco.Core/Services/ContentService.cs index ec1d53867e..fbad5073e4 100644 --- a/src/Umbraco.Core/Services/ContentService.cs +++ b/src/Umbraco.Core/Services/ContentService.cs @@ -1017,16 +1017,17 @@ namespace Umbraco.Core.Services return SaveAndPublishDo(content, omitCacheRefresh, userId); } - /// - /// Internal method that Publishes a object and all its children for legacy purposes. - /// - /// The to publish along with its children - /// Optional boolean to avoid having the cache refreshed when calling this Publish method. By default this method will not update the cache. - /// Optional Id of the User issueing the publishing - /// True if publishing succeeded, otherwise False - internal bool PublishWithChildren(IContent content, bool omitCacheRefresh = true, int userId = 0) + /// + /// Internal method that Publishes a object and all its children for legacy purposes. + /// + /// The to publish along with its children + /// Optional boolean to avoid having the cache refreshed when calling this Publish method. By default this method will not update the cache. + /// Optional Id of the User issueing the publishing + /// If set to true, this will also publish descendants that are completely unpublished, normally this will only publish children that have previously been published + /// True if publishing succeeded, otherwise False + internal bool PublishWithChildren(IContent content, bool omitCacheRefresh = true, int userId = 0, bool includeUnpublished = false) { - return PublishWithChildrenDo(content, omitCacheRefresh, userId); + return PublishWithChildrenDo(content, omitCacheRefresh, userId, includeUnpublished); } /// @@ -1142,8 +1143,9 @@ namespace Umbraco.Core.Services /// The to publish along with its children /// Optional boolean to avoid having the cache refreshed when calling this Publish method. By default this method will update the cache. /// Optional Id of the User issueing the publishing + /// If set to true, this will also publish descendants that are completely unpublished, normally this will only publish children that have previously been published /// True if publishing succeeded, otherwise False - private bool PublishWithChildrenDo(IContent content, bool omitCacheRefresh = false, int userId = 0) + private bool PublishWithChildrenDo(IContent content, bool omitCacheRefresh = false, int userId = 0, bool includeUnpublished = 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) diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index b21f82b8b5..4db747c5c1 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -636,6 +636,8 @@ + + diff --git a/src/Umbraco.Core/UrlHelperExtensions.cs b/src/Umbraco.Core/UrlHelperExtensions.cs index 9755dc24cc..0a0f4aaecc 100644 --- a/src/Umbraco.Core/UrlHelperExtensions.cs +++ b/src/Umbraco.Core/UrlHelperExtensions.cs @@ -23,5 +23,16 @@ namespace Umbraco.Core return result.TrimEnd("SavePartialView"); } + /// + /// Returns the base path (not including the 'action') of the MVC controller "BulkPublishController" + /// + /// + /// + public static string GetBulkPublishServicePath(this UrlHelper url) + { + var result = url.Action("PublishDocument", "BulkPublish", new { area = GlobalSettings.UmbracoMvcArea }); + return result.TrimEnd("PublishDocument"); + } + } } diff --git a/src/Umbraco.Tests/Publishing/PublishingStrategyTests.cs b/src/Umbraco.Tests/Publishing/PublishingStrategyTests.cs index 0c601a227b..83a11814e1 100644 --- a/src/Umbraco.Tests/Publishing/PublishingStrategyTests.cs +++ b/src/Umbraco.Tests/Publishing/PublishingStrategyTests.cs @@ -7,10 +7,12 @@ using Umbraco.Core.IO; using Umbraco.Core.Models; using Umbraco.Core.ObjectResolution; using Umbraco.Core.Persistence; +using Umbraco.Core.Publishing; using Umbraco.Tests.TestHelpers; using Umbraco.Tests.TestHelpers.Entities; using umbraco.editorControls.tinyMCE3; using umbraco.interfaces; +using System.Linq; namespace Umbraco.Tests.Publishing { @@ -58,6 +60,56 @@ namespace Umbraco.Tests.Publishing UmbracoSettings.ResetSetters(); } + private IContent _homePage; + + [Test] + public void Publishes_Many_Ignores_Unpublished_Items() + { + var strategy = new PublishingStrategy(); + + //publish root and nodes at it's children level + var result1 = strategy.Publish(_homePage, 0); + Assert.IsTrue(result1); + Assert.IsTrue(_homePage.Published); + foreach (var c in ServiceContext.ContentService.GetChildren(_homePage.Id)) + { + var r = strategy.Publish(c, 0); + Assert.IsTrue(r); + Assert.IsTrue(c.Published); + } + + //ok, all are published except the deepest descendant, we will pass in a flag to not include it to + //be published + var result = strategy.PublishWithChildrenInternal( + ServiceContext.ContentService.GetDescendants(_homePage).Concat(new[] {_homePage}), 0, false); + Assert.AreEqual(0, result.Count()); + } + + [Test] + public void Publishes_Many_Does_Not_Ignore_Unpublished_Items() + { + var strategy = new PublishingStrategy(); + + //publish root and nodes at it's children level + var result1 = strategy.Publish(_homePage, 0); + Assert.IsTrue(result1); + Assert.IsTrue(_homePage.Published); + foreach (var c in ServiceContext.ContentService.GetChildren(_homePage.Id)) + { + var r = strategy.Publish(c, 0); + Assert.IsTrue(r); + Assert.IsTrue(c.Published); + } + + //ok, all are published except the deepest descendant, we will pass in a flag to include it to + //be published + var result = strategy.PublishWithChildrenInternal( + ServiceContext.ContentService.GetDescendants(_homePage).Concat(new[] { _homePage }), 0, true); + Assert.AreEqual(1, result.Count()); + Assert.IsTrue(result.First().Success); + Assert.IsTrue(result.First().Result.ContentItem.Published); + } + [Test] public void Can_Publish_And_Update_Xml_Cache() { @@ -73,16 +125,21 @@ namespace Umbraco.Tests.Publishing ServiceContext.ContentTypeService.Save(contentType); //Create and Save Content "Homepage" based on "umbTextpage" -> 1046 - Content textpage = MockedContent.CreateSimpleContent(contentType); - ServiceContext.ContentService.Save(textpage, 0); + _homePage = MockedContent.CreateSimpleContent(contentType); + ServiceContext.ContentService.Save(_homePage, 0); //Create and Save Content "Text Page 1" based on "umbTextpage" -> 1047 - Content subpage = MockedContent.CreateSimpleContent(contentType, "Text Page 1", textpage.Id); + Content subpage = MockedContent.CreateSimpleContent(contentType, "Text Page 1", _homePage.Id); ServiceContext.ContentService.Save(subpage, 0); - //Create and Save Content "Text Page 1" based on "umbTextpage" -> 1048 - Content subpage2 = MockedContent.CreateSimpleContent(contentType, "Text Page 2", textpage.Id); + //Create and Save Content "Text Page 2" based on "umbTextpage" -> 1048 + Content subpage2 = MockedContent.CreateSimpleContent(contentType, "Text Page 2", _homePage.Id); ServiceContext.ContentService.Save(subpage2, 0); + + //Create and Save Content "Text Page 3" based on "umbTextpage" -> 1048 + Content subpage3 = MockedContent.CreateSimpleContent(contentType, "Text Page 3", subpage2.Id); + ServiceContext.ContentService.Save(subpage3, 0); + } } } \ No newline at end of file diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 13de47d66e..568fd21aa1 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -375,6 +375,13 @@ EditMacro.aspx + + publish.aspx + ASPXCodeBehind + + + publish.aspx + ASPXCodeBehind @@ -712,6 +719,8 @@ + + diff --git a/src/Umbraco.Web.UI/umbraco/dialogs/Publish.aspx.cs b/src/Umbraco.Web.UI/umbraco/dialogs/Publish.aspx.cs new file mode 100644 index 0000000000..d9bdf2cd44 --- /dev/null +++ b/src/Umbraco.Web.UI/umbraco/dialogs/Publish.aspx.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using Umbraco.Web.UI.Pages; + +namespace Umbraco.Web.UI.Umbraco.Dialogs +{ + public partial class Publish : UmbracoEnsuredPage + { + protected int TotalNodesToPublish { get; private set; } + protected string PageName { get; private set; } + protected int DocumentId { get; private set; } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web.UI/umbraco/dialogs/Publish.aspx.designer.cs b/src/Umbraco.Web.UI/umbraco/dialogs/Publish.aspx.designer.cs new file mode 100644 index 0000000000..ee386da7b8 --- /dev/null +++ b/src/Umbraco.Web.UI/umbraco/dialogs/Publish.aspx.designer.cs @@ -0,0 +1,51 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Umbraco.Web.UI.Umbraco.Dialogs { + + + public partial class Publish { + + /// + /// JsInclude1 control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::ClientDependency.Core.Controls.JsInclude JsInclude1; + + /// + /// JsInclude2 control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::ClientDependency.Core.Controls.JsInclude JsInclude2; + + /// + /// CssInclude1 control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::ClientDependency.Core.Controls.CssInclude CssInclude1; + + /// + /// ProgBar1 control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::umbraco.uicontrols.ProgressBar ProgBar1; + } +} diff --git a/src/Umbraco.Web.UI/umbraco/dialogs/publish.aspx b/src/Umbraco.Web.UI/umbraco/dialogs/publish.aspx index b402e89381..2c065d0d75 100644 --- a/src/Umbraco.Web.UI/umbraco/dialogs/publish.aspx +++ b/src/Umbraco.Web.UI/umbraco/dialogs/publish.aspx @@ -1,119 +1,86 @@ -<%@ Page Language="c#" MasterPageFile="../masterpages/umbracoDialog.Master" Codebehind="publish.aspx.cs" AutoEventWireup="True" Inherits="umbraco.dialogs.publish" %> +<%@ Page Language="c#" MasterPageFile="../masterpages/umbracoDialog.Master" CodeBehind="Publish.aspx.cs" AutoEventWireup="True" Inherits="Umbraco.Web.UI.Umbraco.Dialogs.Publish" %> + +<%@ Import Namespace="Umbraco.Core" %> +<%@ Import Namespace="Umbraco.Web" %> <%@ Register TagPrefix="cc1" Namespace="umbraco.uicontrols" Assembly="controls" %> <%@ Register TagPrefix="umb" Namespace="ClientDependency.Core.Controls" Assembly="ClientDependency.Core" %> - + - - - -
-
-

- <%= umbraco.ui.Text("publish", "publishHelp", pageName, base.getUser()) %> -

- -

- -

- - <%= umbraco.ui.Text("publish", "includeUnpublished")%> +
+
+

+ <%= umbraco.ui.Text("publish", "publishHelp", PageName, UmbracoUser) %> +

+ +
+ +
-

+ +
+ + +
+ + + + <%= umbraco.ui.Text("general","or") %> + + + <%=umbraco.ui.Text("general", "cancel", UmbracoUser)%> + +
- - <%= umbraco.ui.Text("general","or") %> <%=umbraco.ui.Text("general", "cancel", this.getUser())%> -
- - + + diff --git a/src/Umbraco.Web.UI/umbraco_client/Dialogs/PublishDialog.css b/src/Umbraco.Web.UI/umbraco_client/Dialogs/PublishDialog.css new file mode 100644 index 0000000000..3e0aa5e809 --- /dev/null +++ b/src/Umbraco.Web.UI/umbraco_client/Dialogs/PublishDialog.css @@ -0,0 +1,23 @@ +#includeUnpublished { + margin-left: 16px; + margin-bottom: 20px; + margin-top: 5px; +} + +#animDiv > div { + width: 230px; + margin-left:auto; + margin-right:auto; +} + +#container a { + color: blue; +} + +.disabled { + color: #999; +} + +#feedbackMsg > div { + padding: 5px; +} \ No newline at end of file diff --git a/src/Umbraco.Web.UI/umbraco_client/Dialogs/PublishDialog.js b/src/Umbraco.Web.UI/umbraco_client/Dialogs/PublishDialog.js new file mode 100644 index 0000000000..3995c9165b --- /dev/null +++ b/src/Umbraco.Web.UI/umbraco_client/Dialogs/PublishDialog.js @@ -0,0 +1,83 @@ +Umbraco.Sys.registerNamespace("Umbraco.Dialogs"); + +(function ($) { + + Umbraco.Dialogs.PublishDialog = base2.Base.extend({ + + //private methods/variables + _opts: null, + + // Constructor + constructor: function () { + }, + + //public methods + + init: function (opts) { + /// Initializes the class and any UI bindings + + // Merge options with default + this._opts = $.extend({ + + }, opts); + + var self = this; + + //The knockout js view model for the selected item + var koViewModel = { + publishAll: ko.observable(false), + includeUnpublished: ko.observable(false), + processStatus: ko.observable("init"), + isSuccessful: ko.observable(false), + closeDialog: function () { + UmbClientMgr.closeModalWindow(); + }, + startPublish: function() { + this.processStatus("publishing"); + + $.post(self._opts.restServiceLocation + "PublishDocument", + JSON.stringify({ + documentId: self._opts.documentId + }), + function (e) { + if (e.success) { + self.submitSuccess(e.message, e.header); + } else { + self.submitFailure(e.message, e.header); + } + }); + } + }; + //ensure includeUnpublished is always false if publishAll is ever false + koViewModel.publishAll.subscribe(function (newValue) { + if (newValue === false) { + koViewModel.includeUnpublished(false); + } + }); + + ko.applyBindings(koViewModel); + } + + + }, { + //Static members + + //private methods/variables + _instance: null, + + // Singleton accessor + getInstance: function () { + if (this._instance == null) + this._instance = new Umbraco.Dialogs.PublishDialog(); + return this._instance; + } + }); + + //Set defaults for jQuery ajax calls. + $.ajaxSetup({ + dataType: 'json', + cache: false, + contentType: 'application/json; charset=utf-8' + }); + +})(jQuery); \ No newline at end of file diff --git a/src/Umbraco.Web/Mvc/RenderMvcController.cs b/src/Umbraco.Web/Mvc/RenderMvcController.cs index 92e2715a0b..9b8c5b505d 100644 --- a/src/Umbraco.Web/Mvc/RenderMvcController.cs +++ b/src/Umbraco.Web/Mvc/RenderMvcController.cs @@ -11,7 +11,11 @@ using Umbraco.Web.Routing; namespace Umbraco.Web.Mvc { - public class RenderMvcController : Controller + + /// + /// A controller to render front-end requests + /// + public class RenderMvcController : UmbracoController { public RenderMvcController() @@ -21,46 +25,13 @@ namespace Umbraco.Web.Mvc private PublishedContentRequest _publishedContentRequest; - private UmbracoHelper _umbraco; - /// - /// Returns an UmbracoHelper object - /// - public UmbracoHelper Umbraco - { - get { return _umbraco ?? (_umbraco = new UmbracoHelper(UmbracoContext)); } - } - - /// - /// Returns the current UmbracoContext - /// - protected UmbracoContext UmbracoContext - { - get { return PublishedContentRequest.RoutingContext.UmbracoContext; } - } - - /// - /// Returns the current ApplicationContext - /// - public ApplicationContext ApplicationContext - { - get { return UmbracoContext.Application; } - } - - /// - /// Returns a ServiceContext - /// - public ServiceContext Services - { - get { return ApplicationContext.Services; } - } - - /// - /// Returns a DatabaseContext - /// - public DatabaseContext DatabaseContext - { - get { return ApplicationContext.DatabaseContext; } - } + /// + /// Returns the current UmbracoContext + /// + protected new UmbracoContext UmbracoContext + { + get { return PublishedContentRequest.RoutingContext.UmbracoContext; } + } /// /// Returns the Current published content item for rendering the content diff --git a/src/Umbraco.Web/Mvc/UmbracoAuthorizeAttribute.cs b/src/Umbraco.Web/Mvc/UmbracoAuthorizeAttribute.cs index 5d25dd69de..d357dead13 100644 --- a/src/Umbraco.Web/Mvc/UmbracoAuthorizeAttribute.cs +++ b/src/Umbraco.Web/Mvc/UmbracoAuthorizeAttribute.cs @@ -2,6 +2,7 @@ using System.Web; using System.Web.Mvc; using Umbraco.Core; +using Umbraco.Web.Security; using umbraco.BasePages; namespace Umbraco.Web.Mvc @@ -43,7 +44,7 @@ namespace Umbraco.Web.Mvc //we need to that the app is configured and that a user is logged in if (!_applicationContext.IsConfigured) return false; - var isLoggedIn = BasePage.ValidateUserContextID(BasePage.umbracoUserContextID); + var isLoggedIn = WebSecurity.ValidateUserContextId(WebSecurity.UmbracoUserContextId); return isLoggedIn; } catch (Exception) diff --git a/src/Umbraco.Web/Mvc/UmbracoAuthorizedController.cs b/src/Umbraco.Web/Mvc/UmbracoAuthorizedController.cs index 044109ee12..0006867568 100644 --- a/src/Umbraco.Web/Mvc/UmbracoAuthorizedController.cs +++ b/src/Umbraco.Web/Mvc/UmbracoAuthorizedController.cs @@ -1,11 +1,16 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using System.Text; using System.Web.Mvc; +using Umbraco.Core.Configuration; +using Umbraco.Web.Routing; +using Umbraco.Web.Security; +using umbraco.BusinessLogic; namespace Umbraco.Web.Mvc { - /// + /// /// A base MVC controller for use in the back office that ensures that every call to it authorizes the current user. /// /// @@ -13,7 +18,64 @@ namespace Umbraco.Web.Mvc /// authorization of each method can use this attribute instead of inheriting from this controller. /// [UmbracoAuthorize] - public abstract class UmbracoAuthorizedController : Controller + public abstract class UmbracoAuthorizedController : UmbracoController { + + private User _user; + private bool _userisValidated = false; + + /// + /// The current user ID + /// + private int _uid = 0; + + /// + /// The page timeout in seconds. + /// + private long _timeout = 0; + + /// + /// Returns the currently logged in Umbraco User + /// + protected User UmbracoUser + { + get + { + if (!_userisValidated) ValidateUser(); + return _user; + } + } + + private void ValidateUser() + { + if ((WebSecurity.UmbracoUserContextId != "")) + { + _uid = WebSecurity.GetUserId(WebSecurity.UmbracoUserContextId); + _timeout = WebSecurity.GetTimeout(WebSecurity.UmbracoUserContextId); + + if (_timeout > DateTime.Now.Ticks) + { + _user = global::umbraco.BusinessLogic.User.GetUser(_uid); + + // Check for console access + if (_user.Disabled || (_user.NoConsole && GlobalSettings.RequestIsInUmbracoApplication(HttpContext) && !GlobalSettings.RequestIsLiveEditRedirector(HttpContext))) + { + throw new ArgumentException("You have no priviledges to the umbraco console. Please contact your administrator"); + } + _userisValidated = true; + WebSecurity.UpdateLogin(_timeout); + } + else + { + throw new ArgumentException("User has timed out!!"); + } + } + else + { + throw new InvalidOperationException("The user has no umbraco contextid - try logging in"); + } + + } + } } diff --git a/src/Umbraco.Web/Mvc/UmbracoController.cs b/src/Umbraco.Web/Mvc/UmbracoController.cs new file mode 100644 index 0000000000..78dc6502fc --- /dev/null +++ b/src/Umbraco.Web/Mvc/UmbracoController.cs @@ -0,0 +1,63 @@ +using System; +using System.Web.Mvc; +using Umbraco.Core; +using Umbraco.Core.Services; + +namespace Umbraco.Web.Mvc +{ + /// + /// A base controller class containing all of the Umbraco objects as properties that a developer requires + /// + public abstract class UmbracoController : Controller + { + protected UmbracoController(UmbracoContext umbracoContext) + { + if (umbracoContext == null) throw new ArgumentNullException("umbracoContext"); + UmbracoContext = umbracoContext; + } + + protected UmbracoController() + : this(UmbracoContext.Current) + { + + } + + private UmbracoHelper _umbraco; + /// + /// Returns an UmbracoHelper object + /// + public UmbracoHelper Umbraco + { + get { return _umbraco ?? (_umbraco = new UmbracoHelper(UmbracoContext)); } + } + + /// + /// Returns the current UmbracoContext + /// + protected UmbracoContext UmbracoContext { get; private set; } + + /// + /// Returns the current ApplicationContext + /// + public ApplicationContext ApplicationContext + { + get { return UmbracoContext.Application; } + } + + /// + /// Returns a ServiceContext + /// + public ServiceContext Services + { + get { return ApplicationContext.Services; } + } + + /// + /// Returns a DatabaseContext + /// + public DatabaseContext DatabaseContext + { + get { return ApplicationContext.DatabaseContext; } + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/UI/Pages/BasePage.cs b/src/Umbraco.Web/UI/Pages/BasePage.cs index 00b456ef56..a7a60616e8 100644 --- a/src/Umbraco.Web/UI/Pages/BasePage.cs +++ b/src/Umbraco.Web/UI/Pages/BasePage.cs @@ -104,7 +104,7 @@ namespace Umbraco.Web.UI.Pages _user = global::umbraco.BusinessLogic.User.GetUser(_uid); // Check for console access - if (_user.Disabled || (_user.NoConsole && GlobalSettings.RequestIsInUmbracoApplication(HttpContext.Current) && !GlobalSettings.RequestIsLiveEditRedirector(HttpContext.Current))) + if (_user.Disabled || (_user.NoConsole && GlobalSettings.RequestIsInUmbracoApplication(Context) && !GlobalSettings.RequestIsLiveEditRedirector(Context))) { throw new ArgumentException("You have no priviledges to the umbraco console. Please contact your administrator"); } diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index de75f975b0..bf6848f623 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -302,6 +302,7 @@ + @@ -406,6 +407,9 @@ ASPXCodeBehind + + ASPXCodeBehind + ASPXCodeBehind @@ -1230,13 +1234,6 @@ protectPage.aspx - - publish.aspx - ASPXCodeBehind - - - publish.aspx - RegexWs.aspx ASPXCodeBehind @@ -1767,7 +1764,9 @@ - + + ASPXCodeBehind + ASPXCodeBehind @@ -1830,7 +1829,6 @@ - diff --git a/src/Umbraco.Web/WebServices/SaveFileController.cs b/src/Umbraco.Web/WebServices/SaveFileController.cs index 3665c3470f..2371aa001c 100644 --- a/src/Umbraco.Web/WebServices/SaveFileController.cs +++ b/src/Umbraco.Web/WebServices/SaveFileController.cs @@ -19,7 +19,26 @@ using Umbraco.Core; namespace Umbraco.Web.WebServices { - /// + /// + /// A REST controller used for the publish dialog in order to publish bulk items at once + /// + public class BulkPublishController : UmbracoAuthorizedController + { + /// + /// Publishes an document + /// + /// + /// A Json array containing objects with the child id's of the document and it's current published status + [HttpPost] + public JsonResult PublishDocument(int documentId, bool publishChildren) + { + //var doc = Services.ContentService.GetById(documentId); + //if (Services.ContentService.PublishWithChildren(doc, UmbracoUser.Id)) + return null; + } + } + + /// /// A REST controller used to save files such as templates, partial views, macro files, etc... /// /// diff --git a/src/Umbraco.Web/umbraco.presentation/library.cs b/src/Umbraco.Web/umbraco.presentation/library.cs index 10dd8ec202..03e157fa4b 100644 --- a/src/Umbraco.Web/umbraco.presentation/library.cs +++ b/src/Umbraco.Web/umbraco.presentation/library.cs @@ -232,10 +232,7 @@ namespace umbraco /// internal static void UpdateDocumentCache(Document doc) { - if (UmbracoSettings.UseDistributedCalls) - DistributedCache.Instance.RefreshPageCache(doc.Id); - else - content.Instance.UpdateDocumentCache(doc); + DistributedCache.Instance.RefreshPageCache(doc.Id); } diff --git a/src/Umbraco.Web/umbraco.presentation/publishingService.cs b/src/Umbraco.Web/umbraco.presentation/publishingService.cs index f1d30e7005..be039bcd63 100644 --- a/src/Umbraco.Web/umbraco.presentation/publishingService.cs +++ b/src/Umbraco.Web/umbraco.presentation/publishingService.cs @@ -15,31 +15,26 @@ namespace umbraco.presentation /// public class publishingService { - private static Hashtable scheduledTaskTimes = new Hashtable(); - private static bool isPublishingRunning = false; + private static readonly Hashtable ScheduledTaskTimes = new Hashtable(); + private static bool _isPublishingRunning = false; public static void CheckPublishing(object sender) { - if(isPublishingRunning) + if(_isPublishingRunning) return; - isPublishingRunning = true; + _isPublishingRunning = true; try { // DO not run publishing if content is re-loading if(!content.Instance.isInitializing) { - foreach (Document d in Document.GetDocumentsForRelease()) + foreach (var d in Document.GetDocumentsForRelease()) { try { - //d.HttpContext = (HttpContext)sender; - d.ReleaseDate = DateTime.MinValue; //new DateTime(1, 1, 1); // Causes release date to be null - - d.Publish(d.User); - library.UpdateDocumentCache(d); - + d.SaveAndPublish(d.User); } catch(Exception ee) { @@ -48,9 +43,6 @@ namespace umbraco.presentation } foreach(Document d in Document.GetDocumentsForExpiration()) { - //d.HttpContext = (HttpContext)sender; - //d.Published = false; - try { d.ExpireDate = DateTime.MinValue; @@ -78,20 +70,20 @@ namespace umbraco.presentation foreach (XmlNode task in tasks) { bool runTask = false; - if (!scheduledTaskTimes.ContainsKey(task.Attributes.GetNamedItem("alias").Value)) + if (!ScheduledTaskTimes.ContainsKey(task.Attributes.GetNamedItem("alias").Value)) { runTask = true; - scheduledTaskTimes.Add(task.Attributes.GetNamedItem("alias").Value, DateTime.Now); + ScheduledTaskTimes.Add(task.Attributes.GetNamedItem("alias").Value, DateTime.Now); } // Add 1 second to timespan to compensate for differencies in timer else if ( new TimeSpan(DateTime.Now.Ticks - - ((DateTime) scheduledTaskTimes[task.Attributes.GetNamedItem("alias").Value]).Ticks).TotalSeconds + + ((DateTime) ScheduledTaskTimes[task.Attributes.GetNamedItem("alias").Value]).Ticks).TotalSeconds + 1 >= int.Parse(task.Attributes.GetNamedItem("interval").Value)) { runTask = true; - scheduledTaskTimes[task.Attributes.GetNamedItem("alias").Value] = DateTime.Now; + ScheduledTaskTimes[task.Attributes.GetNamedItem("alias").Value] = DateTime.Now; } if (runTask) @@ -115,7 +107,7 @@ namespace umbraco.presentation } finally { - isPublishingRunning = false; + _isPublishingRunning = false; } } diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/LiveEditing/Modules/CreateModule/CreateModule.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/LiveEditing/Modules/CreateModule/CreateModule.cs index fd353d09cc..43748c80bd 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/LiveEditing/Modules/CreateModule/CreateModule.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/LiveEditing/Modules/CreateModule/CreateModule.cs @@ -128,11 +128,10 @@ namespace umbraco.presentation.LiveEditing.Modules.CreateModule switch (e.Type) { case "createcontent": - int userid = BasePages.UmbracoEnsuredPage.GetUserId(BasePages.UmbracoEnsuredPage.umbracoUserContextID); - DocumentType typeToCreate = new DocumentType(Convert.ToInt32(m_AllowedDocTypesDropdown.SelectedValue)); - Document newDoc = Document.MakeNew(m_NameTextBox.Text, typeToCreate, new global::umbraco.BusinessLogic.User(userid), (int)UmbracoContext.Current.PageId); - newDoc.Publish(new global::umbraco.BusinessLogic.User(userid)); - library.UpdateDocumentCache(newDoc); + var userid = BasePages.UmbracoEnsuredPage.GetUserId(BasePages.UmbracoEnsuredPage.umbracoUserContextID); + var typeToCreate = new DocumentType(Convert.ToInt32(m_AllowedDocTypesDropdown.SelectedValue)); + var newDoc = Document.MakeNew(m_NameTextBox.Text, typeToCreate, new BusinessLogic.User(userid), (int)UmbracoContext.Current.PageId); + newDoc.SaveAndPublish(new BusinessLogic.User(userid)); Page.Response.Redirect(library.NiceUrl(newDoc.Id), false); break; } diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/publish.aspx b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/publish.aspx deleted file mode 100644 index b402e89381..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/publish.aspx +++ /dev/null @@ -1,119 +0,0 @@ -<%@ Page Language="c#" MasterPageFile="../masterpages/umbracoDialog.Master" Codebehind="publish.aspx.cs" AutoEventWireup="True" Inherits="umbraco.dialogs.publish" %> -<%@ Register TagPrefix="cc1" Namespace="umbraco.uicontrols" Assembly="controls" %> -<%@ Register TagPrefix="umb" Namespace="ClientDependency.Core.Controls" Assembly="ClientDependency.Core" %> - - - - - - - - - - - - - -
-
-

- <%= umbraco.ui.Text("publish", "publishHelp", pageName, base.getUser()) %> -

- -

- -

- - <%= umbraco.ui.Text("publish", "includeUnpublished")%> -
-

-
- - <%= umbraco.ui.Text("general","or") %> <%=umbraco.ui.Text("general", "cancel", this.getUser())%> -
- - - -
- - - - - - - -
\ No newline at end of file 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 bfe92ef3c6..8c526a4d6f 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/publish.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/publish.aspx.cs @@ -1,5 +1,6 @@ -using System; +using System; using System.Collections; +using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; @@ -11,6 +12,7 @@ using System.Web.UI.HtmlControls; using System.Threading; using Umbraco.Core.Logging; +using umbraco.cms.businesslogic.web; using umbraco.cms.helpers; using umbraco.BasePages; @@ -89,7 +91,7 @@ namespace umbraco.dialogs //PPH added load balancing... //content.Instance.PublishNode(documents); - foreach (cms.businesslogic.web.Document doc in documents) + foreach (cms.businesslogic.web.Document doc in _documents) { if (doc.Published) { @@ -132,19 +134,19 @@ namespace umbraco.dialogs theEnd.Visible = true; } } - private System.Collections.Generic.List documents = new System.Collections.Generic.List(); + private readonly List _documents = new List(); - private void doPublishSubs(cms.businesslogic.web.Document d) + private void doPublishSubs(Document d) { if (d.Published || PublishUnpublishedItems.Checked) { - if (d.PublishWithResult(base.getUser())) + if (d.PublishWithResult(UmbracoUser)) { // Needed for supporting distributed calls if (UmbracoSettings.UseDistributedCalls) library.UpdateDocumentCache(d); else - documents.Add(d); + _documents.Add(d); nodesPublished++; Application.Lock(); @@ -168,5 +170,86 @@ namespace umbraco.dialogs ScriptManager.GetCurrent(Page).Services.Add(new ServiceReference("../webservices/legacyAjaxCalls.asmx")); } + + /// + /// masterPagePrefix control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Literal masterPagePrefix; + + /// + /// JsInclude1 control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::ClientDependency.Core.Controls.JsInclude JsInclude1; + + /// + /// TheForm control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Panel TheForm; + + /// + /// PublishAll control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.CheckBox PublishAll; + + /// + /// PublishUnpublishedItems control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.CheckBox PublishUnpublishedItems; + + /// + /// ok control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Button ok; + + /// + /// ProgBar1 control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::umbraco.uicontrols.ProgressBar ProgBar1; + + /// + /// theEnd control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Panel theEnd; + + /// + /// feedbackMsg control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::umbraco.uicontrols.Feedback feedbackMsg; } } diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/publish.aspx.designer.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/publish.aspx.designer.cs deleted file mode 100644 index d9ebc3eefe..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/publish.aspx.designer.cs +++ /dev/null @@ -1,96 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace umbraco.dialogs { - - - public partial class publish { - - /// - /// masterPagePrefix control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Literal masterPagePrefix; - - /// - /// JsInclude1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude1; - - /// - /// TheForm control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Panel TheForm; - - /// - /// PublishAll control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.CheckBox PublishAll; - - /// - /// PublishUnpublishedItems control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.CheckBox PublishUnpublishedItems; - - /// - /// ok control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Button ok; - - /// - /// ProgBar1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::umbraco.uicontrols.ProgressBar ProgBar1; - - /// - /// theEnd control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Panel theEnd; - - /// - /// feedbackMsg control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::umbraco.uicontrols.Feedback feedbackMsg; - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs index 09487683c5..e2ece7bf2f 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs @@ -448,8 +448,6 @@ namespace umbraco.cms.presentation tp.ErrorControl.Visible = false; } } - //Audit trail... - Log.Add(LogTypes.Save, UmbracoUser, _document.Id, ""); if (_dpRelease.DateTime > new DateTime(1753, 1, 1) && _dpRelease.DateTime < new DateTime(9999, 12, 31)) _document.ReleaseDate = _dpRelease.DateTime; diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/uQuery/DocumentExtensions.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/uQuery/DocumentExtensions.cs index de897b6209..b89fddf8a4 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/uQuery/DocumentExtensions.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/uQuery/DocumentExtensions.cs @@ -240,18 +240,15 @@ namespace umbraco { if (useAdminUser) { - document.Publish(new User(0)); + document.SaveAndPublish(new User(0)); } else { if (User.GetCurrent() != null) { - document.Publish(User.GetCurrent()); + document.SaveAndPublish(User.GetCurrent()); } } - - library.UpdateDocumentCache(document); - return document; } diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/publication.asmx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/publication.asmx.cs index 56fbdf7ae0..c68d7a7bf7 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/publication.asmx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/publication.asmx.cs @@ -13,12 +13,7 @@ namespace umbraco.webservices [ScriptService] public class publication : WebService { - public publication() - { - //CODEGEN: This call is required by the ASP.NET Web Services Designer - InitializeComponent(); - } - + [WebMethod] [ScriptMethod] public int GetPublicationStatus(string key) @@ -82,14 +77,7 @@ namespace umbraco.webservices //Required by the Web Services Designer private IContainer components = null; - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - } + /// /// Clean up any resources being used. diff --git a/src/umbraco.cms/businesslogic/web/Document.cs b/src/umbraco.cms/businesslogic/web/Document.cs index 8164317df1..690b3a0750 100644 --- a/src/umbraco.cms/businesslogic/web/Document.cs +++ b/src/umbraco.cms/businesslogic/web/Document.cs @@ -801,7 +801,7 @@ namespace umbraco.cms.businesslogic.web if (!e.Cancel) { - var result = ((ContentService)ApplicationContext.Current.Services.ContentService).Publish(Content, true, u.Id); + var result = ((ContentService)ApplicationContext.Current.Services.ContentService).Publish(Content, false, u.Id); _published = result; FireAfterPublish(e); diff --git a/src/umbraco.webservices/documents/documentService.cs b/src/umbraco.webservices/documents/documentService.cs index 634033cffd..70e25c16f3 100644 --- a/src/umbraco.webservices/documents/documentService.cs +++ b/src/umbraco.webservices/documents/documentService.cs @@ -36,31 +36,31 @@ namespace umbraco.webservices.documents if (carrier.ParentID == 0) throw new Exception("Document needs a parent"); if (carrier.DocumentTypeID == 0) throw new Exception("Documenttype must be specified"); if (carrier.Id != 0) throw new Exception("ID cannot be specifed when creating. Must be 0"); - if (carrier.Name == null || carrier.Name.Length == 0) carrier.Name = "unnamed"; + if (string.IsNullOrEmpty(carrier.Name)) carrier.Name = "unnamed"; - umbraco.BusinessLogic.User user = GetUser(username, password); + var user = GetUser(username, password); // We get the documenttype - umbraco.cms.businesslogic.web.DocumentType docType = new umbraco.cms.businesslogic.web.DocumentType(carrier.DocumentTypeID); + var docType = new DocumentType(carrier.DocumentTypeID); if (docType == null) throw new Exception("DocumenttypeID " + carrier.DocumentTypeID + " not found"); // We create the document - Document newDoc = Document.MakeNew(carrier.Name, docType, user, carrier.ParentID); + var newDoc = Document.MakeNew(carrier.Name, docType, user, carrier.ParentID); newDoc.ReleaseDate = carrier.ReleaseDate; newDoc.ExpireDate = carrier.ExpireDate; // We iterate the properties in the carrier if (carrier.DocumentProperties != null) { - foreach (documentProperty updatedproperty in carrier.DocumentProperties) + foreach (var updatedproperty in carrier.DocumentProperties) { - umbraco.cms.businesslogic.property.Property property = newDoc.getProperty(updatedproperty.Key); + var property = newDoc.getProperty(updatedproperty.Key); if (property == null) throw new Exception("property " + updatedproperty.Key + " was not found"); property.Value = updatedproperty.PropertyValue; } } - // We check the publishaction and do the appropiate + // We check the publish action and do the appropiate handlePublishing(newDoc, carrier, user); // We return the ID of the document..65 @@ -244,31 +244,21 @@ namespace umbraco.webservices.documents switch (carrier.PublishAction) { case documentCarrier.EPublishAction.Publish: - if (doc.PublishWithResult(user)) - { - umbraco.library.UpdateDocumentCache(doc); - } + doc.SaveAndPublish(user); break; case documentCarrier.EPublishAction.Unpublish: - if (doc.PublishWithResult(user)) - { - umbraco.library.UnPublishSingleNode(doc); - } + doc.UnPublish(); + library.UnPublishSingleNode(doc); break; case documentCarrier.EPublishAction.Ignore: if (doc.Published) { - if (doc.PublishWithResult(user)) - { - umbraco.library.UpdateDocumentCache(doc); - } + doc.UnPublish(); + library.UnPublishSingleNode(doc); } else { - if (doc.PublishWithResult(user)) - { - umbraco.library.UpdateDocumentCache(doc); - } + doc.SaveAndPublish(user); } break; }