Merge remote-tracking branch 'origin/temp8-224-db-updates-sched-publishing-with-variants' into temp8-226-sched-pub-angular
This commit is contained in:
@@ -36,11 +36,11 @@ namespace Umbraco.Core
|
||||
else if (culture.IsNullOrWhiteSpace())
|
||||
throw new ArgumentNullException($"{nameof(culture)} cannot be null or empty");
|
||||
|
||||
var expires = content.ContentSchedule.GetSchedule(culture, ContentScheduleChange.End);
|
||||
var expires = content.ContentSchedule.GetSchedule(culture, ContentScheduleAction.Expire);
|
||||
if (expires != null && expires.Any(x => x.Date > DateTime.MinValue && DateTime.Now > x.Date))
|
||||
return ContentStatus.Expired;
|
||||
|
||||
var release = content.ContentSchedule.GetSchedule(culture, ContentScheduleChange.Start);
|
||||
var release = content.ContentSchedule.GetSchedule(culture, ContentScheduleAction.Release);
|
||||
if (release != null && release.Any(x => x.Date > DateTime.MinValue && x.Date > DateTime.Now))
|
||||
return ContentStatus.AwaitingRelease;
|
||||
|
||||
@@ -56,7 +56,6 @@ namespace Umbraco.Core
|
||||
/// <remarks>Gets cultures for which content.UnpublishCulture() has been invoked.</remarks>
|
||||
internal static IReadOnlyList<string> GetCulturesUnpublishing(this IContent content)
|
||||
{
|
||||
// fixme/review - assuming it's || here not && ?
|
||||
if (!content.Published || !content.ContentType.VariesByCulture() || !content.IsPropertyDirty("PublishCultureInfos"))
|
||||
return Array.Empty<string>();
|
||||
|
||||
|
||||
@@ -30,11 +30,11 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
foreach(var s in schedules)
|
||||
{
|
||||
var date = s.Value.releaseDate;
|
||||
var action = ContentScheduleChange.Start.ToString();
|
||||
var action = ContentScheduleAction.Release.ToString();
|
||||
if (!date.HasValue)
|
||||
{
|
||||
date = s.Value.expireDate;
|
||||
action = ContentScheduleChange.End.ToString();
|
||||
action = ContentScheduleAction.Expire.ToString();
|
||||
}
|
||||
|
||||
Insert.IntoTable(ContentScheduleDto.TableName)
|
||||
|
||||
@@ -13,12 +13,12 @@ namespace Umbraco.Core.Models
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ContentSchedule"/> class.
|
||||
/// </summary>
|
||||
public ContentSchedule(int id, string culture, DateTime date, ContentScheduleChange change)
|
||||
public ContentSchedule(int id, string culture, DateTime date, ContentScheduleAction action)
|
||||
{
|
||||
Id = id;
|
||||
Culture = culture;
|
||||
Date = date;
|
||||
Change = change;
|
||||
Action = action;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -46,12 +46,8 @@ namespace Umbraco.Core.Models
|
||||
/// Gets the action to take.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public ContentScheduleChange Change { get; }
|
||||
public ContentScheduleAction Action { get; }
|
||||
|
||||
// fixme/review - must implement Equals?
|
||||
// fixing ContentScheduleCollection.Equals which was broken, breaks content Can_Deep_Clone test
|
||||
// because SequenceEqual on the inner sorted lists fails, because it ends up doing reference-equal
|
||||
// on each content schedule - so we *have* to implement Equals for us too?
|
||||
public override bool Equals(object obj)
|
||||
=> obj is ContentSchedule other && Equals(other);
|
||||
|
||||
@@ -59,12 +55,12 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
// don't compare Ids, two ContentSchedule are equal if they are for the same change
|
||||
// for the same culture, on the same date - and the collection deals w/duplicates
|
||||
return Culture.InvariantEquals(other.Culture) && Date == other.Date && Change == other.Change;
|
||||
return Culture.InvariantEquals(other.Culture) && Date == other.Date && Action == other.Action;
|
||||
}
|
||||
|
||||
public object DeepClone()
|
||||
{
|
||||
return new ContentSchedule(Id, Culture, Date, Change);
|
||||
return new ContentSchedule(Id, Culture, Date, Action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,18 @@
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
// fixme/review - should this be named DocumentScheduleAction?
|
||||
// fixme/review - should values be Release and Expire not Start and Stop?
|
||||
|
||||
/// <summary>
|
||||
/// Defines scheduled actions for documents.
|
||||
/// </summary>
|
||||
public enum ContentScheduleChange
|
||||
public enum ContentScheduleAction
|
||||
{
|
||||
/// <summary>
|
||||
/// Release the document.
|
||||
/// </summary>
|
||||
Start,
|
||||
Release,
|
||||
|
||||
/// <summary>
|
||||
/// Expire the document.
|
||||
/// </summary>
|
||||
End
|
||||
Expire
|
||||
}
|
||||
}
|
||||
@@ -75,14 +75,14 @@ namespace Umbraco.Core.Models
|
||||
|
||||
if (releaseDate.HasValue)
|
||||
{
|
||||
var entry = new ContentSchedule(0, culture, releaseDate.Value, ContentScheduleChange.Start);
|
||||
var entry = new ContentSchedule(0, culture, releaseDate.Value, ContentScheduleAction.Release);
|
||||
changes.Add(releaseDate.Value, entry);
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, entry));
|
||||
}
|
||||
|
||||
if (expireDate.HasValue)
|
||||
{
|
||||
var entry = new ContentSchedule(0, culture, expireDate.Value, ContentScheduleChange.End);
|
||||
var entry = new ContentSchedule(0, culture, expireDate.Value, ContentScheduleAction.Expire);
|
||||
changes.Add(expireDate.Value, entry);
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, entry));
|
||||
}
|
||||
@@ -112,45 +112,46 @@ namespace Umbraco.Core.Models
|
||||
/// <summary>
|
||||
/// Clear all of the scheduled change type for invariant content
|
||||
/// </summary>
|
||||
/// <param name="changeType"></param>
|
||||
/// <param name="action"></param>
|
||||
/// <param name="changeDate">If specified, will clear all entries with dates less than or equal to the value</param>
|
||||
public void Clear(ContentScheduleChange changeType, DateTime? changeDate = null)
|
||||
public void Clear(ContentScheduleAction action, DateTime? changeDate = null)
|
||||
{
|
||||
Clear(string.Empty, changeType, changeDate);
|
||||
Clear(string.Empty, action, changeDate);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clear all of the scheduled change type for the culture
|
||||
/// </summary>
|
||||
/// <param name="culture"></param>
|
||||
/// <param name="changeType"></param>
|
||||
/// <param name="changeDate">If specified, will clear all entries with dates less than or equal to the value</param>
|
||||
public void Clear(string culture, ContentScheduleChange changeType, DateTime? changeDate = null)
|
||||
/// <param name="action"></param>
|
||||
/// <param name="date">If specified, will clear all entries with dates less than or equal to the value</param>
|
||||
public void Clear(string culture, ContentScheduleAction action, DateTime? date = null)
|
||||
{
|
||||
if (_schedule.TryGetValue(culture, out var s))
|
||||
{
|
||||
foreach (var ofChange in s.Where(x => x.Value.Change == changeType
|
||||
&& (changeDate.HasValue ? x.Value.Date <= changeDate.Value : true)).ToList())
|
||||
{
|
||||
var removed = s.Remove(ofChange.Value.Date);
|
||||
if (removed)
|
||||
{
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, ofChange.Value));
|
||||
if (s.Count == 0)
|
||||
_schedule.Remove(culture);
|
||||
}
|
||||
}
|
||||
if (!_schedule.TryGetValue(culture, out var schedules))
|
||||
return;
|
||||
|
||||
var removes = schedules.Where(x => x.Value.Action == action && (!date.HasValue || x.Value.Date <= date.Value)).ToList();
|
||||
|
||||
foreach (var remove in removes)
|
||||
{
|
||||
var removed = schedules.Remove(remove.Value.Date);
|
||||
if (!removed)
|
||||
continue;
|
||||
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, remove.Value));
|
||||
}
|
||||
|
||||
if (schedules.Count == 0)
|
||||
_schedule.Remove(culture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all pending schedules based on the date and type provided
|
||||
/// </summary>
|
||||
/// <param name="changeType"></param>
|
||||
/// <param name="action"></param>
|
||||
/// <param name="date"></param>
|
||||
/// <returns></returns>
|
||||
public IReadOnlyList<ContentSchedule> GetPending(ContentScheduleChange changeType, DateTime date)
|
||||
public IReadOnlyList<ContentSchedule> GetPending(ContentScheduleAction action, DateTime date)
|
||||
{
|
||||
return _schedule.Values.SelectMany(x => x.Values).Where(x => x.Date <= date).ToList();
|
||||
}
|
||||
@@ -159,9 +160,9 @@ namespace Umbraco.Core.Models
|
||||
/// Gets the schedule for invariant content
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<ContentSchedule> GetSchedule(ContentScheduleChange? changeType = null)
|
||||
public IEnumerable<ContentSchedule> GetSchedule(ContentScheduleAction? action = null)
|
||||
{
|
||||
return GetSchedule(string.Empty, changeType);
|
||||
return GetSchedule(string.Empty, action);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -169,10 +170,10 @@ namespace Umbraco.Core.Models
|
||||
/// </summary>
|
||||
/// <param name="culture"></param>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<ContentSchedule> GetSchedule(string culture, ContentScheduleChange? changeType = null)
|
||||
public IEnumerable<ContentSchedule> GetSchedule(string culture, ContentScheduleAction? action = null)
|
||||
{
|
||||
if (_schedule.TryGetValue(culture, out var changes))
|
||||
return changeType == null ? changes.Values : changes.Values.Where(x => x.Change == changeType.Value);
|
||||
return action == null ? changes.Values : changes.Values.Where(x => x.Action == action.Value);
|
||||
return Enumerable.Empty<ContentSchedule>();
|
||||
}
|
||||
|
||||
@@ -208,7 +209,6 @@ namespace Umbraco.Core.Models
|
||||
if (thisSched.Count != thatSched.Count)
|
||||
return false;
|
||||
|
||||
// fixme/review - code was returning false *if* thatList.SequenceEqual(thisList) and not the opposite?
|
||||
foreach (var (culture, thisList) in thisSched)
|
||||
{
|
||||
// if culture is missing, or actions differ, false
|
||||
|
||||
@@ -73,10 +73,9 @@ namespace Umbraco.Core.Models
|
||||
// so, the logic below ensures that the name always end up being the correct name
|
||||
// see also LanguageController.GetAllCultures which is doing the same
|
||||
//
|
||||
// fixme/review - stop saving language names in database?
|
||||
// all this, including the ugly settings injection, because se store language names in db,
|
||||
// otherwise it would be ok to simply return new CultureInfo(IsoCode).DisplayName to get the name
|
||||
// in whatever culture is current - could we ... not do it?
|
||||
// in whatever culture is current - we should not do it, see task #3623
|
||||
//
|
||||
// but then, some tests that compare audit strings (for culture names) would need to be fixed
|
||||
|
||||
|
||||
@@ -178,7 +178,7 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
return entity.ContentSchedule.FullSchedule.Select(x =>
|
||||
new ContentScheduleDto
|
||||
{
|
||||
Action = x.Change.ToString(),
|
||||
Action = x.Action.ToString(),
|
||||
Date = x.Date,
|
||||
NodeId = entity.Id,
|
||||
LanguageId = languageRepository.GetIdByIsoCode(x.Culture, false),
|
||||
|
||||
@@ -917,14 +917,14 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<IContent> GetContentForRelease(DateTime date)
|
||||
{
|
||||
var action = ContentScheduleChange.Start.ToString();
|
||||
var action = ContentScheduleAction.Release.ToString();
|
||||
|
||||
var sql = GetBaseQuery(QueryType.Many)
|
||||
.WhereIn<NodeDto>(x => x.NodeId, Sql()
|
||||
.Select<ContentScheduleDto>(x => x.NodeId)
|
||||
.From<ContentScheduleDto>()
|
||||
.Where<ContentScheduleDto>(x => x.Action == action && x.Date <= date));
|
||||
|
||||
|
||||
AddGetByQueryOrderBy(sql);
|
||||
|
||||
return MapDtosToContent(Database.Fetch<DocumentDto>(sql));
|
||||
@@ -933,9 +933,8 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<IContent> GetContentForExpiration(DateTime date)
|
||||
{
|
||||
var action = ContentScheduleChange.End.ToString();
|
||||
var action = ContentScheduleAction.Expire.ToString();
|
||||
|
||||
// fixme/review - see as above
|
||||
var sql = GetBaseQuery(QueryType.Many)
|
||||
.WhereIn<NodeDto>(x => x.NodeId, Sql()
|
||||
.Select<ContentScheduleDto>(x => x.NodeId)
|
||||
@@ -1165,17 +1164,15 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
|
||||
foreach (var scheduleDto in scheduleDtos)
|
||||
{
|
||||
// fixme/review - code was adding a new collection on each dto?
|
||||
|
||||
if (!result.TryGetValue(scheduleDto.NodeId, out var col))
|
||||
col = result[scheduleDto.NodeId] = new ContentScheduleCollection();
|
||||
|
||||
col.Add(new ContentSchedule(scheduleDto.Id,
|
||||
LanguageRepository.GetIsoCodeById(scheduleDto.LanguageId) ?? string.Empty,
|
||||
scheduleDto.Date,
|
||||
scheduleDto.Action == ContentScheduleChange.Start.ToString()
|
||||
? ContentScheduleChange.Start
|
||||
: ContentScheduleChange.End));
|
||||
scheduleDto.Action == ContentScheduleAction.Release.ToString()
|
||||
? ContentScheduleAction.Release
|
||||
: ContentScheduleAction.Expire));
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -362,8 +362,6 @@ namespace Umbraco.Core.Services
|
||||
/// </remarks>
|
||||
PublishResult SavePublishing(IContent content, int userId = 0, bool raiseEvents = true);
|
||||
|
||||
// fixme/review - should SaveAndPublishBranch always publish the root document of the branch, even when !force?
|
||||
|
||||
/// <summary>
|
||||
/// Saves and publishes a document branch.
|
||||
/// </summary>
|
||||
|
||||
@@ -1197,7 +1197,7 @@ namespace Umbraco.Core.Services.Implement
|
||||
if (d.ContentType.VariesByCulture())
|
||||
{
|
||||
//find which cultures have pending schedules
|
||||
var pendingCultures = d.ContentSchedule.GetPending(ContentScheduleChange.Start, date)
|
||||
var pendingCultures = d.ContentSchedule.GetPending(ContentScheduleAction.Release, date)
|
||||
.Select(x => x.Culture)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
@@ -1206,7 +1206,7 @@ namespace Umbraco.Core.Services.Implement
|
||||
foreach (var culture in pendingCultures)
|
||||
{
|
||||
//Clear this schedule for this culture
|
||||
d.ContentSchedule.Clear(culture, ContentScheduleChange.Start, date);
|
||||
d.ContentSchedule.Clear(culture, ContentScheduleAction.Release, date);
|
||||
|
||||
if (d.Trashed) continue; // won't publish
|
||||
|
||||
@@ -1229,7 +1229,7 @@ namespace Umbraco.Core.Services.Implement
|
||||
else
|
||||
{
|
||||
//Clear this schedule
|
||||
d.ContentSchedule.Clear(ContentScheduleChange.Start, date);
|
||||
d.ContentSchedule.Clear(ContentScheduleAction.Release, date);
|
||||
|
||||
result = d.Trashed
|
||||
? new PublishResult(PublishResultType.FailedPublishIsTrashed, evtMsgs, d)
|
||||
@@ -1248,7 +1248,7 @@ namespace Umbraco.Core.Services.Implement
|
||||
if (d.ContentType.VariesByCulture())
|
||||
{
|
||||
//find which cultures have pending schedules
|
||||
var pendingCultures = d.ContentSchedule.GetPending(ContentScheduleChange.End, date)
|
||||
var pendingCultures = d.ContentSchedule.GetPending(ContentScheduleAction.Expire, date)
|
||||
.Select(x => x.Culture)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
@@ -1256,7 +1256,7 @@ namespace Umbraco.Core.Services.Implement
|
||||
foreach (var c in pendingCultures)
|
||||
{
|
||||
//Clear this schedule for this culture
|
||||
d.ContentSchedule.Clear(c, ContentScheduleChange.End, date);
|
||||
d.ContentSchedule.Clear(c, ContentScheduleAction.Expire, date);
|
||||
//set the culture to be published
|
||||
d.UnpublishCulture(c);
|
||||
}
|
||||
@@ -1272,7 +1272,7 @@ namespace Umbraco.Core.Services.Implement
|
||||
else
|
||||
{
|
||||
//Clear this schedule
|
||||
d.ContentSchedule.Clear(ContentScheduleChange.End, date);
|
||||
d.ContentSchedule.Clear(ContentScheduleAction.Expire, date);
|
||||
result = Unpublish(d, userId: d.WriterId);
|
||||
if (result.Success == false)
|
||||
Logger.Error<ContentService>(null, "Failed to unpublish document id={DocumentId}, reason={Reason}.", d.Id, result.Result);
|
||||
@@ -2505,7 +2505,7 @@ namespace Umbraco.Core.Services.Implement
|
||||
// they should be removed so they don't interrupt an unpublish
|
||||
// otherwise it would remain released == published
|
||||
|
||||
var pastReleases = content.ContentSchedule.GetPending(ContentScheduleChange.End, DateTime.Now);
|
||||
var pastReleases = content.ContentSchedule.GetPending(ContentScheduleAction.Expire, DateTime.Now);
|
||||
foreach (var p in pastReleases)
|
||||
content.ContentSchedule.Remove(p);
|
||||
if (pastReleases.Count > 0)
|
||||
|
||||
@@ -378,7 +378,7 @@
|
||||
<Compile Include="Models\ContentEditing\ContentApp.cs" />
|
||||
<Compile Include="Models\ContentEditing\IContentAppDefinition.cs" />
|
||||
<Compile Include="Models\ContentSchedule.cs" />
|
||||
<Compile Include="Models\ContentScheduleChange.cs" />
|
||||
<Compile Include="Models\ContentScheduleAction.cs" />
|
||||
<Compile Include="Models\ContentScheduleCollection.cs" />
|
||||
<Compile Include="Models\ContentTagsExtensions.cs" />
|
||||
<Compile Include="Models\ContentTypeBaseExtensions.cs" />
|
||||
|
||||
@@ -71,10 +71,10 @@ namespace Umbraco.Tests.Models
|
||||
var schedule = new ContentScheduleCollection();
|
||||
schedule.Add(now, now.AddDays(1));
|
||||
|
||||
schedule.Clear(ContentScheduleChange.Start);
|
||||
schedule.Clear(ContentScheduleAction.Release);
|
||||
|
||||
Assert.AreEqual(0, schedule.GetSchedule(ContentScheduleChange.Start).Count());
|
||||
Assert.AreEqual(1, schedule.GetSchedule(ContentScheduleChange.End).Count());
|
||||
Assert.AreEqual(0, schedule.GetSchedule(ContentScheduleAction.Release).Count());
|
||||
Assert.AreEqual(1, schedule.GetSchedule(ContentScheduleAction.Expire).Count());
|
||||
Assert.AreEqual(1, schedule.FullSchedule.Count());
|
||||
}
|
||||
|
||||
@@ -86,20 +86,20 @@ namespace Umbraco.Tests.Models
|
||||
schedule.Add(now, now.AddDays(1));
|
||||
schedule.Add("en-US", now, now.AddDays(1));
|
||||
|
||||
schedule.Clear(ContentScheduleChange.End);
|
||||
schedule.Clear(ContentScheduleAction.Expire);
|
||||
|
||||
Assert.AreEqual(0, schedule.GetSchedule(ContentScheduleChange.End).Count());
|
||||
Assert.AreEqual(1, schedule.GetSchedule(ContentScheduleChange.Start).Count());
|
||||
Assert.AreEqual(1, schedule.GetSchedule("en-US", ContentScheduleChange.End).Count());
|
||||
Assert.AreEqual(1, schedule.GetSchedule("en-US", ContentScheduleChange.Start).Count());
|
||||
Assert.AreEqual(0, schedule.GetSchedule(ContentScheduleAction.Expire).Count());
|
||||
Assert.AreEqual(1, schedule.GetSchedule(ContentScheduleAction.Release).Count());
|
||||
Assert.AreEqual(1, schedule.GetSchedule("en-US", ContentScheduleAction.Expire).Count());
|
||||
Assert.AreEqual(1, schedule.GetSchedule("en-US", ContentScheduleAction.Release).Count());
|
||||
Assert.AreEqual(3, schedule.FullSchedule.Count());
|
||||
|
||||
schedule.Clear("en-US", ContentScheduleChange.End);
|
||||
schedule.Clear("en-US", ContentScheduleAction.Expire);
|
||||
|
||||
Assert.AreEqual(0, schedule.GetSchedule(ContentScheduleChange.End).Count());
|
||||
Assert.AreEqual(1, schedule.GetSchedule(ContentScheduleChange.Start).Count());
|
||||
Assert.AreEqual(0, schedule.GetSchedule("en-US", ContentScheduleChange.End).Count());
|
||||
Assert.AreEqual(1, schedule.GetSchedule("en-US", ContentScheduleChange.Start).Count());
|
||||
Assert.AreEqual(0, schedule.GetSchedule(ContentScheduleAction.Expire).Count());
|
||||
Assert.AreEqual(1, schedule.GetSchedule(ContentScheduleAction.Release).Count());
|
||||
Assert.AreEqual(0, schedule.GetSchedule("en-US", ContentScheduleAction.Expire).Count());
|
||||
Assert.AreEqual(1, schedule.GetSchedule("en-US", ContentScheduleAction.Release).Count());
|
||||
Assert.AreEqual(2, schedule.FullSchedule.Count());
|
||||
}
|
||||
|
||||
|
||||
@@ -357,7 +357,7 @@ namespace Umbraco.Tests.Services
|
||||
var sched = content.ContentSchedule.FullSchedule;
|
||||
Assert.AreEqual(1, sched.Count);
|
||||
Assert.AreEqual(1, sched.Count(x => x.Culture == string.Empty));
|
||||
content.ContentSchedule.Clear(ContentScheduleChange.End);
|
||||
content.ContentSchedule.Clear(ContentScheduleAction.Expire);
|
||||
contentService.Save(content, Constants.Security.SuperUserId);
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user