diff --git a/build/NuSpecs/UmbracoCms.Core.nuspec b/build/NuSpecs/UmbracoCms.Core.nuspec index 9758c05dd6..88281cb84b 100644 --- a/build/NuSpecs/UmbracoCms.Core.nuspec +++ b/build/NuSpecs/UmbracoCms.Core.nuspec @@ -15,31 +15,35 @@ en-US umbraco - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/NuSpecs/UmbracoCms.Web.nuspec b/build/NuSpecs/UmbracoCms.Web.nuspec index fabd1e25a8..c52c8831e0 100644 --- a/build/NuSpecs/UmbracoCms.Web.nuspec +++ b/build/NuSpecs/UmbracoCms.Web.nuspec @@ -15,30 +15,35 @@ en-US umbraco - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/NuSpecs/UmbracoCms.nuspec b/build/NuSpecs/UmbracoCms.nuspec index b0f30b9779..ee0764bdd3 100644 --- a/build/NuSpecs/UmbracoCms.nuspec +++ b/build/NuSpecs/UmbracoCms.nuspec @@ -15,18 +15,25 @@ en-US umbraco - - - - - - - - + + + + + + + + + + + + + + + diff --git a/src/Umbraco.Core/Configuration/GlobalSettings.cs b/src/Umbraco.Core/Configuration/GlobalSettings.cs index e30bf85fd0..02b26aec86 100644 --- a/src/Umbraco.Core/Configuration/GlobalSettings.cs +++ b/src/Umbraco.Core/Configuration/GlobalSettings.cs @@ -31,7 +31,7 @@ namespace Umbraco.Core.Configuration private static string _reservedPaths; private static string _reservedUrls; //ensure the built on (non-changeable) reserved paths are there at all times - internal const string StaticReservedPaths = "~/app_plugins/,~/install/,"; //must end with a comma! + internal const string StaticReservedPaths = "~/app_plugins/,~/install/,~/mini-profiler-resources/,"; //must end with a comma! internal const string StaticReservedUrls = "~/config/splashes/noNodes.aspx,~/.well-known,"; //must end with a comma! #endregion diff --git a/src/Umbraco.Core/ContentExtensions.cs b/src/Umbraco.Core/ContentExtensions.cs index 174b4233f4..f802c2d0d9 100644 --- a/src/Umbraco.Core/ContentExtensions.cs +++ b/src/Umbraco.Core/ContentExtensions.cs @@ -109,10 +109,9 @@ namespace Umbraco.Core /// public static IEnumerable GetNonGroupedProperties(this IContentBase content) { - var propertyIdsInTabs = content.PropertyGroups.SelectMany(pg => pg.PropertyTypes); return content.Properties - .Where(property => propertyIdsInTabs.Contains(property.PropertyType) == false) - .OrderBy(x => x.PropertyType.SortOrder); + .Where(x => x.PropertyType.PropertyGroupId == null) + .OrderBy(x => x.PropertyType.SortOrder); } /// @@ -178,8 +177,7 @@ namespace Umbraco.Core var property = content.Properties.FirstOrDefault(x => x.Alias.InvariantEquals(propertyTypeAlias)); if (property != null) return property; - var contentTypeService = contentTypeBaseServiceProvider.For(content); - var contentType = contentTypeService.Get(content.ContentTypeId); + var contentType = contentTypeBaseServiceProvider.GetContentTypeOf(content); var propertyType = contentType.CompositionPropertyTypes .FirstOrDefault(x => x.Alias.InvariantEquals(propertyTypeAlias)); if (propertyType == null) @@ -208,8 +206,7 @@ namespace Umbraco.Core /// public static string StoreFile(this IContentBase content, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, string propertyTypeAlias, string filename, Stream filestream, string filepath) { - var contentTypeService = contentTypeBaseServiceProvider.For(content); - var contentType = contentTypeService.Get(content.ContentTypeId); + var contentType = contentTypeBaseServiceProvider.GetContentTypeOf(content); var propertyType = contentType .CompositionPropertyTypes.FirstOrDefault(x => x.Alias.InvariantEquals(propertyTypeAlias)); if (propertyType == null) throw new ArgumentException("Invalid property type alias " + propertyTypeAlias + "."); diff --git a/src/Umbraco.Core/Events/CancellableEnumerableObjectEventArgs.cs b/src/Umbraco.Core/Events/CancellableEnumerableObjectEventArgs.cs index 1a651ef348..1d52d0d847 100644 --- a/src/Umbraco.Core/Events/CancellableEnumerableObjectEventArgs.cs +++ b/src/Umbraco.Core/Events/CancellableEnumerableObjectEventArgs.cs @@ -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 : CancellableObjectEventArgs>, IEquatable> + /// + /// Represents event data, for events that support cancellation, and expose impacted objects. + /// + /// The type of the exposed, impacted objects. + public class CancellableEnumerableObjectEventArgs : CancellableObjectEventArgs>, IEquatable> { - public CancellableEnumerableObjectEventArgs(IEnumerable eventObject, bool canCancel, EventMessages messages, IDictionary additionalData) + public CancellableEnumerableObjectEventArgs(IEnumerable eventObject, bool canCancel, EventMessages messages, IDictionary additionalData) : base(eventObject, canCancel, messages, additionalData) { } - public CancellableEnumerableObjectEventArgs(IEnumerable eventObject, bool canCancel, EventMessages eventMessages) + public CancellableEnumerableObjectEventArgs(IEnumerable eventObject, bool canCancel, EventMessages eventMessages) : base(eventObject, canCancel, eventMessages) { } - public CancellableEnumerableObjectEventArgs(IEnumerable eventObject, EventMessages eventMessages) + public CancellableEnumerableObjectEventArgs(IEnumerable eventObject, EventMessages eventMessages) : base(eventObject, eventMessages) { } - public CancellableEnumerableObjectEventArgs(IEnumerable eventObject, bool canCancel) + public CancellableEnumerableObjectEventArgs(IEnumerable eventObject, bool canCancel) : base(eventObject, canCancel) { } - public CancellableEnumerableObjectEventArgs(IEnumerable eventObject) + public CancellableEnumerableObjectEventArgs(IEnumerable eventObject) : base(eventObject) { } - public bool Equals(CancellableEnumerableObjectEventArgs other) + public bool Equals(CancellableEnumerableObjectEventArgs 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)obj); + return Equals((CancellableEnumerableObjectEventArgs)obj); } public override int GetHashCode() @@ -49,4 +51,4 @@ namespace Umbraco.Core.Events return HashCodeHelper.GetHashCode(EventObject); } } -} \ No newline at end of file +} diff --git a/src/Umbraco.Core/Events/CancellableEventArgs.cs b/src/Umbraco.Core/Events/CancellableEventArgs.cs index 19f576478f..d9d670ea59 100644 --- a/src/Umbraco.Core/Events/CancellableEventArgs.cs +++ b/src/Umbraco.Core/Events/CancellableEventArgs.cs @@ -1,14 +1,12 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; -using System.Security.Permissions; namespace Umbraco.Core.Events { /// - /// Event args for that can support cancellation + /// Represents event data for events that support cancellation. /// - [HostProtection(SecurityAction.LinkDemand, SharedState = true)] public class CancellableEventArgs : EventArgs, IEquatable { private bool _cancel; diff --git a/src/Umbraco.Core/Events/CancellableObjectEventArgs.cs b/src/Umbraco.Core/Events/CancellableObjectEventArgs.cs index 27ffb1b75d..daf36fd6c8 100644 --- a/src/Umbraco.Core/Events/CancellableObjectEventArgs.cs +++ b/src/Umbraco.Core/Events/CancellableObjectEventArgs.cs @@ -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 { /// - /// 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. /// - [HostProtection(SecurityAction.LinkDemand, SharedState = true)] public abstract class CancellableObjectEventArgs : CancellableEventArgs { protected CancellableObjectEventArgs(object eventObject, bool canCancel, EventMessages messages, IDictionary additionalData) @@ -41,90 +36,11 @@ namespace Umbraco.Core.Events } /// - /// Returns the object relating to the event + /// Gets or sets the impacted object. /// /// /// This is protected so that inheritors can expose it with their own name /// internal object EventObject { get; set; } - - } - - /// - /// Event args for a strongly typed object that can support cancellation - /// - /// - [HostProtection(SecurityAction.LinkDemand, SharedState = true)] - public class CancellableObjectEventArgs : CancellableObjectEventArgs, IEquatable> - { - public CancellableObjectEventArgs(T eventObject, bool canCancel, EventMessages messages, IDictionary 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) - { - } - - /// - /// Returns the object relating to the event - /// - /// - /// This is protected so that inheritors can expose it with their own name - /// - protected new T EventObject - { - get { return (T) base.EventObject; } - set { base.EventObject = value; } - } - - public bool Equals(CancellableObjectEventArgs other) - { - if (other is null) return false; - if (ReferenceEquals(this, other)) return true; - return base.Equals(other) && EqualityComparer.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)obj); - } - - public override int GetHashCode() - { - unchecked - { - return (base.GetHashCode() * 397) ^ EqualityComparer.Default.GetHashCode(EventObject); - } - } - - public static bool operator ==(CancellableObjectEventArgs left, CancellableObjectEventArgs right) - { - return Equals(left, right); - } - - public static bool operator !=(CancellableObjectEventArgs left, CancellableObjectEventArgs right) - { - return !Equals(left, right); - } } } diff --git a/src/Umbraco.Core/Events/CancellableObjectEventArgsOfTEventObject.cs b/src/Umbraco.Core/Events/CancellableObjectEventArgsOfTEventObject.cs new file mode 100644 index 0000000000..ace2ce0a4f --- /dev/null +++ b/src/Umbraco.Core/Events/CancellableObjectEventArgsOfTEventObject.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; + +namespace Umbraco.Core.Events +{ + /// + /// Represent event data, for events that support cancellation, and expose an impacted object. + /// + /// The type of the exposed, impacted object. + public class CancellableObjectEventArgs : CancellableObjectEventArgs, IEquatable> + { + public CancellableObjectEventArgs(TEventObject eventObject, bool canCancel, EventMessages messages, IDictionary 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) + { + } + + /// + /// Gets or sets the impacted object. + /// + /// + /// This is protected so that inheritors can expose it with their own name + /// + protected new TEventObject EventObject + { + get => (TEventObject) base.EventObject; + set => base.EventObject = value; + } + + public bool Equals(CancellableObjectEventArgs other) + { + if (other is null) return false; + if (ReferenceEquals(this, other)) return true; + return base.Equals(other) && EqualityComparer.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)obj); + } + + public override int GetHashCode() + { + unchecked + { + return (base.GetHashCode() * 397) ^ EqualityComparer.Default.GetHashCode(EventObject); + } + } + + public static bool operator ==(CancellableObjectEventArgs left, CancellableObjectEventArgs right) + { + return Equals(left, right); + } + + public static bool operator !=(CancellableObjectEventArgs left, CancellableObjectEventArgs right) + { + return !Equals(left, right); + } + } +} diff --git a/src/Umbraco.Core/Events/ContentPublishedEventArgs.cs b/src/Umbraco.Core/Events/ContentPublishedEventArgs.cs index 589e447ba7..8c0690d591 100644 --- a/src/Umbraco.Core/Events/ContentPublishedEventArgs.cs +++ b/src/Umbraco.Core/Events/ContentPublishedEventArgs.cs @@ -1,29 +1,30 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using Umbraco.Core.Models; namespace Umbraco.Core.Events { + /// + /// Represents event data for the Published event. + /// public class ContentPublishedEventArgs : PublishEventArgs { + /// + /// Initializes a new instance of the class. + /// public ContentPublishedEventArgs(IEnumerable eventObject, bool canCancel, EventMessages eventMessages) : base(eventObject, canCancel, eventMessages) - { - } + { } /// /// Determines whether a culture has been published, during a Published event. /// public bool HasPublishedCulture(IContent content, string culture) - => content.WasPropertyDirty("_changedCulture_" + culture); + => content.WasPropertyDirty(ContentBase.ChangeTrackingPrefix.ChangedCulture + culture); /// /// Determines whether a culture has been unpublished, during a Published event. /// public bool HasUnpublishedCulture(IContent content, string culture) - => content.WasPropertyDirty("_unpublishedCulture_" + culture); - - - + => content.WasPropertyDirty(ContentBase.ChangeTrackingPrefix.UnpublishedCulture + culture); } } diff --git a/src/Umbraco.Core/Events/ContentPublishingEventArgs.cs b/src/Umbraco.Core/Events/ContentPublishingEventArgs.cs index 35cbf63441..b64bb19def 100644 --- a/src/Umbraco.Core/Events/ContentPublishingEventArgs.cs +++ b/src/Umbraco.Core/Events/ContentPublishingEventArgs.cs @@ -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 { + /// + /// Represents event data for the Publishing event. + /// public class ContentPublishingEventArgs : PublishEventArgs { /// - /// Creates a new + /// Initializes a new instance of the class. /// - /// - /// public ContentPublishingEventArgs(IEnumerable eventObject, EventMessages eventMessages) : base(eventObject, eventMessages) - { - } + { } /// /// 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. /// 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 } } diff --git a/src/Umbraco.Core/Events/ContentSavedEventArgs.cs b/src/Umbraco.Core/Events/ContentSavedEventArgs.cs index 4d4085b064..e2d8c25dd1 100644 --- a/src/Umbraco.Core/Events/ContentSavedEventArgs.cs +++ b/src/Umbraco.Core/Events/ContentSavedEventArgs.cs @@ -1,30 +1,24 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using Umbraco.Core.Models; namespace Umbraco.Core.Events { + /// + /// Represents event data for the Saved event. + /// public class ContentSavedEventArgs : SaveEventArgs { - #region Constructors - /// - /// Creates a new + /// Initializes a new instance of the class. /// - /// - /// - /// public ContentSavedEventArgs(IEnumerable eventObject, EventMessages messages, IDictionary additionalData) : base(eventObject, false, messages, additionalData) - { - } - - #endregion + { } /// /// Determines whether a culture has been saved, during a Saved event. /// public bool HasSavedCulture(IContent content, string culture) - => content.WasPropertyDirty("_updatedCulture_" + culture); + => content.WasPropertyDirty(ContentBase.ChangeTrackingPrefix.UpdatedCulture + culture); } } diff --git a/src/Umbraco.Core/Events/ContentSavingEventArgs.cs b/src/Umbraco.Core/Events/ContentSavingEventArgs.cs index aa62f64349..384353ee2e 100644 --- a/src/Umbraco.Core/Events/ContentSavingEventArgs.cs +++ b/src/Umbraco.Core/Events/ContentSavingEventArgs.cs @@ -1,12 +1,15 @@ -using System.Linq; -using System.Collections.Generic; +using System.Collections.Generic; using Umbraco.Core.Models; namespace Umbraco.Core.Events { + /// + /// Represent event data for the Saving event. + /// public class ContentSavingEventArgs : SaveEventArgs { #region Factory Methods + /// /// Converts to while preserving all args state /// @@ -43,24 +46,32 @@ namespace Umbraco.Core.Events EventState = EventState, AdditionalData = AdditionalData }; - } + } + #endregion #region Constructors - public ContentSavingEventArgs(IEnumerable eventObject, EventMessages eventMessages) : base(eventObject, eventMessages) - { - } + /// + /// Initializes a new instance of the class. + /// + public ContentSavingEventArgs(IEnumerable eventObject, EventMessages eventMessages) + : base(eventObject, eventMessages) + { } - public ContentSavingEventArgs(IContent eventObject, EventMessages eventMessages) : base(eventObject, eventMessages) - { - } + /// + /// Initializes a new instance of the class. + /// + public ContentSavingEventArgs(IContent eventObject, EventMessages eventMessages) + : base(eventObject, eventMessages) + { } #endregion /// /// Determines whether a culture is being saved, during a Saving event. /// - 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(); } } diff --git a/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs b/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs index ef55048122..7f7229ccd6 100644 --- a/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs +++ b/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs @@ -69,7 +69,7 @@ namespace Umbraco.Core.Migrations.Install if (tableName.Equals(Constants.DatabaseSchema.Tables.RelationType)) CreateRelationTypeData(); - + if (tableName.Equals(Constants.DatabaseSchema.Tables.KeyValue)) CreateKeyValueData(); @@ -210,12 +210,12 @@ namespace Umbraco.Core.Migrations.Install private void CreatePropertyTypeData() { - _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 6, UniqueId = 6.ToGuid(), DataTypeId = 1043, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.File, Name = "Upload image", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing }); + _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 6, UniqueId = 6.ToGuid(), DataTypeId = 1043, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.File, Name = "Upload image", SortOrder = 0, Mandatory = true, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing }); _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 7, UniqueId = 7.ToGuid(), DataTypeId = Constants.DataTypes.LabelInt, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.Width, Name = "Width", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = "in pixels", Variations = (byte) ContentVariation.Nothing }); _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 8, UniqueId = 8.ToGuid(), DataTypeId = Constants.DataTypes.LabelInt, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.Height, Name = "Height", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = "in pixels", Variations = (byte) ContentVariation.Nothing }); _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 9, UniqueId = 9.ToGuid(), DataTypeId = Constants.DataTypes.LabelBigint, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.Bytes, Name = "Size", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = "in bytes", Variations = (byte) ContentVariation.Nothing }); _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 10, UniqueId = 10.ToGuid(), DataTypeId = -92, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.Extension, Name = "Type", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing }); - _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 24, UniqueId = 24.ToGuid(), DataTypeId = -90, ContentTypeId = 1033, PropertyTypeGroupId = 4, Alias = Constants.Conventions.Media.File, Name = "Upload file", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing }); + _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 24, UniqueId = 24.ToGuid(), DataTypeId = -90, ContentTypeId = 1033, PropertyTypeGroupId = 4, Alias = Constants.Conventions.Media.File, Name = "Upload file", SortOrder = 0, Mandatory = true, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing }); _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 25, UniqueId = 25.ToGuid(), DataTypeId = -92, ContentTypeId = 1033, PropertyTypeGroupId = 4, Alias = Constants.Conventions.Media.Extension, Name = "Type", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing }); _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 26, UniqueId = 26.ToGuid(), DataTypeId = Constants.DataTypes.LabelBigint, ContentTypeId = 1033, PropertyTypeGroupId = 4, Alias = Constants.Conventions.Media.Bytes, Name = "Size", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = "in bytes", Variations = (byte) ContentVariation.Nothing }); //membership property types diff --git a/src/Umbraco.Core/Models/Content.cs b/src/Umbraco.Core/Models/Content.cs index 483ba8b0d2..c5930bf998 100644 --- a/src/Umbraco.Core/Models/Content.cs +++ b/src/Umbraco.Core/Models/Content.cs @@ -51,7 +51,6 @@ namespace Umbraco.Core.Models : base(name, parent, contentType, properties, culture) { if (contentType == null) throw new ArgumentNullException(nameof(contentType)); - ContentType = new SimpleContentType(contentType); _publishedState = PublishedState.Unpublished; PublishedVersionId = 0; } @@ -79,7 +78,6 @@ namespace Umbraco.Core.Models : base(name, parentId, contentType, properties, culture) { if (contentType == null) throw new ArgumentNullException(nameof(contentType)); - ContentType = new SimpleContentType(contentType); _publishedState = PublishedState.Unpublished; PublishedVersionId = 0; } @@ -172,12 +170,6 @@ namespace Umbraco.Core.Models [IgnoreDataMember] public bool Edited { get; set; } - /// - /// Gets the ContentType used by this content object - /// - [IgnoreDataMember] - public ISimpleContentType ContentType { get; private set; } - /// [IgnoreDataMember] public DateTime? PublishDate { get; set; } // set by persistence @@ -242,7 +234,7 @@ namespace Umbraco.Core.Models public string GetPublishName(string culture) { if (culture.IsNullOrWhiteSpace()) return PublishName; - if (!ContentTypeBase.VariesByCulture()) return null; + if (!ContentType.VariesByCulture()) return null; if (_publishInfos == null) return null; return _publishInfos.TryGetValue(culture, out var infos) ? infos.Name : null; } @@ -251,7 +243,7 @@ namespace Umbraco.Core.Models public DateTime? GetPublishDate(string culture) { if (culture.IsNullOrWhiteSpace()) return PublishDate; - if (!ContentTypeBase.VariesByCulture()) return null; + if (!ContentType.VariesByCulture()) return null; if (_publishInfos == null) return null; return _publishInfos.TryGetValue(culture, out var infos) ? infos.Date : (DateTime?)null; } @@ -311,13 +303,7 @@ namespace Umbraco.Core.Models /// Leaves PropertyTypes intact after change internal void ChangeContentType(IContentType contentType) { - ContentTypeId = contentType.Id; - ContentType = new SimpleContentType(contentType); - ContentTypeBase = contentType; - Properties.EnsurePropertyTypes(PropertyTypes); - - Properties.CollectionChanged -= PropertiesChanged; // be sure not to double add - Properties.CollectionChanged += PropertiesChanged; + ChangeContentType(contentType, false); } /// @@ -328,19 +314,15 @@ namespace Umbraco.Core.Models /// Boolean indicating whether to clear PropertyTypes upon change internal void ChangeContentType(IContentType contentType, bool clearProperties) { + ChangeContentType(new SimpleContentType(contentType)); + if (clearProperties) - { - ContentTypeId = contentType.Id; - ContentType = new SimpleContentType(contentType); - ContentTypeBase = contentType; - Properties.EnsureCleanPropertyTypes(PropertyTypes); + Properties.EnsureCleanPropertyTypes(contentType.CompositionPropertyTypes); + else + Properties.EnsurePropertyTypes(contentType.CompositionPropertyTypes); - Properties.CollectionChanged -= PropertiesChanged; // be sure not to double add - Properties.CollectionChanged += PropertiesChanged; - return; - } - - ChangeContentType(contentType); + Properties.CollectionChanged -= PropertiesChanged; // be sure not to double add + Properties.CollectionChanged += PropertiesChanged; } public override void ResetWereDirtyProperties() @@ -385,19 +367,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 +391,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; } @@ -453,9 +435,6 @@ namespace Umbraco.Core.Models //fixme - need to reset change tracking bits - //need to manually clone this since it's not settable - clonedContent.ContentType = ContentType; - //if culture infos exist then deal with event bindings if (clonedContent._publishInfos != null) { diff --git a/src/Umbraco.Core/Models/ContentBase.cs b/src/Umbraco.Core/Models/ContentBase.cs index 50de59931c..fbb68194b7 100644 --- a/src/Umbraco.Core/Models/ContentBase.cs +++ b/src/Umbraco.Core/Models/ContentBase.cs @@ -4,6 +4,7 @@ using System.Collections.Specialized; using System.Diagnostics; using System.Linq; using System.Runtime.Serialization; +using Umbraco.Core.Composing; using Umbraco.Core.Exceptions; using Umbraco.Core.Models.Entities; @@ -14,21 +15,30 @@ namespace Umbraco.Core.Models /// [Serializable] [DataContract(IsReference = true)] - [DebuggerDisplay("Id: {Id}, Name: {Name}, ContentType: {ContentTypeBase.Alias}")] + [DebuggerDisplay("Id: {Id}, Name: {Name}, ContentType: {ContentType.Alias}")] public abstract class ContentBase : TreeEntityBase, IContentBase { - private int _contentTypeId; - protected IContentTypeComposition ContentTypeBase; private int _writerId; private PropertyCollection _properties; private ContentCultureInfosCollection _cultureInfos; + internal IReadOnlyList AllPropertyTypes { get; } #region Used for change tracking private (HashSet addedCultures, HashSet removedCultures, HashSet updatedCultures) _currentCultureChanges; private (HashSet addedCultures, HashSet removedCultures, HashSet 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 /// @@ -53,7 +63,7 @@ namespace Umbraco.Core.Models private ContentBase(string name, IContentTypeComposition contentType, PropertyCollection properties, string culture = null) { - ContentTypeBase = contentType ?? throw new ArgumentNullException(nameof(contentType)); + ContentType = contentType?.ToSimple() ?? throw new ArgumentNullException(nameof(contentType)); // initially, all new instances have Id = 0; // no identity @@ -63,7 +73,21 @@ namespace Umbraco.Core.Models _contentTypeId = contentType.Id; _properties = properties ?? throw new ArgumentNullException(nameof(properties)); - _properties.EnsurePropertyTypes(PropertyTypes); + _properties.EnsurePropertyTypes(contentType.CompositionPropertyTypes); + + //track all property types on this content type, these can never change during the lifetime of this single instance + //there is no real extra memory overhead of doing this since these property types are already cached on this object via the + //properties already. + AllPropertyTypes = new List(contentType.CompositionPropertyTypes); + } + + [IgnoreDataMember] + public ISimpleContentType ContentType { get; private set; } + + internal void ChangeContentType(ISimpleContentType contentType) + { + ContentType = contentType; + ContentTypeId = contentType.Id; } protected void PropertiesChanged(object sender, NotifyCollectionChangedEventArgs e) @@ -71,8 +95,6 @@ namespace Umbraco.Core.Models OnPropertyChanged(nameof(Properties)); } - - /// /// Id of the user who wrote/updated this entity /// @@ -96,13 +118,13 @@ namespace Umbraco.Core.Models { //There will be cases where this has not been updated to reflect the true content type ID. //This will occur when inserting new content. - if (_contentTypeId == 0 && ContentTypeBase != null && ContentTypeBase.HasIdentity) + if (_contentTypeId == 0 && ContentType != null) { - _contentTypeId = ContentTypeBase.Id; + _contentTypeId = ContentType.Id; } return _contentTypeId; } - protected set => SetPropertyValueAndDetectChanges(value, ref _contentTypeId, nameof(ContentTypeId)); + private set => SetPropertyValueAndDetectChanges(value, ref _contentTypeId, nameof(ContentTypeId)); } /// @@ -124,20 +146,6 @@ namespace Umbraco.Core.Models } } - /// - /// Gets the enumeration of property groups for the entity. - /// TODO: remove this proxy method - /// - [IgnoreDataMember] - public IEnumerable PropertyGroups => ContentTypeBase.CompositionPropertyGroups; - - /// - /// Gets the numeration of property types for the entity. - /// TODO: remove this proxy method - /// - [IgnoreDataMember] - public IEnumerable PropertyTypes => ContentTypeBase.CompositionPropertyTypes; - #region Cultures // notes - common rules @@ -178,7 +186,7 @@ namespace Umbraco.Core.Models public string GetCultureName(string culture) { if (culture.IsNullOrWhiteSpace()) return Name; - if (!ContentTypeBase.VariesByCulture()) return null; + if (!ContentType.VariesByCulture()) return null; if (_cultureInfos == null) return null; return _cultureInfos.TryGetValue(culture, out var infos) ? infos.Name : null; } @@ -187,7 +195,7 @@ namespace Umbraco.Core.Models public DateTime? GetUpdateDate(string culture) { if (culture.IsNullOrWhiteSpace()) return null; - if (!ContentTypeBase.VariesByCulture()) return null; + if (!ContentType.VariesByCulture()) return null; if (_cultureInfos == null) return null; return _cultureInfos.TryGetValue(culture, out var infos) ? infos.Date : (DateTime?)null; } @@ -195,7 +203,7 @@ namespace Umbraco.Core.Models /// public void SetCultureName(string name, string culture) { - if (ContentTypeBase.VariesByCulture()) // set on variant content type + if (ContentType.VariesByCulture()) // set on variant content type { if (culture.IsNullOrWhiteSpace()) // invariant is ok { @@ -299,21 +307,10 @@ namespace Umbraco.Core.Models /// public void SetValue(string propertyTypeAlias, object value, string culture = null, string segment = null) { - if (Properties.Contains(propertyTypeAlias)) - { - Properties[propertyTypeAlias].SetValue(value, culture, segment); - //bump the culture to be flagged for updating - this.TouchCulture(culture); - return; - } - - var propertyType = PropertyTypes.FirstOrDefault(x => x.Alias.InvariantEquals(propertyTypeAlias)); - if (propertyType == null) + if (!Properties.TryGetValue(propertyTypeAlias, out var property)) throw new InvalidOperationException($"No PropertyType exists with the supplied alias \"{propertyTypeAlias}\"."); - var property = propertyType.CreateProperty(); property.SetValue(value, culture, segment); - Properties.Add(property); //bump the culture to be flagged for updating this.TouchCulture(culture); @@ -402,19 +399,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 +426,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; } @@ -478,6 +475,9 @@ namespace Umbraco.Core.Models var clonedContent = (ContentBase)clone; + //need to manually clone this since it's not settable + clonedContent.ContentType = ContentType; + //if culture infos exist then deal with event bindings if (clonedContent._cultureInfos != null) { diff --git a/src/Umbraco.Core/Models/ContentRepositoryExtensions.cs b/src/Umbraco.Core/Models/ContentRepositoryExtensions.cs index ca9bf57902..27678c047c 100644 --- a/src/Umbraco.Core/Models/ContentRepositoryExtensions.cs +++ b/src/Umbraco.Core/Models/ContentRepositoryExtensions.cs @@ -20,7 +20,7 @@ namespace Umbraco.Core.Models return Array.Empty(); 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); diff --git a/src/Umbraco.Core/Models/ContentType.cs b/src/Umbraco.Core/Models/ContentType.cs index 61fabe6fb0..63c758611a 100644 --- a/src/Umbraco.Core/Models/ContentType.cs +++ b/src/Umbraco.Core/Models/ContentType.cs @@ -41,6 +41,9 @@ namespace Umbraco.Core.Models _allowedTemplates = new List(); } + /// + public override ISimpleContentType ToSimple() => new SimpleContentType(this); + /// public override bool IsPublishing => IsPublishingConst; @@ -97,8 +100,8 @@ namespace Umbraco.Core.Models /// True if AllowedTemplates contains the templateId else False public bool IsAllowedTemplate(int templateId) { - return AllowedTemplates == null - ? false + return AllowedTemplates == null + ? false : AllowedTemplates.Any(t => t.Id == templateId); } diff --git a/src/Umbraco.Core/Models/ContentTypeBase.cs b/src/Umbraco.Core/Models/ContentTypeBase.cs index 2aa114a88f..320f667e07 100644 --- a/src/Umbraco.Core/Models/ContentTypeBase.cs +++ b/src/Umbraco.Core/Models/ContentTypeBase.cs @@ -67,6 +67,8 @@ namespace Umbraco.Core.Models _variations = ContentVariation.Nothing; } + public abstract ISimpleContentType ToSimple(); + /// /// Gets a value indicating whether the content type is publishing. /// diff --git a/src/Umbraco.Core/Models/IContent.cs b/src/Umbraco.Core/Models/IContent.cs index e953bef1eb..6990a7f7da 100644 --- a/src/Umbraco.Core/Models/IContent.cs +++ b/src/Umbraco.Core/Models/IContent.cs @@ -66,11 +66,6 @@ namespace Umbraco.Core.Models /// DateTime? PublishDate { get; set; } - /// - /// Gets the content type of this content. - /// - ISimpleContentType ContentType { get; } - /// /// Gets a value indicating whether a culture is published. /// diff --git a/src/Umbraco.Core/Models/IContentBase.cs b/src/Umbraco.Core/Models/IContentBase.cs index 1ebbfa1d49..0f660181fb 100644 --- a/src/Umbraco.Core/Models/IContentBase.cs +++ b/src/Umbraco.Core/Models/IContentBase.cs @@ -18,6 +18,11 @@ namespace Umbraco.Core.Models /// int ContentTypeId { get; } + /// + /// Gets the content type of this content. + /// + ISimpleContentType ContentType { get; } + /// /// Gets the identifier of the writer. /// @@ -58,7 +63,7 @@ namespace Umbraco.Core.Models /// culture name, which must be get or set via the property. /// ContentCultureInfosCollection CultureInfos { get; set; } - + /// /// Gets the available cultures. /// @@ -95,18 +100,6 @@ namespace Umbraco.Core.Models /// Properties are loaded as part of the Content object graph PropertyCollection Properties { get; set; } - /// - /// List of PropertyGroups available on this Content object - /// - /// PropertyGroups are kind of lazy loaded as part of the object graph - IEnumerable PropertyGroups { get; } - - /// - /// List of PropertyTypes available on this Content object - /// - /// PropertyTypes are kind of lazy loaded as part of the object graph - IEnumerable PropertyTypes { get; } - /// /// Gets a value indicating whether the content entity has a property with the supplied alias. /// diff --git a/src/Umbraco.Core/Models/IContentTypeBase.cs b/src/Umbraco.Core/Models/IContentTypeBase.cs index aea84d9767..215c8532c1 100644 --- a/src/Umbraco.Core/Models/IContentTypeBase.cs +++ b/src/Umbraco.Core/Models/IContentTypeBase.cs @@ -159,5 +159,10 @@ namespace Umbraco.Core.Models /// Name of the PropertyGroup to move the PropertyType to /// bool MovePropertyType(string propertyTypeAlias, string propertyGroupName); + + /// + /// Gets an corresponding to this content type. + /// + ISimpleContentType ToSimple(); } } diff --git a/src/Umbraco.Core/Models/IMedia.cs b/src/Umbraco.Core/Models/IMedia.cs index cfb79bbf2c..75e94d66e7 100644 --- a/src/Umbraco.Core/Models/IMedia.cs +++ b/src/Umbraco.Core/Models/IMedia.cs @@ -1,27 +1,5 @@ -using Umbraco.Core.Persistence.Mappers; - -namespace Umbraco.Core.Models +namespace Umbraco.Core.Models { public interface IMedia : IContentBase - { - /// - /// Gets the ContentType used by this Media object - /// - IMediaType ContentType { get; } - - /// - /// Changes the for the current content object - /// - /// New ContentType for this content - /// Leaves PropertyTypes intact after change - void ChangeContentType(IMediaType contentType); - - /// - /// Changes the for the current content object and removes PropertyTypes, - /// which are not part of the new ContentType. - /// - /// New ContentType for this content - /// Boolean indicating whether to clear PropertyTypes upon change - void ChangeContentType(IMediaType contentType, bool clearProperties); - } + { } } diff --git a/src/Umbraco.Core/Models/IMember.cs b/src/Umbraco.Core/Models/IMember.cs index 15826f03f3..199d53b174 100644 --- a/src/Umbraco.Core/Models/IMember.cs +++ b/src/Umbraco.Core/Models/IMember.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using Umbraco.Core.Models.Entities; +using Umbraco.Core.Models.Entities; using Umbraco.Core.Models.Membership; namespace Umbraco.Core.Models @@ -11,10 +9,5 @@ namespace Umbraco.Core.Models /// String alias of the default ContentType /// string ContentTypeAlias { get; } - - /// - /// Gets the ContentType used by this content object - /// - IMemberType ContentType { get; } } } diff --git a/src/Umbraco.Core/Models/ISimpleContentType.cs b/src/Umbraco.Core/Models/ISimpleContentType.cs index 8c9413f934..740db8e73f 100644 --- a/src/Umbraco.Core/Models/ISimpleContentType.cs +++ b/src/Umbraco.Core/Models/ISimpleContentType.cs @@ -1,20 +1,20 @@ -namespace Umbraco.Core.Models +using Umbraco.Core.Models.Entities; + +namespace Umbraco.Core.Models { /// /// Represents a simplified view of a content type. /// - public interface ISimpleContentType + public interface ISimpleContentType : IUmbracoEntity { + new int Id { get; } + new string Name { get; } + /// /// Gets the alias of the content type. /// string Alias { get; } - /// - /// Gets the identifier of the content type. - /// - int Id { get; } - /// /// Gets the default template of the content type. /// @@ -35,11 +35,6 @@ /// bool IsContainer { get; } - /// - /// Gets the name of the content type. - /// - string Name { get; } - /// /// Gets a value indicating whether content of that type can be created at the root of the tree. /// diff --git a/src/Umbraco.Core/Models/Media.cs b/src/Umbraco.Core/Models/Media.cs index a0f3aa35de..002611c09c 100644 --- a/src/Umbraco.Core/Models/Media.cs +++ b/src/Umbraco.Core/Models/Media.cs @@ -10,8 +10,6 @@ namespace Umbraco.Core.Models [DataContract(IsReference = true)] public class Media : ContentBase, IMedia { - private IMediaType _contentType; - /// /// Constructor for creating a Media object /// @@ -31,9 +29,7 @@ namespace Umbraco.Core.Models /// Collection of properties public Media(string name, IMedia parent, IMediaType contentType, PropertyCollection properties) : base(name, parent, contentType, properties) - { - _contentType = contentType ?? throw new ArgumentNullException(nameof(contentType)); - } + { } /// /// Constructor for creating a Media object @@ -54,30 +50,16 @@ namespace Umbraco.Core.Models /// Collection of properties public Media(string name, int parentId, IMediaType contentType, PropertyCollection properties) : base(name, parentId, contentType, properties) - { - _contentType = contentType ?? throw new ArgumentNullException(nameof(contentType)); - } - - /// - /// Gets the ContentType used by this Media object - /// - [IgnoreDataMember] - public IMediaType ContentType => _contentType; + { } /// /// Changes the for the current Media object /// /// New MediaType for this Media /// Leaves PropertyTypes intact after change - public void ChangeContentType(IMediaType contentType) + internal void ChangeContentType(IMediaType contentType) { - ContentTypeId = contentType.Id; - _contentType = contentType; - ContentTypeBase = contentType; - Properties.EnsurePropertyTypes(PropertyTypes); - - Properties.CollectionChanged -= PropertiesChanged; // be sure not to double add - Properties.CollectionChanged += PropertiesChanged; + ChangeContentType(contentType, false); } /// @@ -86,33 +68,17 @@ namespace Umbraco.Core.Models /// /// New MediaType for this Media /// Boolean indicating whether to clear PropertyTypes upon change - public void ChangeContentType(IMediaType contentType, bool clearProperties) + internal void ChangeContentType(IMediaType contentType, bool clearProperties) { + ChangeContentType(new SimpleContentType(contentType)); + if (clearProperties) - { - ContentTypeId = contentType.Id; - _contentType = contentType; - ContentTypeBase = contentType; - Properties.EnsureCleanPropertyTypes(PropertyTypes); + Properties.EnsureCleanPropertyTypes(contentType.CompositionPropertyTypes); + else + Properties.EnsurePropertyTypes(contentType.CompositionPropertyTypes); - Properties.CollectionChanged -= PropertiesChanged; // be sure not to double add - Properties.CollectionChanged += PropertiesChanged; - return; - } - - ChangeContentType(contentType); - } - - /// - /// Changes the Trashed state of the content object - /// - /// Boolean indicating whether content is trashed (true) or not trashed (false) - /// - public void ChangeTrashedState(bool isTrashed, int parentId = -20) - { - Trashed = isTrashed; - //The Media Recycle Bin Id is -21 so we correct that here - ParentId = parentId == -20 ? -21 : parentId; + Properties.CollectionChanged -= PropertiesChanged; // be sure not to double add + Properties.CollectionChanged += PropertiesChanged; } } } diff --git a/src/Umbraco.Core/Models/MediaExtensions.cs b/src/Umbraco.Core/Models/MediaExtensions.cs index e281aaf5ab..1166698adb 100644 --- a/src/Umbraco.Core/Models/MediaExtensions.cs +++ b/src/Umbraco.Core/Models/MediaExtensions.cs @@ -15,20 +15,17 @@ namespace Umbraco.Core.Models /// public static string GetUrl(this IMedia media, string propertyAlias, ILogger logger) { - var propertyType = media.PropertyTypes.FirstOrDefault(x => x.Alias.InvariantEquals(propertyAlias)); - if (propertyType == null) return string.Empty; - - var val = media.Properties[propertyType]; - if (val == null) return string.Empty; + if (!media.Properties.TryGetValue(propertyAlias, out var property)) + return string.Empty; // TODO: would need to be adjusted to variations, when media become variants - var jsonString = val.GetValue() as string; - if (jsonString == null) return string.Empty; + if (!(property.GetValue() is string jsonString)) + return string.Empty; - if (propertyType.PropertyEditorAlias == Constants.PropertyEditors.Aliases.UploadField) + if (property.PropertyType.PropertyEditorAlias == Constants.PropertyEditors.Aliases.UploadField) return jsonString; - if (propertyType.PropertyEditorAlias == Constants.PropertyEditors.Aliases.ImageCropper) + if (property.PropertyType.PropertyEditorAlias == Constants.PropertyEditors.Aliases.ImageCropper) { if (jsonString.DetectIsJson() == false) return jsonString; diff --git a/src/Umbraco.Core/Models/MediaType.cs b/src/Umbraco.Core/Models/MediaType.cs index 83e1acfbc0..f7598b4965 100644 --- a/src/Umbraco.Core/Models/MediaType.cs +++ b/src/Umbraco.Core/Models/MediaType.cs @@ -41,6 +41,9 @@ namespace Umbraco.Core.Models { } + /// + public override ISimpleContentType ToSimple() => new SimpleContentType(this); + /// public override bool IsPublishing => IsPublishingConst; diff --git a/src/Umbraco.Core/Models/Member.cs b/src/Umbraco.Core/Models/Member.cs index 78d1cfafd5..0e91065d56 100644 --- a/src/Umbraco.Core/Models/Member.cs +++ b/src/Umbraco.Core/Models/Member.cs @@ -15,8 +15,6 @@ namespace Umbraco.Core.Models public class Member : ContentBase, IMember { private IDictionary _additionalData; - private IMemberType _contentType; - private readonly string _contentTypeAlias; private string _username; private string _email; private string _rawPasswordValue; @@ -29,8 +27,6 @@ namespace Umbraco.Core.Models public Member(IMemberType contentType) : base("", -1, contentType, new PropertyCollection()) { - _contentType = contentType ?? throw new ArgumentNullException(nameof(contentType)); - _contentTypeAlias = contentType.Alias; IsApproved = true; //this cannot be null but can be empty @@ -49,8 +45,6 @@ namespace Umbraco.Core.Models { if (string.IsNullOrWhiteSpace(name)) throw new ArgumentNullOrEmptyException(nameof(name)); - _contentType = contentType ?? throw new ArgumentNullException(nameof(contentType)); - _contentTypeAlias = contentType.Alias; IsApproved = true; //this cannot be null but can be empty @@ -73,8 +67,6 @@ namespace Umbraco.Core.Models if (string.IsNullOrWhiteSpace(name)) throw new ArgumentNullOrEmptyException(nameof(name)); if (string.IsNullOrWhiteSpace(username)) throw new ArgumentNullOrEmptyException(nameof(username)); - _contentType = contentType ?? throw new ArgumentNullException(nameof(contentType)); - _contentTypeAlias = contentType.Alias; _email = email; _username = username; IsApproved = isApproved; @@ -96,9 +88,6 @@ namespace Umbraco.Core.Models public Member(string name, string email, string username, string rawPasswordValue, IMemberType contentType) : base(name, -1, contentType, new PropertyCollection()) { - _contentType = contentType ?? throw new ArgumentNullException(nameof(contentType)); - _contentTypeAlias = contentType.Alias; - _email = email; _username = username; _rawPasswordValue = rawPasswordValue; @@ -119,8 +108,6 @@ namespace Umbraco.Core.Models public Member(string name, string email, string username, string rawPasswordValue, IMemberType contentType, bool isApproved) : base(name, -1, contentType, new PropertyCollection()) { - _contentType = contentType ?? throw new ArgumentNullException(nameof(contentType)); - _contentTypeAlias = contentType.Alias; _email = email; _username = username; _rawPasswordValue = rawPasswordValue; @@ -473,7 +460,7 @@ namespace Umbraco.Core.Models /// String alias of the default ContentType /// [DataMember] - public virtual string ContentTypeAlias => _contentTypeAlias; + public virtual string ContentTypeAlias => ContentType.Alias; /// /// User key from the Provider. @@ -504,12 +491,6 @@ namespace Umbraco.Core.Models ProviderUserKey = Key; } - /// - /// Gets the ContentType used by this content object - /// - [IgnoreDataMember] - public IMemberType ContentType => _contentType; - /* Internal experiment - only used for mapping queries. * Adding these to have first level properties instead of the Properties collection. */ @@ -575,17 +556,6 @@ namespace Umbraco.Core.Models return true; } - protected override void PerformDeepClone(object clone) - { - base.PerformDeepClone(clone); - - var clonedEntity = (Member)clone; - - //need to manually clone this since it's not settable - clonedEntity._contentType = (IMemberType)ContentType.DeepClone(); - - } - /// [DataMember] [DoNotClone] diff --git a/src/Umbraco.Core/Models/MemberType.cs b/src/Umbraco.Core/Models/MemberType.cs index a6c1518446..e85aa0e15e 100644 --- a/src/Umbraco.Core/Models/MemberType.cs +++ b/src/Umbraco.Core/Models/MemberType.cs @@ -31,6 +31,9 @@ namespace Umbraco.Core.Models MemberTypePropertyTypes = new Dictionary(); } + /// + public override ISimpleContentType ToSimple() => new SimpleContentType(this); + /// public override bool IsPublishing => IsPublishingConst; diff --git a/src/Umbraco.Core/Models/PropertyCollection.cs b/src/Umbraco.Core/Models/PropertyCollection.cs index 5e71fe9f65..977600a2f7 100644 --- a/src/Umbraco.Core/Models/PropertyCollection.cs +++ b/src/Umbraco.Core/Models/PropertyCollection.cs @@ -93,7 +93,7 @@ namespace Umbraco.Core.Models } /// - /// Adds a property. + /// Adds or updates a property. /// internal new void Add(Property property) { diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedContentTypeFactory.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedContentTypeFactory.cs index 8a44a7a9b4..2ca3593b55 100644 --- a/src/Umbraco.Core/Models/PublishedContent/PublishedContentTypeFactory.cs +++ b/src/Umbraco.Core/Models/PublishedContent/PublishedContentTypeFactory.cs @@ -87,8 +87,20 @@ namespace Umbraco.Core.Models.PublishedContent { lock (_publishedDataTypesLocker) { - var dataTypes = _dataTypeService.GetAll(ids); - _publishedDataTypes = dataTypes.ToDictionary(x => x.Id, CreatePublishedDataType); + if (_publishedDataTypes == null) + { + var dataTypes = _dataTypeService.GetAll(); + _publishedDataTypes = dataTypes.ToDictionary(x => x.Id, CreatePublishedDataType); + } + else + { + foreach (var id in ids) + _publishedDataTypes.Remove(id); + + var dataTypes = _dataTypeService.GetAll(ids); + foreach (var dataType in dataTypes) + _publishedDataTypes[dataType.Id] = CreatePublishedDataType(dataType); + } } } diff --git a/src/Umbraco.Core/Models/SimpleContentType.cs b/src/Umbraco.Core/Models/SimpleContentType.cs index be1f87fcda..5c81017ec8 100644 --- a/src/Umbraco.Core/Models/SimpleContentType.cs +++ b/src/Umbraco.Core/Models/SimpleContentType.cs @@ -1,4 +1,8 @@ -namespace Umbraco.Core.Models +using System; +using System.Collections.Generic; +using Umbraco.Core.Models.Entities; + +namespace Umbraco.Core.Models { /// /// Implements . @@ -9,14 +13,34 @@ /// Initializes a new instance of the class. /// public SimpleContentType(IContentType contentType) + : this((IContentTypeBase)contentType) { + DefaultTemplate = contentType.DefaultTemplate; + } + + /// + /// Initializes a new instance of the class. + /// + public SimpleContentType(IMediaType mediaType) + : this((IContentTypeBase)mediaType) + { } + + /// + /// Initializes a new instance of the class. + /// + public SimpleContentType(IMemberType memberType) + : this((IContentTypeBase)memberType) + { } + + private SimpleContentType(IContentTypeBase contentType) + { + if (contentType == null) throw new ArgumentNullException(nameof(contentType)); + Id = contentType.Id; Alias = contentType.Alias; - DefaultTemplate = contentType.DefaultTemplate; Variations = contentType.Variations; Icon = contentType.Icon; IsContainer = contentType.IsContainer; - Icon = contentType.Icon; Name = contentType.Name; AllowedAsRoot = contentType.AllowedAsRoot; IsElement = contentType.IsElement; @@ -25,8 +49,7 @@ /// public string Alias { get; } - /// - public int Id { get; } + public int Id { get; } /// public ITemplate DefaultTemplate { get; } @@ -39,8 +62,7 @@ /// public bool IsContainer { get; } - - /// + public string Name { get; } /// @@ -80,5 +102,33 @@ return ((Alias != null ? Alias.GetHashCode() : 0) * 397) ^ Id; } } + + // we have to have all this, because we're an IUmbracoEntity, because that is + // required by the query expression visitor / SimpleContentTypeMapper + + string ITreeEntity.Name { get => this.Name; set => throw new NotImplementedException(); } + int IEntity.Id { get => this.Id; set => throw new NotImplementedException(); } + bool IEntity.HasIdentity => this.Id != default; + int ITreeEntity.CreatorId { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + int ITreeEntity.ParentId { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + int ITreeEntity.Level { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + string ITreeEntity.Path { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + int ITreeEntity.SortOrder { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + bool ITreeEntity.Trashed => throw new NotImplementedException(); + Guid IEntity.Key { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + DateTime IEntity.CreateDate { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + DateTime IEntity.UpdateDate { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + DateTime? IEntity.DeleteDate { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + void ITreeEntity.SetParent(ITreeEntity parent) => throw new NotImplementedException(); + object IDeepCloneable.DeepClone() => throw new NotImplementedException(); + bool IRememberBeingDirty.WasDirty() => throw new NotImplementedException(); + bool IRememberBeingDirty.WasPropertyDirty(string propertyName) => throw new NotImplementedException(); + void IRememberBeingDirty.ResetWereDirtyProperties() => throw new NotImplementedException(); + void IRememberBeingDirty.ResetDirtyProperties(bool rememberDirty) => throw new NotImplementedException(); + IEnumerable IRememberBeingDirty.GetWereDirtyProperties() => throw new NotImplementedException(); + bool ICanBeDirty.IsDirty() => throw new NotImplementedException(); + bool ICanBeDirty.IsPropertyDirty(string propName) => throw new NotImplementedException(); + IEnumerable ICanBeDirty.GetDirtyProperties() => throw new NotImplementedException(); + void ICanBeDirty.ResetDirtyProperties() => throw new NotImplementedException(); } } diff --git a/src/Umbraco.Core/Persistence/DbConnectionExtensions.cs b/src/Umbraco.Core/Persistence/DbConnectionExtensions.cs index 20586cb6f4..835f76f9f9 100644 --- a/src/Umbraco.Core/Persistence/DbConnectionExtensions.cs +++ b/src/Umbraco.Core/Persistence/DbConnectionExtensions.cs @@ -76,7 +76,7 @@ namespace Umbraco.Core.Persistence do { c = unwrapped; - if (unwrapped is ProfiledDbConnection profiled) unwrapped = profiled.InnerConnection; + if (unwrapped is ProfiledDbConnection profiled) unwrapped = profiled.WrappedConnection; if (unwrapped is RetryDbConnection retrying) unwrapped = retrying.Inner; } while (c != unwrapped); diff --git a/src/Umbraco.Core/Persistence/Factories/DataTypeFactory.cs b/src/Umbraco.Core/Persistence/Factories/DataTypeFactory.cs index 01b0e59a1d..5a677d219c 100644 --- a/src/Umbraco.Core/Persistence/Factories/DataTypeFactory.cs +++ b/src/Umbraco.Core/Persistence/Factories/DataTypeFactory.cs @@ -2,6 +2,7 @@ using System.Reflection; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; +using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Persistence.Dtos; using Umbraco.Core.PropertyEditors; @@ -10,10 +11,14 @@ namespace Umbraco.Core.Persistence.Factories { internal static class DataTypeFactory { - public static IDataType BuildEntity(DataTypeDto dto, PropertyEditorCollection editors) + public static IDataType BuildEntity(DataTypeDto dto, PropertyEditorCollection editors, ILogger logger) { if (!editors.TryGet(dto.EditorAlias, out var editor)) - throw new InvalidOperationException($"Could not find an editor with alias \"{dto.EditorAlias}\"."); + { + logger.Warn(typeof(DataTypeFactory), "Could not find an editor with alias {dto.EditorAlias}, converting to label", dto.EditorAlias); + //convert to label + editor = new LabelPropertyEditor(logger); + } var dataType = new DataType(editor); diff --git a/src/Umbraco.Core/Persistence/Mappers/MapperCollectionBuilder.cs b/src/Umbraco.Core/Persistence/Mappers/MapperCollectionBuilder.cs index 80819933f5..e20f7c1911 100644 --- a/src/Umbraco.Core/Persistence/Mappers/MapperCollectionBuilder.cs +++ b/src/Umbraco.Core/Persistence/Mappers/MapperCollectionBuilder.cs @@ -25,6 +25,7 @@ namespace Umbraco.Core.Persistence.Mappers Add(); Add(); Add(); + Add(); Add(); Add(); Add(); diff --git a/src/Umbraco.Core/Persistence/Mappers/SimpleContentTypeMapper.cs b/src/Umbraco.Core/Persistence/Mappers/SimpleContentTypeMapper.cs new file mode 100644 index 0000000000..3ad975defb --- /dev/null +++ b/src/Umbraco.Core/Persistence/Mappers/SimpleContentTypeMapper.cs @@ -0,0 +1,38 @@ +using System.Collections.Concurrent; +using Umbraco.Core.Models; +using Umbraco.Core.Persistence.Dtos; + +namespace Umbraco.Core.Persistence.Mappers +{ + [MapperFor(typeof(ISimpleContentType))] + [MapperFor(typeof(SimpleContentType))] + public sealed class SimpleContentTypeMapper : BaseMapper + { + private static readonly ConcurrentDictionary PropertyInfoCacheInstance = new ConcurrentDictionary(); + + internal override ConcurrentDictionary PropertyInfoCache => PropertyInfoCacheInstance; + + protected override void BuildMap() + { + if (PropertyInfoCache.IsEmpty == false) return; + + CacheMap(src => src.Id, dto => dto.NodeId); + CacheMap(src => src.CreateDate, dto => dto.CreateDate); + CacheMap(src => src.Level, dto => dto.Level); + CacheMap(src => src.ParentId, dto => dto.ParentId); + CacheMap(src => src.Path, dto => dto.Path); + CacheMap(src => src.SortOrder, dto => dto.SortOrder); + CacheMap(src => src.Name, dto => dto.Text); + CacheMap(src => src.Trashed, dto => dto.Trashed); + CacheMap(src => src.Key, dto => dto.UniqueId); + CacheMap(src => src.CreatorId, dto => dto.UserId); + CacheMap(src => src.Alias, dto => dto.Alias); + CacheMap(src => src.AllowedAsRoot, dto => dto.AllowAtRoot); + CacheMap(src => src.Description, dto => dto.Description); + CacheMap(src => src.Icon, dto => dto.Icon); + CacheMap(src => src.IsContainer, dto => dto.IsContainer); + CacheMap(src => src.IsElement, dto => dto.IsElement); + CacheMap(src => src.Thumbnail, dto => dto.Thumbnail); + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/NPocoDatabaseExtensions.cs b/src/Umbraco.Core/Persistence/NPocoDatabaseExtensions.cs index 248f91284f..bb4c60a0df 100644 --- a/src/Umbraco.Core/Persistence/NPocoDatabaseExtensions.cs +++ b/src/Umbraco.Core/Persistence/NPocoDatabaseExtensions.cs @@ -148,7 +148,7 @@ namespace Umbraco.Core.Persistence where TConnection : class, IDbConnection { var profiled = connection as ProfiledDbConnection; - return profiled == null ? connection as TConnection : profiled.InnerConnection as TConnection; + return profiled == null ? connection as TConnection : profiled.WrappedConnection as TConnection; } /// diff --git a/src/Umbraco.Core/Persistence/Querying/ModelToSqlExpressionVisitor.cs b/src/Umbraco.Core/Persistence/Querying/ModelToSqlExpressionVisitor.cs index a353f01f5b..bf26523d9e 100644 --- a/src/Umbraco.Core/Persistence/Querying/ModelToSqlExpressionVisitor.cs +++ b/src/Umbraco.Core/Persistence/Querying/ModelToSqlExpressionVisitor.cs @@ -60,7 +60,7 @@ namespace Umbraco.Core.Persistence.Querying if (m.Expression != null && m.Expression.Type != typeof(T) - && TypeHelper.IsTypeAssignableFrom(m.Expression.Type) + && TypeHelper.IsTypeAssignableFrom(m.Expression.Type) //TODO: Could this just be `IEntity` ? why does it need to be IUmbracoEntity, we aren't even using the reference to that below && EndsWithConstant(m) == false) { //if this is the case, it means we have a sub expression / nested property access, such as: x.ContentType.Alias == "Test"; diff --git a/src/Umbraco.Core/Persistence/Repositories/IDocumentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/IDocumentRepository.cs index d49c92f1bf..fc5382499f 100644 --- a/src/Umbraco.Core/Persistence/Repositories/IDocumentRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/IDocumentRepository.cs @@ -7,8 +7,6 @@ namespace Umbraco.Core.Persistence.Repositories { public interface IDocumentRepository : IContentRepository, IReadRepository { - - /// /// Clears the publishing schedule for all entries having an a date before (lower than, or equal to) a specified date. /// diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/DataTypeRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/DataTypeRepository.cs index 3de9e3c99b..02ba4d1c13 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/DataTypeRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/DataTypeRepository.cs @@ -54,7 +54,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement } var dtos = Database.Fetch(dataTypeSql); - return dtos.Select(x => DataTypeFactory.BuildEntity(x, _editors.Value)).ToArray(); + return dtos.Select(x => DataTypeFactory.BuildEntity(x, _editors.Value, Logger)).ToArray(); } protected override IEnumerable PerformGetByQuery(IQuery query) @@ -65,7 +65,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement var dtos = Database.Fetch(sql); - return dtos.Select(x => DataTypeFactory.BuildEntity(x, _editors.Value)).ToArray(); + return dtos.Select(x => DataTypeFactory.BuildEntity(x, _editors.Value, Logger)).ToArray(); } #endregion diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs index 04af52047c..d8e6fd2c0e 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs @@ -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(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 SelectStatement(NPocoSqlExtensions.SqlRef 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(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 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> contentVariations, IDictionary> 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)); } diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/EntityRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/EntityRepository.cs index fc7f36b1a3..b4c0e51c22 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/EntityRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/EntityRepository.cs @@ -83,7 +83,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement } var entities = dtos.Select(x => BuildEntity(isContent, isMedia, x)).ToArray(); - + if (isContent) BuildVariants(entities.Cast()); @@ -211,7 +211,8 @@ namespace Umbraco.Core.Persistence.Repositories.Implement private IEnumerable PerformGetAllPaths(Guid objectType, Action> filter = null) { - var sql = Sql().Select(x => x.NodeId, x => x.Path).From().Where(x => x.NodeObjectType == objectType); + // NodeId is named Id on TreeEntityPath = use an alias + var sql = Sql().Select(x => Alias(x.NodeId, nameof(TreeEntityPath.Id)), x => x.Path).From().Where(x => x.NodeObjectType == objectType); filter?.Invoke(sql); return Database.Fetch(sql); } @@ -418,7 +419,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement .InnerJoin().On((left, right) => left.DataTypeId == right.NodeId) .WhereIn(x => x.VersionId, versionIds) .OrderBy(x => x.VersionId); - } + } // gets the base SELECT + FROM [+ filter] sql // always from the 'current' content version diff --git a/src/Umbraco.Core/Services/ContentServiceExtensions.cs b/src/Umbraco.Core/Services/ContentServiceExtensions.cs index 03a790d4b8..4d673fc902 100644 --- a/src/Umbraco.Core/Services/ContentServiceExtensions.cs +++ b/src/Umbraco.Core/Services/ContentServiceExtensions.cs @@ -34,7 +34,7 @@ namespace Umbraco.Core.Services /// /// /// - public static IContent CreateContent(this IContentService contentService, string name, Udi parentId, string mediaTypeAlias, int userId = 0) + public static IContent CreateContent(this IContentService contentService, string name, Udi parentId, string mediaTypeAlias, int userId = Constants.Security.SuperUserId) { var guidUdi = parentId as GuidUdi; if (guidUdi == null) diff --git a/src/Umbraco.Core/Services/IContentService.cs b/src/Umbraco.Core/Services/IContentService.cs index 600921ee78..b2fce8f3e6 100644 --- a/src/Umbraco.Core/Services/IContentService.cs +++ b/src/Umbraco.Core/Services/IContentService.cs @@ -32,27 +32,27 @@ namespace Umbraco.Core.Services /// /// Saves a blueprint. /// - void SaveBlueprint(IContent content, int userId = 0); + void SaveBlueprint(IContent content, int userId = Constants.Security.SuperUserId); /// /// Deletes a blueprint. /// - void DeleteBlueprint(IContent content, int userId = 0); + void DeleteBlueprint(IContent content, int userId = Constants.Security.SuperUserId); /// /// Creates a new content item from a blueprint. /// - IContent CreateContentFromBlueprint(IContent blueprint, string name, int userId = 0); + IContent CreateContentFromBlueprint(IContent blueprint, string name, int userId = Constants.Security.SuperUserId); /// /// Deletes blueprints for a content type. /// - void DeleteBlueprintsOfType(int contentTypeId, int userId = 0); + void DeleteBlueprintsOfType(int contentTypeId, int userId = Constants.Security.SuperUserId); /// /// Deletes blueprints for content types. /// - void DeleteBlueprintsOfTypes(IEnumerable contentTypeIds, int userId = 0); + void DeleteBlueprintsOfTypes(IEnumerable contentTypeIds, int userId = Constants.Security.SuperUserId); #endregion @@ -237,13 +237,13 @@ namespace Umbraco.Core.Services /// /// Saves a document. /// - OperationResult Save(IContent content, int userId = 0, bool raiseEvents = true); + OperationResult Save(IContent content, int userId = Constants.Security.SuperUserId, bool raiseEvents = true); /// /// Saves documents. /// // TODO: why only 1 result not 1 per content?! - OperationResult Save(IEnumerable contents, int userId = 0, bool raiseEvents = true); + OperationResult Save(IEnumerable contents, int userId = Constants.Security.SuperUserId, bool raiseEvents = true); /// /// Deletes a document. @@ -252,7 +252,7 @@ namespace Umbraco.Core.Services /// This method will also delete associated media files, child content and possibly associated domains. /// This method entirely clears the content from the database. /// - OperationResult Delete(IContent content, int userId = 0); + OperationResult Delete(IContent content, int userId = Constants.Security.SuperUserId); /// /// Deletes all documents of a given document type. @@ -261,7 +261,7 @@ namespace Umbraco.Core.Services /// All non-deleted descendants of the deleted documents are moved to the recycle bin. /// This operation is potentially dangerous and expensive. /// - void DeleteOfType(int documentTypeId, int userId = 0); + void DeleteOfType(int documentTypeId, int userId = Constants.Security.SuperUserId); /// /// Deletes all documents of given document types. @@ -270,17 +270,17 @@ namespace Umbraco.Core.Services /// All non-deleted descendants of the deleted documents are moved to the recycle bin. /// This operation is potentially dangerous and expensive. /// - void DeleteOfTypes(IEnumerable contentTypeIds, int userId = 0); + void DeleteOfTypes(IEnumerable contentTypeIds, int userId = Constants.Security.SuperUserId); /// /// Deletes versions of a document prior to a given date. /// - void DeleteVersions(int id, DateTime date, int userId = 0); + void DeleteVersions(int id, DateTime date, int userId = Constants.Security.SuperUserId); /// /// Deletes a version of a document. /// - void DeleteVersion(int id, int versionId, bool deletePriorVersions, int userId = 0); + void DeleteVersion(int id, int versionId, bool deletePriorVersions, int userId = Constants.Security.SuperUserId); #endregion @@ -289,7 +289,7 @@ namespace Umbraco.Core.Services /// /// Moves a document under a new parent. /// - void Move(IContent content, int parentId, int userId = 0); + void Move(IContent content, int parentId, int userId = Constants.Security.SuperUserId); /// /// Copies a document. @@ -297,7 +297,7 @@ namespace Umbraco.Core.Services /// /// Recursively copies all children. /// - IContent Copy(IContent content, int parentId, bool relateToOriginal, int userId = 0); + IContent Copy(IContent content, int parentId, bool relateToOriginal, int userId = Constants.Security.SuperUserId); /// /// Copies a document. @@ -305,12 +305,12 @@ namespace Umbraco.Core.Services /// /// Optionally recursively copies all children. /// - IContent Copy(IContent content, int parentId, bool relateToOriginal, bool recursive, int userId = 0); + IContent Copy(IContent content, int parentId, bool relateToOriginal, bool recursive, int userId = Constants.Security.SuperUserId); /// /// Moves a document to the recycle bin. /// - OperationResult MoveToRecycleBin(IContent content, int userId = 0); + OperationResult MoveToRecycleBin(IContent content, int userId = Constants.Security.SuperUserId); /// /// Empties the recycle bin. @@ -320,12 +320,12 @@ namespace Umbraco.Core.Services /// /// Sorts documents. /// - OperationResult Sort(IEnumerable items, int userId = 0, bool raiseEvents = true); + OperationResult Sort(IEnumerable items, int userId = Constants.Security.SuperUserId, bool raiseEvents = true); /// /// Sorts documents. /// - OperationResult Sort(IEnumerable ids, int userId = 0, bool raiseEvents = true); + OperationResult Sort(IEnumerable ids, int userId = Constants.Security.SuperUserId, bool raiseEvents = true); #endregion @@ -341,12 +341,11 @@ namespace Umbraco.Core.Services /// 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. /// - /// - /// - /// - /// - /// - PublishResult SaveAndPublish(IContent content, string culture = "*", int userId = 0, bool raiseEvents = true); + /// The document to publish. + /// The culture to publish. + /// The identifier of the user performing the action. + /// A value indicating whether to raise events. + PublishResult SaveAndPublish(IContent content, string culture = "*", int userId = Constants.Security.SuperUserId, bool raiseEvents = true); /// /// Saves and publishes a document. @@ -356,12 +355,11 @@ namespace Umbraco.Core.Services /// When a culture is being published, it includes all varying values along with all invariant values. /// The document is *always* saved, even when publishing fails. /// - /// + /// The document to publish. /// The cultures to publish. - /// - /// - /// - PublishResult SaveAndPublish(IContent content, string[] cultures, int userId = 0, bool raiseEvents = true); + /// The identifier of the user performing the action. + /// A value indicating whether to raise events. + PublishResult SaveAndPublish(IContent content, string[] cultures, int userId = Constants.Security.SuperUserId, bool raiseEvents = true); /// /// Saves and publishes a document branch. @@ -377,7 +375,7 @@ namespace Umbraco.Core.Services /// only those documents that are already published, are republished. When true, all documents are /// published. The root of the branch is always published, regardless of . /// - IEnumerable SaveAndPublishBranch(IContent content, bool force, string culture = "*", int userId = 0); + IEnumerable SaveAndPublishBranch(IContent content, bool force, string culture = "*", int userId = Constants.Security.SuperUserId); /// /// Saves and publishes a document branch. @@ -391,7 +389,7 @@ namespace Umbraco.Core.Services /// only those documents that are already published, are republished. When true, all documents are /// published. The root of the branch is always published, regardless of . /// - IEnumerable SaveAndPublishBranch(IContent content, bool force, string[] cultures, int userId = 0); + IEnumerable SaveAndPublishBranch(IContent content, bool force, string[] cultures, int userId = Constants.Security.SuperUserId); /// /// Saves and publishes a document branch. @@ -416,7 +414,7 @@ namespace Umbraco.Core.Services IEnumerable SaveAndPublishBranch(IContent content, bool force, Func> shouldPublish, Func, bool> publishCultures, - int userId = 0); + int userId = Constants.Security.SuperUserId); /// /// Unpublishes a document. @@ -428,7 +426,7 @@ namespace Umbraco.Core.Services /// 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. /// - PublishResult Unpublish(IContent content, string culture = "*", int userId = 0); + PublishResult Unpublish(IContent content, string culture = "*", int userId = Constants.Security.SuperUserId); /// /// Gets a value indicating whether a document is path-publishable. @@ -445,7 +443,7 @@ namespace Umbraco.Core.Services /// /// Saves a document and raises the "sent to publication" events. /// - bool SendToPublication(IContent content, int userId = 0); + bool SendToPublication(IContent content, int userId = Constants.Security.SuperUserId); /// /// Publishes and unpublishes scheduled documents. @@ -480,27 +478,27 @@ namespace Umbraco.Core.Services /// /// Creates a document. /// - IContent Create(string name, Guid parentId, string documentTypeAlias, int userId = 0); + IContent Create(string name, Guid parentId, string documentTypeAlias, int userId = Constants.Security.SuperUserId); /// /// Creates a document. /// - IContent Create(string name, int parentId, string documentTypeAlias, int userId = 0); + IContent Create(string name, int parentId, string documentTypeAlias, int userId = Constants.Security.SuperUserId); /// /// Creates a document. /// - IContent Create(string name, IContent parent, string documentTypeAlias, int userId = 0); + IContent Create(string name, IContent parent, string documentTypeAlias, int userId = Constants.Security.SuperUserId); /// /// Creates and saves a document. /// - IContent CreateAndSave(string name, int parentId, string contentTypeAlias, int userId = 0); + IContent CreateAndSave(string name, int parentId, string contentTypeAlias, int userId = Constants.Security.SuperUserId); /// /// Creates and saves a document. /// - IContent CreateAndSave(string name, IContent parent, string contentTypeAlias, int userId = 0); + IContent CreateAndSave(string name, IContent parent, string contentTypeAlias, int userId = Constants.Security.SuperUserId); #endregion @@ -516,7 +514,7 @@ namespace Umbraco.Core.Services /// /// When no culture is specified, all cultures are rolled back. /// - OperationResult Rollback(int id, int versionId, string culture = "*", int userId = 0); + OperationResult Rollback(int id, int versionId, string culture = "*", int userId = Constants.Security.SuperUserId); #endregion } diff --git a/src/Umbraco.Core/Services/IContentTypeBaseServiceProvider.cs b/src/Umbraco.Core/Services/IContentTypeBaseServiceProvider.cs index 70327e7baf..d0146ce043 100644 --- a/src/Umbraco.Core/Services/IContentTypeBaseServiceProvider.cs +++ b/src/Umbraco.Core/Services/IContentTypeBaseServiceProvider.cs @@ -18,5 +18,10 @@ namespace Umbraco.Core.Services /// to retrieve the content / media / whatever type as . /// IContentTypeBaseService For(IContentBase contentBase); + + /// + /// Gets the content type of an object. + /// + IContentTypeComposition GetContentTypeOf(IContentBase contentBase); } } diff --git a/src/Umbraco.Core/Services/IContentTypeServiceBase.cs b/src/Umbraco.Core/Services/IContentTypeServiceBase.cs index 8fa77e4836..b86494adb5 100644 --- a/src/Umbraco.Core/Services/IContentTypeServiceBase.cs +++ b/src/Umbraco.Core/Services/IContentTypeServiceBase.cs @@ -47,11 +47,11 @@ namespace Umbraco.Core.Services IEnumerable GetChildren(int id); bool HasChildren(int id); - void Save(TItem item, int userId = 0); - void Save(IEnumerable items, int userId = 0); + void Save(TItem item, int userId = Constants.Security.SuperUserId); + void Save(IEnumerable items, int userId = Constants.Security.SuperUserId); - void Delete(TItem item, int userId = 0); - void Delete(IEnumerable item, int userId = 0); + void Delete(TItem item, int userId = Constants.Security.SuperUserId); + void Delete(IEnumerable item, int userId = Constants.Security.SuperUserId); Attempt ValidateComposition(TItem compo); @@ -63,15 +63,15 @@ namespace Umbraco.Core.Services /// bool HasContainerInPath(string contentPath); - Attempt> CreateContainer(int parentContainerId, string name, int userId = 0); - Attempt SaveContainer(EntityContainer container, int userId = 0); + Attempt> CreateContainer(int parentContainerId, string name, int userId = Constants.Security.SuperUserId); + Attempt SaveContainer(EntityContainer container, int userId = Constants.Security.SuperUserId); EntityContainer GetContainer(int containerId); EntityContainer GetContainer(Guid containerId); IEnumerable GetContainers(int[] containerIds); IEnumerable GetContainers(TItem contentType); IEnumerable GetContainers(string folderName, int level); - Attempt DeleteContainer(int containerId, int userId = 0); - Attempt> RenameContainer(int id, string name, int userId = 0); + Attempt DeleteContainer(int containerId, int userId = Constants.Security.SuperUserId); + Attempt> RenameContainer(int id, string name, int userId = Constants.Security.SuperUserId); Attempt> Move(TItem moving, int containerId); Attempt> Copy(TItem copying, int containerId); diff --git a/src/Umbraco.Core/Services/IDataTypeService.cs b/src/Umbraco.Core/Services/IDataTypeService.cs index 537c0e629f..3dc530e250 100644 --- a/src/Umbraco.Core/Services/IDataTypeService.cs +++ b/src/Umbraco.Core/Services/IDataTypeService.cs @@ -9,15 +9,15 @@ namespace Umbraco.Core.Services /// public interface IDataTypeService : IService { - Attempt> CreateContainer(int parentId, string name, int userId = 0); - Attempt SaveContainer(EntityContainer container, int userId = 0); + Attempt> CreateContainer(int parentId, string name, int userId = Constants.Security.SuperUserId); + Attempt SaveContainer(EntityContainer container, int userId = Constants.Security.SuperUserId); EntityContainer GetContainer(int containerId); EntityContainer GetContainer(Guid containerId); IEnumerable GetContainers(string folderName, int level); IEnumerable GetContainers(IDataType dataType); IEnumerable GetContainers(int[] containerIds); - Attempt DeleteContainer(int containerId, int userId = 0); - Attempt> RenameContainer(int id, string name, int userId = 0); + Attempt DeleteContainer(int containerId, int userId = Constants.Security.SuperUserId); + Attempt> RenameContainer(int id, string name, int userId = Constants.Security.SuperUserId); /// /// Gets a by its Name @@ -52,14 +52,14 @@ namespace Umbraco.Core.Services /// /// to save /// Id of the user issuing the save - void Save(IDataType dataType, int userId = 0); + void Save(IDataType dataType, int userId = Constants.Security.SuperUserId); /// /// Saves a collection of /// /// to save /// Id of the user issuing the save - void Save(IEnumerable dataTypeDefinitions, int userId = 0); + void Save(IEnumerable dataTypeDefinitions, int userId = Constants.Security.SuperUserId); /// /// Saves a collection of @@ -78,7 +78,7 @@ namespace Umbraco.Core.Services /// /// to delete /// Id of the user issuing the deletion - void Delete(IDataType dataType, int userId = 0); + void Delete(IDataType dataType, int userId = Constants.Security.SuperUserId); /// /// Gets a by its control Id diff --git a/src/Umbraco.Core/Services/IFileService.cs b/src/Umbraco.Core/Services/IFileService.cs index 8596424b03..5fe52559ee 100644 --- a/src/Umbraco.Core/Services/IFileService.cs +++ b/src/Umbraco.Core/Services/IFileService.cs @@ -18,12 +18,12 @@ namespace Umbraco.Core.Services IPartialView GetPartialView(string path); IPartialView GetPartialViewMacro(string path); IEnumerable GetPartialViewMacros(params string[] names); - Attempt CreatePartialView(IPartialView partialView, string snippetName = null, int userId = 0); - Attempt CreatePartialViewMacro(IPartialView partialView, string snippetName = null, int userId = 0); - bool DeletePartialView(string path, int userId = 0); - bool DeletePartialViewMacro(string path, int userId = 0); - Attempt SavePartialView(IPartialView partialView, int userId = 0); - Attempt SavePartialViewMacro(IPartialView partialView, int userId = 0); + Attempt CreatePartialView(IPartialView partialView, string snippetName = null, int userId = Constants.Security.SuperUserId); + Attempt CreatePartialViewMacro(IPartialView partialView, string snippetName = null, int userId = Constants.Security.SuperUserId); + bool DeletePartialView(string path, int userId = Constants.Security.SuperUserId); + bool DeletePartialViewMacro(string path, int userId = Constants.Security.SuperUserId); + Attempt SavePartialView(IPartialView partialView, int userId = Constants.Security.SuperUserId); + Attempt SavePartialViewMacro(IPartialView partialView, int userId = Constants.Security.SuperUserId); bool ValidatePartialView(PartialView partialView); bool ValidatePartialViewMacro(PartialView partialView); @@ -45,14 +45,14 @@ namespace Umbraco.Core.Services /// /// to save /// Optional id of the user saving the stylesheet - void SaveStylesheet(Stylesheet stylesheet, int userId = 0); + void SaveStylesheet(Stylesheet stylesheet, int userId = Constants.Security.SuperUserId); /// /// Deletes a stylesheet by its name /// /// Name incl. extension of the Stylesheet to delete /// Optional id of the user deleting the stylesheet - void DeleteStylesheet(string path, int userId = 0); + void DeleteStylesheet(string path, int userId = Constants.Security.SuperUserId); /// /// Validates a @@ -79,14 +79,14 @@ namespace Umbraco.Core.Services /// /// to save /// Optional id of the user saving the script - void SaveScript(Script script, int userId = 0); + void SaveScript(Script script, int userId = Constants.Security.SuperUserId); /// /// Deletes a script by its name /// /// Name incl. extension of the Script to delete /// Optional id of the user deleting the script - void DeleteScript(string path, int userId = 0); + void DeleteScript(string path, int userId = Constants.Security.SuperUserId); /// /// Validates a @@ -187,7 +187,7 @@ namespace Umbraco.Core.Services /// /// to save /// Optional id of the user saving the template - void SaveTemplate(ITemplate template, int userId = 0); + void SaveTemplate(ITemplate template, int userId = Constants.Security.SuperUserId); /// /// Creates a template for a content type @@ -198,16 +198,16 @@ namespace Umbraco.Core.Services /// /// The template created /// - Attempt> CreateTemplateForContentType(string contentTypeAlias, string contentTypeName, int userId = 0); + Attempt> CreateTemplateForContentType(string contentTypeAlias, string contentTypeName, int userId = Constants.Security.SuperUserId); - ITemplate CreateTemplateWithIdentity(string name, string alias, string content, ITemplate masterTemplate = null, int userId = 0); + ITemplate CreateTemplateWithIdentity(string name, string alias, string content, ITemplate masterTemplate = null, int userId = Constants.Security.SuperUserId); /// /// Deletes a template by its alias /// /// Alias of the to delete /// Optional id of the user deleting the template - void DeleteTemplate(string alias, int userId = 0); + void DeleteTemplate(string alias, int userId = Constants.Security.SuperUserId); /// /// Validates a @@ -221,7 +221,7 @@ namespace Umbraco.Core.Services /// /// List of to save /// Optional id of the user - void SaveTemplate(IEnumerable templates, int userId = 0); + void SaveTemplate(IEnumerable templates, int userId = Constants.Security.SuperUserId); /// /// Gets the content of a template as a stream. diff --git a/src/Umbraco.Core/Services/ILocalizationService.cs b/src/Umbraco.Core/Services/ILocalizationService.cs index 4882c7e829..54022d37bb 100644 --- a/src/Umbraco.Core/Services/ILocalizationService.cs +++ b/src/Umbraco.Core/Services/ILocalizationService.cs @@ -86,7 +86,7 @@ namespace Umbraco.Core.Services /// /// to save /// Optional id of the user saving the dictionary item - void Save(IDictionaryItem dictionaryItem, int userId = 0); + void Save(IDictionaryItem dictionaryItem, int userId = Constants.Security.SuperUserId); /// /// Deletes a object and its related translations @@ -94,7 +94,7 @@ namespace Umbraco.Core.Services /// /// to delete /// Optional id of the user deleting the dictionary item - void Delete(IDictionaryItem dictionaryItem, int userId = 0); + void Delete(IDictionaryItem dictionaryItem, int userId = Constants.Security.SuperUserId); /// /// Gets a by its id @@ -153,14 +153,14 @@ namespace Umbraco.Core.Services /// /// to save /// Optional id of the user saving the language - void Save(ILanguage language, int userId = 0); + void Save(ILanguage language, int userId = Constants.Security.SuperUserId); /// /// Deletes a by removing it and its usages from the db /// /// to delete /// Optional id of the user deleting the language - void Delete(ILanguage language, int userId = 0); + void Delete(ILanguage language, int userId = Constants.Security.SuperUserId); /// /// Gets the full dictionary key map. diff --git a/src/Umbraco.Core/Services/IMacroService.cs b/src/Umbraco.Core/Services/IMacroService.cs index 8c3acfd619..597c986f37 100644 --- a/src/Umbraco.Core/Services/IMacroService.cs +++ b/src/Umbraco.Core/Services/IMacroService.cs @@ -39,14 +39,14 @@ namespace Umbraco.Core.Services /// /// to delete /// Optional id of the user deleting the macro - void Delete(IMacro macro, int userId = 0); + void Delete(IMacro macro, int userId = Constants.Security.SuperUserId); /// /// Saves an /// /// to save /// Optional id of the user saving the macro - void Save(IMacro macro, int userId = 0); + void Save(IMacro macro, int userId = Constants.Security.SuperUserId); ///// ///// Gets a list all available plugins diff --git a/src/Umbraco.Core/Services/IMediaService.cs b/src/Umbraco.Core/Services/IMediaService.cs index ce2062d08d..02398c3634 100644 --- a/src/Umbraco.Core/Services/IMediaService.cs +++ b/src/Umbraco.Core/Services/IMediaService.cs @@ -37,7 +37,7 @@ namespace Umbraco.Core.Services /// Alias of the /// Optional id of the user creating the media item /// - IMedia CreateMedia(string name, Guid parentId, string mediaTypeAlias, int userId = 0); + IMedia CreateMedia(string name, Guid parentId, string mediaTypeAlias, int userId = Constants.Security.SuperUserId); /// /// Creates an object using the alias of the @@ -53,7 +53,7 @@ namespace Umbraco.Core.Services /// Alias of the /// Optional id of the user creating the media item /// - IMedia CreateMedia(string name, int parentId, string mediaTypeAlias, int userId = 0); + IMedia CreateMedia(string name, int parentId, string mediaTypeAlias, int userId = Constants.Security.SuperUserId); /// /// Creates an object using the alias of the @@ -69,7 +69,7 @@ namespace Umbraco.Core.Services /// Alias of the /// Optional id of the user creating the media item /// - IMedia CreateMedia(string name, IMedia parent, string mediaTypeAlias, int userId = 0); + IMedia CreateMedia(string name, IMedia parent, string mediaTypeAlias, int userId = Constants.Security.SuperUserId); /// /// Gets an object by Id @@ -152,14 +152,14 @@ namespace Umbraco.Core.Services /// Id of the Media's new Parent /// Id of the User moving the Media /// True if moving succeeded, otherwise False - Attempt Move(IMedia media, int parentId, int userId = 0); + Attempt Move(IMedia media, int parentId, int userId = Constants.Security.SuperUserId); /// /// Deletes an object by moving it to the Recycle Bin /// /// The to delete /// Id of the User deleting the Media - Attempt MoveToRecycleBin(IMedia media, int userId = 0); + Attempt MoveToRecycleBin(IMedia media, int userId = Constants.Security.SuperUserId); /// /// Empties the Recycle Bin by deleting all that resides in the bin @@ -172,7 +172,7 @@ namespace Umbraco.Core.Services /// This needs extra care and attention as its potentially a dangerous and extensive operation /// Id of the /// Optional Id of the user deleting Media - void DeleteMediaOfType(int mediaTypeId, int userId = 0); + void DeleteMediaOfType(int mediaTypeId, int userId = Constants.Security.SuperUserId); /// /// Deletes all media of the specified types. All Descendants of deleted media that is not of these types is moved to Recycle Bin. @@ -180,7 +180,7 @@ namespace Umbraco.Core.Services /// This needs extra care and attention as its potentially a dangerous and extensive operation /// Ids of the s /// Optional Id of the user issuing the delete operation - void DeleteMediaOfTypes(IEnumerable mediaTypeIds, int userId = 0); + void DeleteMediaOfTypes(IEnumerable mediaTypeIds, int userId = Constants.Security.SuperUserId); /// /// Permanently deletes an object @@ -191,7 +191,7 @@ namespace Umbraco.Core.Services /// /// The to delete /// Id of the User deleting the Media - Attempt Delete(IMedia media, int userId = 0); + Attempt Delete(IMedia media, int userId = Constants.Security.SuperUserId); /// /// Saves a single object @@ -199,7 +199,7 @@ namespace Umbraco.Core.Services /// The to save /// Id of the User saving the Media /// Optional boolean indicating whether or not to raise events. - Attempt Save(IMedia media, int userId = 0, bool raiseEvents = true); + Attempt Save(IMedia media, int userId = Constants.Security.SuperUserId, bool raiseEvents = true); /// /// Saves a collection of objects @@ -207,7 +207,7 @@ namespace Umbraco.Core.Services /// Collection of to save /// Id of the User saving the Media /// Optional boolean indicating whether or not to raise events. - Attempt Save(IEnumerable medias, int userId = 0, bool raiseEvents = true); + Attempt Save(IEnumerable medias, int userId = Constants.Security.SuperUserId, bool raiseEvents = true); /// /// Gets an object by its 'UniqueId' @@ -250,7 +250,7 @@ namespace Umbraco.Core.Services /// Id of the object to delete versions from /// Latest version date /// Optional Id of the User deleting versions of a Content object - void DeleteVersions(int id, DateTime versionDate, int userId = 0); + void DeleteVersions(int id, DateTime versionDate, int userId = Constants.Security.SuperUserId); /// /// Permanently deletes specific version(s) from an object. @@ -259,7 +259,7 @@ namespace Umbraco.Core.Services /// Id of the version to delete /// Boolean indicating whether to delete versions prior to the versionId /// Optional Id of the User deleting versions of a Content object - void DeleteVersion(int id, int versionId, bool deletePriorVersions, int userId = 0); + void DeleteVersion(int id, int versionId, bool deletePriorVersions, int userId = Constants.Security.SuperUserId); /// /// Gets an object from the path stored in the 'umbracoFile' property. @@ -304,7 +304,7 @@ namespace Umbraco.Core.Services /// /// /// True if sorting succeeded, otherwise False - bool Sort(IEnumerable items, int userId = 0, bool raiseEvents = true); + bool Sort(IEnumerable items, int userId = Constants.Security.SuperUserId, bool raiseEvents = true); /// /// Creates an object using the alias of the @@ -319,7 +319,7 @@ namespace Umbraco.Core.Services /// Alias of the /// Optional id of the user creating the media item /// - IMedia CreateMediaWithIdentity(string name, IMedia parent, string mediaTypeAlias, int userId = 0); + IMedia CreateMediaWithIdentity(string name, IMedia parent, string mediaTypeAlias, int userId = Constants.Security.SuperUserId); /// /// Creates an object using the alias of the @@ -334,7 +334,7 @@ namespace Umbraco.Core.Services /// Alias of the /// Optional id of the user creating the media item /// - IMedia CreateMediaWithIdentity(string name, int parentId, string mediaTypeAlias, int userId = 0); + IMedia CreateMediaWithIdentity(string name, int parentId, string mediaTypeAlias, int userId = Constants.Security.SuperUserId); /// /// Gets the content of a media as a stream. diff --git a/src/Umbraco.Core/Services/IPackagingService.cs b/src/Umbraco.Core/Services/IPackagingService.cs index c14882fe7a..b38b5a426b 100644 --- a/src/Umbraco.Core/Services/IPackagingService.cs +++ b/src/Umbraco.Core/Services/IPackagingService.cs @@ -27,7 +27,7 @@ namespace Umbraco.Core.Services /// /// /// - IEnumerable InstallCompiledPackageFiles(PackageDefinition packageDefinition, FileInfo packageFile, int userId = 0); + IEnumerable InstallCompiledPackageFiles(PackageDefinition packageDefinition, FileInfo packageFile, int userId = Constants.Security.SuperUserId); /// /// Installs the data, entities, objects contained in an umbraco package file (zip) @@ -35,7 +35,7 @@ namespace Umbraco.Core.Services /// /// /// - InstallationSummary InstallCompiledPackageData(PackageDefinition packageDefinition, FileInfo packageFile, int userId = 0); + InstallationSummary InstallCompiledPackageData(PackageDefinition packageDefinition, FileInfo packageFile, int userId = Constants.Security.SuperUserId); /// /// Uninstalls all versions of the package by name @@ -43,7 +43,7 @@ namespace Umbraco.Core.Services /// /// /// - UninstallationSummary UninstallPackage(string packageName, int userId = 0); + UninstallationSummary UninstallPackage(string packageName, int userId = Constants.Security.SuperUserId); #endregion @@ -75,7 +75,7 @@ namespace Umbraco.Core.Services /// If the package is an upgrade, the original/current PackageDefinition is returned /// PackageInstallType GetPackageInstallType(string packageName, SemVersion packageVersion, out PackageDefinition alreadyInstalled); - void DeleteInstalledPackage(int packageId, int userId = 0); + void DeleteInstalledPackage(int packageId, int userId = Constants.Security.SuperUserId); /// /// Persists a package definition to storage @@ -89,7 +89,7 @@ namespace Umbraco.Core.Services IEnumerable GetAllCreatedPackages(); PackageDefinition GetCreatedPackageById(int id); - void DeleteCreatedPackage(int id, int userId = 0); + void DeleteCreatedPackage(int id, int userId = Constants.Security.SuperUserId); /// /// Persists a package definition to storage diff --git a/src/Umbraco.Core/Services/Implement/ContentService.cs b/src/Umbraco.Core/Services/Implement/ContentService.cs index ce7417722d..485299c18a 100644 --- a/src/Umbraco.Core/Services/Implement/ContentService.cs +++ b/src/Umbraco.Core/Services/Implement/ContentService.cs @@ -159,7 +159,7 @@ namespace Umbraco.Core.Services.Implement /// Alias of the /// Optional id of the user creating the content /// - public IContent Create(string name, Guid parentId, string contentTypeAlias, int userId = 0) + public IContent Create(string name, Guid parentId, string contentTypeAlias, int userId = Constants.Security.SuperUserId) { // TODO: what about culture? @@ -179,7 +179,7 @@ namespace Umbraco.Core.Services.Implement /// The alias of the content type. /// The optional id of the user creating the content. /// The content object. - public IContent Create(string name, int parentId, string contentTypeAlias, int userId = 0) + public IContent Create(string name, int parentId, string contentTypeAlias, int userId = Constants.Security.SuperUserId) { // TODO: what about culture? @@ -212,7 +212,7 @@ namespace Umbraco.Core.Services.Implement /// The alias of the content type. /// The optional id of the user creating the content. /// The content object. - public IContent Create(string name, IContent parent, string contentTypeAlias, int userId = 0) + public IContent Create(string name, IContent parent, string contentTypeAlias, int userId = Constants.Security.SuperUserId) { // TODO: what about culture? @@ -243,7 +243,7 @@ namespace Umbraco.Core.Services.Implement /// The alias of the content type. /// The optional id of the user creating the content. /// The content object. - public IContent CreateAndSave(string name, int parentId, string contentTypeAlias, int userId = 0) + public IContent CreateAndSave(string name, int parentId, string contentTypeAlias, int userId = Constants.Security.SuperUserId) { // TODO: what about culture? @@ -277,7 +277,7 @@ namespace Umbraco.Core.Services.Implement /// The alias of the content type. /// The optional id of the user creating the content. /// The content object. - public IContent CreateAndSave(string name, IContent parent, string contentTypeAlias, int userId = 0) + public IContent CreateAndSave(string name, IContent parent, string contentTypeAlias, int userId = Constants.Security.SuperUserId) { // TODO: what about culture? @@ -749,7 +749,7 @@ namespace Umbraco.Core.Services.Implement #region Save, Publish, Unpublish /// - public OperationResult Save(IContent content, int userId = 0, bool raiseEvents = true) + public OperationResult Save(IContent content, int userId = Constants.Security.SuperUserId, bool raiseEvents = true) { var publishedState = content.PublishedState; if (publishedState != PublishedState.Published && publishedState != PublishedState.Unpublished) @@ -807,7 +807,7 @@ namespace Umbraco.Core.Services.Implement } /// - public OperationResult Save(IEnumerable contents, int userId = 0, bool raiseEvents = true) + public OperationResult Save(IEnumerable contents, int userId = Constants.Security.SuperUserId, bool raiseEvents = true) { var evtMsgs = EventMessagesFactory.Get(); var contentsA = contents.ToArray(); @@ -847,7 +847,7 @@ namespace Umbraco.Core.Services.Implement } /// - public PublishResult SaveAndPublish(IContent content, string culture = "*", int userId = 0, bool raiseEvents = true) + public PublishResult SaveAndPublish(IContent content, string culture = "*", int userId = Constants.Security.SuperUserId, bool raiseEvents = true) { var evtMsgs = EventMessagesFactory.Get(); @@ -908,14 +908,15 @@ 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); } /// - public PublishResult Unpublish(IContent content, string culture = "*", int userId = 0) + public PublishResult Unpublish(IContent content, string culture = "*", int userId = Constants.Security.SuperUserId) { if (content == null) throw new ArgumentNullException(nameof(content)); @@ -980,7 +981,7 @@ namespace Umbraco.Core.Services.Implement /// to actually commit the changes to the database. /// The document is *always* saved, even when publishing fails. /// - internal PublishResult CommitDocumentChanges(IContent content, int userId = 0, bool raiseEvents = true) + internal PublishResult CommitDocumentChanges(IContent content, int userId = Constants.Security.SuperUserId, bool raiseEvents = true) { using (var scope = ScopeProvider.CreateScope()) { @@ -991,7 +992,7 @@ namespace Umbraco.Core.Services.Implement } } - private PublishResult CommitDocumentChangesInternal(IScope scope, IContent content, int userId = 0, bool raiseEvents = true, bool branchOne = false, bool branchRoot = false) + private PublishResult CommitDocumentChangesInternal(IScope scope, IContent content, int userId = Constants.Security.SuperUserId, bool raiseEvents = true, bool branchOne = false, bool branchRoot = false) { var evtMsgs = EventMessagesFactory.Get(); PublishResult publishResult = null; @@ -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; } } @@ -1356,7 +1359,7 @@ namespace Umbraco.Core.Services.Implement /// - public IEnumerable SaveAndPublishBranch(IContent content, bool force, string culture = "*", int userId = 0) + public IEnumerable SaveAndPublishBranch(IContent content, bool force, string culture = "*", int userId = Constants.Security.SuperUserId) { // note: EditedValue and PublishedValue are objects here, so it is important to .Equals() // and not to == them, else we would be comparing references, and that is a bad thing @@ -1398,7 +1401,7 @@ namespace Umbraco.Core.Services.Implement } /// - public IEnumerable SaveAndPublishBranch(IContent content, bool force, string[] cultures, int userId = 0) + public IEnumerable SaveAndPublishBranch(IContent content, bool force, string[] cultures, int userId = Constants.Security.SuperUserId) { // note: EditedValue and PublishedValue are objects here, so it is important to .Equals() // and not to == them, else we would be comparing references, and that is a bad thing @@ -1438,7 +1441,7 @@ namespace Umbraco.Core.Services.Implement public IEnumerable SaveAndPublishBranch(IContent document, bool force, Func> shouldPublish, Func, bool> publishCultures, - int userId = 0) + int userId = Constants.Security.SuperUserId) { if (shouldPublish == null) throw new ArgumentNullException(nameof(shouldPublish)); if (publishCultures == null) throw new ArgumentNullException(nameof(publishCultures)); @@ -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(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(); @@ -1617,7 +1619,7 @@ namespace Umbraco.Core.Services.Implement /// Id of the object to delete versions from /// Latest version date /// Optional Id of the User deleting versions of a Content object - public void DeleteVersions(int id, DateTime versionDate, int userId = 0) + public void DeleteVersions(int id, DateTime versionDate, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { @@ -1647,7 +1649,7 @@ namespace Umbraco.Core.Services.Implement /// Id of the version to delete /// Boolean indicating whether to delete versions prior to the versionId /// Optional Id of the User deleting versions of a Content object - public void DeleteVersion(int id, int versionId, bool deletePriorVersions, int userId = 0) + public void DeleteVersion(int id, int versionId, bool deletePriorVersions, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { @@ -1733,7 +1735,7 @@ namespace Umbraco.Core.Services.Implement /// The to move /// Id of the Content's new Parent /// Optional Id of the User moving the Content - public void Move(IContent content, int parentId, int userId = 0) + public void Move(IContent content, int parentId, int userId = Constants.Security.SuperUserId) { // if moving to the recycle bin then use the proper method if (parentId == Constants.System.RecycleBinContent) @@ -1909,7 +1911,7 @@ namespace Umbraco.Core.Services.Implement /// Boolean indicating whether the copy should be related to the original /// Optional Id of the User copying the Content /// The newly created object - public IContent Copy(IContent content, int parentId, bool relateToOriginal, int userId = 0) + public IContent Copy(IContent content, int parentId, bool relateToOriginal, int userId = Constants.Security.SuperUserId) { return Copy(content, parentId, relateToOriginal, true, userId); } @@ -1924,7 +1926,7 @@ namespace Umbraco.Core.Services.Implement /// A value indicating whether to recursively copy children. /// Optional Id of the User copying the Content /// The newly created object - public IContent Copy(IContent content, int parentId, bool relateToOriginal, bool recursive, int userId = 0) + public IContent Copy(IContent content, int parentId, bool relateToOriginal, bool recursive, int userId = Constants.Security.SuperUserId) { var copy = content.DeepCloneWithResetIdentities(); copy.ParentId = parentId; @@ -2027,7 +2029,7 @@ namespace Umbraco.Core.Services.Implement /// The to send to publication /// Optional Id of the User issuing the send to publication /// True if sending publication was successful otherwise false - public bool SendToPublication(IContent content, int userId = 0) + public bool SendToPublication(IContent content, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { @@ -2081,7 +2083,7 @@ namespace Umbraco.Core.Services.Implement /// /// /// Result indicating what action was taken when handling the command. - public OperationResult Sort(IEnumerable items, int userId = 0, bool raiseEvents = true) + public OperationResult Sort(IEnumerable items, int userId = Constants.Security.SuperUserId, bool raiseEvents = true) { var evtMsgs = EventMessagesFactory.Get(); @@ -2110,7 +2112,7 @@ namespace Umbraco.Core.Services.Implement /// /// /// Result indicating what action was taken when handling the command. - public OperationResult Sort(IEnumerable ids, int userId = 0, bool raiseEvents = true) + public OperationResult Sort(IEnumerable ids, int userId = Constants.Security.SuperUserId, bool raiseEvents = true) { var evtMsgs = EventMessagesFactory.Get(); @@ -2595,7 +2597,7 @@ namespace Umbraco.Core.Services.Implement /// /// Id of the /// Optional Id of the user issuing the delete operation - public void DeleteOfTypes(IEnumerable contentTypeIds, int userId = 0) + public void DeleteOfTypes(IEnumerable contentTypeIds, int userId = Constants.Security.SuperUserId) { // TODO: This currently this is called from the ContentTypeService but that needs to change, // if we are deleting a content type, we should just delete the data and do this operation slightly differently. @@ -2671,7 +2673,7 @@ namespace Umbraco.Core.Services.Implement /// This needs extra care and attention as its potentially a dangerous and extensive operation /// Id of the /// Optional id of the user deleting the media - public void DeleteOfType(int contentTypeId, int userId = 0) + public void DeleteOfType(int contentTypeId, int userId = Constants.Security.SuperUserId) { DeleteOfTypes(new[] { contentTypeId }, userId); } @@ -2729,7 +2731,7 @@ namespace Umbraco.Core.Services.Implement } } - public void SaveBlueprint(IContent content, int userId = 0) + public void SaveBlueprint(IContent content, int userId = Constants.Security.SuperUserId) { //always ensure the blueprint is at the root if (content.ParentId != -1) @@ -2755,7 +2757,7 @@ namespace Umbraco.Core.Services.Implement } } - public void DeleteBlueprint(IContent content, int userId = 0) + public void DeleteBlueprint(IContent content, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { @@ -2768,7 +2770,7 @@ namespace Umbraco.Core.Services.Implement private static readonly string[] ArrayOfOneNullString = { null }; - public IContent CreateContentFromBlueprint(IContent blueprint, string name, int userId = 0) + public IContent CreateContentFromBlueprint(IContent blueprint, string name, int userId = Constants.Security.SuperUserId) { if (blueprint == null) throw new ArgumentNullException(nameof(blueprint)); @@ -2817,7 +2819,7 @@ namespace Umbraco.Core.Services.Implement } } - public void DeleteBlueprintsOfTypes(IEnumerable contentTypeIds, int userId = 0) + public void DeleteBlueprintsOfTypes(IEnumerable contentTypeIds, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { @@ -2844,7 +2846,7 @@ namespace Umbraco.Core.Services.Implement } } - public void DeleteBlueprintsOfType(int contentTypeId, int userId = 0) + public void DeleteBlueprintsOfType(int contentTypeId, int userId = Constants.Security.SuperUserId) { DeleteBlueprintsOfTypes(new[] { contentTypeId }, userId); } @@ -2853,7 +2855,7 @@ namespace Umbraco.Core.Services.Implement #region Rollback - public OperationResult Rollback(int id, int versionId, string culture = "*", int userId = 0) + public OperationResult Rollback(int id, int versionId, string culture = "*", int userId = Constants.Security.SuperUserId) { var evtMsgs = EventMessagesFactory.Get(); diff --git a/src/Umbraco.Core/Services/Implement/ContentTypeBaseServiceProvider.cs b/src/Umbraco.Core/Services/Implement/ContentTypeBaseServiceProvider.cs index d867224b90..5a56dfe3bc 100644 --- a/src/Umbraco.Core/Services/Implement/ContentTypeBaseServiceProvider.cs +++ b/src/Umbraco.Core/Services/Implement/ContentTypeBaseServiceProvider.cs @@ -18,6 +18,7 @@ namespace Umbraco.Core.Services.Implement public IContentTypeBaseService For(IContentBase contentBase) { + if (contentBase == null) throw new ArgumentNullException(nameof(contentBase)); switch (contentBase) { case IContent _: @@ -30,5 +31,12 @@ namespace Umbraco.Core.Services.Implement throw new ArgumentException($"Invalid contentBase type: {contentBase.GetType().FullName}" , nameof(contentBase)); } } + + // note: this should be a default interface method with C# 8 + public IContentTypeComposition GetContentTypeOf(IContentBase contentBase) + { + if (contentBase == null) throw new ArgumentNullException(nameof(contentBase)); + return For(contentBase)?.Get(contentBase.ContentTypeId); + } } } diff --git a/src/Umbraco.Core/Services/Implement/ContentTypeServiceBaseOfTRepositoryTItemTService.cs b/src/Umbraco.Core/Services/Implement/ContentTypeServiceBaseOfTRepositoryTItemTService.cs index d4cb890953..1f1f0d9ac3 100644 --- a/src/Umbraco.Core/Services/Implement/ContentTypeServiceBaseOfTRepositoryTItemTService.cs +++ b/src/Umbraco.Core/Services/Implement/ContentTypeServiceBaseOfTRepositoryTItemTService.cs @@ -376,7 +376,7 @@ namespace Umbraco.Core.Services.Implement #region Save - public void Save(TItem item, int userId = 0) + public void Save(TItem item, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { @@ -414,7 +414,7 @@ namespace Umbraco.Core.Services.Implement } } - public void Save(IEnumerable items, int userId = 0) + public void Save(IEnumerable items, int userId = Constants.Security.SuperUserId) { var itemsA = items.ToArray(); @@ -460,7 +460,7 @@ namespace Umbraco.Core.Services.Implement #region Delete - public void Delete(TItem item, int userId = 0) + public void Delete(TItem item, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { @@ -514,7 +514,7 @@ namespace Umbraco.Core.Services.Implement } } - public void Delete(IEnumerable items, int userId = 0) + public void Delete(IEnumerable items, int userId = Constants.Security.SuperUserId) { var itemsA = items.ToArray(); @@ -735,7 +735,7 @@ namespace Umbraco.Core.Services.Implement protected Guid ContainerObjectType => EntityContainer.GetContainerObjectType(ContainedObjectType); - public Attempt> CreateContainer(int parentId, string name, int userId = 0) + public Attempt> CreateContainer(int parentId, string name, int userId = Constants.Security.SuperUserId) { var evtMsgs = EventMessagesFactory.Get(); using (var scope = ScopeProvider.CreateScope()) @@ -775,7 +775,7 @@ namespace Umbraco.Core.Services.Implement } } - public Attempt SaveContainer(EntityContainer container, int userId = 0) + public Attempt SaveContainer(EntityContainer container, int userId = Constants.Security.SuperUserId) { var evtMsgs = EventMessagesFactory.Get(); @@ -869,7 +869,7 @@ namespace Umbraco.Core.Services.Implement } } - public Attempt DeleteContainer(int containerId, int userId = 0) + public Attempt DeleteContainer(int containerId, int userId = Constants.Security.SuperUserId) { var evtMsgs = EventMessagesFactory.Get(); using (var scope = ScopeProvider.CreateScope()) @@ -906,7 +906,7 @@ namespace Umbraco.Core.Services.Implement } } - public Attempt> RenameContainer(int id, string name, int userId = 0) + public Attempt> RenameContainer(int id, string name, int userId = Constants.Security.SuperUserId) { var evtMsgs = EventMessagesFactory.Get(); using (var scope = ScopeProvider.CreateScope()) diff --git a/src/Umbraco.Core/Services/Implement/DataTypeService.cs b/src/Umbraco.Core/Services/Implement/DataTypeService.cs index 97368e9047..445daddff4 100644 --- a/src/Umbraco.Core/Services/Implement/DataTypeService.cs +++ b/src/Umbraco.Core/Services/Implement/DataTypeService.cs @@ -38,7 +38,7 @@ namespace Umbraco.Core.Services.Implement #region Containers - public Attempt> CreateContainer(int parentId, string name, int userId = 0) + public Attempt> CreateContainer(int parentId, string name, int userId = Constants.Security.SuperUserId) { var evtMsgs = EventMessagesFactory.Get(); using (var scope = ScopeProvider.CreateScope()) @@ -119,7 +119,7 @@ namespace Umbraco.Core.Services.Implement } } - public Attempt SaveContainer(EntityContainer container, int userId = 0) + public Attempt SaveContainer(EntityContainer container, int userId = Constants.Security.SuperUserId) { var evtMsgs = EventMessagesFactory.Get(); @@ -153,7 +153,7 @@ namespace Umbraco.Core.Services.Implement return OperationResult.Attempt.Succeed(evtMsgs); } - public Attempt DeleteContainer(int containerId, int userId = 0) + public Attempt DeleteContainer(int containerId, int userId = Constants.Security.SuperUserId) { var evtMsgs = EventMessagesFactory.Get(); using (var scope = ScopeProvider.CreateScope()) @@ -186,7 +186,7 @@ namespace Umbraco.Core.Services.Implement return OperationResult.Attempt.Succeed(evtMsgs); } - public Attempt> RenameContainer(int id, string name, int userId = 0) + public Attempt> RenameContainer(int id, string name, int userId = Constants.Security.SuperUserId) { var evtMsgs = EventMessagesFactory.Get(); using (var scope = ScopeProvider.CreateScope()) @@ -331,7 +331,7 @@ namespace Umbraco.Core.Services.Implement /// /// to save /// Id of the user issuing the save - public void Save(IDataType dataType, int userId = 0) + public void Save(IDataType dataType, int userId = Constants.Security.SuperUserId) { dataType.CreatorId = userId; @@ -363,7 +363,7 @@ namespace Umbraco.Core.Services.Implement /// /// to save /// Id of the user issuing the save - public void Save(IEnumerable dataTypeDefinitions, int userId = 0) + public void Save(IEnumerable dataTypeDefinitions, int userId = Constants.Security.SuperUserId) { Save(dataTypeDefinitions, userId, true); } @@ -413,7 +413,7 @@ namespace Umbraco.Core.Services.Implement /// /// to delete /// Optional Id of the user issuing the deletion - public void Delete(IDataType dataType, int userId = 0) + public void Delete(IDataType dataType, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { diff --git a/src/Umbraco.Core/Services/Implement/FileService.cs b/src/Umbraco.Core/Services/Implement/FileService.cs index d85b0ca1ba..596d033ae8 100644 --- a/src/Umbraco.Core/Services/Implement/FileService.cs +++ b/src/Umbraco.Core/Services/Implement/FileService.cs @@ -74,7 +74,7 @@ namespace Umbraco.Core.Services.Implement /// /// to save /// - public void SaveStylesheet(Stylesheet stylesheet, int userId = 0) + public void SaveStylesheet(Stylesheet stylesheet, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { @@ -100,7 +100,7 @@ namespace Umbraco.Core.Services.Implement /// /// Name incl. extension of the Stylesheet to delete /// - public void DeleteStylesheet(string path, int userId = 0) + public void DeleteStylesheet(string path, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { @@ -217,7 +217,7 @@ namespace Umbraco.Core.Services.Implement /// /// to save /// - public void SaveScript(Script script, int userId = 0) + public void SaveScript(Script script, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { @@ -242,7 +242,7 @@ namespace Umbraco.Core.Services.Implement /// /// Name incl. extension of the Script to delete /// - public void DeleteScript(string path, int userId = 0) + public void DeleteScript(string path, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { @@ -338,7 +338,7 @@ namespace Umbraco.Core.Services.Implement /// /// The template created /// - public Attempt> CreateTemplateForContentType(string contentTypeAlias, string contentTypeName, int userId = 0) + public Attempt> CreateTemplateForContentType(string contentTypeAlias, string contentTypeName, int userId = Constants.Security.SuperUserId) { var template = new Template(contentTypeName, //NOTE: We are NOT passing in the content type alias here, we want to use it's name since we don't @@ -395,7 +395,7 @@ namespace Umbraco.Core.Services.Implement /// /// /// - public ITemplate CreateTemplateWithIdentity(string name, string alias, string content, ITemplate masterTemplate = null, int userId = 0) + public ITemplate CreateTemplateWithIdentity(string name, string alias, string content, ITemplate masterTemplate = null, int userId = Constants.Security.SuperUserId) { // file might already be on disk, if so grab the content to avoid overwriting var template = new Template(name, alias) @@ -529,7 +529,7 @@ namespace Umbraco.Core.Services.Implement /// /// to save /// - public void SaveTemplate(ITemplate template, int userId = 0) + public void SaveTemplate(ITemplate template, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { @@ -553,7 +553,7 @@ namespace Umbraco.Core.Services.Implement /// /// List of to save /// Optional id of the user - public void SaveTemplate(IEnumerable templates, int userId = 0) + public void SaveTemplate(IEnumerable templates, int userId = Constants.Security.SuperUserId) { var templatesA = templates.ToArray(); using (var scope = ScopeProvider.CreateScope()) @@ -579,7 +579,7 @@ namespace Umbraco.Core.Services.Implement /// /// Alias of the to delete /// - public void DeleteTemplate(string alias, int userId = 0) + public void DeleteTemplate(string alias, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { @@ -723,17 +723,17 @@ namespace Umbraco.Core.Services.Implement } } - public Attempt CreatePartialView(IPartialView partialView, string snippetName = null, int userId = 0) + public Attempt CreatePartialView(IPartialView partialView, string snippetName = null, int userId = Constants.Security.SuperUserId) { return CreatePartialViewMacro(partialView, PartialViewType.PartialView, snippetName, userId); } - public Attempt CreatePartialViewMacro(IPartialView partialView, string snippetName = null, int userId = 0) + public Attempt CreatePartialViewMacro(IPartialView partialView, string snippetName = null, int userId = Constants.Security.SuperUserId) { return CreatePartialViewMacro(partialView, PartialViewType.PartialViewMacro, snippetName, userId); } - private Attempt CreatePartialViewMacro(IPartialView partialView, PartialViewType partialViewType, string snippetName = null, int userId = 0) + private Attempt CreatePartialViewMacro(IPartialView partialView, PartialViewType partialViewType, string snippetName = null, int userId = Constants.Security.SuperUserId) { string partialViewHeader; switch (partialViewType) @@ -799,17 +799,17 @@ namespace Umbraco.Core.Services.Implement return Attempt.Succeed(partialView); } - public bool DeletePartialView(string path, int userId = 0) + public bool DeletePartialView(string path, int userId = Constants.Security.SuperUserId) { return DeletePartialViewMacro(path, PartialViewType.PartialView, userId); } - public bool DeletePartialViewMacro(string path, int userId = 0) + public bool DeletePartialViewMacro(string path, int userId = Constants.Security.SuperUserId) { return DeletePartialViewMacro(path, PartialViewType.PartialViewMacro, userId); } - private bool DeletePartialViewMacro(string path, PartialViewType partialViewType, int userId = 0) + private bool DeletePartialViewMacro(string path, PartialViewType partialViewType, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { @@ -839,17 +839,17 @@ namespace Umbraco.Core.Services.Implement return true; } - public Attempt SavePartialView(IPartialView partialView, int userId = 0) + public Attempt SavePartialView(IPartialView partialView, int userId = Constants.Security.SuperUserId) { return SavePartialView(partialView, PartialViewType.PartialView, userId); } - public Attempt SavePartialViewMacro(IPartialView partialView, int userId = 0) + public Attempt SavePartialViewMacro(IPartialView partialView, int userId = Constants.Security.SuperUserId) { return SavePartialView(partialView, PartialViewType.PartialViewMacro, userId); } - private Attempt SavePartialView(IPartialView partialView, PartialViewType partialViewType, int userId = 0) + private Attempt SavePartialView(IPartialView partialView, PartialViewType partialViewType, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { diff --git a/src/Umbraco.Core/Services/Implement/LocalizationService.cs b/src/Umbraco.Core/Services/Implement/LocalizationService.cs index 678ea10da2..251261cfc8 100644 --- a/src/Umbraco.Core/Services/Implement/LocalizationService.cs +++ b/src/Umbraco.Core/Services/Implement/LocalizationService.cs @@ -227,7 +227,7 @@ namespace Umbraco.Core.Services.Implement /// /// to save /// Optional id of the user saving the dictionary item - public void Save(IDictionaryItem dictionaryItem, int userId = 0) + public void Save(IDictionaryItem dictionaryItem, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { @@ -256,7 +256,7 @@ namespace Umbraco.Core.Services.Implement /// /// to delete /// Optional id of the user deleting the dictionary item - public void Delete(IDictionaryItem dictionaryItem, int userId = 0) + public void Delete(IDictionaryItem dictionaryItem, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { @@ -356,7 +356,7 @@ namespace Umbraco.Core.Services.Implement /// /// to save /// Optional id of the user saving the language - public void Save(ILanguage language, int userId = 0) + public void Save(ILanguage language, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { @@ -409,7 +409,7 @@ namespace Umbraco.Core.Services.Implement /// /// to delete /// Optional id of the user deleting the language - public void Delete(ILanguage language, int userId = 0) + public void Delete(ILanguage language, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { diff --git a/src/Umbraco.Core/Services/Implement/MacroService.cs b/src/Umbraco.Core/Services/Implement/MacroService.cs index d4f2d95bbb..a6631aae4c 100644 --- a/src/Umbraco.Core/Services/Implement/MacroService.cs +++ b/src/Umbraco.Core/Services/Implement/MacroService.cs @@ -81,7 +81,7 @@ namespace Umbraco.Core.Services.Implement /// /// to delete /// Optional id of the user deleting the macro - public void Delete(IMacro macro, int userId = 0) + public void Delete(IMacro macro, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { @@ -106,7 +106,7 @@ namespace Umbraco.Core.Services.Implement /// /// to save /// Optional Id of the user deleting the macro - public void Save(IMacro macro, int userId = 0) + public void Save(IMacro macro, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { diff --git a/src/Umbraco.Core/Services/Implement/MediaService.cs b/src/Umbraco.Core/Services/Implement/MediaService.cs index e7a42e28e4..1fa9b9fdb4 100644 --- a/src/Umbraco.Core/Services/Implement/MediaService.cs +++ b/src/Umbraco.Core/Services/Implement/MediaService.cs @@ -112,7 +112,7 @@ namespace Umbraco.Core.Services.Implement /// Alias of the /// Optional id of the user creating the media item /// - public IMedia CreateMedia(string name, Guid parentId, string mediaTypeAlias, int userId = 0) + public IMedia CreateMedia(string name, Guid parentId, string mediaTypeAlias, int userId = Constants.Security.SuperUserId) { var parent = GetById(parentId); return CreateMedia(name, parent, mediaTypeAlias, userId); @@ -130,7 +130,7 @@ namespace Umbraco.Core.Services.Implement /// The alias of the media type. /// The optional id of the user creating the media. /// The media object. - public IMedia CreateMedia(string name, int parentId, string mediaTypeAlias, int userId = 0) + public IMedia CreateMedia(string name, int parentId, string mediaTypeAlias, int userId = Constants.Security.SuperUserId) { var mediaType = GetMediaType(mediaTypeAlias); if (mediaType == null) @@ -160,7 +160,7 @@ namespace Umbraco.Core.Services.Implement /// The alias of the media type. /// The optional id of the user creating the media. /// The media object. - public IMedia CreateMedia(string name, string mediaTypeAlias, int userId = 0) + public IMedia CreateMedia(string name, string mediaTypeAlias, int userId = Constants.Security.SuperUserId) { // not locking since not saving anything @@ -190,7 +190,7 @@ namespace Umbraco.Core.Services.Implement /// The alias of the media type. /// The optional id of the user creating the media. /// The media object. - public IMedia CreateMedia(string name, IMedia parent, string mediaTypeAlias, int userId = 0) + public IMedia CreateMedia(string name, IMedia parent, string mediaTypeAlias, int userId = Constants.Security.SuperUserId) { if (parent == null) throw new ArgumentNullException(nameof(parent)); @@ -219,7 +219,7 @@ namespace Umbraco.Core.Services.Implement /// The alias of the media type. /// The optional id of the user creating the media. /// The media object. - public IMedia CreateMediaWithIdentity(string name, int parentId, string mediaTypeAlias, int userId = 0) + public IMedia CreateMediaWithIdentity(string name, int parentId, string mediaTypeAlias, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { @@ -251,7 +251,7 @@ namespace Umbraco.Core.Services.Implement /// The alias of the media type. /// The optional id of the user creating the media. /// The media object. - public IMedia CreateMediaWithIdentity(string name, IMedia parent, string mediaTypeAlias, int userId = 0) + public IMedia CreateMediaWithIdentity(string name, IMedia parent, string mediaTypeAlias, int userId = Constants.Security.SuperUserId) { if (parent == null) throw new ArgumentNullException(nameof(parent)); @@ -632,7 +632,7 @@ namespace Umbraco.Core.Services.Implement /// The to save /// Id of the User saving the Media /// Optional boolean indicating whether or not to raise events. - public Attempt Save(IMedia media, int userId = 0, bool raiseEvents = true) + public Attempt Save(IMedia media, int userId = Constants.Security.SuperUserId, bool raiseEvents = true) { var evtMsgs = EventMessagesFactory.Get(); @@ -677,7 +677,7 @@ namespace Umbraco.Core.Services.Implement /// Collection of to save /// Id of the User saving the Media /// Optional boolean indicating whether or not to raise events. - public Attempt Save(IEnumerable medias, int userId = 0, bool raiseEvents = true) + public Attempt Save(IEnumerable medias, int userId = Constants.Security.SuperUserId, bool raiseEvents = true) { var evtMsgs = EventMessagesFactory.Get(); var mediasA = medias.ToArray(); @@ -724,7 +724,7 @@ namespace Umbraco.Core.Services.Implement /// /// The to delete /// Id of the User deleting the Media - public Attempt Delete(IMedia media, int userId = 0) + public Attempt Delete(IMedia media, int userId = Constants.Security.SuperUserId) { var evtMsgs = EventMessagesFactory.Get(); @@ -785,7 +785,7 @@ namespace Umbraco.Core.Services.Implement /// Id of the object to delete versions from /// Latest version date /// Optional Id of the User deleting versions of a Media object - public void DeleteVersions(int id, DateTime versionDate, int userId = 0) + public void DeleteVersions(int id, DateTime versionDate, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { @@ -809,7 +809,7 @@ namespace Umbraco.Core.Services.Implement } } - private void DeleteVersions(IScope scope, bool wlock, int id, DateTime versionDate, int userId = 0) + private void DeleteVersions(IScope scope, bool wlock, int id, DateTime versionDate, int userId = Constants.Security.SuperUserId) { var args = new DeleteRevisionsEventArgs(id, dateToRetain: versionDate); if (scope.Events.DispatchCancelable(DeletingVersions, this, args)) @@ -832,7 +832,7 @@ namespace Umbraco.Core.Services.Implement /// Id of the version to delete /// Boolean indicating whether to delete versions prior to the versionId /// Optional Id of the User deleting versions of a Media object - public void DeleteVersion(int id, int versionId, bool deletePriorVersions, int userId = 0) + public void DeleteVersion(int id, int versionId, bool deletePriorVersions, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { @@ -872,7 +872,7 @@ namespace Umbraco.Core.Services.Implement /// /// The to delete /// Id of the User deleting the Media - public Attempt MoveToRecycleBin(IMedia media, int userId = 0) + public Attempt MoveToRecycleBin(IMedia media, int userId = Constants.Security.SuperUserId) { var evtMsgs = EventMessagesFactory.Get(); var moves = new List>(); @@ -916,7 +916,7 @@ namespace Umbraco.Core.Services.Implement /// The to move /// Id of the Media's new Parent /// Id of the User moving the Media - public Attempt Move(IMedia media, int parentId, int userId = 0) + public Attempt Move(IMedia media, int parentId, int userId = Constants.Security.SuperUserId) { var evtMsgs = EventMessagesFactory.Get(); @@ -1084,7 +1084,7 @@ namespace Umbraco.Core.Services.Implement /// /// /// True if sorting succeeded, otherwise False - public bool Sort(IEnumerable items, int userId = 0, bool raiseEvents = true) + public bool Sort(IEnumerable items, int userId = Constants.Security.SuperUserId, bool raiseEvents = true) { var itemsA = items.ToArray(); if (itemsA.Length == 0) return true; @@ -1273,7 +1273,7 @@ namespace Umbraco.Core.Services.Implement /// /// Id of the /// Optional id of the user deleting the media - public void DeleteMediaOfTypes(IEnumerable mediaTypeIds, int userId = 0) + public void DeleteMediaOfTypes(IEnumerable mediaTypeIds, int userId = Constants.Security.SuperUserId) { // TODO: This currently this is called from the ContentTypeService but that needs to change, // if we are deleting a content type, we should just delete the data and do this operation slightly differently. @@ -1338,7 +1338,7 @@ namespace Umbraco.Core.Services.Implement /// This needs extra care and attention as its potentially a dangerous and extensive operation /// Id of the /// Optional id of the user deleting the media - public void DeleteMediaOfType(int mediaTypeId, int userId = 0) + public void DeleteMediaOfType(int mediaTypeId, int userId = Constants.Security.SuperUserId) { DeleteMediaOfTypes(new[] { mediaTypeId }, userId); } diff --git a/src/Umbraco.Core/Services/Implement/PackagingService.cs b/src/Umbraco.Core/Services/Implement/PackagingService.cs index 9c4c6290a9..5194a26eb5 100644 --- a/src/Umbraco.Core/Services/Implement/PackagingService.cs +++ b/src/Umbraco.Core/Services/Implement/PackagingService.cs @@ -100,7 +100,7 @@ namespace Umbraco.Core.Services.Implement public CompiledPackage GetCompiledPackageInfo(FileInfo packageFile) => _packageInstallation.ReadPackage(packageFile); - public IEnumerable InstallCompiledPackageFiles(PackageDefinition packageDefinition, FileInfo packageFile, int userId = 0) + public IEnumerable InstallCompiledPackageFiles(PackageDefinition packageDefinition, FileInfo packageFile, int userId = Constants.Security.SuperUserId) { if (packageDefinition == null) throw new ArgumentNullException(nameof(packageDefinition)); if (packageDefinition.Id == default) throw new ArgumentException("The package definition has not been persisted"); @@ -118,7 +118,7 @@ namespace Umbraco.Core.Services.Implement return files; } - public InstallationSummary InstallCompiledPackageData(PackageDefinition packageDefinition, FileInfo packageFile, int userId = 0) + public InstallationSummary InstallCompiledPackageData(PackageDefinition packageDefinition, FileInfo packageFile, int userId = Constants.Security.SuperUserId) { if (packageDefinition == null) throw new ArgumentNullException(nameof(packageDefinition)); if (packageDefinition.Id == default) throw new ArgumentException("The package definition has not been persisted"); @@ -141,7 +141,7 @@ namespace Umbraco.Core.Services.Implement return summary; } - public UninstallationSummary UninstallPackage(string packageName, int userId = 0) + public UninstallationSummary UninstallPackage(string packageName, int userId = Constants.Security.SuperUserId) { //this is ordered by descending version var allPackageVersions = GetInstalledPackageByName(packageName)?.ToList(); @@ -187,7 +187,7 @@ namespace Umbraco.Core.Services.Implement #region Created/Installed Package Repositories - public void DeleteCreatedPackage(int id, int userId = 0) + public void DeleteCreatedPackage(int id, int userId = Constants.Security.SuperUserId) { var package = GetCreatedPackageById(id); if (package == null) return; @@ -236,7 +236,7 @@ namespace Umbraco.Core.Services.Implement public bool SaveInstalledPackage(PackageDefinition definition) => _installedPackages.SavePackage(definition); - public void DeleteInstalledPackage(int packageId, int userId = 0) + public void DeleteInstalledPackage(int packageId, int userId = Constants.Security.SuperUserId) { var package = GetInstalledPackageById(packageId); if (package == null) return; diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index ab663b5a24..b80d607d4f 100755 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -55,25 +55,25 @@ - - + + 2.2.2 - 5.2.6 + 5.2.7 - 4.0.0 + 4.0.1 - - + + - 2.7.1 + 2.8.0 2.0.1 @@ -88,7 +88,7 @@ 1.0.0 - 1.0.2 + 1.0.3 2.2.2 @@ -302,6 +302,7 @@ + @@ -473,6 +474,7 @@ + diff --git a/src/Umbraco.Examine/Umbraco.Examine.csproj b/src/Umbraco.Examine/Umbraco.Examine.csproj index 1320f3b0d2..989afd8d1c 100644 --- a/src/Umbraco.Examine/Umbraco.Examine.csproj +++ b/src/Umbraco.Examine/Umbraco.Examine.csproj @@ -49,7 +49,7 @@ - + diff --git a/src/Umbraco.Tests/App.config b/src/Umbraco.Tests/App.config index 5e366eef33..49de625450 100644 --- a/src/Umbraco.Tests/App.config +++ b/src/Umbraco.Tests/App.config @@ -64,23 +64,23 @@ - + - + - + - + - - + + @@ -88,7 +88,7 @@ - + @@ -100,11 +100,11 @@ - + - + diff --git a/src/Umbraco.Tests/Composing/TypeLoaderTests.cs b/src/Umbraco.Tests/Composing/TypeLoaderTests.cs index 2354dc8147..2dbd3055cb 100644 --- a/src/Umbraco.Tests/Composing/TypeLoaderTests.cs +++ b/src/Umbraco.Tests/Composing/TypeLoaderTests.cs @@ -264,7 +264,7 @@ AnotherContentFinder public void Resolves_Assigned_Mappers() { var foundTypes1 = _typeLoader.GetAssignedMapperTypes(); - Assert.AreEqual(29, foundTypes1.Count()); + Assert.AreEqual(30, foundTypes1.Count()); } [Test] diff --git a/src/Umbraco.Tests/Models/ContentExtensionsTests.cs b/src/Umbraco.Tests/Models/ContentExtensionsTests.cs index 5c95f1ead5..efa464a46c 100644 --- a/src/Umbraco.Tests/Models/ContentExtensionsTests.cs +++ b/src/Umbraco.Tests/Models/ContentExtensionsTests.cs @@ -1,22 +1,60 @@ using System; using System.Linq; +using Moq; using NUnit.Framework; using Umbraco.Core; +using Umbraco.Core.Composing; +using Umbraco.Core.Composing.Composers; +using Umbraco.Core.Configuration.UmbracoSettings; +using Umbraco.Core.Logging; using Umbraco.Core.Models; +using Umbraco.Core.PropertyEditors; +using Umbraco.Core.Services; +using Umbraco.Core.Services.Implement; using Umbraco.Tests.TestHelpers.Entities; using Umbraco.Tests.Testing; +using Umbraco.Web.PropertyEditors; namespace Umbraco.Tests.Models { [TestFixture] public class ContentExtensionsTests : UmbracoTestBase { - #region Others + private IContentTypeService _contentTypeService; + + protected override void Compose() + { + base.Compose(); + + Composition.Register(_ => Mock.Of()); + Composition.ComposeFileSystems(); + + Composition.Register(_ => Mock.Of()); + Composition.Register(_ => Mock.Of()); + + // all this is required so we can validate properties... + var editor = new TextboxPropertyEditor(Mock.Of()) { Alias = "test" }; + Composition.Register(_ => new DataEditorCollection(new[] { editor })); + Composition.Register(); + var dataType = Mock.Of(); + Mock.Get(dataType).Setup(x => x.Configuration).Returns(() => new object()); + var dataTypeService = Mock.Of(); + Mock.Get(dataTypeService) + .Setup(x => x.GetDataType(It.IsAny())) + .Returns(() => dataType); + + _contentTypeService = Mock.Of(); + var mediaTypeService = Mock.Of(); + var memberTypeService = Mock.Of(); + Composition.Register(_ => ServiceContext.CreatePartial(dataTypeService: dataTypeService, contentTypeBaseServiceProvider: new ContentTypeBaseServiceProvider(_contentTypeService, mediaTypeService, memberTypeService))); + } [Test] public void DirtyProperty_Reset_Clears_SavedPublishedState() { var contentType = MockedContentTypes.CreateTextPageContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); content.PublishedState = PublishedState.Publishing; @@ -30,6 +68,8 @@ namespace Umbraco.Tests.Models public void DirtyProperty_OnlyIfActuallyChanged_Content() { var contentType = MockedContentTypes.CreateTextPageContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); // if you assign a content property with its value it is not dirty @@ -52,6 +92,8 @@ namespace Umbraco.Tests.Models public void DirtyProperty_OnlyIfActuallyChanged_User() { var contentType = MockedContentTypes.CreateTextPageContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); var prop = content.Properties.First(); @@ -76,6 +118,8 @@ namespace Umbraco.Tests.Models public void DirtyProperty_UpdateDate() { var contentType = MockedContentTypes.CreateTextPageContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); var prop = content.Properties.First(); @@ -99,6 +143,8 @@ namespace Umbraco.Tests.Models public void DirtyProperty_WasDirty_ContentProperty() { var contentType = MockedContentTypes.CreateTextPageContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); content.ResetDirtyProperties(false); Assert.IsFalse(content.IsDirty()); @@ -126,6 +172,8 @@ namespace Umbraco.Tests.Models public void DirtyProperty_WasDirty_ContentSortOrder() { var contentType = MockedContentTypes.CreateTextPageContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); content.ResetDirtyProperties(false); Assert.IsFalse(content.IsDirty()); @@ -153,6 +201,8 @@ namespace Umbraco.Tests.Models public void DirtyProperty_WasDirty_UserProperty() { var contentType = MockedContentTypes.CreateTextPageContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); var prop = content.Properties.First(); content.ResetDirtyProperties(false); @@ -178,7 +228,5 @@ namespace Umbraco.Tests.Models //Assert.IsFalse(content.WasDirty()); // not impacted by user properties Assert.IsTrue(content.WasDirty()); // now it is! } - - #endregion } } diff --git a/src/Umbraco.Tests/Models/ContentTests.cs b/src/Umbraco.Tests/Models/ContentTests.cs index c5dd8a6aea..693f919b7a 100644 --- a/src/Umbraco.Tests/Models/ContentTests.cs +++ b/src/Umbraco.Tests/Models/ContentTests.cs @@ -17,6 +17,7 @@ using Umbraco.Core.Models.Entities; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Serialization; using Umbraco.Core.Services; +using Umbraco.Core.Services.Implement; using Umbraco.Tests.TestHelpers.Entities; using Umbraco.Tests.TestHelpers.Stubs; using Umbraco.Tests.Testing; @@ -28,6 +29,8 @@ namespace Umbraco.Tests.Models [TestFixture] public class ContentTests : UmbracoTestBase { + private IContentTypeService _contentTypeService; + protected override void Compose() { base.Compose(); @@ -48,19 +51,25 @@ namespace Umbraco.Tests.Models Mock.Get(dataTypeService) .Setup(x => x.GetDataType(It.IsAny())) .Returns(() => dataType); - Composition.Register(_ => ServiceContext.CreatePartial(dataTypeService: dataTypeService)); + + _contentTypeService = Mock.Of(); + var mediaTypeService = Mock.Of(); + var memberTypeService = Mock.Of(); + Composition.Register(_ => ServiceContext.CreatePartial(dataTypeService: dataTypeService, contentTypeBaseServiceProvider: new ContentTypeBaseServiceProvider(_contentTypeService, mediaTypeService, memberTypeService))); + } [Test] public void Variant_Culture_Names_Track_Dirty_Changes() { var contentType = new ContentType(-1) { Alias = "contentType" }; + contentType.Variations = ContentVariation.Culture; + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = new Content("content", -1, contentType) { Id = 1, VersionId = 1 }; const string langFr = "fr-FR"; - contentType.Variations = ContentVariation.Culture; - Assert.IsFalse(content.IsPropertyDirty("CultureInfos")); //hasn't been changed Thread.Sleep(500); //The "Date" wont be dirty if the test runs too fast since it will be the same date @@ -123,6 +132,7 @@ namespace Umbraco.Tests.Models //ensure that nothing is marked as dirty contentType.ResetDirtyProperties(false); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); var content = MockedContent.CreateSimpleContent(contentType); @@ -138,6 +148,8 @@ namespace Umbraco.Tests.Models public void All_Dirty_Properties_Get_Reset() { var contentType = MockedContentTypes.CreateTextPageContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); content.ResetDirtyProperties(false); @@ -154,6 +166,8 @@ namespace Umbraco.Tests.Models { // Arrange var contentType = MockedContentTypes.CreateTextPageContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); // Act @@ -167,6 +181,8 @@ namespace Umbraco.Tests.Models { // Arrange var contentType = MockedContentTypes.CreateTextPageContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); // Act @@ -183,6 +199,8 @@ namespace Umbraco.Tests.Models { // Arrange var contentType = MockedContentTypes.CreateTextPageContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); // Act @@ -199,6 +217,8 @@ namespace Umbraco.Tests.Models { // Arrange var contentType = MockedContentTypes.CreateTextPageContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); content.Id = 10; content.Key = new Guid("29181B97-CB8F-403F-86DE-5FEB497F4800"); @@ -278,6 +298,8 @@ namespace Umbraco.Tests.Models var contentType = MockedContentTypes.CreateTextPageContentType(); contentType.Id = 99; contentType.Variations = ContentVariation.Culture; + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); content.SetCultureName("Hello", "en-US"); @@ -387,6 +409,8 @@ namespace Umbraco.Tests.Models var contentType = MockedContentTypes.CreateTextPageContentType(); contentType.Id = 99; contentType.Variations = ContentVariation.Culture; + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); content.SetCultureName("Hello", "en-US"); @@ -458,6 +482,8 @@ namespace Umbraco.Tests.Models // Arrange var contentType = MockedContentTypes.CreateTextPageContentType(); contentType.Id = 99; + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); var i = 200; foreach (var property in content.Properties) @@ -509,10 +535,12 @@ namespace Umbraco.Tests.Models { // Arrange var contentType = MockedContentTypes.CreateTextPageContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); // Act - content.PropertyValues(new {title = "This is the new title"}); + content.PropertyValues(new { title = "This is the new title"}); // Assert Assert.That(content.Properties.Any(), Is.True); @@ -527,6 +555,8 @@ namespace Umbraco.Tests.Models { // Arrange var contentType = MockedContentTypes.CreateTextPageContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); // Act @@ -543,14 +573,12 @@ namespace Umbraco.Tests.Models { // Arrange var contentType = MockedContentTypes.CreateTextPageContentType(); - var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); // Act contentType.PropertyGroups.Add(new PropertyGroup(true) { Name = "Test Group", SortOrder = 3 }); // Assert Assert.That(contentType.PropertyGroups.Count, Is.EqualTo(3)); - Assert.That(content.PropertyGroups.Count(), Is.EqualTo(3)); } [Test] @@ -573,7 +601,6 @@ namespace Umbraco.Tests.Models { // Arrange var contentType = MockedContentTypes.CreateTextPageContentType(); - var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); // Act contentType.PropertyGroups["Content"].PropertyTypes.Add(new PropertyType("test", ValueStorageType.Ntext, "subtitle") @@ -587,7 +614,6 @@ namespace Umbraco.Tests.Models // Assert Assert.That(contentType.PropertyGroups["Content"].PropertyTypes.Count, Is.EqualTo(3)); - Assert.That(content.PropertyGroups.First(x => x.Name == "Content").PropertyTypes.Count, Is.EqualTo(3)); } [Test] @@ -595,6 +621,8 @@ namespace Umbraco.Tests.Models { // Arrange var contentType = MockedContentTypes.CreateTextPageContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); // Act @@ -617,6 +645,8 @@ namespace Umbraco.Tests.Models { // Arrange var contentType = MockedContentTypes.CreateTextPageContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); // Act @@ -637,8 +667,6 @@ namespace Umbraco.Tests.Models // Assert Assert.That(content.Properties.Count, Is.EqualTo(5)); - Assert.That(content.PropertyTypes.Count(), Is.EqualTo(5)); - Assert.That(content.PropertyGroups.Count(), Is.EqualTo(3)); Assert.That(content.Properties["subtitle"].GetValue(), Is.EqualTo("Subtitle Test")); Assert.That(content.Properties["title"].GetValue(), Is.EqualTo("Textpage textpage")); } @@ -648,6 +676,8 @@ namespace Umbraco.Tests.Models { // Arrange var contentType = MockedContentTypes.CreateTextPageContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); // Act - note that the PropertyType's properties like SortOrder is not updated through the Content object @@ -669,6 +699,8 @@ namespace Umbraco.Tests.Models // Arrange var contentType = MockedContentTypes.CreateTextPageContentType(); var simpleContentType = MockedContentTypes.CreateSimpleContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); // Act @@ -676,8 +708,6 @@ namespace Umbraco.Tests.Models // Assert Assert.That(content.Properties.Contains("author"), Is.True); - Assert.That(content.PropertyGroups.Count(), Is.EqualTo(1)); - Assert.That(content.PropertyTypes.Count(), Is.EqualTo(3)); //Note: There was 4 properties, after changing ContentType 1 has been added (no properties are deleted) Assert.That(content.Properties.Count, Is.EqualTo(5)); } @@ -688,6 +718,8 @@ namespace Umbraco.Tests.Models // Arrange var contentType = MockedContentTypes.CreateTextPageContentType(); var simpleContentType = MockedContentTypes.CreateSimpleContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); // Act @@ -705,6 +737,8 @@ namespace Umbraco.Tests.Models // Arrange var contentType = MockedContentTypes.CreateTextPageContentType(); var simpleContentType = MockedContentTypes.CreateSimpleContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); // Act @@ -723,6 +757,7 @@ namespace Umbraco.Tests.Models public void Can_Change_ContentType_On_Content_And_Clear_Old_PropertyTypes() { throw new NotImplementedException(); + //Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); //// Arrange //var contentType = MockedContentTypes.CreateTextPageContentType(); @@ -742,6 +777,8 @@ namespace Umbraco.Tests.Models public void Can_Verify_Content_Is_Published() { var contentType = MockedContentTypes.CreateTextPageContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); content.ResetDirtyProperties(); @@ -811,6 +848,8 @@ namespace Umbraco.Tests.Models // Arrange var contentType = MockedContentTypes.CreateTextPageContentType(); contentType.ResetDirtyProperties(); //reset + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "test", -1); content.ResetDirtyProperties(); diff --git a/src/Umbraco.Tests/Models/Mapping/AutoMapper6Tests.cs b/src/Umbraco.Tests/Models/Mapping/AutoMapper6Tests.cs index 59c514f654..18bceaae49 100644 --- a/src/Umbraco.Tests/Models/Mapping/AutoMapper6Tests.cs +++ b/src/Umbraco.Tests/Models/Mapping/AutoMapper6Tests.cs @@ -121,16 +121,16 @@ namespace Umbraco.Tests.Models.Mapping break; case 1: map - .ForMember(dest => dest.ValueString, opt => opt.ResolveUsing(src => src.ValueString)); + .ForMember(dest => dest.ValueString, opt => opt.MapFrom(src => src.ValueString)); break; case 2: map - .ForMember(dest => dest.ValueString, opt => opt.ResolveUsing()); + .ForMember(dest => dest.ValueString, opt => opt.MapFrom()); break; case 3: // in most cases that should be perfectly enough? map - .ForMember(dest => dest.ValueString, opt => opt.ResolveUsing(source => "!!" + source.ValueString + "!!")); + .ForMember(dest => dest.ValueString, opt => opt.MapFrom(source => "!!" + source.ValueString + "!!")); break; default: throw new ArgumentOutOfRangeException(nameof(ver)); diff --git a/src/Umbraco.Tests/Models/Mapping/ContentWebModelMappingTests.cs b/src/Umbraco.Tests/Models/Mapping/ContentWebModelMappingTests.cs index e3551921d8..1817414f69 100644 --- a/src/Umbraco.Tests/Models/Mapping/ContentWebModelMappingTests.cs +++ b/src/Umbraco.Tests/Models/Mapping/ContentWebModelMappingTests.cs @@ -4,15 +4,20 @@ using AutoMapper; using Moq; using NUnit.Framework; using Umbraco.Core; +using Umbraco.Core.Composing; +using Umbraco.Core.Composing.Composers; +using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.Services; using Umbraco.Core.Dictionary; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.PropertyEditors; +using Umbraco.Core.Services.Implement; using Umbraco.Tests.TestHelpers; using Umbraco.Tests.TestHelpers.Entities; using Umbraco.Web.Models.ContentEditing; using Umbraco.Tests.Testing; +using Umbraco.Web.PropertyEditors; using Current = Umbraco.Web.Composing.Current; namespace Umbraco.Tests.Models.Mapping @@ -21,12 +26,37 @@ namespace Umbraco.Tests.Models.Mapping [UmbracoTest(AutoMapper = true, Database = UmbracoTestOptions.Database.NewSchemaPerFixture)] public class ContentWebModelMappingTests : TestWithDatabaseBase { + private IContentTypeService _contentTypeService; + + protected override void Compose() { base.Compose(); Composition.RegisterUnique(f => Mock.Of()); - Composition.RegisterUnique(f => Mock.Of()); + + Composition.Register(_ => Mock.Of()); + Composition.ComposeFileSystems(); + + Composition.Register(_ => Mock.Of()); + Composition.Register(_ => Mock.Of()); + + // all this is required so we can validate properties... + var editor = new TextboxPropertyEditor(Mock.Of()) { Alias = "test" }; + Composition.Register(_ => new DataEditorCollection(new[] { editor })); + Composition.Register(); + var dataType = Mock.Of(); + Mock.Get(dataType).Setup(x => x.Configuration).Returns(() => new object()); + var dataTypeService = Mock.Of(); + Mock.Get(dataTypeService) + .Setup(x => x.GetDataType(It.IsAny())) + .Returns(() => dataType); + + _contentTypeService = Mock.Of(); + var mediaTypeService = Mock.Of(); + var memberTypeService = Mock.Of(); + Composition.RegisterUnique(_ => _contentTypeService); + Composition.Register(_ => ServiceContext.CreatePartial(dataTypeService: dataTypeService, contentTypeBaseServiceProvider: new ContentTypeBaseServiceProvider(_contentTypeService, mediaTypeService, memberTypeService))); } [DataEditor("Test.Test", "Test", "~/Test.html")] @@ -53,6 +83,8 @@ namespace Umbraco.Tests.Models.Mapping public void To_Media_Item_Simple() { var contentType = MockedContentTypes.CreateImageMediaType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedMedia.CreateMediaImage(contentType, -1); FixUsers(content); @@ -70,6 +102,8 @@ namespace Umbraco.Tests.Models.Mapping public void To_Content_Item_Simple() { var contentType = MockedContentTypes.CreateSimpleContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateSimpleContent(contentType); FixUsers(content); @@ -87,6 +121,8 @@ namespace Umbraco.Tests.Models.Mapping public void To_Content_Item_Dto() { var contentType = MockedContentTypes.CreateSimpleContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateSimpleContent(contentType); FixUsers(content); @@ -117,8 +153,8 @@ namespace Umbraco.Tests.Models.Mapping public void To_Display_Model() { var contentType = MockedContentTypes.CreateSimpleContentType(); - var contentTypeServiceMock = Mock.Get(Current.Services.ContentTypeService); - contentTypeServiceMock.Setup(x => x.Get(contentType.Id)).Returns(() => contentType); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + Mock.Get(_contentTypeService).Setup(x => x.Get(It.IsAny())).Returns(contentType); var content = MockedContent.CreateSimpleContent(contentType); @@ -127,7 +163,7 @@ namespace Umbraco.Tests.Models.Mapping // need ids for tabs var id = 1; - foreach (var g in content.PropertyGroups) + foreach (var g in contentType.CompositionPropertyGroups) g.Id = id++; var result = Mapper.Map(content); @@ -141,7 +177,7 @@ namespace Umbraco.Tests.Models.Mapping AssertDisplayProperty(invariantContent, p); } - Assert.AreEqual(content.PropertyGroups.Count(), invariantContent.Tabs.Count()); + Assert.AreEqual(contentType.CompositionPropertyGroups.Count(), invariantContent.Tabs.Count()); Assert.IsTrue(invariantContent.Tabs.First().IsActive); Assert.IsTrue(invariantContent.Tabs.Except(new[] { invariantContent.Tabs.First() }).All(x => x.IsActive == false)); } @@ -151,9 +187,8 @@ namespace Umbraco.Tests.Models.Mapping { var contentType = MockedContentTypes.CreateSimpleContentType(); contentType.PropertyGroups.Clear(); - var contentTypeServiceMock = Mock.Get(Current.Services.ContentTypeService); - contentTypeServiceMock.Setup(x => x.Get(contentType.Id)).Returns(() => contentType); - + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + Mock.Get(_contentTypeService).Setup(x => x.Get(It.IsAny())).Returns(contentType); var content = new Content("Home", -1, contentType) { Level = 1, SortOrder = 1, CreatorId = 0, WriterId = 0 }; @@ -168,7 +203,7 @@ namespace Umbraco.Tests.Models.Mapping AssertDisplayProperty(invariantContent, p); } - Assert.AreEqual(content.PropertyGroups.Count(), invariantContent.Tabs.Count()); + Assert.AreEqual(contentType.CompositionPropertyGroups.Count(), invariantContent.Tabs.Count()); } [Test] @@ -186,8 +221,8 @@ namespace Umbraco.Tests.Models.Mapping p.Id = idSeed; idSeed++; } - var contentTypeServiceMock = Mock.Get(Current.Services.ContentTypeService); - contentTypeServiceMock.Setup(x => x.Get(contentType.Id)).Returns(() => contentType); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + Mock.Get(_contentTypeService).Setup(x => x.Get(It.IsAny())).Returns(contentType); var content = MockedContent.CreateSimpleContent(contentType); @@ -200,7 +235,7 @@ namespace Umbraco.Tests.Models.Mapping } //need ids for tabs var id = 1; - foreach (var g in content.PropertyGroups) + foreach (var g in contentType.CompositionPropertyGroups) { g.Id = id; id++; @@ -221,7 +256,7 @@ namespace Umbraco.Tests.Models.Mapping AssertDisplayProperty(invariantContent, p); } - Assert.AreEqual(content.PropertyGroups.Count(), invariantContent.Tabs.Count() - 1); + Assert.AreEqual(contentType.CompositionPropertyGroups.Count(), invariantContent.Tabs.Count() - 1); Assert.IsTrue(invariantContent.Tabs.Any(x => x.Label == Current.Services.TextService.Localize("general/properties"))); Assert.AreEqual(2, invariantContent.Tabs.Where(x => x.Label == Current.Services.TextService.Localize("general/properties")).SelectMany(x => x.Properties.Where(p => p.Alias.StartsWith("_umb_") == false)).Count()); } diff --git a/src/Umbraco.Tests/Models/MemberTests.cs b/src/Umbraco.Tests/Models/MemberTests.cs index c09f2e9460..5e92ad7ccf 100644 --- a/src/Umbraco.Tests/Models/MemberTests.cs +++ b/src/Umbraco.Tests/Models/MemberTests.cs @@ -67,20 +67,7 @@ namespace Umbraco.Tests.Models Assert.AreEqual(clone.Id, member.Id); Assert.AreEqual(clone.VersionId, member.VersionId); Assert.AreEqual(clone.AdditionalData, member.AdditionalData); - Assert.AreNotSame(clone.ContentType, member.ContentType); Assert.AreEqual(clone.ContentType, member.ContentType); - Assert.AreEqual(clone.ContentType.PropertyGroups.Count, member.ContentType.PropertyGroups.Count); - for (var index = 0; index < member.ContentType.PropertyGroups.Count; index++) - { - Assert.AreNotSame(clone.ContentType.PropertyGroups[index], member.ContentType.PropertyGroups[index]); - Assert.AreEqual(clone.ContentType.PropertyGroups[index], member.ContentType.PropertyGroups[index]); - } - Assert.AreEqual(clone.ContentType.PropertyTypes.Count(), member.ContentType.PropertyTypes.Count()); - for (var index = 0; index < member.ContentType.PropertyTypes.Count(); index++) - { - Assert.AreNotSame(clone.ContentType.PropertyTypes.ElementAt(index), member.ContentType.PropertyTypes.ElementAt(index)); - Assert.AreEqual(clone.ContentType.PropertyTypes.ElementAt(index), member.ContentType.PropertyTypes.ElementAt(index)); - } Assert.AreEqual(clone.ContentTypeId, member.ContentTypeId); Assert.AreEqual(clone.CreateDate, member.CreateDate); Assert.AreEqual(clone.CreatorId, member.CreatorId); @@ -112,6 +99,9 @@ namespace Umbraco.Tests.Models Assert.AreEqual(clone.Properties[index], member.Properties[index]); } + // this can be the same, it is immutable + Assert.AreSame(clone.ContentType, member.ContentType); + //This double verifies by reflection var allProps = clone.GetType().GetProperties(); foreach (var propertyInfo in allProps) diff --git a/src/Umbraco.Tests/Models/VariationTests.cs b/src/Umbraco.Tests/Models/VariationTests.cs index 0ccdabe928..36fb399fa7 100644 --- a/src/Umbraco.Tests/Models/VariationTests.cs +++ b/src/Umbraco.Tests/Models/VariationTests.cs @@ -227,6 +227,9 @@ namespace Umbraco.Tests.Models // now it will work contentType.Variations = ContentVariation.Culture; + // recreate content to re-capture content type variations + content = new Content("content", -1, contentType) { Id = 1, VersionId = 1 }; + // invariant name works content.Name = "name"; Assert.AreEqual("name", content.GetCultureName(null)); diff --git a/src/Umbraco.Tests/Persistence/Repositories/DocumentRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/DocumentRepositoryTest.cs index 459dbeb587..2c4f3f1908 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/DocumentRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/DocumentRepositoryTest.cs @@ -130,10 +130,11 @@ namespace Umbraco.Tests.Persistence.Repositories var hasPropertiesContentType = MockedContentTypes.CreateSimpleContentType("umbTextpage1", "Textpage"); ServiceContext.FileService.SaveTemplate(hasPropertiesContentType.DefaultTemplate); // else, FK violation on contentType! + contentTypeRepository.Save(hasPropertiesContentType); + IContent content1 = MockedContent.CreateSimpleContent(hasPropertiesContentType); // save = create the initial version - contentTypeRepository.Save(hasPropertiesContentType); repository.Save(content1); versions.Add(content1.VersionId); // the first version @@ -399,9 +400,10 @@ namespace Umbraco.Tests.Persistence.Repositories var repository = CreateRepository((IScopeAccessor)provider, out var contentTypeRepository); var contentType = MockedContentTypes.CreateSimpleContentType("umbTextpage2", "Textpage"); ServiceContext.FileService.SaveTemplate(contentType.DefaultTemplate); // else, FK violation on contentType! + contentTypeRepository.Save(contentType); + IContent textpage = MockedContent.CreateSimpleContent(contentType); - contentTypeRepository.Save(contentType); repository.Save(textpage); scope.Complete(); @@ -487,9 +489,10 @@ namespace Umbraco.Tests.Persistence.Repositories var repository = CreateRepository((IScopeAccessor)provider, out var contentTypeRepository); var contentType = MockedContentTypes.CreateSimpleContentType("umbTextpage1", "Textpage"); ServiceContext.FileService.SaveTemplate(contentType.DefaultTemplate); // else, FK violation on contentType! + contentTypeRepository.Save(contentType); + var textpage = MockedContent.CreateSimpleContent(contentType); - contentTypeRepository.Save(contentType); repository.Save(textpage); diff --git a/src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs index cbd591950a..1c1b5e60f4 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs @@ -61,8 +61,9 @@ namespace Umbraco.Tests.Persistence.Repositories udb.EnableSqlCount = false; var mediaType = MockedContentTypes.CreateSimpleMediaType("umbTextpage1", "Textpage"); - var media = MockedMedia.CreateSimpleMedia(mediaType, "hello", -1); mediaTypeRepository.Save(mediaType); + + var media = MockedMedia.CreateSimpleMedia(mediaType, "hello", -1); repository.Save(media); udb.EnableSqlCount = true; @@ -271,7 +272,7 @@ namespace Umbraco.Tests.Persistence.Repositories var folder = MockedMedia.CreateMediaFolder(folderMediaType, -1); repository.Save(folder); } - + var types = new[] { 1031 }; var query = scope.SqlContext.Query().Where(x => types.Contains(x.ContentTypeId)); @@ -302,7 +303,7 @@ namespace Umbraco.Tests.Persistence.Repositories var folder = MockedMedia.CreateMediaFolder(folderMediaType, -1); repository.Save(folder); } - + var types = new[] { "Folder" }; var query = scope.SqlContext.Query().Where(x => types.Contains(x.ContentType.Alias)); diff --git a/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs index dea15cd4ad..c46a090685 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs @@ -164,21 +164,19 @@ namespace Umbraco.Tests.Persistence.Repositories var memberType = MockedContentTypes.CreateSimpleMemberType(); memberTypeRepository.Save(memberType); - var member = MockedMember.CreateSimpleMember(memberType, "Johnny Hefty", "johnny@example.com", "123", "hefty"); repository.Save(member); - var sut = repository.Get(member.Id); - Assert.That(sut.ContentType.PropertyGroups.Count(), Is.EqualTo(2)); - Assert.That(sut.ContentType.PropertyTypes.Count(), Is.EqualTo(3 + Constants.Conventions.Member.GetStandardPropertyTypeStubs().Count)); + Assert.That(memberType.CompositionPropertyGroups.Count(), Is.EqualTo(2)); + Assert.That(memberType.CompositionPropertyTypes.Count(), Is.EqualTo(3 + Constants.Conventions.Member.GetStandardPropertyTypeStubs().Count)); Assert.That(sut.Properties.Count(), Is.EqualTo(3 + Constants.Conventions.Member.GetStandardPropertyTypeStubs().Count)); - var grp = sut.PropertyGroups.FirstOrDefault(x => x.Name == Constants.Conventions.Member.StandardPropertiesGroupName); + var grp = memberType.CompositionPropertyGroups.FirstOrDefault(x => x.Name == Constants.Conventions.Member.StandardPropertiesGroupName); Assert.IsNotNull(grp); var aliases = Constants.Conventions.Member.GetStandardPropertyTypeStubs().Select(x => x.Key).ToArray(); - foreach (var p in sut.PropertyTypes.Where(x => aliases.Contains(x.Alias))) + foreach (var p in memberType.CompositionPropertyTypes.Where(x => aliases.Contains(x.Alias))) { Assert.AreEqual(grp.Id, p.PropertyGroupId.Value); } diff --git a/src/Umbraco.Tests/Persistence/Repositories/UserRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/UserRepositoryTest.cs index 8f750f9238..1d50fcac9e 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/UserRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/UserRepositoryTest.cs @@ -75,7 +75,7 @@ namespace Umbraco.Tests.Persistence.Repositories // Act repository.Save(user); - + // Assert Assert.That(user.HasIdentity, Is.True); @@ -96,9 +96,9 @@ namespace Umbraco.Tests.Persistence.Repositories // Act repository.Save(user1); - + repository.Save(use2); - + // Assert Assert.That(user1.HasIdentity, Is.True); @@ -117,7 +117,7 @@ namespace Umbraco.Tests.Persistence.Repositories var user = MockedUser.CreateUser(); repository.Save(user); - + // Act var resolved = repository.Get((int)user.Id); @@ -132,9 +132,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Update_On_UserRepository() { var ct = MockedContentTypes.CreateBasicContentType("test"); - var content = MockedContent.CreateBasicContent(ct); var mt = MockedContentTypes.CreateSimpleMediaType("testmedia", "TestMedia"); - var media = MockedMedia.CreateSimpleMedia(mt, "asdf", -1); // Arrange var provider = TestObjects.GetScopeProvider(Logger); @@ -147,11 +145,12 @@ namespace Umbraco.Tests.Persistence.Repositories contentTypeRepo.Save(ct); mediaTypeRepo.Save(mt); - + + var content = MockedContent.CreateBasicContent(ct); + var media = MockedMedia.CreateSimpleMedia(mt, "asdf", -1); contentRepository.Save(content); mediaRepository.Save(media); - var user = CreateAndCommitUserWithGroup(userRepository, userGroupRepository); @@ -171,7 +170,7 @@ namespace Umbraco.Tests.Persistence.Repositories resolved.Username = "newName"; userRepository.Save(resolved); - + var updatedItem = (User) userRepository.Get(user.Id); // Assert @@ -204,13 +203,13 @@ namespace Umbraco.Tests.Persistence.Repositories // Act repository.Save(user); - + var id = user.Id; var repository2 = new UserRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, Mock.Of(),TestObjects.GetGlobalSettings()); repository2.Delete(user); - + var resolved = repository2.Get((int) id); @@ -373,7 +372,7 @@ namespace Umbraco.Tests.Persistence.Repositories scope.Database.AsUmbracoDatabase().EnableSqlCount = false; } } - + } [Test] @@ -429,7 +428,7 @@ namespace Umbraco.Tests.Persistence.Repositories { var user = MockedUser.CreateUser(); repository.Save(user); - + var group = MockedUserGroup.CreateUserGroup(); userGroupRepository.AddOrUpdateGroupWithUsers(@group, new[] { user.Id }); diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs index 5f3a51f4f6..0dcc4bea99 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs @@ -195,7 +195,7 @@ namespace Umbraco.Tests.PublishedContent [Test] public void PublishedContentQueryTypedContentList() { - var query = new PublishedContentQuery(UmbracoContext.Current.ContentCache, UmbracoContext.Current.MediaCache, UmbracoContext.Current.VariationContextAccessor); + var query = new PublishedContentQuery(UmbracoContext.Current.PublishedSnapshot, UmbracoContext.Current.VariationContextAccessor); var result = query.Content(new[] { 1, 2, 4 }).ToArray(); Assert.AreEqual(2, result.Length); Assert.AreEqual(1, result[0].Id); diff --git a/src/Umbraco.Tests/Services/ContentServiceTests.cs b/src/Umbraco.Tests/Services/ContentServiceTests.cs index 94cbf69b63..85c195e553 100644 --- a/src/Umbraco.Tests/Services/ContentServiceTests.cs +++ b/src/Umbraco.Tests/Services/ContentServiceTests.cs @@ -66,7 +66,7 @@ namespace Umbraco.Tests.Services ServiceContext.FileService.SaveTemplate(contentType.DefaultTemplate); contentTypeService.Save(contentType); - var blueprint = MockedContent.CreateTextpageContent(contentType, "hello", -1); + var blueprint = MockedContent.CreateTextpageContent(contentType, "hello", Constants.System.Root); blueprint.SetValue("title", "blueprint 1"); blueprint.SetValue("bodyText", "blueprint 2"); blueprint.SetValue("keywords", "blueprint 3"); @@ -92,7 +92,7 @@ namespace Umbraco.Tests.Services ServiceContext.FileService.SaveTemplate(contentType.DefaultTemplate); contentTypeService.Save(contentType); - var blueprint = MockedContent.CreateTextpageContent(contentType, "hello", -1); + var blueprint = MockedContent.CreateTextpageContent(contentType, "hello", Constants.System.Root); blueprint.SetValue("title", "blueprint 1"); blueprint.SetValue("bodyText", "blueprint 2"); blueprint.SetValue("keywords", "blueprint 3"); @@ -118,7 +118,7 @@ namespace Umbraco.Tests.Services ServiceContext.FileService.SaveTemplate(contentType.DefaultTemplate); contentTypeService.Save(contentType); - var blueprint = MockedContent.CreateTextpageContent(contentType, "hello", -1); + var blueprint = MockedContent.CreateTextpageContent(contentType, "hello", Constants.System.Root); blueprint.SetValue("title", "blueprint 1"); blueprint.SetValue("bodyText", "blueprint 2"); blueprint.SetValue("keywords", "blueprint 3"); @@ -153,7 +153,7 @@ namespace Umbraco.Tests.Services for (int i = 0; i < 10; i++) { - var blueprint = MockedContent.CreateTextpageContent(i % 2 == 0 ? ct1 : ct2, "hello" + i, -1); + var blueprint = MockedContent.CreateTextpageContent(i % 2 == 0 ? ct1 : ct2, "hello" + i, Constants.System.Root); contentService.SaveBlueprint(blueprint); } @@ -264,7 +264,7 @@ namespace Umbraco.Tests.Services var contentService = ServiceContext.ContentService; // Act - var content = contentService.CreateAndSave("Test", -1, "umbTextpage", Constants.Security.SuperUserId); + var content = contentService.CreateAndSave("Test", Constants.System.Root, "umbTextpage", Constants.Security.SuperUserId); content.ContentSchedule.Add(null, DateTime.Now.AddHours(2)); contentService.Save(content, Constants.Security.SuperUserId); @@ -292,7 +292,7 @@ namespace Umbraco.Tests.Services var contentService = ServiceContext.ContentService; // Act - var content = contentService.CreateAndSave("Test", -1, "umbTextpage", Constants.Security.SuperUserId); + var content = contentService.CreateAndSave("Test", Constants.System.Root, "umbTextpage", Constants.Security.SuperUserId); for (var i = 0; i < 20; i++) { content.SetValue("bodyText", "hello world " + Guid.NewGuid()); @@ -317,7 +317,7 @@ namespace Umbraco.Tests.Services var results = new List(); for (var i = 0; i < 20; i++) { - results.Add(contentService.CreateAndSave("Test", -1, "umbTextpage", 0)); + results.Add(contentService.CreateAndSave("Test", Constants.System.Root, "umbTextpage", 0)); } var sortedGet = contentService.GetByIds(new[] {results[10].Id, results[5].Id, results[12].Id}).ToArray(); @@ -337,7 +337,7 @@ namespace Umbraco.Tests.Services // Act for (int i = 0; i < 20; i++) { - contentService.CreateAndSave("Test", -1, "umbTextpage", Constants.Security.SuperUserId); + contentService.CreateAndSave("Test", Constants.System.Root, "umbTextpage", Constants.Security.SuperUserId); } // Assert @@ -356,7 +356,7 @@ namespace Umbraco.Tests.Services // Act for (int i = 0; i < 20; i++) { - contentService.CreateAndSave("Test", -1, "umbBlah", Constants.Security.SuperUserId); + contentService.CreateAndSave("Test", Constants.System.Root, "umbBlah", Constants.Security.SuperUserId); } // Assert @@ -371,7 +371,7 @@ namespace Umbraco.Tests.Services var contentTypeService = ServiceContext.ContentTypeService; var contentType = MockedContentTypes.CreateSimpleContentType("umbBlah", "test Doc Type"); contentTypeService.Save(contentType); - var parent = contentService.CreateAndSave("Test", -1, "umbBlah", Constants.Security.SuperUserId); + var parent = contentService.CreateAndSave("Test", Constants.System.Root, "umbBlah", Constants.Security.SuperUserId); // Act for (int i = 0; i < 20; i++) @@ -391,7 +391,7 @@ namespace Umbraco.Tests.Services var contentTypeService = ServiceContext.ContentTypeService; var contentType = MockedContentTypes.CreateSimpleContentType("umbBlah", "test Doc Type"); contentTypeService.Save(contentType); - var parent = contentService.CreateAndSave("Test", -1, "umbBlah", Constants.Security.SuperUserId); + var parent = contentService.CreateAndSave("Test", Constants.System.Root, "umbBlah", Constants.Security.SuperUserId); // Act IContent current = parent; @@ -425,7 +425,7 @@ namespace Umbraco.Tests.Services var contentService = ServiceContext.ContentService; // Act - var content = contentService.Create("Test", -1, "umbTextpage", Constants.Security.SuperUserId); + var content = contentService.Create("Test", Constants.System.Root, "umbTextpage", Constants.Security.SuperUserId); // Assert Assert.That(content, Is.Not.Null); @@ -439,7 +439,7 @@ namespace Umbraco.Tests.Services var contentService = ServiceContext.ContentService; // Act - var content = contentService.Create("Test", -1, "umbTextpage", Constants.Security.SuperUserId); + var content = contentService.Create("Test", Constants.System.Root, "umbTextpage", Constants.Security.SuperUserId); // Assert Assert.That(content, Is.Not.Null); @@ -453,12 +453,12 @@ namespace Umbraco.Tests.Services var contentService = ServiceContext.ContentService; // Act - var content = contentService.Create("Test", -1, "umbTextpage"); + var content = contentService.Create("Test", Constants.System.Root, "umbTextpage"); // Assert Assert.That(content, Is.Not.Null); Assert.That(content.HasIdentity, Is.False); - Assert.That(content.CreatorId, Is.EqualTo(0)); //Default to 0 (unknown) since we didn't explicitly set this in the Create call + Assert.That(content.CreatorId, Is.EqualTo(Constants.Security.SuperUserId)); //Default to -1 aka SuperUser (unknown) since we didn't explicitly set this in the Create call } [Test] @@ -472,7 +472,7 @@ namespace Umbraco.Tests.Services RawPasswordValue = "test" }; ServiceContext.UserService.Save(user); - var content = new Content("Test", -1, ServiceContext.ContentTypeService.Get("umbTextpage")); + var content = new Content("Test", Constants.System.Root, ServiceContext.ContentTypeService.Get("umbTextpage")); // Act ServiceContext.ContentService.Save(content, (int)user.Id); @@ -489,7 +489,7 @@ namespace Umbraco.Tests.Services var contentService = ServiceContext.ContentService; // Act & Assert - Assert.Throws(() => contentService.Create("Test", -1, "umbAliasDoesntExist")); + Assert.Throws(() => contentService.Create("Test", Constants.System.Root, "umbAliasDoesntExist")); } [Test] @@ -497,7 +497,7 @@ namespace Umbraco.Tests.Services { // Arrange var contentService = ServiceContext.ContentService; - var content = new Content(string.Empty, -1, ServiceContext.ContentTypeService.Get("umbTextpage")); + var content = new Content(string.Empty, Constants.System.Root, ServiceContext.ContentTypeService.Get("umbTextpage")); // Act & Assert Assert.Throws(() => contentService.Save(content)); @@ -727,7 +727,7 @@ namespace Umbraco.Tests.Services contentType.Variations = ContentVariation.Culture; ServiceContext.ContentTypeService.Save(contentType); - IContent content = new Content("content", -1, contentType); + IContent content = new Content("content", Constants.System.Root, contentType); content.SetCultureName("content-fr", langFr.IsoCode); content.SetCultureName("content-en", langUk.IsoCode); content.PublishCulture(langFr.IsoCode); @@ -779,7 +779,7 @@ namespace Umbraco.Tests.Services ServiceContext.ContentTypeService.Save(contentType); - IContent content = new Content("content", -1, contentType); + IContent content = new Content("content", Constants.System.Root, contentType); content.SetCultureName("content-en", langGB.IsoCode); content.SetCultureName("content-fr", langFr.IsoCode); @@ -821,7 +821,7 @@ namespace Umbraco.Tests.Services contentType.Variations = ContentVariation.Culture; ServiceContext.ContentTypeService.Save(contentType); - IContent content = new Content("content", -1, contentType); + IContent content = new Content("content", Constants.System.Root, contentType); content.SetCultureName("content-fr", langFr.IsoCode); var published = ServiceContext.ContentService.SaveAndPublish(content, langFr.IsoCode); //audit log will only show that french was published @@ -852,7 +852,7 @@ namespace Umbraco.Tests.Services contentType.Variations = ContentVariation.Culture; ServiceContext.ContentTypeService.Save(contentType); - IContent content = new Content("content", -1, contentType); + IContent content = new Content("content", Constants.System.Root, contentType); content.SetCultureName("content-fr", langFr.IsoCode); content.SetCultureName("content-gb", langGB.IsoCode); var published = ServiceContext.ContentService.SaveAndPublish(content, new[] {langGB.IsoCode, langFr.IsoCode}); @@ -910,7 +910,7 @@ namespace Umbraco.Tests.Services { // Arrange var contentService = ServiceContext.ContentService; - var parent = contentService.Create("parent", -1, "umbTextpage"); + var parent = contentService.Create("parent", Constants.System.Root, "umbTextpage"); contentService.SaveAndPublish(parent); var content = contentService.Create("child", parent, "umbTextpage"); @@ -1235,7 +1235,7 @@ namespace Umbraco.Tests.Services { // Arrange var contentService = ServiceContext.ContentService; - var content = contentService.Create("Home US", -1, "umbTextpage", Constants.Security.SuperUserId); + var content = contentService.Create("Home US", Constants.System.Root, "umbTextpage", Constants.Security.SuperUserId); content.SetValue("author", "Barack Obama"); // Act @@ -1574,7 +1574,7 @@ namespace Umbraco.Tests.Services var contentType = MockedContentTypes.CreateAllTypesContentType("test", "test"); ServiceContext.ContentTypeService.Save(contentType, Constants.Security.SuperUserId); - + object obj = new { @@ -1730,7 +1730,7 @@ namespace Umbraco.Tests.Services ServiceContext.FileService.SaveTemplate(contentType.DefaultTemplate); // else, FK violation on contentType! ServiceContext.ContentTypeService.Save(contentType); - var content = MockedContent.CreateSimpleContent(contentType, "Simple Tags Page", -1); + var content = MockedContent.CreateSimpleContent(contentType, "Simple Tags Page", Constants.System.Root); content.AssignTags(propAlias, new[] {"hello", "world"}); contentService.Save(content); @@ -1906,7 +1906,7 @@ namespace Umbraco.Tests.Services ServiceContext.FileService.SaveTemplate(contentType.DefaultTemplate); // else, FK violation on contentType! ServiceContext.ContentTypeService.Save(contentType); - var page = new Content("Page", -1, contentType) + var page = new Content("Page", Constants.System.Root, contentType) { Level = 1, SortOrder = 1, @@ -2133,7 +2133,7 @@ namespace Umbraco.Tests.Services var contentType = MockedContentTypes.CreateAllTypesContentType("allDataTypes", "All DataTypes"); contentTypeService.Save(contentType); var contentService = ServiceContext.ContentService; - var content = MockedContent.CreateAllTypesContent(contentType, "Random Content", -1); + var content = MockedContent.CreateAllTypesContent(contentType, "Random Content", Constants.System.Root); contentService.Save(content); var id = content.Id; @@ -2186,7 +2186,7 @@ namespace Umbraco.Tests.Services public void Ensure_Content_Xml_Created() { var contentService = ServiceContext.ContentService; - var content = contentService.Create("Home US", -1, "umbTextpage", Constants.Security.SuperUserId); + var content = contentService.Create("Home US", Constants.System.Root, "umbTextpage", Constants.Security.SuperUserId); content.SetValue("author", "Barack Obama"); contentService.Save(content); @@ -2208,7 +2208,7 @@ namespace Umbraco.Tests.Services public void Ensure_Preview_Xml_Created() { var contentService = ServiceContext.ContentService; - var content = contentService.Create("Home US", -1, "umbTextpage", Constants.Security.SuperUserId); + var content = contentService.Create("Home US", Constants.System.Root, "umbTextpage", Constants.Security.SuperUserId); content.SetValue("author", "Barack Obama"); contentService.Save(content); @@ -2236,10 +2236,10 @@ namespace Umbraco.Tests.Services } long total; - var entities = service.GetPagedChildren(-1, 0, 6, out total).ToArray(); + var entities = service.GetPagedChildren(Constants.System.Root, 0, 6, out total).ToArray(); Assert.That(entities.Length, Is.EqualTo(6)); Assert.That(total, Is.EqualTo(10)); - entities = service.GetPagedChildren(-1, 1, 6, out total).ToArray(); + entities = service.GetPagedChildren(Constants.System.Root, 1, 6, out total).ToArray(); Assert.That(entities.Length, Is.EqualTo(4)); Assert.That(total, Is.EqualTo(10)); } @@ -2271,10 +2271,10 @@ namespace Umbraco.Tests.Services long total; // children in root including the folder - not the descendants in the folder - var entities = service.GetPagedChildren(-1, 0, 6, out total).ToArray(); + var entities = service.GetPagedChildren(Constants.System.Root, 0, 6, out total).ToArray(); Assert.That(entities.Length, Is.EqualTo(6)); Assert.That(total, Is.EqualTo(10)); - entities = service.GetPagedChildren(-1, 1, 6, out total).ToArray(); + entities = service.GetPagedChildren(Constants.System.Root, 1, 6, out total).ToArray(); Assert.That(entities.Length, Is.EqualTo(4)); Assert.That(total, Is.EqualTo(10)); @@ -2290,7 +2290,7 @@ namespace Umbraco.Tests.Services [Test] public void PublishingTest() { - var contentType = new ContentType(-1) + var contentType = new ContentType(Constants.System.Root) { Alias = "foo", Name = "Foo" @@ -2308,7 +2308,7 @@ namespace Umbraco.Tests.Services ServiceContext.ContentTypeService.Save(contentType); var contentService = ServiceContext.ContentService; - var content = contentService.Create("foo", -1, "foo"); + var content = contentService.Create("foo", Constants.System.Root, "foo"); contentService.Save(content); Assert.IsFalse(content.Published); @@ -2436,7 +2436,7 @@ namespace Umbraco.Tests.Services contentTypeService.Save(contentType); var contentService = ServiceContext.ContentService; - var content = new Content(null, -1, contentType); + var content = new Content(null, Constants.System.Root, contentType); content.SetCultureName("name-us", langUk.IsoCode); content.SetCultureName("name-fr", langFr.IsoCode); @@ -2471,7 +2471,7 @@ namespace Umbraco.Tests.Services var contentService = ServiceContext.ContentService; - var content = new Content(null, -1, contentType); + var content = new Content(null, Constants.System.Root, contentType); content.SetCultureName("root", langUk.IsoCode); contentService.Save(content); @@ -2513,13 +2513,13 @@ namespace Umbraco.Tests.Services var o = new[] { 2, 1, 3, 0, 4 }; // randomly different for (var i = 0; i < 5; i++) { - var contentA = new Content(null, -1, contentType); + var contentA = new Content(null, Constants.System.Root, contentType); contentA.SetCultureName("contentA" + i + "uk", langUk.IsoCode); contentA.SetCultureName("contentA" + o[i] + "fr", langFr.IsoCode); contentA.SetCultureName("contentX" + i + "da", langDa.IsoCode); contentService.Save(contentA); - var contentB = new Content(null, -1, contentType); + var contentB = new Content(null, Constants.System.Root, contentType); contentB.SetCultureName("contentB" + i + "uk", langUk.IsoCode); contentB.SetCultureName("contentB" + o[i] + "fr", langFr.IsoCode); contentB.SetCultureName("contentX" + i + "da", langDa.IsoCode); @@ -2527,7 +2527,7 @@ namespace Umbraco.Tests.Services } // get all - var list = contentService.GetPagedChildren(-1, 0, 100, out var total).ToList(); + var list = contentService.GetPagedChildren(Constants.System.Root, 0, 100, out var total).ToList(); Console.WriteLine("ALL"); WriteList(list); @@ -2537,7 +2537,7 @@ namespace Umbraco.Tests.Services Assert.AreEqual(11, list.Count); // filter - list = contentService.GetPagedChildren(-1, 0, 100, out total, + list = contentService.GetPagedChildren(Constants.System.Root, 0, 100, out total, SqlContext.Query().Where(x => x.Name.Contains("contentX")), Ordering.By("name", culture: langFr.IsoCode)).ToList(); @@ -2545,7 +2545,7 @@ namespace Umbraco.Tests.Services Assert.AreEqual(0, list.Count); // filter - list = contentService.GetPagedChildren(-1, 0, 100, out total, + list = contentService.GetPagedChildren(Constants.System.Root, 0, 100, out total, SqlContext.Query().Where(x => x.Name.Contains("contentX")), Ordering.By("name", culture: langDa.IsoCode)).ToList(); @@ -2556,7 +2556,7 @@ namespace Umbraco.Tests.Services Assert.AreEqual(10, list.Count); // filter - list = contentService.GetPagedChildren(-1, 0, 100, out total, + list = contentService.GetPagedChildren(Constants.System.Root, 0, 100, out total, SqlContext.Query().Where(x => x.Name.Contains("contentA")), Ordering.By("name", culture: langFr.IsoCode)).ToList(); @@ -2569,7 +2569,7 @@ namespace Umbraco.Tests.Services for (var i = 0; i < 5; i++) Assert.AreEqual("contentA" + i + "fr", list[i].GetCultureName(langFr.IsoCode)); - list = contentService.GetPagedChildren(-1, 0, 100, out total, + list = contentService.GetPagedChildren(Constants.System.Root, 0, 100, out total, SqlContext.Query().Where(x => x.Name.Contains("contentA")), Ordering.By("name", direction: Direction.Descending, culture: langFr.IsoCode)).ToList(); @@ -2614,7 +2614,7 @@ namespace Umbraco.Tests.Services contentTypeService.Save(contentType); var contentService = ServiceContext.ContentService; - var content = contentService.Create("Home US", -1, "umbTextpage"); + var content = contentService.Create("Home US", Constants.System.Root, "umbTextpage"); // creating content with a name but no culture - will set the invariant name // but, because that content is variant, as soon as we save, we'll need to diff --git a/src/Umbraco.Tests/Services/ContentTypeServiceTests.cs b/src/Umbraco.Tests/Services/ContentTypeServiceTests.cs index 1319d00c48..7a7aad6905 100644 --- a/src/Umbraco.Tests/Services/ContentTypeServiceTests.cs +++ b/src/Umbraco.Tests/Services/ContentTypeServiceTests.cs @@ -554,7 +554,6 @@ namespace Umbraco.Tests.Services IContent contentItem = MockedContent.CreateTextpageContent(contentType1, "Testing", -1); ServiceContext.ContentService.SaveAndPublish(contentItem); var initProps = contentItem.Properties.Count; - var initPropTypes = contentItem.PropertyTypes.Count(); //remove a property contentType1.RemovePropertyType(contentType1.PropertyTypes.First().Alias); @@ -563,7 +562,6 @@ namespace Umbraco.Tests.Services //re-load it from the db contentItem = ServiceContext.ContentService.GetById(contentItem.Id); - Assert.AreEqual(initPropTypes - 1, contentItem.PropertyTypes.Count()); Assert.AreEqual(initProps - 1, contentItem.Properties.Count); } diff --git a/src/Umbraco.Tests/Services/MemberTypeServiceTests.cs b/src/Umbraco.Tests/Services/MemberTypeServiceTests.cs index 459daa3da6..5f4a87c3eb 100644 --- a/src/Umbraco.Tests/Services/MemberTypeServiceTests.cs +++ b/src/Umbraco.Tests/Services/MemberTypeServiceTests.cs @@ -83,7 +83,6 @@ namespace Umbraco.Tests.Services IMember member = MockedMember.CreateSimpleMember(memberType, "test", "test@test.com", "pass", "test"); ServiceContext.MemberService.Save(member); var initProps = member.Properties.Count; - var initPropTypes = member.PropertyTypes.Count(); //remove a property (NOT ONE OF THE DEFAULTS) var standardProps = Constants.Conventions.Member.GetStandardPropertyTypeStubs(); @@ -93,7 +92,6 @@ namespace Umbraco.Tests.Services //re-load it from the db member = ServiceContext.MemberService.GetById(member.Id); - Assert.AreEqual(initPropTypes - 1, member.PropertyTypes.Count()); Assert.AreEqual(initProps - 1, member.Properties.Count); } diff --git a/src/Umbraco.Tests/TestHelpers/Stubs/TestProfiler.cs b/src/Umbraco.Tests/TestHelpers/Stubs/TestProfiler.cs index 0ffcfb7a3f..39cac6e24f 100644 --- a/src/Umbraco.Tests/TestHelpers/Stubs/TestProfiler.cs +++ b/src/Umbraco.Tests/TestHelpers/Stubs/TestProfiler.cs @@ -33,15 +33,20 @@ namespace Umbraco.Tests.TestHelpers.Stubs { if (_enabled == false) return; - MiniProfiler.Settings.SqlFormatter = new SqlServerFormatter(); - MiniProfiler.Settings.StackMaxLength = 5000; - MiniProfiler.Start(); + //see https://miniprofiler.com/dotnet/AspDotNet + MiniProfiler.Configure(new MiniProfilerOptions + { + SqlFormatter = new SqlServerFormatter(), + StackMaxLength = 5000, + }); + + MiniProfiler.StartNew(); } public void Stop(bool discardResults = false) { if (_enabled) - MiniProfiler.Stop(discardResults); + MiniProfiler.Current.Stop(discardResults); } } } diff --git a/src/Umbraco.Tests/Testing/ContentBaseExtensions.cs b/src/Umbraco.Tests/Testing/ContentBaseExtensions.cs index 58d4dfbd7f..d33818a31b 100644 --- a/src/Umbraco.Tests/Testing/ContentBaseExtensions.cs +++ b/src/Umbraco.Tests/Testing/ContentBaseExtensions.cs @@ -1,13 +1,17 @@ using System; using System.Linq; +using Umbraco.Core; +using Umbraco.Core.Composing; using Umbraco.Core.Models; +using Umbraco.Core.Services; namespace Umbraco.Tests.Testing { public static class ContentBaseExtensions { + /// - /// Set property values by alias with an annonymous object. + /// Set property values by alias with an anonymous object. /// /// Does not support variants. public static void PropertyValues(this IContentBase content, object value, string culture = null, string segment = null) @@ -18,26 +22,12 @@ namespace Umbraco.Tests.Testing var propertyInfos = value.GetType().GetProperties(); foreach (var propertyInfo in propertyInfos) { - //Check if a PropertyType with alias exists thus being a valid property - var propertyType = content.PropertyTypes.FirstOrDefault(x => x.Alias == propertyInfo.Name); - if (propertyType == null) + if (!content.Properties.TryGetValue(propertyInfo.Name, out var property)) throw new Exception($"The property alias {propertyInfo.Name} is not valid, because no PropertyType with this alias exists"); - //Check if a Property with the alias already exists in the collection thus being updated or inserted - var item = content.Properties.FirstOrDefault(x => x.Alias == propertyInfo.Name); - if (item != null) - { - item.SetValue(propertyInfo.GetValue(value, null), culture, segment); - //Update item with newly added value - content.Properties.Add(item); - } - else - { - //Create new Property to add to collection - var property = propertyType.CreateProperty(); - property.SetValue(propertyInfo.GetValue(value, null), culture, segment); - content.Properties.Add(property); - } + property.SetValue(propertyInfo.GetValue(value, null), culture, segment); + //Update item with newly added value + content.Properties.Add(property); } } } diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index 3bfc3387fe..e88aa5ae61 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -78,40 +78,39 @@ - - + + - 1.8.9 + 1.8.14 - + - - - - - - - - - - + + + + + + + + + + - - + + - - - + + + - + - - + diff --git a/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs b/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs index 6fe921e13f..f7b1799d63 100644 --- a/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs +++ b/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs @@ -110,7 +110,7 @@ namespace Umbraco.Tests.UmbracoExamine m.GetCultureName(It.IsAny()) == (string)x.Attribute("nodeName") && m.Path == (string)x.Attribute("path") && m.Properties == new PropertyCollection() && - m.ContentType == Mock.Of(mt => + m.ContentType == Mock.Of(mt => mt.Alias == (string)x.Attribute("nodeTypeAlias") && mt.Id == (int)x.Attribute("nodeType")))) .ToArray(); diff --git a/src/Umbraco.Tests/Web/Controllers/ContentControllerTests.cs b/src/Umbraco.Tests/Web/Controllers/ContentControllerTests.cs index 37600e2f89..d0c09d3340 100644 --- a/src/Umbraco.Tests/Web/Controllers/ContentControllerTests.cs +++ b/src/Umbraco.Tests/Web/Controllers/ContentControllerTests.cs @@ -43,6 +43,14 @@ namespace Umbraco.Tests.Web.Controllers [UmbracoTest(Database = UmbracoTestOptions.Database.None)] public class ContentControllerTests : TestWithDatabaseBase { + private IContentType _contentTypeForMockedContent; + + public override void SetUp() + { + base.SetUp(); + _contentTypeForMockedContent = null; + } + protected override void ComposeApplication(bool withApplication) { base.ComposeApplication(withApplication); @@ -115,23 +123,42 @@ namespace Umbraco.Tests.Web.Controllers }; } - private IContent GetMockedContent() + private IContentType GetMockedContentType() { - var content = MockedContent.CreateSimpleContent(MockedContentTypes.CreateSimpleContentType()); - content.Id = 123; - content.Path = "-1,123"; + var contentType = MockedContentTypes.CreateSimpleContentType(); //ensure things have ids var ids = 888; - foreach (var g in content.PropertyGroups) + foreach (var g in contentType.CompositionPropertyGroups) { g.Id = ids; ids++; } - foreach (var p in content.PropertyTypes) + foreach (var p in contentType.CompositionPropertyGroups) { p.Id = ids; ids++; } + + return contentType; + } + + private IContent GetMockedContent() + { + if (_contentTypeForMockedContent == null) + { + _contentTypeForMockedContent = GetMockedContentType(); + Mock.Get(Current.Services.ContentTypeService) + .Setup(x => x.Get(_contentTypeForMockedContent.Id)) + .Returns(_contentTypeForMockedContent); + Mock.Get(Current.Services.ContentTypeService) + .As() + .Setup(x => x.Get(_contentTypeForMockedContent.Id)) + .Returns(_contentTypeForMockedContent); + } + + var content = MockedContent.CreateSimpleContent(_contentTypeForMockedContent); + content.Id = 123; + content.Path = "-1,123"; return content; } @@ -229,7 +256,7 @@ namespace Umbraco.Tests.Web.Controllers Factory.GetInstance(), Factory.GetInstance(), helper); - + return controller; } @@ -251,9 +278,6 @@ namespace Umbraco.Tests.Web.Controllers { ApiController CtrlFactory(HttpRequestMessage message, UmbracoContext umbracoContext, UmbracoHelper helper) { - var contentServiceMock = Mock.Get(Current.Services.ContentService); - contentServiceMock.Setup(x => x.GetById(123)).Returns(() => GetMockedContent()); - var propertyEditorCollection = new PropertyEditorCollection(new DataEditorCollection(Enumerable.Empty())); var controller = new ContentController( propertyEditorCollection, @@ -336,15 +360,11 @@ namespace Umbraco.Tests.Web.Controllers ApiController CtrlFactory(HttpRequestMessage message, UmbracoContext umbracoContext, UmbracoHelper helper) { - var contentServiceMock = Mock.Get(Current.Services.ContentService); contentServiceMock.Setup(x => x.GetById(123)).Returns(() => content); contentServiceMock.Setup(x => x.Save(It.IsAny(), It.IsAny(), It.IsAny())) .Returns(new OperationResult(OperationResultType.Success, new Core.Events.EventMessages())); //success - var contentTypeServiceMock = Mock.Get(Current.Services.ContentTypeService); - contentTypeServiceMock.Setup(x => x.Get(content.ContentTypeId)).Returns(() => MockedContentTypes.CreateSimpleContentType()); - var propertyEditorCollection = new PropertyEditorCollection(new DataEditorCollection(Enumerable.Empty())); var controller = new ContentController( propertyEditorCollection, @@ -369,8 +389,6 @@ namespace Umbraco.Tests.Web.Controllers Assert.AreEqual(HttpStatusCode.OK, response.Item1.StatusCode); var display = JsonConvert.DeserializeObject(response.Item2); Assert.AreEqual(1, display.Variants.Count()); - Assert.AreEqual(content.PropertyGroups.Count(), display.Variants.ElementAt(0).Tabs.Count()); - Assert.AreEqual(content.PropertyTypes.Count(), display.Variants.ElementAt(0).Tabs.ElementAt(0).Properties.Count()); } [Test] @@ -380,15 +398,11 @@ namespace Umbraco.Tests.Web.Controllers ApiController CtrlFactory(HttpRequestMessage message, UmbracoContext umbracoContext, UmbracoHelper helper) { - var contentServiceMock = Mock.Get(Current.Services.ContentService); contentServiceMock.Setup(x => x.GetById(123)).Returns(() => content); contentServiceMock.Setup(x => x.Save(It.IsAny(), It.IsAny(), It.IsAny())) .Returns(new OperationResult(OperationResultType.Success, new Core.Events.EventMessages())); //success - var contentTypeServiceMock = Mock.Get(Current.Services.ContentTypeService); - contentTypeServiceMock.Setup(x => x.Get(content.ContentTypeId)).Returns(() => MockedContentTypes.CreateSimpleContentType()); - var propertyEditorCollection = new PropertyEditorCollection(new DataEditorCollection(Enumerable.Empty())); var controller = new ContentController( propertyEditorCollection, @@ -428,15 +442,11 @@ namespace Umbraco.Tests.Web.Controllers ApiController CtrlFactory(HttpRequestMessage message, UmbracoContext umbracoContext, UmbracoHelper helper) { - var contentServiceMock = Mock.Get(Current.Services.ContentService); contentServiceMock.Setup(x => x.GetById(123)).Returns(() => content); contentServiceMock.Setup(x => x.Save(It.IsAny(), It.IsAny(), It.IsAny())) .Returns(new OperationResult(OperationResultType.Success, new Core.Events.EventMessages())); //success - var contentTypeServiceMock = Mock.Get(Current.Services.ContentTypeService); - contentTypeServiceMock.Setup(x => x.Get(content.ContentTypeId)).Returns(() => MockedContentTypes.CreateSimpleContentType()); - var propertyEditorCollection = new PropertyEditorCollection(new DataEditorCollection(Enumerable.Empty())); var controller = new ContentController( propertyEditorCollection, diff --git a/src/Umbraco.Web.UI.Client/gulp/tasks/build.js b/src/Umbraco.Web.UI.Client/gulp/tasks/build.js index 4e519c58e9..8fe582e406 100644 --- a/src/Umbraco.Web.UI.Client/gulp/tasks/build.js +++ b/src/Umbraco.Web.UI.Client/gulp/tasks/build.js @@ -6,5 +6,5 @@ var runSequence = require('run-sequence'); // Build - build the files ready for production gulp.task('build', function(cb) { - runSequence(["dependencies", "js", "less", "views"], cb); + runSequence(["js", "dependencies", "less", "views"], /*"test:unit",*/ cb); }); diff --git a/src/Umbraco.Web.UI.Client/gulp/tasks/test.js b/src/Umbraco.Web.UI.Client/gulp/tasks/test.js index 76712f1454..eae65613c4 100644 --- a/src/Umbraco.Web.UI.Client/gulp/tasks/test.js +++ b/src/Umbraco.Web.UI.Client/gulp/tasks/test.js @@ -11,7 +11,7 @@ var runSequence = require('run-sequence'); // Karma test gulp.task('runTests', function(cb) { - runSequence(["js"], "test:unit", cb); + runSequence("js", "test:unit", cb); }); gulp.task('test:unit', function () { diff --git a/src/Umbraco.Web.UI.Client/package-lock.json b/src/Umbraco.Web.UI.Client/package-lock.json index 4c796ab2a7..207eba38c5 100644 --- a/src/Umbraco.Web.UI.Client/package-lock.json +++ b/src/Umbraco.Web.UI.Client/package-lock.json @@ -937,7 +937,7 @@ }, "ansi-colors": { "version": "1.1.0", - "resolved": "http://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", "dev": true, "requires": { @@ -955,7 +955,7 @@ }, "ansi-escapes": { "version": "3.1.0", - "resolved": "http://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==", "dev": true }, @@ -1104,6 +1104,7 @@ "resolved": "https://registry.npmjs.org/archive-type/-/archive-type-3.2.0.tgz", "integrity": "sha1-nNnABpV+vpX62tW9YJiUKoE3N/Y=", "dev": true, + "optional": true, "requires": { "file-type": "^3.1.0" }, @@ -1112,7 +1113,8 @@ "version": "3.9.0", "resolved": "http://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=", - "dev": true + "dev": true, + "optional": true } } }, @@ -1170,7 +1172,7 @@ "array-slice": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", - "integrity": "sha1-42jqFfibxwaff/uJrsOmx9SsItQ=", + "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", "dev": true }, "array-sort": { @@ -1216,7 +1218,7 @@ "arraybuffer.slice": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", - "integrity": "sha1-O7xCdd1YTMGxCAm4nU6LY6aednU=", + "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==", "dev": true }, "asap": { @@ -1269,7 +1271,7 @@ "async-limiter": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", - "integrity": "sha1-ePrtjD0HSrgfIrTphdeehzj3IPg=", + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", "dev": true }, "asynckit": { @@ -1523,6 +1525,7 @@ "resolved": "http://registry.npmjs.org/bl/-/bl-1.2.2.tgz", "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", "dev": true, + "optional": true, "requires": { "readable-stream": "^2.3.5", "safe-buffer": "^5.1.1" @@ -1745,7 +1748,8 @@ "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true + "dev": true, + "optional": true }, "buffer-fill": { "version": "1.0.0", @@ -1764,6 +1768,7 @@ "resolved": "https://registry.npmjs.org/buffer-to-vinyl/-/buffer-to-vinyl-1.1.0.tgz", "integrity": "sha1-APFfruOreh3aLN5tkSG//dB7ImI=", "dev": true, + "optional": true, "requires": { "file-type": "^3.1.0", "readable-stream": "^2.0.2", @@ -1775,19 +1780,22 @@ "version": "3.9.0", "resolved": "http://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=", - "dev": true + "dev": true, + "optional": true }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "dev": true, + "optional": true }, "readable-stream": { "version": "2.3.6", "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, + "optional": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -1803,6 +1811,7 @@ "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, + "optional": true, "requires": { "safe-buffer": "~5.1.0" } @@ -1811,13 +1820,15 @@ "version": "2.0.3", "resolved": "http://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=", - "dev": true + "dev": true, + "optional": true }, "vinyl": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", "dev": true, + "optional": true, "requires": { "clone": "^1.0.0", "clone-stats": "^0.0.1", @@ -1938,7 +1949,8 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz", "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==", - "dev": true + "dev": true, + "optional": true }, "caseless": { "version": "0.12.0", @@ -1951,6 +1963,7 @@ "resolved": "https://registry.npmjs.org/caw/-/caw-1.2.0.tgz", "integrity": "sha1-/7Im/n78VHKI3GLuPpcHPCEtEDQ=", "dev": true, + "optional": true, "requires": { "get-proxy": "^1.0.1", "is-obj": "^1.0.0", @@ -1962,7 +1975,8 @@ "version": "0.4.3", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=", - "dev": true + "dev": true, + "optional": true } } }, @@ -2223,7 +2237,8 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/co/-/co-3.1.0.tgz", "integrity": "sha1-TqVOpaCJOBUxheFSEMaNkJK8G3g=", - "dev": true + "dev": true, + "optional": true }, "coa": { "version": "2.0.1", @@ -2319,6 +2334,7 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz", "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=", "dev": true, + "optional": true, "requires": { "graceful-readlink": ">= 1.0.0" } @@ -2382,7 +2398,7 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { @@ -2462,7 +2478,7 @@ "content-type": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha1-4TjMdeBAxyexlm/l5fjJruJW/js=", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", "dev": true }, "continuable-cache": { @@ -2505,7 +2521,7 @@ "core-js": { "version": "2.5.7", "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", - "integrity": "sha1-+XJgj/DOrWi4QaFqky0LGDeRgU4=", + "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==", "dev": true }, "core-util-is": { @@ -2531,6 +2547,7 @@ "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", "dev": true, + "optional": true, "requires": { "capture-stack-trace": "^1.0.0" } @@ -2785,6 +2802,7 @@ "resolved": "https://registry.npmjs.org/decompress/-/decompress-3.0.0.tgz", "integrity": "sha1-rx3VDQbjv8QyRh033hGzjA2ZG+0=", "dev": true, + "optional": true, "requires": { "buffer-to-vinyl": "^1.0.0", "concat-stream": "^1.4.6", @@ -2802,6 +2820,7 @@ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", "dev": true, + "optional": true, "requires": { "arr-flatten": "^1.0.1" } @@ -2810,13 +2829,15 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true + "dev": true, + "optional": true }, "braces": { "version": "1.8.5", "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", "dev": true, + "optional": true, "requires": { "expand-range": "^1.8.1", "preserve": "^0.2.0", @@ -2828,6 +2849,7 @@ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", "dev": true, + "optional": true, "requires": { "is-posix-bracket": "^0.1.0" } @@ -2837,6 +2859,7 @@ "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", "dev": true, + "optional": true, "requires": { "is-extglob": "^1.0.0" } @@ -2846,6 +2869,7 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", "dev": true, + "optional": true, "requires": { "inflight": "^1.0.4", "inherits": "2", @@ -2859,6 +2883,7 @@ "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-5.3.5.tgz", "integrity": "sha1-pVZlqajM3EGRWofHAeMtTgFvrSI=", "dev": true, + "optional": true, "requires": { "extend": "^3.0.0", "glob": "^5.0.3", @@ -2874,13 +2899,15 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true + "dev": true, + "optional": true }, "readable-stream": { "version": "1.0.34", "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, + "optional": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", @@ -2892,13 +2919,15 @@ "version": "0.10.31", "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true + "dev": true, + "optional": true }, "through2": { "version": "0.6.5", "resolved": "http://registry.npmjs.org/through2/-/through2-0.6.5.tgz", "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", "dev": true, + "optional": true, "requires": { "readable-stream": ">=1.0.33-1 <1.1.0-0", "xtend": ">=4.0.0 <4.1.0-0" @@ -2910,19 +2939,22 @@ "version": "4.1.15", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", - "dev": true + "dev": true, + "optional": true }, "is-extglob": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true + "dev": true, + "optional": true }, "is-glob": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", "dev": true, + "optional": true, "requires": { "is-extglob": "^1.0.0" } @@ -2931,13 +2963,15 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "dev": true, + "optional": true }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, + "optional": true, "requires": { "is-buffer": "^1.1.5" } @@ -2947,6 +2981,7 @@ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", "dev": true, + "optional": true, "requires": { "arr-diff": "^2.0.0", "array-unique": "^0.2.1", @@ -2967,13 +3002,15 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true + "dev": true, + "optional": true }, "ordered-read-streams": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.3.0.tgz", "integrity": "sha1-cTfmmzKYuzQiR6G77jiByA4v14s=", "dev": true, + "optional": true, "requires": { "is-stream": "^1.0.1", "readable-stream": "^2.0.1" @@ -2984,6 +3021,7 @@ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, + "optional": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -2999,6 +3037,7 @@ "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, + "optional": true, "requires": { "safe-buffer": "~5.1.0" } @@ -3008,6 +3047,7 @@ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", "dev": true, + "optional": true, "requires": { "is-utf8": "^0.2.0" } @@ -3017,6 +3057,7 @@ "resolved": "https://registry.npmjs.org/strip-bom-stream/-/strip-bom-stream-1.0.0.tgz", "integrity": "sha1-5xRDmFd9Uaa+0PoZlPoF9D/ZiO4=", "dev": true, + "optional": true, "requires": { "first-chunk-stream": "^1.0.0", "strip-bom": "^2.0.0" @@ -3027,6 +3068,7 @@ "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", "dev": true, + "optional": true, "requires": { "json-stable-stringify-without-jsonify": "^1.0.1", "through2-filter": "^3.0.0" @@ -3037,6 +3079,7 @@ "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", "dev": true, + "optional": true, "requires": { "through2": "~2.0.0", "xtend": "~4.0.0" @@ -3049,6 +3092,7 @@ "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", "dev": true, + "optional": true, "requires": { "clone": "^1.0.0", "clone-stats": "^0.0.1", @@ -3060,6 +3104,7 @@ "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-2.4.4.tgz", "integrity": "sha1-vm/zJwy1Xf19MGNkDegfJddTIjk=", "dev": true, + "optional": true, "requires": { "duplexify": "^3.2.0", "glob-stream": "^5.3.2", @@ -3087,6 +3132,7 @@ "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-3.1.0.tgz", "integrity": "sha1-IXx4n5uURQ76rcXF5TeXj8MzxGY=", "dev": true, + "optional": true, "requires": { "is-tar": "^1.0.0", "object-assign": "^2.0.0", @@ -3100,19 +3146,22 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz", "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=", - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz", "integrity": "sha1-Q8NuXVaf+OSBbE76i+AtJpZ8GKo=", - "dev": true + "dev": true, + "optional": true }, "readable-stream": { "version": "1.0.34", "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, + "optional": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", @@ -3125,6 +3174,7 @@ "resolved": "http://registry.npmjs.org/through2/-/through2-0.6.5.tgz", "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", "dev": true, + "optional": true, "requires": { "readable-stream": ">=1.0.33-1 <1.1.0-0", "xtend": ">=4.0.0 <4.1.0-0" @@ -3135,6 +3185,7 @@ "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz", "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=", "dev": true, + "optional": true, "requires": { "clone": "^0.2.0", "clone-stats": "^0.0.1" @@ -3147,6 +3198,7 @@ "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-3.1.0.tgz", "integrity": "sha1-iyOTVoE1X58YnYclag+L3ZbZZm0=", "dev": true, + "optional": true, "requires": { "is-bzip2": "^1.0.0", "object-assign": "^2.0.0", @@ -3161,19 +3213,22 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz", "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=", - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz", "integrity": "sha1-Q8NuXVaf+OSBbE76i+AtJpZ8GKo=", - "dev": true + "dev": true, + "optional": true }, "readable-stream": { "version": "1.0.34", "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, + "optional": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", @@ -3186,6 +3241,7 @@ "resolved": "http://registry.npmjs.org/through2/-/through2-0.6.5.tgz", "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", "dev": true, + "optional": true, "requires": { "readable-stream": ">=1.0.33-1 <1.1.0-0", "xtend": ">=4.0.0 <4.1.0-0" @@ -3196,6 +3252,7 @@ "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz", "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=", "dev": true, + "optional": true, "requires": { "clone": "^0.2.0", "clone-stats": "^0.0.1" @@ -3208,6 +3265,7 @@ "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-3.1.0.tgz", "integrity": "sha1-ssE9+YFmJomRtxXWRH9kLpaW9aA=", "dev": true, + "optional": true, "requires": { "is-gzip": "^1.0.0", "object-assign": "^2.0.0", @@ -3221,19 +3279,22 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz", "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=", - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz", "integrity": "sha1-Q8NuXVaf+OSBbE76i+AtJpZ8GKo=", - "dev": true + "dev": true, + "optional": true }, "readable-stream": { "version": "1.0.34", "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, + "optional": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", @@ -3246,6 +3307,7 @@ "resolved": "http://registry.npmjs.org/through2/-/through2-0.6.5.tgz", "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", "dev": true, + "optional": true, "requires": { "readable-stream": ">=1.0.33-1 <1.1.0-0", "xtend": ">=4.0.0 <4.1.0-0" @@ -3256,6 +3318,7 @@ "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz", "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=", "dev": true, + "optional": true, "requires": { "clone": "^0.2.0", "clone-stats": "^0.0.1" @@ -3268,6 +3331,7 @@ "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-3.4.0.tgz", "integrity": "sha1-YUdbQVIGa74/7hL51inRX+ZHjus=", "dev": true, + "optional": true, "requires": { "is-zip": "^1.0.0", "read-all-stream": "^3.0.0", @@ -3283,6 +3347,7 @@ "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", "dev": true, + "optional": true, "requires": { "clone": "^1.0.0", "clone-stats": "^0.0.1", @@ -3295,7 +3360,8 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true + "dev": true, + "optional": true }, "deep-is": { "version": "0.1.3", @@ -3428,7 +3494,7 @@ "doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha1-XNAfwQFiG0LEzX9dGmYkNxbT850=", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, "requires": { "esutils": "^2.0.2" @@ -3494,6 +3560,7 @@ "resolved": "https://registry.npmjs.org/download/-/download-4.4.3.tgz", "integrity": "sha1-qlX9rTktldS2jowr4D4MKqIbqaw=", "dev": true, + "optional": true, "requires": { "caw": "^1.0.1", "concat-stream": "^1.4.7", @@ -3517,6 +3584,7 @@ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", "dev": true, + "optional": true, "requires": { "arr-flatten": "^1.0.1" } @@ -3525,13 +3593,15 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true + "dev": true, + "optional": true }, "braces": { "version": "1.8.5", "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", "dev": true, + "optional": true, "requires": { "expand-range": "^1.8.1", "preserve": "^0.2.0", @@ -3543,6 +3613,7 @@ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", "dev": true, + "optional": true, "requires": { "is-posix-bracket": "^0.1.0" } @@ -3552,6 +3623,7 @@ "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", "dev": true, + "optional": true, "requires": { "is-extglob": "^1.0.0" } @@ -3561,6 +3633,7 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", "dev": true, + "optional": true, "requires": { "inflight": "^1.0.4", "inherits": "2", @@ -3574,6 +3647,7 @@ "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-5.3.5.tgz", "integrity": "sha1-pVZlqajM3EGRWofHAeMtTgFvrSI=", "dev": true, + "optional": true, "requires": { "extend": "^3.0.0", "glob": "^5.0.3", @@ -3589,13 +3663,15 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true + "dev": true, + "optional": true }, "readable-stream": { "version": "1.0.34", "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, + "optional": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", @@ -3607,13 +3683,15 @@ "version": "0.10.31", "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true + "dev": true, + "optional": true }, "through2": { "version": "0.6.5", "resolved": "http://registry.npmjs.org/through2/-/through2-0.6.5.tgz", "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", "dev": true, + "optional": true, "requires": { "readable-stream": ">=1.0.33-1 <1.1.0-0", "xtend": ">=4.0.0 <4.1.0-0" @@ -3625,19 +3703,22 @@ "version": "4.1.15", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", - "dev": true + "dev": true, + "optional": true }, "is-extglob": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true + "dev": true, + "optional": true }, "is-glob": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", "dev": true, + "optional": true, "requires": { "is-extglob": "^1.0.0" } @@ -3646,13 +3727,15 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "dev": true, + "optional": true }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, + "optional": true, "requires": { "is-buffer": "^1.1.5" } @@ -3662,6 +3745,7 @@ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", "dev": true, + "optional": true, "requires": { "arr-diff": "^2.0.0", "array-unique": "^0.2.1", @@ -3682,13 +3766,15 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true + "dev": true, + "optional": true }, "ordered-read-streams": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.3.0.tgz", "integrity": "sha1-cTfmmzKYuzQiR6G77jiByA4v14s=", "dev": true, + "optional": true, "requires": { "is-stream": "^1.0.1", "readable-stream": "^2.0.1" @@ -3699,6 +3785,7 @@ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, + "optional": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -3714,6 +3801,7 @@ "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, + "optional": true, "requires": { "safe-buffer": "~5.1.0" } @@ -3723,6 +3811,7 @@ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", "dev": true, + "optional": true, "requires": { "is-utf8": "^0.2.0" } @@ -3732,6 +3821,7 @@ "resolved": "https://registry.npmjs.org/strip-bom-stream/-/strip-bom-stream-1.0.0.tgz", "integrity": "sha1-5xRDmFd9Uaa+0PoZlPoF9D/ZiO4=", "dev": true, + "optional": true, "requires": { "first-chunk-stream": "^1.0.0", "strip-bom": "^2.0.0" @@ -3742,6 +3832,7 @@ "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", "dev": true, + "optional": true, "requires": { "json-stable-stringify-without-jsonify": "^1.0.1", "through2-filter": "^3.0.0" @@ -3752,6 +3843,7 @@ "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", "dev": true, + "optional": true, "requires": { "through2": "~2.0.0", "xtend": "~4.0.0" @@ -3764,6 +3856,7 @@ "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", "dev": true, + "optional": true, "requires": { "clone": "^1.0.0", "clone-stats": "^0.0.1", @@ -3775,6 +3868,7 @@ "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-2.4.4.tgz", "integrity": "sha1-vm/zJwy1Xf19MGNkDegfJddTIjk=", "dev": true, + "optional": true, "requires": { "duplexify": "^3.2.0", "glob-stream": "^5.3.2", @@ -3817,6 +3911,7 @@ "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.6.1.tgz", "integrity": "sha512-vM58DwdnKmty+FSPzT14K9JXb90H+j5emaR4KYbr2KTIz00WHGbWOe5ghQTx233ZCLZtrGDALzKwcjEtSt35mA==", "dev": true, + "optional": true, "requires": { "end-of-stream": "^1.0.0", "inherits": "^2.0.1", @@ -3829,6 +3924,7 @@ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", "dev": true, + "optional": true, "requires": { "once": "^1.4.0" } @@ -3837,13 +3933,15 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "dev": true, + "optional": true }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -3853,6 +3951,7 @@ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, + "optional": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -3868,6 +3967,7 @@ "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, + "optional": true, "requires": { "safe-buffer": "~5.1.0" } @@ -3879,6 +3979,7 @@ "resolved": "https://registry.npmjs.org/each-async/-/each-async-1.1.1.tgz", "integrity": "sha1-3uUim98KtrogEqOV4bhpq/iBNHM=", "dev": true, + "optional": true, "requires": { "onetime": "^1.0.0", "set-immediate-shim": "^1.0.0" @@ -3888,7 +3989,8 @@ "version": "1.1.0", "resolved": "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", - "dev": true + "dev": true, + "optional": true } } }, @@ -3956,7 +4058,7 @@ "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "requires": { "ms": "2.0.0" @@ -3992,7 +4094,7 @@ "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "requires": { "ms": "2.0.0" @@ -4156,7 +4258,7 @@ "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, "optional": true } @@ -4251,7 +4353,7 @@ "eslint-scope": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.0.tgz", - "integrity": "sha1-UL8wcekzi83EMzF5Sgy1M/ATYXI=", + "integrity": "sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA==", "dev": true, "requires": { "esrecurse": "^4.1.0", @@ -4261,13 +4363,13 @@ "eslint-utils": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz", - "integrity": "sha1-moUbqJ7nxGA0b5fPiTnHKYgn5RI=", + "integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==", "dev": true }, "eslint-visitor-keys": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", - "integrity": "sha1-PzGA+y4pEBdxastMnW1bXDSmqB0=", + "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", "dev": true }, "espree": { @@ -4290,7 +4392,7 @@ "esquery": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", - "integrity": "sha1-QGxRZYsfWZGl+bYrHcJbAOPlxwg=", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", "dev": true, "requires": { "estraverse": "^4.0.0" @@ -4299,7 +4401,7 @@ "esrecurse": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha1-AHo7n9vCs7uH5IeeoZyS/b05Qs8=", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", "dev": true, "requires": { "estraverse": "^4.1.0" @@ -4359,7 +4461,7 @@ "eventemitter3": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz", - "integrity": "sha1-CQtNbNvWRe0Qv3UNS1QHlC17oWM=", + "integrity": "sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA==", "dev": true }, "exec-buffer": { @@ -4574,7 +4676,7 @@ "fill-range": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", + "integrity": "sha1-6x53OrsFbc2N8r/favWbizqTZWU=", "dev": true, "requires": { "is-number": "^2.1.0", @@ -4828,6 +4930,7 @@ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", "dev": true, + "optional": true, "requires": { "pend": "~1.2.0" } @@ -4875,13 +4978,15 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-1.0.0.tgz", "integrity": "sha1-5hz4BfDeHJhFZ9A4bcXfUO5a9+Q=", - "dev": true + "dev": true, + "optional": true }, "filenamify": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-1.2.1.tgz", "integrity": "sha1-qfL/0RxQO+0wABUCknI3jx8TZaU=", "dev": true, + "optional": true, "requires": { "filename-reserved-regex": "^1.0.0", "strip-outer": "^1.0.0", @@ -5128,7 +5233,8 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", "integrity": "sha1-a+Dem+mYzhavivwkSXue6bfM2a0=", - "dev": true + "dev": true, + "optional": true }, "fs-extra": { "version": "1.0.0", @@ -5192,7 +5298,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -5213,12 +5320,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -5233,17 +5342,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -5360,7 +5472,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -5372,6 +5485,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -5386,6 +5500,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -5393,12 +5508,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.2.4", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.1", "yallist": "^3.0.0" @@ -5417,6 +5534,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -5497,7 +5615,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -5509,6 +5628,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -5594,7 +5714,8 @@ "safe-buffer": { "version": "5.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -5630,6 +5751,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -5649,6 +5771,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -5692,12 +5815,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, @@ -5733,6 +5858,7 @@ "resolved": "https://registry.npmjs.org/get-proxy/-/get-proxy-1.1.0.tgz", "integrity": "sha1-iUhUSRvFkbDxR9euVw9cZ4tyVus=", "dev": true, + "optional": true, "requires": { "rc": "^1.1.2" } @@ -5894,7 +6020,7 @@ "global-modules": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", - "integrity": "sha1-bXcPDrUjrHgWTXK15xqIdyZcw+o=", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", "dev": true, "requires": { "global-prefix": "^1.0.1", @@ -6039,6 +6165,7 @@ "resolved": "http://registry.npmjs.org/got/-/got-5.7.1.tgz", "integrity": "sha1-X4FjWmHkplifGAVp6k44FoClHzU=", "dev": true, + "optional": true, "requires": { "create-error-class": "^3.0.1", "duplexer2": "^0.1.4", @@ -6062,6 +6189,7 @@ "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", "dev": true, + "optional": true, "requires": { "readable-stream": "^2.0.2" } @@ -6070,19 +6198,22 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true + "dev": true, + "optional": true }, "parse-json": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "dev": true, + "optional": true, "requires": { "error-ex": "^1.2.0" } @@ -6092,6 +6223,7 @@ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, + "optional": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -6107,6 +6239,7 @@ "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, + "optional": true, "requires": { "safe-buffer": "~5.1.0" } @@ -6126,7 +6259,8 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", - "dev": true + "dev": true, + "optional": true }, "growly": { "version": "1.3.0", @@ -6422,6 +6556,7 @@ "resolved": "https://registry.npmjs.org/gulp-decompress/-/gulp-decompress-1.2.0.tgz", "integrity": "sha1-jutlpeAV+O2FMsr+KEVJYGJvDcc=", "dev": true, + "optional": true, "requires": { "archive-type": "^3.0.0", "decompress": "^3.0.0", @@ -6433,13 +6568,15 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "dev": true, + "optional": true }, "readable-stream": { "version": "2.3.6", "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, + "optional": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -6455,6 +6592,7 @@ "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, + "optional": true, "requires": { "safe-buffer": "~5.1.0" } @@ -6464,7 +6602,7 @@ "gulp-eslint": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/gulp-eslint/-/gulp-eslint-5.0.0.tgz", - "integrity": "sha1-KiaECV93Syz3kxAmIHjFbMehK1I=", + "integrity": "sha512-9GUqCqh85C7rP9120cpxXuZz2ayq3BZc85pCTuPJS03VQYxne0aWPIXWx6LSvsGPa3uRqtSO537vaugOh+5cXg==", "dev": true, "requires": { "eslint": "^5.0.1", @@ -7072,6 +7210,7 @@ "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-1.6.0.tgz", "integrity": "sha1-uG/zSdgBzrVuHZ59x7vLS33uYAw=", "dev": true, + "optional": true, "requires": { "convert-source-map": "^1.1.1", "graceful-fs": "^4.1.2", @@ -7084,13 +7223,15 @@ "version": "4.1.15", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", - "dev": true + "dev": true, + "optional": true }, "strip-bom": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", "dev": true, + "optional": true, "requires": { "is-utf8": "^0.2.0" } @@ -7100,6 +7241,7 @@ "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", "dev": true, + "optional": true, "requires": { "clone": "^1.0.0", "clone-stats": "^0.0.1", @@ -7418,7 +7560,7 @@ "has-binary2": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", - "integrity": "sha1-d3asYn8+p3JQz8My2rfd9eT10R0=", + "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", "dev": true, "requires": { "isarray": "2.0.1" @@ -7569,7 +7711,7 @@ "http-proxy": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz", - "integrity": "sha1-etOElGWPhGBeL220Q230EPTlvpo=", + "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==", "dev": true, "requires": { "eventemitter3": "^3.0.0", @@ -7863,7 +8005,7 @@ "is-absolute": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", - "integrity": "sha1-OV4a6EsR8mrReV5zwXN45IowFXY=", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", "dev": true, "requires": { "is-relative": "^1.0.0", @@ -7930,7 +8072,8 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-bzip2/-/is-bzip2-1.0.0.tgz", "integrity": "sha1-XuWOqlounIDiFAe+3yOuWsCRs/w=", - "dev": true + "dev": true, + "optional": true }, "is-callable": { "version": "1.1.4", @@ -8065,7 +8208,8 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-gzip/-/is-gzip-1.0.0.tgz", "integrity": "sha1-bKiwe5nHeZgCWQDlVc7Y7YCHmoM=", - "dev": true + "dev": true, + "optional": true }, "is-jpg": { "version": "1.0.1", @@ -8078,7 +8222,8 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-2.1.1.tgz", "integrity": "sha1-fUxXKDd+84bD4ZSpkRv1fG3DNec=", - "dev": true + "dev": true, + "optional": true }, "is-number": { "version": "3.0.0", @@ -8144,7 +8289,8 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=", - "dev": true + "dev": true, + "optional": true }, "is-regex": { "version": "1.0.4", @@ -8158,7 +8304,7 @@ "is-relative": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", - "integrity": "sha1-obtpNc6MXboei5dUubLcwCDiJg0=", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", "dev": true, "requires": { "is-unc-path": "^1.0.0" @@ -8167,14 +8313,15 @@ "is-resolvable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha1-+xj4fOH+uSUWnJpAfBkxijIG7Yg=", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", "dev": true }, "is-retry-allowed": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=", - "dev": true + "dev": true, + "optional": true }, "is-stream": { "version": "1.1.0", @@ -8204,7 +8351,8 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-tar/-/is-tar-1.0.0.tgz", "integrity": "sha1-L2suF5LB9bs2UZrKqdZcDSb+hT0=", - "dev": true + "dev": true, + "optional": true }, "is-typedarray": { "version": "1.0.0", @@ -8215,7 +8363,7 @@ "is-unc-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", - "integrity": "sha1-1zHoiY7QkKEsNSrS6u1Qla0yLJ0=", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", "dev": true, "requires": { "unc-path-regex": "^0.1.2" @@ -8225,7 +8373,8 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==", - "dev": true + "dev": true, + "optional": true }, "is-utf8": { "version": "0.2.1", @@ -8237,7 +8386,8 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-0.3.0.tgz", "integrity": "sha1-1LVcafUYhvm2XHDWwmItN+KfSP4=", - "dev": true + "dev": true, + "optional": true }, "is-windows": { "version": "1.0.2", @@ -8255,7 +8405,8 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-zip/-/is-zip-1.0.0.tgz", "integrity": "sha1-R7Co/004p2QxzP2ZqOFaTIa6IyU=", - "dev": true + "dev": true, + "optional": true }, "isarray": { "version": "0.0.1", @@ -8372,7 +8523,7 @@ "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha1-afaofZUTq4u4/mO9sJecRI5oRmA=", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, "json-stable-stringify-without-jsonify": { @@ -8499,7 +8650,7 @@ "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true } } @@ -8576,6 +8727,7 @@ "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", "dev": true, + "optional": true, "requires": { "readable-stream": "^2.0.5" }, @@ -8584,13 +8736,15 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "dev": true, + "optional": true }, "readable-stream": { "version": "2.3.6", "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, + "optional": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -8606,6 +8760,7 @@ "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, + "optional": true, "requires": { "safe-buffer": "~5.1.0" } @@ -8911,7 +9066,8 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=", - "dev": true + "dev": true, + "optional": true }, "lodash.isobject": { "version": "2.4.1", @@ -9108,7 +9264,8 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", "integrity": "sha1-b54wtHCE2XGnyCD/FabFFnt0wm8=", - "dev": true + "dev": true, + "optional": true }, "lpad-align": { "version": "1.1.2", @@ -9149,7 +9306,7 @@ "make-iterator": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", - "integrity": "sha1-KbM/MSqo9UfEpeSQ9Wr87JkTOtY=", + "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", "dev": true, "requires": { "kind-of": "^6.0.2" @@ -9330,7 +9487,7 @@ "mimic-fn": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha1-ggyGo5M0ZA6ZUWkovQP8qIBX0CI=", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", "dev": true }, "minimatch": { @@ -9504,7 +9661,8 @@ "version": "1.0.0", "resolved": "http://registry.npmjs.org/node-status-codes/-/node-status-codes-1.0.0.tgz", "integrity": "sha1-WuVUHQJGRdMqWPzdyc7s6nrjrC8=", - "dev": true + "dev": true, + "optional": true }, "node.extend": { "version": "1.1.8", @@ -12554,7 +12712,8 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true + "dev": true, + "optional": true }, "p-pipe": { "version": "1.2.0", @@ -12858,7 +13017,7 @@ "pluralize": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", - "integrity": "sha1-KYuJ34uTsCIdv0Ia0rGx6iP8Z3c=", + "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", "dev": true }, "posix-character-classes": { @@ -13265,7 +13424,8 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", - "dev": true + "dev": true, + "optional": true }, "preserve": { "version": "0.2.0", @@ -13348,7 +13508,7 @@ "qjobs": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", - "integrity": "sha1-xF6cYYAL0IfviNfiVkI73Unl0HE=", + "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", "dev": true }, "qs": { @@ -13397,6 +13557,7 @@ "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", "dev": true, + "optional": true, "requires": { "deep-extend": "^0.6.0", "ini": "~1.3.0", @@ -13409,6 +13570,7 @@ "resolved": "https://registry.npmjs.org/read-all-stream/-/read-all-stream-3.1.0.tgz", "integrity": "sha1-NcPhd/IHjveJ7kv6+kNzB06u9Po=", "dev": true, + "optional": true, "requires": { "pinkie-promise": "^2.0.0", "readable-stream": "^2.0.0" @@ -13418,13 +13580,15 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "dev": true, + "optional": true }, "readable-stream": { "version": "2.3.6", "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, + "optional": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -13440,6 +13604,7 @@ "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, + "optional": true, "requires": { "safe-buffer": "~5.1.0" } @@ -13544,7 +13709,7 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { @@ -14042,7 +14207,7 @@ "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo=", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, "sax": { @@ -14056,6 +14221,7 @@ "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.5.tgz", "integrity": "sha1-z+kXyz0nS8/6x5J1ivUxc+sfq9w=", "dev": true, + "optional": true, "requires": { "commander": "~2.8.1" } @@ -14201,7 +14367,8 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", - "dev": true + "dev": true, + "optional": true }, "set-value": { "version": "2.0.0", @@ -14229,7 +14396,7 @@ "setprototypeof": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha1-0L2FU2iHtv58DYGMuWLZ2RxU5lY=", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", "dev": true }, "shebang-command": { @@ -14519,7 +14686,7 @@ "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "requires": { "ms": "2.0.0" @@ -14706,7 +14873,8 @@ "version": "0.2.2", "resolved": "https://registry.npmjs.org/stat-mode/-/stat-mode-0.2.2.tgz", "integrity": "sha1-5sgLYjEj19gM8TLOU480YokHJQI=", - "dev": true + "dev": true, + "optional": true }, "static-extend": { "version": "0.1.2", @@ -14750,6 +14918,7 @@ "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=", "dev": true, + "optional": true, "requires": { "duplexer2": "~0.1.0", "readable-stream": "^2.0.2" @@ -14760,6 +14929,7 @@ "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", "dev": true, + "optional": true, "requires": { "readable-stream": "^2.0.2" } @@ -14768,13 +14938,15 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "dev": true, + "optional": true }, "readable-stream": { "version": "2.3.6", "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, + "optional": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -14790,6 +14962,7 @@ "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, + "optional": true, "requires": { "safe-buffer": "~5.1.0" } @@ -14799,19 +14972,20 @@ "stream-consume": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/stream-consume/-/stream-consume-0.1.1.tgz", - "integrity": "sha1-0721mMK9CugrjKx6xQsRB6eZbEg=", + "integrity": "sha512-tNa3hzgkjEP7XbCkbRXe1jpg+ievoa0O4SCFlMOYEscGSS4JJsckGL8swUyAa/ApGU3Ae4t6Honor4HhL+tRyg==", "dev": true }, "stream-shift": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", - "dev": true + "dev": true, + "optional": true }, "streamroller": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-0.7.0.tgz", - "integrity": "sha1-odG3z4PTmvsNYwSaWsv5NJO99ks=", + "integrity": "sha512-WREzfy0r0zUqp3lGO096wRuUp7ho1X6uo/7DJfTlEi0Iv/4gT7YHqXDjKC2ioVGBZtE8QzsQD9nx1nIuoZ57jQ==", "dev": true, "requires": { "date-format": "^1.2.0", @@ -14838,7 +15012,7 @@ "readable-stream": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha1-sRwn2IuP8fvgcGQ8+UsMea4bCq8=", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { "core-util-is": "~1.0.0", @@ -14853,7 +15027,7 @@ "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { "safe-buffer": "~5.1.0" @@ -14870,7 +15044,7 @@ "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", @@ -14984,6 +15158,7 @@ "resolved": "http://registry.npmjs.org/strip-dirs/-/strip-dirs-1.1.1.tgz", "integrity": "sha1-lgu9EoeETzl1pFWKoQOoJV4kVqA=", "dev": true, + "optional": true, "requires": { "chalk": "^1.0.0", "get-stdin": "^4.0.1", @@ -14997,13 +15172,15 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true + "dev": true, + "optional": true }, "chalk": { "version": "1.1.3", "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, + "optional": true, "requires": { "ansi-styles": "^2.2.1", "escape-string-regexp": "^1.0.2", @@ -15017,6 +15194,7 @@ "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-0.1.7.tgz", "integrity": "sha1-hHSREZ/MtftDYhfMc39/qtUPYD8=", "dev": true, + "optional": true, "requires": { "is-relative": "^0.1.0" } @@ -15025,13 +15203,15 @@ "version": "0.1.3", "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-0.1.3.tgz", "integrity": "sha1-kF/uiuhvRbPsYUvDwVyGnfCHboI=", - "dev": true + "dev": true, + "optional": true }, "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true + "dev": true, + "optional": true } } }, @@ -15062,6 +15242,7 @@ "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", "integrity": "sha1-sv0qv2YEudHmATBXGV34Nrip1jE=", "dev": true, + "optional": true, "requires": { "escape-string-regexp": "^1.0.2" } @@ -15095,6 +15276,7 @@ "resolved": "https://registry.npmjs.org/sum-up/-/sum-up-1.0.3.tgz", "integrity": "sha1-HGYfZnBX9jvLeHWqFDi8FiUlFW4=", "dev": true, + "optional": true, "requires": { "chalk": "^1.0.0" }, @@ -15103,13 +15285,15 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true + "dev": true, + "optional": true }, "chalk": { "version": "1.1.3", "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, + "optional": true, "requires": { "ansi-styles": "^2.2.1", "escape-string-regexp": "^1.0.2", @@ -15122,7 +15306,8 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true + "dev": true, + "optional": true } } }, @@ -15184,6 +15369,7 @@ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", "dev": true, + "optional": true, "requires": { "bl": "^1.0.0", "buffer-alloc": "^1.2.0", @@ -15199,6 +15385,7 @@ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", "integrity": "sha1-7SljTRm6ukY7bOa4CjchPqtx7EM=", "dev": true, + "optional": true, "requires": { "once": "^1.4.0" } @@ -15207,13 +15394,15 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "dev": true, + "optional": true }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -15223,6 +15412,7 @@ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, + "optional": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -15238,6 +15428,7 @@ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, + "optional": true, "requires": { "safe-buffer": "~5.1.0" } @@ -15336,6 +15527,7 @@ "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-2.0.0.tgz", "integrity": "sha1-YLxVoNrLdghdsfna6Zq0P4PWIuw=", "dev": true, + "optional": true, "requires": { "through2": "~2.0.0", "xtend": "~4.0.0" @@ -15360,7 +15552,8 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-3.1.3.tgz", "integrity": "sha1-lYYL/MXHbCd/j4Mm/Q9bLiDrohc=", - "dev": true + "dev": true, + "optional": true }, "timsort": { "version": "0.3.0", @@ -15412,7 +15605,7 @@ "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha1-bTQzWIl2jSGyvNoKonfO07G/rfk=", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "dev": true, "requires": { "os-tmpdir": "~1.0.2" @@ -15423,6 +15616,7 @@ "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-0.1.1.tgz", "integrity": "sha1-HN+kcqnvUMI57maZm2YsoOs5k38=", "dev": true, + "optional": true, "requires": { "extend-shallow": "^2.0.1" }, @@ -15432,6 +15626,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, + "optional": true, "requires": { "is-extendable": "^0.1.0" } @@ -15448,7 +15643,8 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", "integrity": "sha1-STvUj2LXxD/N7TE6A9ytsuEhOoA=", - "dev": true + "dev": true, + "optional": true }, "to-fast-properties": { "version": "2.0.0", @@ -15527,6 +15723,7 @@ "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", "integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=", "dev": true, + "optional": true, "requires": { "escape-string-regexp": "^1.0.2" } @@ -15576,7 +15773,7 @@ "type-is": { "version": "1.6.16", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", - "integrity": "sha1-+JzjQVQcZysl7nrjxz3uOyvlAZQ=", + "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", "dev": true, "requires": { "media-typer": "0.3.0", @@ -15618,7 +15815,7 @@ "ultron": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", - "integrity": "sha1-n+FTahCmZKZSZqHjzPhf02MCvJw=", + "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", "dev": true }, "unc-path-regex": { @@ -15775,18 +15972,19 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-1.0.2.tgz", "integrity": "sha1-uYTwh3/AqJwsdzzB73tbIytbBv4=", - "dev": true + "dev": true, + "optional": true }, "upath": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz", - "integrity": "sha1-NSVll+RqWB20eT0M5H+prr/J+r0=", + "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==", "dev": true }, "uri-js": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha1-lMVA4f93KVbiKZUHwBCupsiDjrA=", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", "dev": true, "requires": { "punycode": "^2.1.0" @@ -15803,6 +16001,7 @@ "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", "dev": true, + "optional": true, "requires": { "prepend-http": "^1.0.1" } @@ -15888,7 +16087,8 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/vali-date/-/vali-date-1.0.0.tgz", "integrity": "sha1-G5BKWWCfsyjvB4E4Qgk09rhnCaY=", - "dev": true + "dev": true, + "optional": true }, "validate-npm-package-license": { "version": "3.0.4", @@ -15933,6 +16133,7 @@ "resolved": "https://registry.npmjs.org/vinyl-assign/-/vinyl-assign-1.2.1.tgz", "integrity": "sha1-TRmIkbVRWRHXcajNnFSApGoHSkU=", "dev": true, + "optional": true, "requires": { "object-assign": "^4.0.1", "readable-stream": "^2.0.0" @@ -15942,19 +16143,22 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true + "dev": true, + "optional": true }, "readable-stream": { "version": "2.3.6", "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, + "optional": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -15970,6 +16174,7 @@ "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, + "optional": true, "requires": { "safe-buffer": "~5.1.0" } @@ -16109,6 +16314,7 @@ "resolved": "https://registry.npmjs.org/ware/-/ware-1.3.0.tgz", "integrity": "sha1-0bFPOdLiy0q4xAmPdW/ksWTkc9Q=", "dev": true, + "optional": true, "requires": { "wrap-fn": "^0.1.0" } @@ -16199,6 +16405,7 @@ "resolved": "https://registry.npmjs.org/wrap-fn/-/wrap-fn-0.1.5.tgz", "integrity": "sha1-8htuQQFv9KfjFyDbxjoJAWvfmEU=", "dev": true, + "optional": true, "requires": { "co": "3.1.0" } @@ -16221,7 +16428,7 @@ "ws": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", - "integrity": "sha1-8c+E/i1ekB686U767OeF8YeiKPI=", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", "dev": true, "requires": { "async-limiter": "~1.0.0", @@ -16296,6 +16503,7 @@ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", "dev": true, + "optional": true, "requires": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbsections.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbsections.directive.js index 5006087ca5..14c9878839 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbsections.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbsections.directive.js @@ -105,11 +105,6 @@ function sectionsDirective($timeout, $window, navigationService, treeService, se return; } - if (scope.userDialog) { - closeUserDialog(); - } - - navigationService.hideSearch(); navigationService.showTree(section.alias); diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js index 16db974df9..b1ce4a266c 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js @@ -871,6 +871,8 @@ $scope.app = app; + $scope.$broadcast("editors.apps.appChanged", { app: app }); + if (infiniteMode) { createInfiniteModeButtons($scope.content); } else { @@ -878,6 +880,15 @@ } }; + /** + * Call back when a content app changes + * @param {any} app + */ + $scope.appAnchorChanged = function (app, anchor) { + //send an event downwards + $scope.$broadcast("editors.apps.appAnchorChanged", { app: app, anchor: anchor }); + }; + // methods for infinite editing $scope.close = function () { if ($scope.infiniteModel.close) { diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbcontentnodeinfo.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbcontentnodeinfo.directive.js index 06a147969a..a043b292ef 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbcontentnodeinfo.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbcontentnodeinfo.directive.js @@ -3,7 +3,7 @@ function ContentNodeInfoDirective($timeout, logResource, eventsService, userService, localizationService, dateHelper, editorService, redirectUrlsResource, overlayService) { - function link(scope, umbVariantContentCtrl) { + function link(scope) { var evts = []; var isInfoTab = false; @@ -96,22 +96,17 @@ scope.previewOpenUrl = '#/settings/documenttypes/edit/' + scope.documentType.id; } - //load in the audit trail if we are currently looking at the INFO tab - if (umbVariantContentCtrl && umbVariantContentCtrl.editor) { - var activeApp = _.find(umbVariantContentCtrl.editor.content.apps, a => a.active); - if (activeApp && activeApp.alias === "umbInfo") { - isInfoTab = true; - loadAuditTrail(); - loadRedirectUrls(); - } + var activeApp = _.find(scope.node.apps, (a) => a.active); + if (activeApp.alias === "umbInfo") { + loadRedirectUrls(); + loadAuditTrail(); } } scope.auditTrailPageChange = function (pageNumber) { scope.auditTrailOptions.pageNumber = pageNumber; - auditTrailLoaded = false; - loadAuditTrail(); + loadAuditTrail(true); }; scope.openDocumentType = function (documentType) { @@ -192,10 +187,12 @@ editorService.rollback(rollback); }; - function loadAuditTrail() { + function loadAuditTrail(forceReload) { //don't load this if it's already done - if (auditTrailLoaded) { return; }; + if (auditTrailLoaded && !forceReload) { + return; + } scope.loadingAuditTrail = true; @@ -334,8 +331,7 @@ if (newValue === oldValue) { return; } if (isInfoTab) { - auditTrailLoaded = false; - loadAuditTrail(); + loadAuditTrail(true); loadRedirectUrls(); setNodePublishStatus(); updateCurrentUrls(); diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbtabbedcontent.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbtabbedcontent.directive.js index 5ebb40fac6..06f426889f 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbtabbedcontent.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbtabbedcontent.directive.js @@ -2,40 +2,153 @@ 'use strict'; /** This directive is used to render out the current variant tabs and properties and exposes an API for other directives to consume */ - function tabbedContentDirective() { + function tabbedContentDirective($timeout) { + + function link($scope, $element, $attrs) { + + var appRootNode = $element[0]; + + // Directive for cached property groups. + var propertyGroupNodesDictionary = {}; + + var scrollableNode = appRootNode.closest(".umb-scrollable"); + scrollableNode.addEventListener("scroll", onScroll); + scrollableNode.addEventListener("mousewheel", cancelScrollTween); + + function onScroll(event) { + + var viewFocusY = scrollableNode.scrollTop + scrollableNode.clientHeight * .5; + + for(var i in $scope.content.tabs) { + var group = $scope.content.tabs[i]; + var node = propertyGroupNodesDictionary[group.id]; + if (viewFocusY >= node.offsetTop && viewFocusY <= node.offsetTop + node.clientHeight) { + setActiveAnchor(group); + return; + } + } + + } + + function setActiveAnchor(tab) { + if (tab.active !== true) { + var i = $scope.content.tabs.length; + while(i--) { + $scope.content.tabs[i].active = false; + } + tab.active = true; + } + } + function getActiveAnchor() { + var i = $scope.content.tabs.length; + while(i--) { + if ($scope.content.tabs[i].active === true) + return $scope.content.tabs[i]; + } + return false; + } + function getScrollPositionFor(id) { + if (propertyGroupNodesDictionary[id]) { + return propertyGroupNodesDictionary[id].offsetTop - 20;// currently only relative to closest relatively positioned parent + } + return null; + } + function scrollTo(id) { + var y = getScrollPositionFor(id); + if (getScrollPositionFor !== null) { + + var viewportHeight = scrollableNode.clientHeight; + var from = scrollableNode.scrollTop; + var to = Math.min(y, scrollableNode.scrollHeight - viewportHeight); + + var animeObject = {_y: from}; + $scope.scrollTween = anime({ + targets: animeObject, + _y: to, + easing: 'easeOutExpo', + duration: 200 + Math.min(Math.abs(to-from)/viewportHeight*100, 400), + update: () => { + scrollableNode.scrollTo(0, animeObject._y); + } + }); + + } + } + function jumpTo(id) { + var y = getScrollPositionFor(id); + if (getScrollPositionFor !== null) { + cancelScrollTween(); + scrollableNode.scrollTo(0, y); + } + } + function cancelScrollTween() { + if($scope.scrollTween) { + $scope.scrollTween.pause(); + } + } + + $scope.registerPropertyGroup = function(element, appAnchor) { + propertyGroupNodesDictionary[appAnchor] = element; + }; + + $scope.$on("editors.apps.appChanged", function($event, $args) { + // if app changed to this app, then we want to scroll to the current anchor + if($args.app.alias === "umbContent") { + var activeAnchor = getActiveAnchor(); + $timeout(jumpTo.bind(null, [activeAnchor.id])); + } + }); + + $scope.$on("editors.apps.appAnchorChanged", function($event, $args) { + if($args.app.alias === "umbContent") { + setActiveAnchor($args.anchor); + scrollTo($args.anchor.id); + } + }); + + //ensure to unregister from all dom-events + $scope.$on('$destroy', function () { + cancelScrollTween(); + scrollableNode.removeEventListener("scroll", onScroll); + scrollableNode.removeEventListener("mousewheel", cancelScrollTween); + }); + + } + + function controller($scope, $element, $attrs) { + + + //expose the property/methods for other directives to use + this.content = $scope.content; + this.activeVariant = _.find(this.content.variants, variant => { + return variant.active; + }); + + $scope.activeVariant = this.activeVariant; + + $scope.defaultVariant = _.find(this.content.variants, variant => { + return variant.language.isDefault; + }); + + $scope.unlockInvariantValue = function(property) { + property.unlockInvariantValue = !property.unlockInvariantValue; + }; + + $scope.$watch("tabbedContentForm.$dirty", + function (newValue, oldValue) { + if (newValue === true) { + $scope.content.isDirty = true; + } + } + ); + } var directive = { restrict: 'E', replace: true, templateUrl: 'views/components/content/umb-tabbed-content.html', - controller: function ($scope) { - - //expose the property/methods for other directives to use - this.content = $scope.content; - this.activeVariant = _.find(this.content.variants, variant => { - return variant.active; - }); - - $scope.activeVariant = this.activeVariant; - - $scope.defaultVariant = _.find(this.content.variants, variant => { - return variant.language.isDefault; - }); - - $scope.unlockInvariantValue = function(property) { - property.unlockInvariantValue = !property.unlockInvariantValue; - }; - - $scope.$watch("tabbedContentForm.$dirty", - function (newValue, oldValue) { - if (newValue === true) { - $scope.content.isDirty = true; - } - }); - }, - link: function(scope) { - - }, + controller: controller, + link: link, scope: { content: "=" } diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbvariantcontent.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbvariantcontent.directive.js index 8545854992..5556308e06 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbvariantcontent.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbvariantcontent.directive.js @@ -16,7 +16,8 @@ onCloseSplitView: "&", onSelectVariant: "&", onOpenSplitView: "&", - onSelectApp: "&" + onSelectApp: "&", + onSelectAppAnchor: "&" }, controllerAs: 'vm', controller: umbVariantContentController @@ -35,6 +36,7 @@ vm.selectVariant = selectVariant; vm.openSplitView = openSplitView; vm.selectApp = selectApp; + vm.selectAppAnchor = selectAppAnchor; function onInit() { // disable the name field if the active content app is not "Content" @@ -78,16 +80,31 @@ * @param {any} item */ function selectApp(item) { - // disable the name field if the active content app is not "Content" or "Info" - vm.nameDisabled = false; - if(item && item.alias !== "umbContent" && item.alias !== "umbInfo") { - vm.nameDisabled = true; - } // call the callback if any is registered if(vm.onSelectApp) { vm.onSelectApp({"app": item}); } } + + $scope.$on("editors.apps.appChanged", function($event, $args) { + var app = $args.app; + // disable the name field if the active content app is not "Content" or "Info" + vm.nameDisabled = false; + if(app && app.alias !== "umbContent" && app.alias !== "umbInfo") { + vm.nameDisabled = true; + } + }); + + /** + * Used to proxy a callback + * @param {any} item + */ + function selectAppAnchor(item, anchor) { + // call the callback if any is registered + if(vm.onSelectAppAnchor) { + vm.onSelectAppAnchor({"app": item, "anchor": anchor}); + } + } /** * Used to proxy a callback diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbvariantcontenteditors.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbvariantcontenteditors.directive.js index addbb3b11b..bd21cca541 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbvariantcontenteditors.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbvariantcontenteditors.directive.js @@ -10,7 +10,8 @@ page: "<", content: "<", // TODO: Not sure if this should be = since we are changing the 'active' property of a variant culture: "<", - onSelectApp: "&?" + onSelectApp: "&?", + onSelectAppAnchor: "&?" }, controllerAs: 'vm', controller: umbVariantContentEditorsController @@ -32,6 +33,7 @@ vm.closeSplitView = closeSplitView; vm.selectVariant = selectVariant; vm.selectApp = selectApp; + vm.selectAppAnchor = selectAppAnchor; //Used to track how many content views there are (for split view there will be 2, it could support more in theory) vm.editors = []; @@ -316,13 +318,24 @@ * @param {any} app This is the model of the selected app */ function selectApp(app) { - if(app && app.alias) { - activeAppAlias = app.alias; - } if(vm.onSelectApp) { vm.onSelectApp({"app": app}); } } + + function selectAppAnchor(app, anchor) { + if(vm.onSelectAppAnchor) { + vm.onSelectAppAnchor({"app": app, "anchor": anchor}); + } + } + + + $scope.$on("editors.apps.appChanged", function($event, $args) { + var app = $args.app; + if(app && app.alias) { + activeAppAlias = app.alias; + } + }); } diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorcontentheader.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorcontentheader.directive.js index 0d78aab0eb..ad20c6bbae 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorcontentheader.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorcontentheader.directive.js @@ -11,17 +11,26 @@ if (!scope.serverValidationAliasField) { scope.serverValidationAliasField = "Alias"; } - + scope.vm = {}; scope.vm.dropdownOpen = false; scope.vm.currentVariant = ""; function onInit() { + setCurrentVariant(); + + angular.forEach(scope.content.apps, (app) => { + if (app.alias === "umbContent") { + console.log("app: ", app) + app.anchors = scope.content.tabs; + } + }); + } function setCurrentVariant() { - angular.forEach(scope.variants, function (variant) { + angular.forEach(scope.content.variants, function (variant) { if (variant.active) { scope.vm.currentVariant = variant; } @@ -46,6 +55,12 @@ } } + scope.selectAnchorItem = function(item, anchor) { + if(scope.onSelectAnchorItem) { + scope.onSelectAnchorItem({"item": item, "anchor": anchor}); + } + } + scope.closeSplitView = function () { if (scope.onCloseSplitView) { scope.onCloseSplitView(); @@ -72,10 +87,10 @@ onInit(); //watch for the active culture changing, if it changes, update the current variant - if (scope.variants) { + if (scope.content.variants) { scope.$watch(function () { - for (var i = 0; i < scope.variants.length; i++) { - var v = scope.variants[i]; + for (var i = 0; i < scope.content.variants.length; i++) { + var v = scope.content.variants[i]; if (v.active) { return v.language.culture; } @@ -100,11 +115,11 @@ nameDisabled: " a { + text-align: center; + cursor: pointer; + display: block; + padding: 4px 10px 0 10px; + min-width: 70px; + border-right: 1px solid @gray-9; + box-sizing: border-box; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: @editorHeaderHeight; + position: relative; + + color: @ui-active-type; + + &:hover { + color: @ui-active-type-hover !important; + } + + &::after { + content: ""; + height: 0px; + left: 8px; + right: 8px; + background-color: @ui-light-active-border; + position: absolute; + bottom: 0; + border-radius: 3px 3px 0 0; + opacity: 0; + transition: all .2s linear; + } +} + +.umb-sub-views-nav-item > a:active { + .box-shadow(~"inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05)"); +} +.umb-sub-views-nav-item > a:focus { + outline: none; +} + +.umb-sub-views-nav-item > a:hover, +.umb-sub-views-nav-item > a:focus { + text-decoration: none; +} + +.umb-sub-views-nav-item > a.is-active { + + color: @ui-light-active-type; + + &::after { + opacity: 1; + height: 4px; + } +} + +.show-validation .umb-sub-views-nav-item > a.-has-error { + color: @red; +} + +.umb-sub-views-nav-item .icon { + font-size: 24px; + display: block; + text-align: center; + margin-bottom: 7px; +} + +.umb-sub-views-nav-item .badge { + position: absolute; + top: 6px; + right: 6px; + min-width: 16px; + color: @white; + background-color: @ui-active-type; + border: 2px solid @white; + border-radius: 50%; + font-size: 10px; + font-weight: bold; + padding: 2px; + line-height: 16px; + display: block; + + &.-type-alert { + background-color: @red; + } + &.-type-warning { + background-color: @yellow-d2; + } + &:empty { + height: 12px; + min-width: 12px; + } +} + +.umb-sub-views-nav-item-text { + font-size: 12px; + line-height: 1em; +} + + +.umb-sub-views-nav-item__anchor_dropdown {// inherits from .dropdown-menu + display: block; + margin: 0; + overflow: hidden; + + // center align horizontal + left: 50%; + transform: translateX(-50%); + + visibility:hidden; + opacity: 0; + transition: visibility 0s 500ms, opacity 250ms 250ms; +} +.umb-sub-views-nav-item__anchor_dropdown li a { + border-left: 4px solid transparent; +} +.umb-sub-views-nav-item__anchor_dropdown li.is-active a { + border-left-color: @ui-selected-border; +} + +.umb-sub-views-nav-item:hover .umb-sub-views-nav-item__anchor_dropdown { + visibility:visible; + opacity: 1; + transition: visibility 0s 0s, opacity 20ms 0s; +} + + + +// -------------------------------- +// item__more, appears when there is not enough room for the visible items. +// -------------------------------- + +.umb-sub-views-nav-item-more__icon { + margin-bottom: 10px; +} + +.umb-sub-views-nav-item-more__icon i { + height: 5px; + width: 5px; + border-radius: 50%; + background: @ui-active-type;// fallback if browser doesnt support currentColor + background: currentColor; + display: inline-block; + margin: 0 5px 0 0; +} + +.umb-sub-views-nav-item-more__icon i:last-of-type { + margin-right: 0; +} + +.umb-sub-views-nav-item-more__dropdown { + left: auto; + right: 0; + display: grid; + grid-template-columns: 1fr 1fr 1fr; + min-width: auto; + margin-top: 10px; +} +.umb-sub-views-nav-item-more__dropdown > li { + display: flex; +} +.umb-sub-views-nav-item-more__dropdown .umb-sub-views-nav-item:first { + border-left: none; +} diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-editor-navigation.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-editor-navigation.less index c1f099c2a5..985765e53a 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/umb-editor-navigation.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-editor-navigation.less @@ -4,135 +4,3 @@ margin: 0; border-left: 1px solid @gray-9; } - -.umb-sub-views-nav-item { - text-align: center; - cursor: pointer; - display: block; - padding: 4px 10px 0 10px; - //border-bottom: 4px solid transparent; - min-width: 70px; - border-right: 1px solid @gray-9; - box-sizing: border-box; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - height: @editorHeaderHeight; - position: relative; - - color: @ui-active-type; - - &:hover { - color: @ui-active-type-hover !important; - } - - &::after { - content: ""; - height: 0px; - left: 8px; - right: 8px; - background-color: @ui-light-active-border; - position: absolute; - bottom: 0; - border-radius: 3px 3px 0 0; - opacity: 0; - transition: all .2s linear; - } -} - -.umb-sub-views-nav-item:focus { - outline: none; -} - -.umb-sub-views-nav-item:hover, -.umb-sub-views-nav-item:focus { - text-decoration: none; -} - -.umb-sub-views-nav-item.is-active { - //color: @ui-active; - //border-bottom-color: @ui-active; - - //background-color: rgba(@ui-active, 0.25); - color: @ui-light-active-type; - //border-bottom-color: @ui-active; - &::after { - opacity: 1; - height: 4px; - } -} - -.show-validation .umb-sub-views-nav-item.-has-error { - color: @red; -} - -.umb-sub-views-nav-item .icon { - font-size: 24px; - display: block; - text-align: center; - margin-bottom: 7px; -} - -.umb-sub-views-nav-item .badge { - position: absolute; - top: 6px; - right: 6px; - min-width: 16px; - color: @white; - background-color: @ui-active-type; - border: 2px solid @white; - border-radius: 50%; - font-size: 10px; - font-weight: bold; - padding: 2px; - line-height: 16px; - display: block; - - &.-type-alert { - background-color: @red; - } - &.-type-warning { - background-color: @yellow-d2; - } - &:empty { - height: 12px; - min-width: 12px; - } -} - -.umb-sub-views-nav-item-text { - font-size: 12px; - line-height: 1em; -} - -.umb-sub-views-nav-item__more { - margin-bottom: 10px; -} - -.umb-sub-views-nav-item__more i { - height: 5px; - width: 5px; - border-radius: 50%; - background: @gray-3; - display: inline-block; - margin: 0 5px 0 0; -} - -.umb-sub-views-nav-item__more i:last-of-type { - margin-right: 0; -} - -// make dots green the an item is active -.umb-sub-views-nav-item.is-active .umb-sub-views-nav-item__more i { - background-color: @ui-active; -} - -.umb-sub-views-nav__dropdown.umb-sub-views-nav__dropdown { - left: auto; - right: 0; - display: grid; - grid-template-columns: 1fr 1fr 1fr; - min-width: auto; - margin-top: 10px; -} diff --git a/src/Umbraco.Web.UI.Client/src/less/navs.less b/src/Umbraco.Web.UI.Client/src/less/navs.less index 0101113670..a2710fab6c 100644 --- a/src/Umbraco.Web.UI.Client/src/less/navs.less +++ b/src/Umbraco.Web.UI.Client/src/less/navs.less @@ -220,6 +220,7 @@ // DROPDOWNS // --------- .dropdown-menu { + display: block; border-radius: @dropdownBorderRadius; box-shadow: 0 5px 20px rgba(0,0,0,.3); padding-top: 0; diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/datatypesettings/datatypesettings.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/datatypesettings/datatypesettings.controller.js index 9fbbad8f09..099439fa4b 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/datatypesettings/datatypesettings.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/datatypesettings/datatypesettings.controller.js @@ -10,7 +10,7 @@ (function () { "use strict"; - function DataTypeSettingsController($scope, dataTypeResource, dataTypeHelper, localizationService) { + function DataTypeSettingsController($scope, dataTypeResource, dataTypeHelper, localizationService, notificationsService, overlayService, formHelper) { var vm = this; @@ -102,7 +102,7 @@ vm.saveButtonState = "busy"; var preValues = dataTypeHelper.createPreValueProps(vm.dataType.preValues); - + dataTypeResource.save(vm.dataType, preValues, $scope.model.create).then(function(newDataType) { $scope.model.dataType = newDataType; vm.saveButtonState = "success"; @@ -110,6 +110,19 @@ if ($scope.model && $scope.model.submit) { $scope.model.submit($scope.model); } + }, function(err) { + vm.saveButtonState = "error"; + + if(err.status === 400) { + if (err.data && (err.data.ModelState)) { + + formHelper.handleServerValidation(err.data.ModelState); + + for (var e in err.data.ModelState) { + notificationsService.error("Validation", err.data.ModelState[e][0]); + } + } + } }); } @@ -120,4 +133,4 @@ angular.module("umbraco").controller("Umbraco.Editors.DataTypeSettingsController", DataTypeSettingsController); -})(); \ No newline at end of file +})(); diff --git a/src/Umbraco.Web.UI.Client/src/views/components/content/edit.html b/src/Umbraco.Web.UI.Client/src/views/components/content/edit.html index e97eabf17f..dda9334e05 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/content/edit.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/content/edit.html @@ -10,7 +10,8 @@ page="page" content="content" culture="culture" - on-select-app="appChanged(app)"> + on-select-app="appChanged(app)" + on-select-app-anchor="appAnchorChanged(app, anchor)"> diff --git a/src/Umbraco.Web.UI.Client/src/views/components/content/umb-tabbed-content.html b/src/Umbraco.Web.UI.Client/src/views/components/content/umb-tabbed-content.html index cdacea7cf1..b76c74149d 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/content/umb-tabbed-content.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/content/umb-tabbed-content.html @@ -1,16 +1,15 @@ 
-
+
-
+
{{ group.label }}
-  
-
- + diff --git a/src/Umbraco.Web.UI.Client/src/views/components/content/umb-variant-content-editors.html b/src/Umbraco.Web.UI.Client/src/views/components/content/umb-variant-content-editors.html index 9d879fac22..76bca6fce2 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/content/umb-variant-content-editors.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/content/umb-variant-content-editors.html @@ -13,7 +13,8 @@ on-open-split-view="vm.openSplitView(variant)" on-close-split-view="vm.closeSplitView($index)" on-select-variant="vm.selectVariant(variant, $index)" - on-select-app="vm.selectApp(app)"> + on-select-app="vm.selectApp(app)" + on-select-app-anchor="vm.selectAppAnchor(app, anchor)">
diff --git a/src/Umbraco.Web.UI.Client/src/views/components/content/umb-variant-content.html b/src/Umbraco.Web.UI.Client/src/views/components/content/umb-variant-content.html index c03b017a82..34c7792055 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/content/umb-variant-content.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/content/umb-variant-content.html @@ -1,19 +1,19 @@ 
- -
+
+ navigation="content.apps" + on-select="selectNavigationItem(item)" + on-anchor-select="selectAnchorItem(item, anchor)">
diff --git a/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-navigation-item.html b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-navigation-item.html new file mode 100644 index 0000000000..90408e00cc --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-navigation-item.html @@ -0,0 +1,19 @@ + + + {{ vm.item.name }} +
{{vm.item.badge.count}}
+
+ + diff --git a/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-navigation.html b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-navigation.html index e278a8c401..0c8f0be7a2 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-navigation.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-navigation.html @@ -1,46 +1,41 @@
    -
  • -
  • +
    + +
  • - -
    - {{ moreButton.name }} -
    +
  • diff --git a/src/Umbraco.Web.UI.Client/src/views/components/umb-dropdown.html b/src/Umbraco.Web.UI.Client/src/views/components/umb-dropdown.html index 141793f6b1..2f24186597 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/umb-dropdown.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/umb-dropdown.html @@ -1 +1 @@ - \ No newline at end of file + diff --git a/src/Umbraco.Web.UI.Client/src/views/media/media.edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/media/media.edit.controller.js index 175007e9ad..1f898230ac 100644 --- a/src/Umbraco.Web.UI.Client/src/views/media/media.edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/media/media.edit.controller.js @@ -194,7 +194,7 @@ function mediaEditController($scope, $routeParams, $q, appState, mediaResource, contentEditingHelper.handleSaveError({ err: err, - redirectOnError: !infiniteMode, + redirectOnFailure: !infiniteMode, rebindCallback: contentEditingHelper.reBindChangedProperties($scope.content, err.data) }); diff --git a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/mediapicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/mediapicker.controller.js index 89878e3750..4258229042 100644 --- a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/mediapicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/mediapicker.controller.js @@ -18,7 +18,7 @@ function mediaPickerController($scope, entityResource, iconHelper, editorService entityType: "Media", section: "media", treeAlias: "media", - idType: "int" + idType: "udi" }; //combine the dialogOptions with any values returned from the server diff --git a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/treepicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/treepicker.controller.js index 3de4611ca2..951b76193f 100644 --- a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/treepicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/treepicker.controller.js @@ -16,7 +16,7 @@ angular.module('umbraco') entityType: "Document", type: "content", treeAlias: "content", - idType: "int" + idType: "udi" }; //combine the config with any values returned from the server diff --git a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/treesource.controller.js b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/treesource.controller.js index 166e86a582..ba8902a017 100644 --- a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/treesource.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/treesource.controller.js @@ -15,7 +15,7 @@ angular.module('umbraco') } if (!$scope.model.config) { $scope.model.config = { - idType: "int" + idType: "udi" }; } @@ -76,4 +76,4 @@ angular.module('umbraco') $scope.node = item; $scope.model.value.id = $scope.model.config.idType === "udi" ? item.udi : item.id; } -}); \ No newline at end of file +}); diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.controller.js index b558cba459..e6d30803cf 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.controller.js @@ -144,7 +144,7 @@ function contentPickerController($scope, entityResource, editorState, iconHelper }, treeAlias: $scope.model.config.startNode.type, section: $scope.model.config.startNode.type, - idType: "int" + idType: "udi" }; //since most of the pre-value config's are used in the dialog options (i.e. maxNumber, minNumber, etc...) we'll merge the diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.prevalues.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.prevalues.controller.js index 2a00df32dc..19057fa842 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.prevalues.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.prevalues.controller.js @@ -96,7 +96,7 @@ angular.module("umbraco") $scope.layoutConfigOverlay.rows = $scope.model.value.layouts; $scope.layoutConfigOverlay.columns = $scope.model.value.columns; $scope.layoutConfigOverlay.show = true; - + $scope.layoutConfigOverlay.submit = function(model) { $scope.layoutConfigOverlay.show = false; $scope.layoutConfigOverlay = null; @@ -218,8 +218,8 @@ angular.module("umbraco") $scope.editConfigCollectionOverlay.show = true; $scope.editConfigCollectionOverlay.submit = function(model) { - - callback(model.config) + + callback(model.config); $scope.editConfigCollectionOverlay.show = false; $scope.editConfigCollectionOverlay = null; diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/relatedlinks/relatedlinks.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/relatedlinks/relatedlinks.controller.js index 78da1f482d..d54a17e15a 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/relatedlinks/relatedlinks.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/relatedlinks/relatedlinks.controller.js @@ -47,7 +47,7 @@ section: "content", treeAlias: "content", multiPicker: false, - idType: $scope.model.config.idType ? $scope.model.config.idType : "int", + idType: $scope.model.config.idType ? $scope.model.config.idType : "udi", submit: function (model) { select(model.selection[0]); editorService.close(); diff --git a/src/Umbraco.Web.UI/App_Plugins/ModelsBuilder/modelsbuilder.controller.js b/src/Umbraco.Web.UI/App_Plugins/ModelsBuilder/modelsbuilder.controller.js index 942b79eabd..b0e0c303cf 100644 --- a/src/Umbraco.Web.UI/App_Plugins/ModelsBuilder/modelsbuilder.controller.js +++ b/src/Umbraco.Web.UI/App_Plugins/ModelsBuilder/modelsbuilder.controller.js @@ -1,28 +1,35 @@ -function modelsBuilderController($scope, umbRequestHelper, $log, $http, modelsBuilderResource) { +function modelsBuilderController($scope, $http, umbRequestHelper, modelsBuilderResource) { - $scope.generate = function() { - $scope.generating = true; + var vm = this; + + vm.reload = reload; + vm.generate = generate; + vm.dashboard = null; + + function generate() { + vm.generating = true; umbRequestHelper.resourcePromise( $http.post(umbRequestHelper.getApiUrl("modelsBuilderBaseUrl", "BuildModels")), 'Failed to generate.') .then(function (result) { - $scope.generating = false; - $scope.dashboard = result; + vm.generating = false; + vm.dashboard = result; }); - }; + } - $scope.reload = function () { - $scope.ready = false; + function reload() { + vm.loading = true; modelsBuilderResource.getDashboard().then(function (result) { - $scope.dashboard = result; - $scope.ready = true; + vm.dashboard = result; + vm.loading = false; }); - }; + } function init() { - modelsBuilderResource.getDashboard().then(function(result) { - $scope.dashboard = result; - $scope.ready = true; + vm.loading = true; + modelsBuilderResource.getDashboard().then(function (result) { + vm.dashboard = result; + vm.loading = false; }); } diff --git a/src/Umbraco.Web.UI/App_Plugins/ModelsBuilder/modelsbuilder.htm b/src/Umbraco.Web.UI/App_Plugins/ModelsBuilder/modelsbuilder.htm deleted file mode 100644 index eeca93bf3a..0000000000 --- a/src/Umbraco.Web.UI/App_Plugins/ModelsBuilder/modelsbuilder.htm +++ /dev/null @@ -1,41 +0,0 @@ -
    - -
    - -
    - -

    Models Builder

    - -
    - Loading... -
    - -
    -
    - -
    -

    Models are out-of-date. -

    -
    - -
    -
    -

    Generating models will restart the application.

    -
    -
    - -
    -
    -
    -
    -
    - -
    - Last generation failed with the following error: -
    {{dashboard.lastError}}
    -
    -
    - -
    diff --git a/src/Umbraco.Web.UI/App_Plugins/ModelsBuilder/modelsbuilder.html b/src/Umbraco.Web.UI/App_Plugins/ModelsBuilder/modelsbuilder.html new file mode 100644 index 0000000000..0c10c33e39 --- /dev/null +++ b/src/Umbraco.Web.UI/App_Plugins/ModelsBuilder/modelsbuilder.html @@ -0,0 +1,44 @@ +
    + + + + +
    + +
    + +

    Models Builder

    + + + +
    +
    + +
    +

    Models are out-of-date.

    +
    + +
    +
    +

    Generating models will restart the application.

    +
    +
    + +
    +
    +
    +
    +
    + +
    + Last generation failed with the following error: +
    {{vm.dashboard.lastError}}
    +
    +
    + +
    +
    + +
    diff --git a/src/Umbraco.Web.UI/App_Plugins/ModelsBuilder/package.manifest b/src/Umbraco.Web.UI/App_Plugins/ModelsBuilder/package.manifest index d83523517a..5e64177046 100644 --- a/src/Umbraco.Web.UI/App_Plugins/ModelsBuilder/package.manifest +++ b/src/Umbraco.Web.UI/App_Plugins/ModelsBuilder/package.manifest @@ -1,7 +1,18 @@ { - //array of files we want to inject into the application on app_start - javascript: [ - '~/App_Plugins/ModelsBuilder/modelsbuilder.controller.js', - '~/App_Plugins/ModelsBuilder/modelsbuilder.resource.js' + // array of files we want to inject into the application + "javascript": [ + "~/App_Plugins/ModelsBuilder/modelsbuilder.controller.js", + "~/App_Plugins/ModelsBuilder/modelsbuilder.resource.js" + ], + + // models builder dashboard + "dashboards": [ + { + "alias": "settingsModelsBuilder", + "name": "Models Builder", + "view": "/App_Plugins/ModelsBuilder/modelsbuilder.html", + "sections": [ "settings" ], + "weight": 40 + } ] } \ 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 7c3293183d..3658ef7066 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -83,7 +83,7 @@ - + @@ -91,21 +91,21 @@ - - + + all - - - - - + + + + + - 8.0.0-alpha.36 + 8.0.0-alpha.37 @@ -141,7 +141,7 @@ Settings.settings - + diff --git a/src/Umbraco.Web.UI/Views/Web.config b/src/Umbraco.Web.UI/Views/Web.config index c137c3705e..efd80424e5 100644 --- a/src/Umbraco.Web.UI/Views/Web.config +++ b/src/Umbraco.Web.UI/Views/Web.config @@ -9,7 +9,7 @@ - + @@ -41,7 +41,7 @@ - +