diff --git a/src/Umbraco.Core/Models/Content.cs b/src/Umbraco.Core/Models/Content.cs
index e70078a857..8436da6230 100644
--- a/src/Umbraco.Core/Models/Content.cs
+++ b/src/Umbraco.Core/Models/Content.cs
@@ -69,6 +69,7 @@ namespace Umbraco.Core.Models
///
/// Gets the current status of the Content
///
+ [IgnoreDataMember]
public ContentStatus Status
{
get
diff --git a/src/Umbraco.Core/Models/IContent.cs b/src/Umbraco.Core/Models/IContent.cs
index 461680aa50..d66a8bbceb 100644
--- a/src/Umbraco.Core/Models/IContent.cs
+++ b/src/Umbraco.Core/Models/IContent.cs
@@ -38,6 +38,11 @@ namespace Umbraco.Core.Models
///
IContentType ContentType { get; }
+ ///
+ /// Gets the current status of the Content
+ ///
+ ContentStatus Status { get; }
+
///
/// Changes the for the current content object
///
diff --git a/src/Umbraco.Tests/Services/ContentServiceTests.cs b/src/Umbraco.Tests/Services/ContentServiceTests.cs
index 08a14e0d40..9cd91b0b03 100644
--- a/src/Umbraco.Tests/Services/ContentServiceTests.cs
+++ b/src/Umbraco.Tests/Services/ContentServiceTests.cs
@@ -300,6 +300,79 @@ namespace Umbraco.Tests.Services
Assert.That(children.First(x => x.Id == 1048).Published, Is.False);//Expired 5 mins ago, so shouldn't be published
}
+ [Test]
+ public void Cannot_Publish_Expired_Content()
+ {
+ // Arrange
+ var contentService = ServiceContext.ContentService;
+ var content = contentService.GetById(1048); //This Content expired 5min ago
+
+ var parent = contentService.GetById(1046);
+ bool parentPublished = contentService.Publish(parent, 0);//Publish root Home node to enable publishing of '1048'
+
+ // Act
+ bool published = contentService.Publish(content, 0);
+
+ // Assert
+ Assert.That(parentPublished, Is.True);
+ Assert.That(published, Is.False);
+ Assert.That(content.Published, Is.False);
+ }
+
+ [Test]
+ public void Cannot_Publish_Content_Awaiting_Release()
+ {
+ // Arrange
+ var contentService = ServiceContext.ContentService;
+ var content = contentService.GetById(1047);
+ content.ReleaseDate = DateTime.UtcNow.AddHours(2);
+ contentService.Save(content, 0);
+
+ var parent = contentService.GetById(1046);
+ bool parentPublished = contentService.Publish(parent, 0);//Publish root Home node to enable publishing of '1048'
+
+ // Act
+ bool published = contentService.Publish(content, 0);
+
+ // Assert
+ Assert.That(parentPublished, Is.True);
+ Assert.That(published, Is.False);
+ Assert.That(content.Published, Is.False);
+ }
+
+ [Test]
+ public void Cannot_Publish_Content_Where_Parent_Is_Unpublished()
+ {
+ // Arrange
+ var contentService = ServiceContext.ContentService;
+ var content = contentService.CreateContent(1046, "umbTextpage");
+ content.Name = "Subpage with Unpublisehed Parent";
+ contentService.Save(content, 0);
+
+ // Act
+ bool published = contentService.PublishWithChildren(content, 0);
+
+ // Assert
+ Assert.That(published, Is.False);
+ Assert.That(content.Published, Is.False);
+ }
+
+ [Test]
+ public void Cannot_Publish_Trashed_Content()
+ {
+ // Arrange
+ var contentService = ServiceContext.ContentService;
+ var content = contentService.GetById(1049);
+
+ // Act
+ bool published = contentService.Publish(content, 0);
+
+ // Assert
+ Assert.That(published, Is.False);
+ Assert.That(content.Published, Is.False);
+ Assert.That(content.Trashed, Is.True);
+ }
+
[Test]
public void Can_Save_And_Publish_Content()
{
@@ -487,6 +560,7 @@ namespace Umbraco.Tests.Services
//Create and Save Content "Text Page 1" based on "umbTextpage" -> 1047
Content subpage = MockedContent.CreateTextpageContent(contentType, "Text Page 1", textpage.Id);
subpage.ReleaseDate = DateTime.UtcNow.AddMinutes(-5);
+ subpage.ChangePublishedState(false);
ServiceContext.ContentService.Save(subpage, 0);
//Create and Save Content "Text Page 1" based on "umbTextpage" -> 1048
diff --git a/src/Umbraco.Web/Publishing/PublishingStrategy.cs b/src/Umbraco.Web/Publishing/PublishingStrategy.cs
index c8966d432e..bba152335e 100644
--- a/src/Umbraco.Web/Publishing/PublishingStrategy.cs
+++ b/src/Umbraco.Web/Publishing/PublishingStrategy.cs
@@ -30,6 +30,33 @@ namespace Umbraco.Web.Publishing
if (!e.Cancel)
{
+ //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 false;
+ }
+
+ //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(true);
LogHelper.Info(
@@ -57,7 +84,9 @@ namespace Umbraco.Web.Publishing
{
var e = new PublishEventArgs();
- //Only update content thats not already been published
+ /* 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 BeforePublish event
@@ -65,6 +94,33 @@ namespace Umbraco.Web.Publishing
if (e.Cancel)
return false;
+ //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(true);
LogHelper.Info(
@@ -97,8 +153,15 @@ namespace Umbraco.Web.Publishing
//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
if (content.ReleaseDate.HasValue && content.ReleaseDate.Value <= DateTime.UtcNow)
+ {
content.ReleaseDate = null;
+ LogHelper.Info(
+ string.Format(
+ "Content '{0}' with Id '{1}' had its release date removed, because it was unpublished.",
+ content.Name, content.Id));
+ }
+
content.ChangePublishedState(false);
LogHelper.Info(
@@ -137,8 +200,14 @@ namespace Umbraco.Web.Publishing
//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
if (item.ReleaseDate.HasValue && item.ReleaseDate.Value <= DateTime.UtcNow)
+ {
item.ReleaseDate = null;
+ LogHelper.Info(
+ string.Format("Content '{0}' with Id '{1}' had its release date removed, because it was unpublished.",
+ item.Name, item.Id));
+ }
+
item.ChangePublishedState(false);
LogHelper.Info(
diff --git a/src/Umbraco.Web/Services/ContentService.cs b/src/Umbraco.Web/Services/ContentService.cs
index 63f279aa91..b07fd2fa4e 100644
--- a/src/Umbraco.Web/Services/ContentService.cs
+++ b/src/Umbraco.Web/Services/ContentService.cs
@@ -251,7 +251,7 @@ namespace Umbraco.Web.Services
var repository = RepositoryResolver.ResolveByType(_unitOfWork);
//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 && !GetById(content.ParentId).Published)
+ if (content.ParentId != -1 && content.ParentId != -20 && !GetById(content.ParentId).Published)
{
LogHelper.Info(
string.Format("Content '{0}' with Id '{1}' could not be published because its parent is not published.",
@@ -374,7 +374,7 @@ namespace Umbraco.Web.Services
var repository = RepositoryResolver.ResolveByType(_unitOfWork);
//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 && GetById(content.ParentId).Published == false)
+ if (content.ParentId != -1 && content.ParentId != -20 && GetById(content.ParentId).Published == false)
{
LogHelper.Info(
string.Format("Content '{0}' with Id '{1}' could not be published because its parent is not published.",