Review PR, adjustments

This commit is contained in:
Stephan
2019-02-06 17:28:48 +01:00
parent 87c85341fb
commit 8329097974
17 changed files with 212 additions and 207 deletions

View File

@@ -1,34 +1,36 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Permissions;
namespace Umbraco.Core.Events
{
[HostProtection(SecurityAction.LinkDemand, SharedState = true)]
public class CancellableEnumerableObjectEventArgs<T> : CancellableObjectEventArgs<IEnumerable<T>>, IEquatable<CancellableEnumerableObjectEventArgs<T>>
/// <summary>
/// Represents event data, for events that support cancellation, and expose impacted objects.
/// </summary>
/// <typeparam name="TEventObject">The type of the exposed, impacted objects.</typeparam>
public class CancellableEnumerableObjectEventArgs<TEventObject> : CancellableObjectEventArgs<IEnumerable<TEventObject>>, IEquatable<CancellableEnumerableObjectEventArgs<TEventObject>>
{
public CancellableEnumerableObjectEventArgs(IEnumerable<T> eventObject, bool canCancel, EventMessages messages, IDictionary<string, object> additionalData)
public CancellableEnumerableObjectEventArgs(IEnumerable<TEventObject> eventObject, bool canCancel, EventMessages messages, IDictionary<string, object> additionalData)
: base(eventObject, canCancel, messages, additionalData)
{ }
public CancellableEnumerableObjectEventArgs(IEnumerable<T> eventObject, bool canCancel, EventMessages eventMessages)
public CancellableEnumerableObjectEventArgs(IEnumerable<TEventObject> eventObject, bool canCancel, EventMessages eventMessages)
: base(eventObject, canCancel, eventMessages)
{ }
public CancellableEnumerableObjectEventArgs(IEnumerable<T> eventObject, EventMessages eventMessages)
public CancellableEnumerableObjectEventArgs(IEnumerable<TEventObject> eventObject, EventMessages eventMessages)
: base(eventObject, eventMessages)
{ }
public CancellableEnumerableObjectEventArgs(IEnumerable<T> eventObject, bool canCancel)
public CancellableEnumerableObjectEventArgs(IEnumerable<TEventObject> eventObject, bool canCancel)
: base(eventObject, canCancel)
{ }
public CancellableEnumerableObjectEventArgs(IEnumerable<T> eventObject)
public CancellableEnumerableObjectEventArgs(IEnumerable<TEventObject> eventObject)
: base(eventObject)
{ }
public bool Equals(CancellableEnumerableObjectEventArgs<T> other)
public bool Equals(CancellableEnumerableObjectEventArgs<TEventObject> other)
{
if (other is null) return false;
if (ReferenceEquals(this, other)) return true;
@@ -41,7 +43,7 @@ namespace Umbraco.Core.Events
if (obj is null) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((CancellableEnumerableObjectEventArgs<T>)obj);
return Equals((CancellableEnumerableObjectEventArgs<TEventObject>)obj);
}
public override int GetHashCode()
@@ -49,4 +51,4 @@ namespace Umbraco.Core.Events
return HashCodeHelper.GetHashCode(EventObject);
}
}
}
}

View File

@@ -1,14 +1,12 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Security.Permissions;
namespace Umbraco.Core.Events
{
/// <summary>
/// Event args for that can support cancellation
/// Represents event data for events that support cancellation.
/// </summary>
[HostProtection(SecurityAction.LinkDemand, SharedState = true)]
public class CancellableEventArgs : EventArgs, IEquatable<CancellableEventArgs>
{
private bool _cancel;

View File

@@ -1,15 +1,10 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Security.Permissions;
using Umbraco.Core.Models;
using System.Collections.Generic;
namespace Umbraco.Core.Events
{
/// <summary>
/// Used as a base class for the generic type CancellableObjectEventArgs{T} so that we can get direct 'object' access to the underlying EventObject
/// Provides a base class for classes representing event data, for events that support cancellation, and expose an impacted object.
/// </summary>
[HostProtection(SecurityAction.LinkDemand, SharedState = true)]
public abstract class CancellableObjectEventArgs : CancellableEventArgs
{
protected CancellableObjectEventArgs(object eventObject, bool canCancel, EventMessages messages, IDictionary<string, object> additionalData)
@@ -41,90 +36,11 @@ namespace Umbraco.Core.Events
}
/// <summary>
/// Returns the object relating to the event
/// Gets or sets the impacted object.
/// </summary>
/// <remarks>
/// This is protected so that inheritors can expose it with their own name
/// </remarks>
internal object EventObject { get; set; }
}
/// <summary>
/// Event args for a strongly typed object that can support cancellation
/// </summary>
/// <typeparam name="T"></typeparam>
[HostProtection(SecurityAction.LinkDemand, SharedState = true)]
public class CancellableObjectEventArgs<T> : CancellableObjectEventArgs, IEquatable<CancellableObjectEventArgs<T>>
{
public CancellableObjectEventArgs(T eventObject, bool canCancel, EventMessages messages, IDictionary<string, object> additionalData)
: base(eventObject, canCancel, messages, additionalData)
{
}
public CancellableObjectEventArgs(T eventObject, bool canCancel, EventMessages eventMessages)
: base(eventObject, canCancel, eventMessages)
{
}
public CancellableObjectEventArgs(T eventObject, EventMessages eventMessages)
: base(eventObject, eventMessages)
{
}
public CancellableObjectEventArgs(T eventObject, bool canCancel)
: base(eventObject, canCancel)
{
}
public CancellableObjectEventArgs(T eventObject)
: base(eventObject)
{
}
/// <summary>
/// Returns the object relating to the event
/// </summary>
/// <remarks>
/// This is protected so that inheritors can expose it with their own name
/// </remarks>
protected new T EventObject
{
get { return (T) base.EventObject; }
set { base.EventObject = value; }
}
public bool Equals(CancellableObjectEventArgs<T> other)
{
if (other is null) return false;
if (ReferenceEquals(this, other)) return true;
return base.Equals(other) && EqualityComparer<T>.Default.Equals(EventObject, other.EventObject);
}
public override bool Equals(object obj)
{
if (obj is null) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((CancellableObjectEventArgs<T>)obj);
}
public override int GetHashCode()
{
unchecked
{
return (base.GetHashCode() * 397) ^ EqualityComparer<T>.Default.GetHashCode(EventObject);
}
}
public static bool operator ==(CancellableObjectEventArgs<T> left, CancellableObjectEventArgs<T> right)
{
return Equals(left, right);
}
public static bool operator !=(CancellableObjectEventArgs<T> left, CancellableObjectEventArgs<T> right)
{
return !Equals(left, right);
}
}
}

View File

@@ -0,0 +1,82 @@
using System;
using System.Collections.Generic;
namespace Umbraco.Core.Events
{
/// <summary>
/// Represent event data, for events that support cancellation, and expose an impacted object.
/// </summary>
/// <typeparam name="TEventObject">The type of the exposed, impacted object.</typeparam>
public class CancellableObjectEventArgs<TEventObject> : CancellableObjectEventArgs, IEquatable<CancellableObjectEventArgs<TEventObject>>
{
public CancellableObjectEventArgs(TEventObject eventObject, bool canCancel, EventMessages messages, IDictionary<string, object> additionalData)
: base(eventObject, canCancel, messages, additionalData)
{
}
public CancellableObjectEventArgs(TEventObject eventObject, bool canCancel, EventMessages eventMessages)
: base(eventObject, canCancel, eventMessages)
{
}
public CancellableObjectEventArgs(TEventObject eventObject, EventMessages eventMessages)
: base(eventObject, eventMessages)
{
}
public CancellableObjectEventArgs(TEventObject eventObject, bool canCancel)
: base(eventObject, canCancel)
{
}
public CancellableObjectEventArgs(TEventObject eventObject)
: base(eventObject)
{
}
/// <summary>
/// Gets or sets the impacted object.
/// </summary>
/// <remarks>
/// This is protected so that inheritors can expose it with their own name
/// </remarks>
protected new TEventObject EventObject
{
get => (TEventObject) base.EventObject;
set => base.EventObject = value;
}
public bool Equals(CancellableObjectEventArgs<TEventObject> other)
{
if (other is null) return false;
if (ReferenceEquals(this, other)) return true;
return base.Equals(other) && EqualityComparer<TEventObject>.Default.Equals(EventObject, other.EventObject);
}
public override bool Equals(object obj)
{
if (obj is null) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((CancellableObjectEventArgs<TEventObject>)obj);
}
public override int GetHashCode()
{
unchecked
{
return (base.GetHashCode() * 397) ^ EqualityComparer<TEventObject>.Default.GetHashCode(EventObject);
}
}
public static bool operator ==(CancellableObjectEventArgs<TEventObject> left, CancellableObjectEventArgs<TEventObject> right)
{
return Equals(left, right);
}
public static bool operator !=(CancellableObjectEventArgs<TEventObject> left, CancellableObjectEventArgs<TEventObject> right)
{
return !Equals(left, right);
}
}
}

View File

@@ -1,29 +1,30 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using Umbraco.Core.Models;
namespace Umbraco.Core.Events
{
/// <summary>
/// Represents event data for the Published event.
/// </summary>
public class ContentPublishedEventArgs : PublishEventArgs<IContent>
{
/// <summary>
/// Initializes a new instance of the <see cref="ContentPublishedEventArgs"/> class.
/// </summary>
public ContentPublishedEventArgs(IEnumerable<IContent> eventObject, bool canCancel, EventMessages eventMessages)
: base(eventObject, canCancel, eventMessages)
{
}
{ }
/// <summary>
/// Determines whether a culture has been published, during a Published event.
/// </summary>
public bool HasPublishedCulture(IContent content, string culture)
=> content.WasPropertyDirty("_changedCulture_" + culture);
=> content.WasPropertyDirty(ContentBase.ChangeTrackingPrefix.ChangedCulture + culture);
/// <summary>
/// Determines whether a culture has been unpublished, during a Published event.
/// </summary>
public bool HasUnpublishedCulture(IContent content, string culture)
=> content.WasPropertyDirty("_unpublishedCulture_" + culture);
=> content.WasPropertyDirty(ContentBase.ChangeTrackingPrefix.UnpublishedCulture + culture);
}
}

View File

@@ -1,21 +1,19 @@
using System;
using System.Linq;
using System.Collections.Generic;
using System.Collections.Generic;
using Umbraco.Core.Models;
namespace Umbraco.Core.Events
{
/// <summary>
/// Represents event data for the Publishing event.
/// </summary>
public class ContentPublishingEventArgs : PublishEventArgs<IContent>
{
/// <summary>
/// Creates a new <see cref="ContentPublishingEventArgs"/>
/// Initializes a new instance of the <see cref="ContentPublishingEventArgs"/> class.
/// </summary>
/// <param name="eventObject"></param>
/// <param name="eventMessages"></param>
public ContentPublishingEventArgs(IEnumerable<IContent> eventObject, EventMessages eventMessages)
: base(eventObject, eventMessages)
{
}
{ }
/// <summary>
/// Determines whether a culture is being published, during a Publishing event.
@@ -27,7 +25,6 @@ namespace Umbraco.Core.Events
/// Determines whether a culture is being unpublished, during a Publishing event.
/// </summary>
public bool IsUnpublishingCulture(IContent content, string culture)
=> content.IsPropertyDirty("_unpublishedCulture_" + culture); //bit of a hack since we know that the content implementation tracks changes this way
=> content.IsPropertyDirty(ContentBase.ChangeTrackingPrefix.UnpublishedCulture + culture); //bit of a hack since we know that the content implementation tracks changes this way
}
}

View File

@@ -1,30 +1,24 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using Umbraco.Core.Models;
namespace Umbraco.Core.Events
{
/// <summary>
/// Represents event data for the Saved event.
/// </summary>
public class ContentSavedEventArgs : SaveEventArgs<IContent>
{
#region Constructors
/// <summary>
/// Creates a new <see cref="ContentSavedEventArgs"/>
/// Initializes a new instance of the <see cref="ContentSavedEventArgs"/> class.
/// </summary>
/// <param name="eventObject"></param>
/// <param name="messages"></param>
/// <param name="additionalData"></param>
public ContentSavedEventArgs(IEnumerable<IContent> eventObject, EventMessages messages, IDictionary<string, object> additionalData)
: base(eventObject, false, messages, additionalData)
{
}
#endregion
{ }
/// <summary>
/// Determines whether a culture has been saved, during a Saved event.
/// </summary>
public bool HasSavedCulture(IContent content, string culture)
=> content.WasPropertyDirty("_updatedCulture_" + culture);
=> content.WasPropertyDirty(ContentBase.ChangeTrackingPrefix.UpdatedCulture + culture);
}
}

View File

@@ -1,12 +1,15 @@
using System.Linq;
using System.Collections.Generic;
using System.Collections.Generic;
using Umbraco.Core.Models;
namespace Umbraco.Core.Events
{
/// <summary>
/// Represent event data for the Saving event.
/// </summary>
public class ContentSavingEventArgs : SaveEventArgs<IContent>
{
#region Factory Methods
/// <summary>
/// Converts <see cref="ContentSavingEventArgs"/> to <see cref="ContentSavedEventArgs"/> while preserving all args state
/// </summary>
@@ -43,24 +46,32 @@ namespace Umbraco.Core.Events
EventState = EventState,
AdditionalData = AdditionalData
};
}
}
#endregion
#region Constructors
public ContentSavingEventArgs(IEnumerable<IContent> eventObject, EventMessages eventMessages) : base(eventObject, eventMessages)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="ContentSavingEventArgs"/> class.
/// </summary>
public ContentSavingEventArgs(IEnumerable<IContent> eventObject, EventMessages eventMessages)
: base(eventObject, eventMessages)
{ }
public ContentSavingEventArgs(IContent eventObject, EventMessages eventMessages) : base(eventObject, eventMessages)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="ContentSavingEventArgs"/> class.
/// </summary>
public ContentSavingEventArgs(IContent eventObject, EventMessages eventMessages)
: base(eventObject, eventMessages)
{ }
#endregion
/// <summary>
/// Determines whether a culture is being saved, during a Saving event.
/// </summary>
public bool IsSavingCulture(IContent content, string culture) => content.CultureInfos.TryGetValue(culture, out var cultureInfo) && cultureInfo.IsDirty();
public bool IsSavingCulture(IContent content, string culture)
=> content.CultureInfos.TryGetValue(culture, out var cultureInfo) && cultureInfo.IsDirty();
}
}

View File

@@ -385,19 +385,19 @@ namespace Umbraco.Core.Models
public override bool IsPropertyDirty(string propertyName)
{
//Special check here since we want to check if the request is for changed cultures
if (propertyName.StartsWith("_publishedCulture_"))
if (propertyName.StartsWith(ChangeTrackingPrefix.PublishedCulture))
{
var culture = propertyName.TrimStart("_publishedCulture_");
var culture = propertyName.TrimStart(ChangeTrackingPrefix.PublishedCulture);
return _currentPublishCultureChanges.addedCultures?.Contains(culture) ?? false;
}
if (propertyName.StartsWith("_unpublishedCulture_"))
if (propertyName.StartsWith(ChangeTrackingPrefix.UnpublishedCulture))
{
var culture = propertyName.TrimStart("_unpublishedCulture_");
var culture = propertyName.TrimStart(ChangeTrackingPrefix.UnpublishedCulture);
return _currentPublishCultureChanges.removedCultures?.Contains(culture) ?? false;
}
if (propertyName.StartsWith("_changedCulture_"))
if (propertyName.StartsWith(ChangeTrackingPrefix.ChangedCulture))
{
var culture = propertyName.TrimStart("_changedCulture_");
var culture = propertyName.TrimStart(ChangeTrackingPrefix.ChangedCulture);
return _currentPublishCultureChanges.updatedCultures?.Contains(culture) ?? false;
}
@@ -409,19 +409,19 @@ namespace Umbraco.Core.Models
public override bool WasPropertyDirty(string propertyName)
{
//Special check here since we want to check if the request is for changed cultures
if (propertyName.StartsWith("_publishedCulture_"))
if (propertyName.StartsWith(ChangeTrackingPrefix.PublishedCulture))
{
var culture = propertyName.TrimStart("_publishedCulture_");
var culture = propertyName.TrimStart(ChangeTrackingPrefix.PublishedCulture);
return _previousPublishCultureChanges.addedCultures?.Contains(culture) ?? false;
}
if (propertyName.StartsWith("_unpublishedCulture_"))
if (propertyName.StartsWith(ChangeTrackingPrefix.UnpublishedCulture))
{
var culture = propertyName.TrimStart("_unpublishedCulture_");
var culture = propertyName.TrimStart(ChangeTrackingPrefix.UnpublishedCulture);
return _previousPublishCultureChanges.removedCultures?.Contains(culture) ?? false;
}
if (propertyName.StartsWith("_changedCulture_"))
if (propertyName.StartsWith(ChangeTrackingPrefix.ChangedCulture))
{
var culture = propertyName.TrimStart("_changedCulture_");
var culture = propertyName.TrimStart(ChangeTrackingPrefix.ChangedCulture);
return _previousPublishCultureChanges.updatedCultures?.Contains(culture) ?? false;
}

View File

@@ -17,7 +17,6 @@ namespace Umbraco.Core.Models
[DebuggerDisplay("Id: {Id}, Name: {Name}, ContentType: {ContentTypeBase.Alias}")]
public abstract class ContentBase : TreeEntityBase, IContentBase
{
private int _contentTypeId;
protected IContentTypeComposition ContentTypeBase;
private int _writerId;
@@ -29,6 +28,16 @@ namespace Umbraco.Core.Models
private (HashSet<string> addedCultures, HashSet<string> removedCultures, HashSet<string> updatedCultures) _currentCultureChanges;
private (HashSet<string> addedCultures, HashSet<string> removedCultures, HashSet<string> updatedCultures) _previousCultureChanges;
public static class ChangeTrackingPrefix
{
public const string UpdatedCulture = "_updatedCulture_";
public const string ChangedCulture = "_changedCulture_";
public const string PublishedCulture = "_publishedCulture_";
public const string UnpublishedCulture = "_unpublishedCulture_";
public const string AddedCulture = "_addedCulture_";
public const string RemovedCulture = "_removedCulture_";
}
#endregion
/// <summary>
@@ -71,8 +80,6 @@ namespace Umbraco.Core.Models
OnPropertyChanged(nameof(Properties));
}
/// <summary>
/// Id of the user who wrote/updated this entity
/// </summary>
@@ -402,19 +409,19 @@ namespace Umbraco.Core.Models
return true;
//Special check here since we want to check if the request is for changed cultures
if (propertyName.StartsWith("_addedCulture_"))
if (propertyName.StartsWith(ChangeTrackingPrefix.AddedCulture))
{
var culture = propertyName.TrimStart("_addedCulture_");
var culture = propertyName.TrimStart(ChangeTrackingPrefix.AddedCulture);
return _currentCultureChanges.addedCultures?.Contains(culture) ?? false;
}
if (propertyName.StartsWith("_removedCulture_"))
if (propertyName.StartsWith(ChangeTrackingPrefix.RemovedCulture))
{
var culture = propertyName.TrimStart("_removedCulture_");
var culture = propertyName.TrimStart(ChangeTrackingPrefix.RemovedCulture);
return _currentCultureChanges.removedCultures?.Contains(culture) ?? false;
}
if (propertyName.StartsWith("_updatedCulture_"))
if (propertyName.StartsWith(ChangeTrackingPrefix.UpdatedCulture))
{
var culture = propertyName.TrimStart("_updatedCulture_");
var culture = propertyName.TrimStart(ChangeTrackingPrefix.UpdatedCulture);
return _currentCultureChanges.updatedCultures?.Contains(culture) ?? false;
}
@@ -429,19 +436,19 @@ namespace Umbraco.Core.Models
return true;
//Special check here since we want to check if the request is for changed cultures
if (propertyName.StartsWith("_addedCulture_"))
if (propertyName.StartsWith(ChangeTrackingPrefix.AddedCulture))
{
var culture = propertyName.TrimStart("_addedCulture_");
var culture = propertyName.TrimStart(ChangeTrackingPrefix.AddedCulture);
return _previousCultureChanges.addedCultures?.Contains(culture) ?? false;
}
if (propertyName.StartsWith("_removedCulture_"))
if (propertyName.StartsWith(ChangeTrackingPrefix.RemovedCulture))
{
var culture = propertyName.TrimStart("_removedCulture_");
var culture = propertyName.TrimStart(ChangeTrackingPrefix.RemovedCulture);
return _previousCultureChanges.removedCultures?.Contains(culture) ?? false;
}
if (propertyName.StartsWith("_updatedCulture_"))
if (propertyName.StartsWith(ChangeTrackingPrefix.UpdatedCulture))
{
var culture = propertyName.TrimStart("_updatedCulture_");
var culture = propertyName.TrimStart(ChangeTrackingPrefix.UpdatedCulture);
return _previousCultureChanges.updatedCultures?.Contains(culture) ?? false;
}

View File

@@ -20,7 +20,7 @@ namespace Umbraco.Core.Models
return Array.Empty<string>();
var culturesUnpublishing = content.CultureInfos.Values
.Where(x => content.IsPropertyDirty("_unpublishedCulture_" + x.Culture))
.Where(x => content.IsPropertyDirty(ContentBase.ChangeTrackingPrefix.UnpublishedCulture + x.Culture))
.Select(x => x.Culture);
return culturesUnpublishing.ToList();
@@ -88,8 +88,7 @@ namespace Umbraco.Core.Models
{
content.CultureInfos.Clear();
content.CultureInfos = null;
}
}
if (culture == null || culture == "*")
content.Name = other.Name;
@@ -158,8 +157,9 @@ namespace Umbraco.Core.Models
if (!content.PublishCultureInfos.TryGetValue(culture, out var publishInfos))
continue;
// if it's not dirty, it means it hasn't changed so there's nothing to adjust
if (!publishInfos.IsDirty())
continue; //if it's not dirty, it means it hasn't changed so there's nothing to adjust
continue;
content.PublishCultureInfos.AddOrUpdate(culture, publishInfos.Name, date);

View File

@@ -58,7 +58,7 @@ namespace Umbraco.Core.Models
/// culture name, which must be get or set via the <see cref="TreeEntityBase.Name"/> property.</para>
/// </remarks>
ContentCultureInfosCollection CultureInfos { get; set; }
/// <summary>
/// Gets the available cultures.
/// </summary>

View File

@@ -7,8 +7,6 @@ namespace Umbraco.Core.Persistence.Repositories
{
public interface IDocumentRepository : IContentRepository<int, IContent>, IReadRepository<Guid, IContent>
{
/// <summary>
/// Clears the publishing schedule for all entries having an a date before (lower than, or equal to) a specified date.
/// </summary>

View File

@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Linq;
using NPoco;
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Exceptions;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
@@ -120,15 +119,15 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
break;
case QueryType.Single:
case QueryType.Many:
// R# may flag this ambiguous and red-squiggle it, but it is not
sql = sql.Select<DocumentDto>(r =>
r.Select(documentDto => documentDto.ContentDto, r1 =>
r1.Select(contentDto => contentDto.NodeDto))
.Select(documentDto => documentDto.DocumentVersionDto, r1 =>
r1.Select(documentVersionDto => documentVersionDto.ContentVersionDto))
.Select(documentDto => documentDto.PublishedVersionDto, "pdv", r1 =>
r1.Select(documentVersionDto => documentVersionDto.ContentVersionDto, "pcv")))
//we've put this in a local function so that the below sql.Select statement doesn't have a problem
//thinking that the call is ambiguous
NPocoSqlExtensions.SqlRef<DocumentDto> SelectStatement(NPocoSqlExtensions.SqlRef<DocumentDto> r) =>
r.Select(documentDto => documentDto.ContentDto, r1 => r1.Select(contentDto => contentDto.NodeDto))
.Select(documentDto => documentDto.DocumentVersionDto, r1 => r1.Select(documentVersionDto => documentVersionDto.ContentVersionDto))
.Select(documentDto => documentDto.PublishedVersionDto, "pdv", r1 => r1.Select(documentVersionDto => documentVersionDto.ContentVersionDto, "pcv"));
sql = sql.Select<DocumentDto>(SelectStatement)
// select the variant name, coalesce to the invariant name, as "variantName"
.AndSelect(VariantNameSqlExpression + " AS variantName");
break;
@@ -954,8 +953,6 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
#endregion
protected override string ApplySystemOrdering(ref Sql<ISqlContext> sql, Ordering ordering)
{
// note: 'updater' is the user who created the latest draft version,
@@ -1187,17 +1184,18 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
return result;
}
private void SetVariations(Content content, IDictionary<int, List<ContentVariation>> contentVariations, IDictionary<int, List<DocumentVariation>> documentVariations)
{
if (contentVariations.TryGetValue(content.VersionId, out var contentVariation))
foreach (var v in contentVariation)
content.SetCultureInfo(v.Culture, v.Name, v.Date);
if (content.PublishedVersionId > 0 && contentVariations.TryGetValue(content.PublishedVersionId, out contentVariation))
{
foreach (var v in contentVariation)
content.SetPublishInfo(v.Culture, v.Name, v.Date);
}
if (documentVariations.TryGetValue(content.Id, out var documentVariation))
content.SetCultureEdited(documentVariation.Where(x => x.Edited).Select(x => x.Culture));
}

View File

@@ -341,11 +341,10 @@ namespace Umbraco.Core.Services
/// <para>If the content type is variant, then culture can be either '*' or an actual culture, but neither 'null' nor
/// 'empty'. If the content type is invariant, then culture can be either '*' or null or empty.</para>
/// </remarks>
/// <param name="content"></param>
/// <param name="culture"></param>
/// <param name="userId"></param>
/// <param name="raiseEvents"></param>
/// <returns></returns>
/// <param name="content">The document to publish.</param>
/// <param name="culture">The culture to publish.</param>
/// <param name="userId">The identifier of the user performing the action.</param>
/// <param name="raiseEvents">A value indicating whether to raise events.</param>
PublishResult SaveAndPublish(IContent content, string culture = "*", int userId = 0, bool raiseEvents = true);
/// <summary>
@@ -356,11 +355,10 @@ namespace Umbraco.Core.Services
/// <para>When a culture is being published, it includes all varying values along with all invariant values.</para>
/// <para>The document is *always* saved, even when publishing fails.</para>
/// </remarks>
/// <param name="content"></param>
/// <param name="content">The document to publish.</param>
/// <param name="cultures">The cultures to publish.</param>
/// <param name="userId"></param>
/// <param name="raiseEvents"></param>
/// <returns></returns>
/// <param name="userId">The identifier of the user performing the action.</param>
/// <param name="raiseEvents">A value indicating whether to raise events.</param>
PublishResult SaveAndPublish(IContent content, string[] cultures, int userId = 0, bool raiseEvents = true);
/// <summary>

View File

@@ -908,8 +908,9 @@ namespace Umbraco.Core.Services.Implement
: new PublishResult(PublishResultType.FailedPublishNothingToPublish, evtMsgs, content);
}
// TODO: currently, no way to know which one failed
if (cultures.Select(content.PublishCulture).Any(isValid => !isValid))
return new PublishResult(PublishResultType.FailedPublishContentInvalid, evtMsgs, content); //fixme: no way to know which one failed?
return new PublishResult(PublishResultType.FailedPublishContentInvalid, evtMsgs, content);
return CommitDocumentChanges(content, userId, raiseEvents);
}
@@ -1055,9 +1056,10 @@ namespace Umbraco.Core.Services.Implement
}
// reset published state from temp values (publishing, unpublishing) to original value
// (published, unpublished) in order to save the document, unchanged
//TODO: why? this seems odd, were just setting the exact same value that it already has
// instead do we want to just set the PublishState?
// (published, unpublished) in order to save the document, unchanged - yes, this is odd,
// but: (a) it means we don't reproduce the PublishState logic here and (b) setting the
// PublishState to anything other than Publishing or Unpublishing - which is precisely
// what we want to do here - throws
content.Published = content.Published;
}
}
@@ -1080,9 +1082,10 @@ namespace Umbraco.Core.Services.Implement
else
{
// reset published state from temp values (publishing, unpublishing) to original value
// (published, unpublished) in order to save the document, unchanged
//TODO: why? this seems odd, were just setting the exact same value that it already has
// instead do we want to just set the PublishState?
// (published, unpublished) in order to save the document, unchanged - yes, this is odd,
// but: (a) it means we don't reproduce the PublishState logic here and (b) setting the
// PublishState to anything other than Publishing or Unpublishing - which is precisely
// what we want to do here - throws
content.Published = content.Published;
}
}
@@ -1507,9 +1510,8 @@ namespace Umbraco.Core.Services.Implement
Audit(AuditType.Publish, userId, document.Id, "Branch published");
// trigger events for the entire branch
// (SaveAndPublishBranchOne does *not* do it)
scope.Events.Dispatch(TreeChanged, this, new TreeChange<IContent>(document, TreeChangeTypes.RefreshBranch).ToEventArgs());
//fixme - in the SaveAndPublishBranchOne -> CommitDocumentChangesInternal publishing/published is going to be raised there, so are we raising it 2x for the same thing?
scope.Events.Dispatch(Published, this, new ContentPublishedEventArgs(publishedDocuments, false, evtMsgs), nameof(Published));
scope.Complete();

View File

@@ -302,6 +302,7 @@
<Compile Include="DisposableObjectSlim.cs" />
<Compile Include="EnumExtensions.cs" />
<Compile Include="Events\CancellableEnumerableObjectEventArgs.cs" />
<Compile Include="Events\CancellableObjectEventArgsOfTEventObject.cs" />
<Compile Include="Events\ContentPublishedEventArgs.cs" />
<Compile Include="Events\ContentPublishingEventArgs.cs" />
<Compile Include="Events\ContentSavedEventArgs.cs" />