diff --git a/src/Umbraco.Core/Events/RecycleBinEventArgs.cs b/src/Umbraco.Core/Events/RecycleBinEventArgs.cs index 9dd82922e1..4a51e76108 100644 --- a/src/Umbraco.Core/Events/RecycleBinEventArgs.cs +++ b/src/Umbraco.Core/Events/RecycleBinEventArgs.cs @@ -1,128 +1,32 @@ using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Linq; using Umbraco.Core.Models; namespace Umbraco.Core.Events { - public class RecycleBinEventArgs : CancellableEventArgs, IEquatable, IDeletingMediaFilesEventArgs + public class RecycleBinEventArgs : CancellableEventArgs, IEquatable { - public RecycleBinEventArgs(Guid nodeObjectType, Dictionary> allPropertyData, bool emptiedSuccessfully) - : base(false) + public RecycleBinEventArgs(Guid nodeObjectType, EventMessages eventMessages) + : base(true, eventMessages) { - AllPropertyData = allPropertyData; NodeObjectType = nodeObjectType; - Ids = AllPropertyData.Select(x => x.Key); - RecycleBinEmptiedSuccessfully = emptiedSuccessfully; - Files = new List(); - } - - public RecycleBinEventArgs(Guid nodeObjectType, bool emptiedSuccessfully) - : base(false) - { - AllPropertyData = new Dictionary>(); - NodeObjectType = nodeObjectType; - Ids = new int[0]; - RecycleBinEmptiedSuccessfully = emptiedSuccessfully; - Files = new List(); - } - - public RecycleBinEventArgs(Guid nodeObjectType, Dictionary> allPropertyData) - : base(true) - { - AllPropertyData = allPropertyData; - NodeObjectType = nodeObjectType; - Ids = AllPropertyData.Select(x => x.Key); - Files = new List(); } public RecycleBinEventArgs(Guid nodeObjectType) : base(true) { - AllPropertyData = new Dictionary>(); NodeObjectType = nodeObjectType; - Ids = new int[0]; - Files = new List(); - } - /// - /// Backwards compatibility constructor - /// - /// - /// - /// - /// - internal RecycleBinEventArgs(Guid nodeObjectType, Dictionary> allPropertyData, List files, bool emptiedSuccessfully) - : base(false) - { - AllPropertyData = allPropertyData; - NodeObjectType = nodeObjectType; - Ids = AllPropertyData.Select(x => x.Key); - RecycleBinEmptiedSuccessfully = emptiedSuccessfully; - Files = files; } - - /// - /// Backwards compatibility constructor - /// - /// - /// - /// - internal RecycleBinEventArgs(Guid nodeObjectType, Dictionary> allPropertyData, List files) - : base(true) - { - AllPropertyData = allPropertyData; - NodeObjectType = nodeObjectType; - Ids = AllPropertyData.Select(x => x.Key); - Files = files; - } - - [Obsolete("Use the other ctor that specifies all property data instead")] - public RecycleBinEventArgs(Guid nodeObjectType, IEnumerable ids, List files, bool emptiedSuccessfully) - : base(false) - { - NodeObjectType = nodeObjectType; - Ids = ids; - Files = files; - RecycleBinEmptiedSuccessfully = emptiedSuccessfully; - } - - [Obsolete("Use the other ctor that specifies all property data instead")] - public RecycleBinEventArgs(Guid nodeObjectType, IEnumerable ids, List files) - : base(true) - { - NodeObjectType = nodeObjectType; - Ids = ids; - Files = files; - } - + /// /// Gets the Id of the node object type of the items /// being deleted from the Recycle Bin. /// - public Guid NodeObjectType { get; private set; } - - /// - /// Gets the list of Ids for each of the items being deleted from the Recycle Bin. - /// - public IEnumerable Ids { get; private set; } - - /// - /// Gets the list of Files that should be deleted as part - /// of emptying the Recycle Bin. - /// - /// - /// This list can be appended to during an event handling operation, generally this is done based on the property data contained in these event args - /// - public List Files { get; private set; } - - public List MediaFilesToDelete { get { return Files; } } - - /// - /// Gets the list of all property data associated with a content id - /// - public Dictionary> AllPropertyData { get; private set; } - + public Guid NodeObjectType { get; } + /// /// Boolean indicating whether the Recycle Bin was emptied successfully /// @@ -142,7 +46,7 @@ namespace Umbraco.Core.Events { if (ReferenceEquals(null, other)) return false; if (ReferenceEquals(this, other)) return true; - return base.Equals(other) && AllPropertyData.Equals(other.AllPropertyData) && Files.Equals(other.Files) && Ids.Equals(other.Ids) && NodeObjectType.Equals(other.NodeObjectType) && RecycleBinEmptiedSuccessfully == other.RecycleBinEmptiedSuccessfully; + return base.Equals(other) && NodeObjectType.Equals(other.NodeObjectType) && RecycleBinEmptiedSuccessfully == other.RecycleBinEmptiedSuccessfully; } public override bool Equals(object obj) @@ -158,9 +62,6 @@ namespace Umbraco.Core.Events unchecked { int hashCode = base.GetHashCode(); - hashCode = (hashCode * 397) ^ AllPropertyData.GetHashCode(); - hashCode = (hashCode * 397) ^ Files.GetHashCode(); - hashCode = (hashCode * 397) ^ Ids.GetHashCode(); hashCode = (hashCode * 397) ^ NodeObjectType.GetHashCode(); hashCode = (hashCode * 397) ^ RecycleBinEmptiedSuccessfully.GetHashCode(); return hashCode; diff --git a/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs b/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs index f12533a5de..77bd1f6280 100644 --- a/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs +++ b/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs @@ -250,7 +250,8 @@ namespace Umbraco.Core.Migrations.Install _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = 1041, EditorAlias = Constants.PropertyEditors.Aliases.Tags, DbType = "Ntext", Configuration = "{\"group\":\"default\"}" }); _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = 1043, EditorAlias = Constants.PropertyEditors.Aliases.ImageCropper, DbType = "Ntext" }); - _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = Constants.DataTypes.DefaultContentListView, EditorAlias = Constants.PropertyEditors.Aliases.ListView, DbType = "Nvarchar" }); + _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = Constants.DataTypes.DefaultContentListView, EditorAlias = Constants.PropertyEditors.Aliases.ListView, DbType = "Nvarchar", + Configuration = "{\"pageSize\":100, \"orderBy\":\"updateDate\", \"orderDirection\":\"desc\", \"layouts\":" + layouts + ", \"includeProperties\":[{\"alias\":\"updateDate\",\"header\":\"Last edited\",\"isSystem\":1},{\"alias\":\"owner\",\"header\":\"Updated by\",\"isSystem\":1}]}" }); _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = Constants.DataTypes.DefaultMediaListView, EditorAlias = Constants.PropertyEditors.Aliases.ListView, DbType = "Nvarchar", Configuration = "{\"pageSize\":100, \"orderBy\":\"updateDate\", \"orderDirection\":\"desc\", \"layouts\":" + layouts + ", \"includeProperties\":[{\"alias\":\"updateDate\",\"header\":\"Last edited\",\"isSystem\":1},{\"alias\":\"owner\",\"header\":\"Updated by\",\"isSystem\":1}]}" }); _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = Constants.DataTypes.DefaultMembersListView, EditorAlias = Constants.PropertyEditors.Aliases.ListView, DbType = "Nvarchar", diff --git a/src/Umbraco.Core/Models/MediaExtensions.cs b/src/Umbraco.Core/Models/MediaExtensions.cs index 2267843120..1f219d5e10 100644 --- a/src/Umbraco.Core/Models/MediaExtensions.cs +++ b/src/Umbraco.Core/Models/MediaExtensions.cs @@ -21,6 +21,7 @@ namespace Umbraco.Core.Models var val = media.Properties[propertyType]; if (val == null) return string.Empty; + //fixme doesn't take into account variants var jsonString = val.GetValue() as string; if (jsonString == null) return string.Empty; diff --git a/src/Umbraco.Core/Models/Property.cs b/src/Umbraco.Core/Models/Property.cs index 0ff1c534c4..9e3f5fc2e0 100644 --- a/src/Umbraco.Core/Models/Property.cs +++ b/src/Umbraco.Core/Models/Property.cs @@ -89,7 +89,7 @@ namespace Umbraco.Core.Models /// Gets the list of values. /// [DataMember] - public List Values + public IReadOnlyCollection Values { get => _values; set diff --git a/src/Umbraco.Core/Models/PropertyTagsExtensions.cs b/src/Umbraco.Core/Models/PropertyTagsExtensions.cs index 7e5254201f..3121da85bd 100644 --- a/src/Umbraco.Core/Models/PropertyTagsExtensions.cs +++ b/src/Umbraco.Core/Models/PropertyTagsExtensions.cs @@ -112,6 +112,7 @@ namespace Umbraco.Core.Models private static void RemoveTags(this Property property, IEnumerable tags, TagsStorageType storageType, char delimiter) { // already empty = nothing to do + //fixme doesn't take into account variants var value = property.GetValue()?.ToString(); if (string.IsNullOrWhiteSpace(value)) return; @@ -145,6 +146,7 @@ namespace Umbraco.Core.Models { if (property == null) throw new ArgumentNullException(nameof(property)); + //fixme doesn't take into account variants var value = property.GetValue()?.ToString(); if (string.IsNullOrWhiteSpace(value)) return Enumerable.Empty(); @@ -154,6 +156,7 @@ namespace Umbraco.Core.Models return value.Split(new[] { delimiter }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()); case TagsStorageType.Json: + //fixme doesn't take into account variants return JsonConvert.DeserializeObject(property.GetValue().ToString()).Select(x => x.ToString().Trim()); default: diff --git a/src/Umbraco.Core/Persistence/Repositories/IDocumentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/IDocumentRepository.cs index bf6fda3758..a3fb50149d 100644 --- a/src/Umbraco.Core/Persistence/Repositories/IDocumentRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/IDocumentRepository.cs @@ -39,14 +39,7 @@ namespace Umbraco.Core.Persistence.Repositories /// /// EntityPermissionCollection GetPermissionsForEntity(int entityId); - - ///// - ///// Gets the implicit/inherited list of permissions for the content item - ///// - ///// - ///// - //IEnumerable GetPermissionsForPath(string path); - + /// /// Used to add/update a permission for a content item /// diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/ContentRepositoryBase.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/ContentRepositoryBase.cs index 17e00b3e76..84ff426e91 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/ContentRepositoryBase.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/ContentRepositoryBase.cs @@ -476,6 +476,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement if (!tagConfigurations.TryGetValue(property.PropertyType.PropertyEditorAlias, out var tagConfiguration)) continue; + //fixme doesn't take into account variants property.SetTagsValue(property.GetValue(), tagConfiguration); } diff --git a/src/Umbraco.Core/PropertyEditors/ConfigurationEditor.cs b/src/Umbraco.Core/PropertyEditors/ConfigurationEditor.cs index a4b6e52b3d..58fde70467 100644 --- a/src/Umbraco.Core/PropertyEditors/ConfigurationEditor.cs +++ b/src/Umbraco.Core/PropertyEditors/ConfigurationEditor.cs @@ -67,7 +67,7 @@ namespace Umbraco.Core.PropertyEditors : JsonConvert.DeserializeObject>(configurationJson); /// - public virtual object FromConfigurationEditor(Dictionary editorValues, object configuration) + public virtual object FromConfigurationEditor(IDictionary editorValues, object configuration) { // by default, return the posted dictionary // but only keep entries that have a non-null/empty value @@ -80,7 +80,7 @@ namespace Umbraco.Core.PropertyEditors } /// - public virtual Dictionary ToConfigurationEditor(object configuration) + public virtual IDictionary ToConfigurationEditor(object configuration) { // editors that do not override ToEditor/FromEditor have their configuration // as a dictionary of and, by default, we merge their default @@ -100,7 +100,7 @@ namespace Umbraco.Core.PropertyEditors } /// - public virtual Dictionary ToValueEditor(object configuration) + public virtual IDictionary ToValueEditor(object configuration) => ToConfigurationEditor(configuration); /// @@ -133,4 +133,4 @@ namespace Umbraco.Core.PropertyEditors } } } -} \ No newline at end of file +} diff --git a/src/Umbraco.Core/PropertyEditors/ConfigurationEditorOfTConfiguration.cs b/src/Umbraco.Core/PropertyEditors/ConfigurationEditorOfTConfiguration.cs index ae48d51a52..15676f134c 100644 --- a/src/Umbraco.Core/PropertyEditors/ConfigurationEditorOfTConfiguration.cs +++ b/src/Umbraco.Core/PropertyEditors/ConfigurationEditorOfTConfiguration.cs @@ -113,7 +113,7 @@ namespace Umbraco.Core.PropertyEditors } /// - public sealed override object FromConfigurationEditor(Dictionary editorValues, object configuration) + public sealed override object FromConfigurationEditor(IDictionary editorValues, object configuration) { return FromConfigurationEditor(editorValues, (TConfiguration) configuration); } @@ -123,7 +123,7 @@ namespace Umbraco.Core.PropertyEditors /// /// The configuration object posted by the editor. /// The current configuration object. - public virtual TConfiguration FromConfigurationEditor(Dictionary editorValues, TConfiguration configuration) + public virtual TConfiguration FromConfigurationEditor(IDictionary editorValues, TConfiguration configuration) { // note - editorValue contains a mix of Clr types (string, int...) and JToken // turning everything back into a JToken... might not be fastest but is simplest @@ -144,7 +144,7 @@ namespace Umbraco.Core.PropertyEditors } /// - public sealed override Dictionary ToConfigurationEditor(object configuration) + public sealed override IDictionary ToConfigurationEditor(object configuration) { return ToConfigurationEditor((TConfiguration) configuration); } @@ -152,7 +152,6 @@ namespace Umbraco.Core.PropertyEditors /// /// Converts configuration values to values for the editor. /// - /// The default configuration. /// The configuration. public virtual Dictionary ToConfigurationEditor(TConfiguration configuration) { @@ -170,4 +169,4 @@ namespace Umbraco.Core.PropertyEditors return ObjectExtensions.ToObjectDictionary(configuration, FieldNamer); } } -} \ No newline at end of file +} diff --git a/src/Umbraco.Core/PropertyEditors/IConfigurationEditor.cs b/src/Umbraco.Core/PropertyEditors/IConfigurationEditor.cs index 0bbd42a966..cd8c8be030 100644 --- a/src/Umbraco.Core/PropertyEditors/IConfigurationEditor.cs +++ b/src/Umbraco.Core/PropertyEditors/IConfigurationEditor.cs @@ -39,18 +39,18 @@ namespace Umbraco.Core.PropertyEditors /// /// The values posted by the configuration editor. /// The current configuration object. - object FromConfigurationEditor(Dictionary editorValues, object configuration); + object FromConfigurationEditor(IDictionary editorValues, object configuration); /// /// Converts the configuration object to values for the configuration editor. /// /// The configuration. - Dictionary ToConfigurationEditor(object configuration); + IDictionary ToConfigurationEditor(object configuration); /// /// Converts the configuration object to values for the value editror. /// /// The configuration. - Dictionary ToValueEditor(object configuration); + IDictionary ToValueEditor(object configuration); } -} \ No newline at end of file +} diff --git a/src/Umbraco.Core/Services/IContentService.cs b/src/Umbraco.Core/Services/IContentService.cs index b08a7ed55d..93128ca67c 100644 --- a/src/Umbraco.Core/Services/IContentService.cs +++ b/src/Umbraco.Core/Services/IContentService.cs @@ -329,7 +329,7 @@ namespace Umbraco.Core.Services /// /// Empties the recycle bin. /// - void EmptyRecycleBin(); + OperationResult EmptyRecycleBin(); /// /// Sorts documents. diff --git a/src/Umbraco.Core/Services/IMediaService.cs b/src/Umbraco.Core/Services/IMediaService.cs index 749ade323e..3fd4199490 100644 --- a/src/Umbraco.Core/Services/IMediaService.cs +++ b/src/Umbraco.Core/Services/IMediaService.cs @@ -248,7 +248,7 @@ namespace Umbraco.Core.Services /// /// Empties the Recycle Bin by deleting all that resides in the bin /// - void EmptyRecycleBin(); + OperationResult EmptyRecycleBin(); /// /// Deletes all media of specified type. All children of deleted media is moved to Recycle Bin. diff --git a/src/Umbraco.Core/Services/Implement/ContentService.cs b/src/Umbraco.Core/Services/Implement/ContentService.cs index 789ae30cab..c5f20878ae 100644 --- a/src/Umbraco.Core/Services/Implement/ContentService.cs +++ b/src/Umbraco.Core/Services/Implement/ContentService.cs @@ -1518,11 +1518,11 @@ namespace Umbraco.Core.Services.Implement /// /// Empties the Recycle Bin by deleting all that resides in the bin /// - public void EmptyRecycleBin() + public OperationResult EmptyRecycleBin() { var nodeObjectType = Constants.ObjectTypes.Document; var deleted = new List(); - var evtMsgs = EventMessagesFactory.Get(); // todo - and then? + var evtMsgs = EventMessagesFactory.Get(); using (var scope = ScopeProvider.CreateScope()) { @@ -1533,11 +1533,11 @@ namespace Umbraco.Core.Services.Implement // are managed by Delete, and not here. // no idea what those events are for, keep a simplified version - var recycleBinEventArgs = new RecycleBinEventArgs(nodeObjectType); + var recycleBinEventArgs = new RecycleBinEventArgs(nodeObjectType, evtMsgs); if (scope.Events.DispatchCancelable(EmptyingRecycleBin, this, recycleBinEventArgs)) { scope.Complete(); - return; // causes rollback + return OperationResult.Cancel(evtMsgs); } // emptying the recycle bin means deleting whetever is in there - do it properly! @@ -1557,6 +1557,8 @@ namespace Umbraco.Core.Services.Implement scope.Complete(); } + + return OperationResult.Succeed(evtMsgs); } #endregion @@ -2311,7 +2313,7 @@ namespace Umbraco.Core.Services.Implement content.WriterId = userId; foreach (var property in blueprint.Properties) - content.SetValue(property.Alias, property.GetValue()); + content.SetValue(property.Alias, property.GetValue()); //fixme doesn't take into account variants return content; } diff --git a/src/Umbraco.Core/Services/Implement/MediaService.cs b/src/Umbraco.Core/Services/Implement/MediaService.cs index dec4e56714..504750874c 100644 --- a/src/Umbraco.Core/Services/Implement/MediaService.cs +++ b/src/Umbraco.Core/Services/Implement/MediaService.cs @@ -1185,7 +1185,7 @@ namespace Umbraco.Core.Services.Implement /// /// Empties the Recycle Bin by deleting all that resides in the bin /// - public void EmptyRecycleBin() + public OperationResult EmptyRecycleBin() { var nodeObjectType = Constants.ObjectTypes.Media; var deleted = new List(); @@ -1206,12 +1206,12 @@ namespace Umbraco.Core.Services.Implement // emptying the recycle bin means deleting whetever is in there - do it properly! // are managed by Delete, and not here. // no idea what those events are for, keep a simplified version - var args = new RecycleBinEventArgs(nodeObjectType); + var args = new RecycleBinEventArgs(nodeObjectType, evtMsgs); if (scope.Events.DispatchCancelable(EmptyingRecycleBin, this, args)) { scope.Complete(); - return; + return OperationResult.Cancel(evtMsgs); } // emptying the recycle bin means deleting whetever is in there - do it properly! var query = Query().Where(x => x.ParentId == Constants.System.RecycleBinMedia); @@ -1227,6 +1227,8 @@ namespace Umbraco.Core.Services.Implement Audit(AuditType.Delete, "Empty Media Recycle Bin performed by user", 0, Constants.System.RecycleBinMedia); scope.Complete(); } + + return OperationResult.Succeed(evtMsgs); } #endregion diff --git a/src/Umbraco.Core/Services/Implement/NotificationService.cs b/src/Umbraco.Core/Services/Implement/NotificationService.cs index 0b57958724..c24e82c14f 100644 --- a/src/Umbraco.Core/Services/Implement/NotificationService.cs +++ b/src/Umbraco.Core/Services/Implement/NotificationService.cs @@ -368,6 +368,8 @@ namespace Umbraco.Core.Services.Implement var props = content.Properties.ToArray(); foreach (var p in props) { + //fixme doesn't take into account variants + var newText = p.GetValue() != null ? p.GetValue().ToString() : ""; var oldText = newText; diff --git a/src/Umbraco.Core/StringExtensions.cs b/src/Umbraco.Core/StringExtensions.cs index f08acbe74d..8040e6397b 100644 --- a/src/Umbraco.Core/StringExtensions.cs +++ b/src/Umbraco.Core/StringExtensions.cs @@ -135,6 +135,7 @@ namespace Umbraco.Core /// public static bool DetectIsJson(this string input) { + if (input.IsNullOrWhiteSpace()) return false; input = input.Trim(); return (input.StartsWith("{") && input.EndsWith("}")) || (input.StartsWith("[") && input.EndsWith("]")); diff --git a/src/Umbraco.Tests/Cache/CacheRefresherComponentTests.cs b/src/Umbraco.Tests/Cache/CacheRefresherComponentTests.cs index 4399380f92..e79b26cd1d 100644 --- a/src/Umbraco.Tests/Cache/CacheRefresherComponentTests.cs +++ b/src/Umbraco.Tests/Cache/CacheRefresherComponentTests.cs @@ -86,7 +86,7 @@ namespace Umbraco.Tests.Cache new EventDefinition>(null, serviceContext.MediaService, new DeleteEventArgs(Enumerable.Empty())), new EventDefinition>(null, serviceContext.MediaService, new MoveEventArgs(new MoveEventInfo(null, "", -1)), "Moved"), new EventDefinition>(null, serviceContext.MediaService, new MoveEventArgs(new MoveEventInfo(null, "", -1)), "Trashed"), - new EventDefinition(null, serviceContext.MediaService, new RecycleBinEventArgs(Guid.NewGuid(), new Dictionary>(), true)), + new EventDefinition(null, serviceContext.MediaService, new RecycleBinEventArgs(Guid.NewGuid())), new EventDefinition>(null, serviceContext.ContentService, new SaveEventArgs(Enumerable.Empty()), "Saved"), new EventDefinition>(null, serviceContext.ContentService, new DeleteEventArgs(Enumerable.Empty()), "Deleted"), @@ -97,7 +97,7 @@ namespace Umbraco.Tests.Cache new EventDefinition>(null, serviceContext.ContentService, new CopyEventArgs(null, null, -1)), new EventDefinition>(null, serviceContext.ContentService, new MoveEventArgs(new MoveEventInfo(null, "", -1)), "Trashed"), - new EventDefinition(null, serviceContext.ContentService, new RecycleBinEventArgs(Guid.NewGuid(), new Dictionary>(), true)), + new EventDefinition(null, serviceContext.ContentService, new RecycleBinEventArgs(Guid.NewGuid())), new EventDefinition>(null, serviceContext.ContentService, new PublishEventArgs(Enumerable.Empty()), "Published"), new EventDefinition>(null, serviceContext.ContentService, new PublishEventArgs(Enumerable.Empty()), "UnPublished"), diff --git a/src/Umbraco.Web.UI.Client/src/common/services/listviewhelper.service.js b/src/Umbraco.Web.UI.Client/src/common/services/listviewhelper.service.js index 2ffdc3f1dd..e4ba9b337c 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/listviewhelper.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/listviewhelper.service.js @@ -181,11 +181,13 @@ var firstAllowedLayout = {}; - for (var i = 0; layouts.length > i; i++) { - var layout = layouts[i]; - if (layout.selected === true) { - firstAllowedLayout = layout; - break; + if (layouts != null) { + for (var i = 0; layouts.length > i; i++) { + var layout = layouts[i]; + if (layout.selected === true) { + firstAllowedLayout = layout; + break; + } } } diff --git a/src/Umbraco.Web/Editors/ImagesController.cs b/src/Umbraco.Web/Editors/ImagesController.cs index ee4d4658cd..f8f49ba2da 100644 --- a/src/Umbraco.Web/Editors/ImagesController.cs +++ b/src/Umbraco.Web/Editors/ImagesController.cs @@ -40,6 +40,7 @@ namespace Umbraco.Web.Editors if (imageProp == null) return Request.CreateResponse(HttpStatusCode.NotFound); + //fixme doesn't take into account variants var imagePath = imageProp.GetValue().ToString(); return GetBigThumbnail(imagePath); } @@ -78,6 +79,7 @@ namespace Umbraco.Web.Editors if (imageProp == null) return new HttpResponseMessage(HttpStatusCode.NotFound); + //fixme doesn't take into account variants var imagePath = imageProp.GetValue().ToString(); return GetResized(imagePath, width); } diff --git a/src/Umbraco.Web/Models/Mapping/TabsAndPropertiesResolver.cs b/src/Umbraco.Web/Models/Mapping/TabsAndPropertiesResolver.cs index 4102c3fe90..6da8b39297 100644 --- a/src/Umbraco.Web/Models/Mapping/TabsAndPropertiesResolver.cs +++ b/src/Umbraco.Web/Models/Mapping/TabsAndPropertiesResolver.cs @@ -106,14 +106,28 @@ namespace Umbraco.Web.Models.Mapping SetChildItemsTabPosition(display, listViewConfig, listViewTab); } + private static int GetTabNumberFromConfig(IDictionary listViewConfig) + { + if (!listViewConfig.TryGetValue("displayAtTabNumber", out var displayTabNum)) + return -1; + switch (displayTabNum) + { + case int i: + return i; + case string s when int.TryParse(s, out var parsed): + return parsed; + } + return -1; + } + private static void SetChildItemsTabPosition(TabbedContentItem display, IDictionary listViewConfig, Tab listViewTab) where TPersisted : IContentBase { // Find position of tab from config - var tabIndexForChildItems = 0; - if (listViewConfig["displayAtTabNumber"] != null && int.TryParse((string)listViewConfig["displayAtTabNumber"], out tabIndexForChildItems)) + var tabIndexForChildItems = GetTabNumberFromConfig(listViewConfig); + if (tabIndexForChildItems != -1) { // Tab position is recorded 1-based but we insert into collection 0-based tabIndexForChildItems--; @@ -129,8 +143,9 @@ namespace Umbraco.Web.Models.Mapping tabIndexForChildItems = display.Tabs.Count(); } } - - // Recreate tab list with child items tab at configured position + else tabIndexForChildItems = 0; + + // Recreate tab list with child items tab at configured position var tabs = new List>(); tabs.AddRange(display.Tabs); tabs.Insert(tabIndexForChildItems, listViewTab); diff --git a/src/Umbraco.Web/PropertyEditors/ColorPickerConfigurationEditor.cs b/src/Umbraco.Web/PropertyEditors/ColorPickerConfigurationEditor.cs index 17d0cfb383..ddc4b50858 100644 --- a/src/Umbraco.Web/PropertyEditors/ColorPickerConfigurationEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/ColorPickerConfigurationEditor.cs @@ -50,7 +50,7 @@ namespace Umbraco.Web.PropertyEditors return jobject.Property("color").Value.Value(); } - public override ColorPickerConfiguration FromConfigurationEditor(Dictionary editorValues, ColorPickerConfiguration configuration) + public override ColorPickerConfiguration FromConfigurationEditor(IDictionary editorValues, ColorPickerConfiguration configuration) { var output = new ColorPickerConfiguration(); diff --git a/src/Umbraco.Web/PropertyEditors/ContentPickerConfigurationEditor.cs b/src/Umbraco.Web/PropertyEditors/ContentPickerConfigurationEditor.cs index 9cb5a3fe6b..5be97e5f76 100644 --- a/src/Umbraco.Web/PropertyEditors/ContentPickerConfigurationEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/ContentPickerConfigurationEditor.cs @@ -12,7 +12,7 @@ namespace Umbraco.Web.PropertyEditors .Config = new Dictionary { { "idType", "udi" } }; } - public override Dictionary ToValueEditor(object configuration) + public override IDictionary ToValueEditor(object configuration) { // these are not configuration fields, but constants required by the value editor var d = base.ToValueEditor(configuration); @@ -22,4 +22,4 @@ namespace Umbraco.Web.PropertyEditors return d; } } -} \ No newline at end of file +} diff --git a/src/Umbraco.Web/PropertyEditors/DateConfigurationEditor.cs b/src/Umbraco.Web/PropertyEditors/DateConfigurationEditor.cs index caca3e7e2f..b0839c5157 100644 --- a/src/Umbraco.Web/PropertyEditors/DateConfigurationEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/DateConfigurationEditor.cs @@ -8,7 +8,7 @@ namespace Umbraco.Web.PropertyEditors /// public class DateConfigurationEditor : ConfigurationEditor { - public override Dictionary ToValueEditor(object configuration) + public override IDictionary ToValueEditor(object configuration) { var d = base.ToValueEditor(configuration); d["pickTime"] = false; diff --git a/src/Umbraco.Web/PropertyEditors/DateTimeConfigurationEditor.cs b/src/Umbraco.Web/PropertyEditors/DateTimeConfigurationEditor.cs index 68d9252064..494d8814f4 100644 --- a/src/Umbraco.Web/PropertyEditors/DateTimeConfigurationEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/DateTimeConfigurationEditor.cs @@ -8,7 +8,7 @@ namespace Umbraco.Web.PropertyEditors /// public class DateTimeConfigurationEditor : ConfigurationEditor { - public override Dictionary ToValueEditor(object configuration) + public override IDictionary ToValueEditor(object configuration) { var d = base.ToValueEditor(configuration); d["pickTime"] = true; diff --git a/src/Umbraco.Web/PropertyEditors/DropDownFlexibleConfigurationEditor.cs b/src/Umbraco.Web/PropertyEditors/DropDownFlexibleConfigurationEditor.cs index 530ca283ff..5821823576 100644 --- a/src/Umbraco.Web/PropertyEditors/DropDownFlexibleConfigurationEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/DropDownFlexibleConfigurationEditor.cs @@ -18,7 +18,7 @@ namespace Umbraco.Web.PropertyEditors items.Validators.Add(new ValueListUniqueValueValidator()); } - public override DropDownFlexibleConfiguration FromConfigurationEditor(Dictionary editorValues, DropDownFlexibleConfiguration configuration) + public override DropDownFlexibleConfiguration FromConfigurationEditor(IDictionary editorValues, DropDownFlexibleConfiguration configuration) { var output = new DropDownFlexibleConfiguration(); diff --git a/src/Umbraco.Web/PropertyEditors/FileUploadPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/FileUploadPropertyEditor.cs index bc4d21c4c4..e969d2e45b 100644 --- a/src/Umbraco.Web/PropertyEditors/FileUploadPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/FileUploadPropertyEditor.cs @@ -36,30 +36,12 @@ namespace Umbraco.Web.PropertyEditors /// Gets a value indicating whether a property is an upload field. /// /// The property. - /// A value indicating whether to check that the property has a non-empty value. /// A value indicating whether a property is an upload field, and (optionaly) has a non-empty value. - private static bool IsUploadField(Property property, bool ensureValue) + private static bool IsUploadField(Property property) { - if (property.PropertyType.PropertyEditorAlias != Constants.PropertyEditors.Aliases.UploadField) - return false; - if (ensureValue == false) - return true; - var stringValue = property.GetValue() as string; - return string.IsNullOrWhiteSpace(stringValue) == false; + return property.PropertyType.PropertyEditorAlias == Constants.PropertyEditors.Aliases.UploadField; } - - /// - /// Ensures any files associated are removed - /// - /// - internal IEnumerable ServiceEmptiedRecycleBin(Dictionary> allPropertyData) - { - return allPropertyData.SelectMany(x => x.Value) - .Where (x => IsUploadField(x, true)) - .Select(x => _mediaFileSystem.GetRelativePath((string)x.GetValue())) - .ToList(); - } - + /// /// Ensures any files associated are removed /// @@ -67,10 +49,32 @@ namespace Umbraco.Web.PropertyEditors internal IEnumerable ServiceDeleted(IEnumerable deletedEntities) { return deletedEntities.SelectMany(x => x.Properties) - .Where(x => IsUploadField(x, true)) - .Select(x => _mediaFileSystem.GetRelativePath((string) x.GetValue())) - .ToList(); + .Where(IsUploadField) + .SelectMany(GetFilePathsFromPropertyValues) + .Distinct(); } + + /// + /// Look through all propery values stored against the property and resolve any file paths stored + /// + /// + /// + private IEnumerable GetFilePathsFromPropertyValues(Property prop) + { + var propVals = prop.Values; + foreach (var propertyValue in propVals) + { + //check if the published value contains data and return it + var propVal = propertyValue.PublishedValue; + if (propVal != null && propVal is string str1 && !str1.IsNullOrWhiteSpace()) + yield return _mediaFileSystem.GetRelativePath(str1); + + //check if the edited value contains data and return it + propVal = propertyValue.EditedValue; + if (propVal != null && propVal is string str2 && !str2.IsNullOrWhiteSpace()) + yield return _mediaFileSystem.GetRelativePath(str2); + } + } /// /// After a content has been copied, also copy uploaded files. @@ -80,16 +84,22 @@ namespace Umbraco.Web.PropertyEditors internal void ContentServiceCopied(IContentService sender, Core.Events.CopyEventArgs args) { // get the upload field properties with a value - var properties = args.Original.Properties.Where(x => IsUploadField(x, true)); + var properties = args.Original.Properties.Where(IsUploadField); // copy files var isUpdated = false; foreach (var property in properties) { - var sourcePath = _mediaFileSystem.GetRelativePath((string) property.GetValue()); - var copyPath = _mediaFileSystem.CopyFile(args.Copy, property.PropertyType, sourcePath); - args.Copy.SetValue(property.Alias, _mediaFileSystem.GetUrl(copyPath)); - isUpdated = true; + //copy each of the property values (variants, segments) to the destination + foreach (var propertyValue in property.Values) + { + var propVal = property.GetValue(propertyValue.LanguageId, propertyValue.Segment); + if (propVal == null || !(propVal is string str) || str.IsNullOrWhiteSpace()) continue; + var sourcePath = _mediaFileSystem.GetRelativePath(str); + var copyPath = _mediaFileSystem.CopyFile(args.Copy, property.PropertyType, sourcePath); + args.Copy.SetValue(property.Alias, _mediaFileSystem.GetUrl(copyPath), propertyValue.LanguageId, propertyValue.Segment); + isUpdated = true; + } } // if updated, re-save the copy with the updated value @@ -134,7 +144,7 @@ namespace Umbraco.Web.PropertyEditors /// private void AutoFillProperties(IContentBase model) { - var properties = model.Properties.Where(x => IsUploadField(x, false)); + var properties = model.Properties.Where(IsUploadField); foreach (var property in properties) { diff --git a/src/Umbraco.Web/PropertyEditors/ImageCropperConfigurationEditor.cs b/src/Umbraco.Web/PropertyEditors/ImageCropperConfigurationEditor.cs index f2bb4d6a53..2751b3bdc1 100644 --- a/src/Umbraco.Web/PropertyEditors/ImageCropperConfigurationEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/ImageCropperConfigurationEditor.cs @@ -9,7 +9,7 @@ namespace Umbraco.Web.PropertyEditors internal class ImageCropperConfigurationEditor : ConfigurationEditor { /// - public override Dictionary ToValueEditor(object configuration) + public override IDictionary ToValueEditor(object configuration) { var d = base.ToValueEditor(configuration); if (!d.ContainsKey("focalPoint")) d["focalPoint"] = new { left = 0.5, top = 0.5 }; diff --git a/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyEditor.cs index 9a903b932d..6d3c5b4f61 100644 --- a/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyEditor.cs @@ -50,17 +50,11 @@ namespace Umbraco.Web.PropertyEditors /// /// Gets a value indicating whether a property is an image cropper field. /// - /// The property. - /// A value indicating whether to check that the property has a non-empty value. + /// The property. /// A value indicating whether a property is an image cropper field, and (optionaly) has a non-empty value. - private static bool IsCropperField(Property property, bool ensureValue) + private static bool IsCropperField(Property property) { - if (property.PropertyType.PropertyEditorAlias != Constants.PropertyEditors.Aliases.ImageCropper) - return false; - if (ensureValue == false) - return true; - var val = property.GetValue(); - return val is string s && string.IsNullOrWhiteSpace(s) == false; + return property.PropertyType.PropertyEditorAlias == Constants.PropertyEditors.Aliases.ImageCropper; } /// @@ -87,22 +81,6 @@ namespace Umbraco.Web.PropertyEditors } } - /// - /// Ensures any files associated are removed - /// - /// - internal IEnumerable ServiceEmptiedRecycleBin(Dictionary> allPropertyData) - { - return allPropertyData.SelectMany(x => x.Value) - .Where(x => IsCropperField(x, true)).Select(x => - { - var jo = GetJObject((string) x.GetValue(), true); - if (jo?["src"] == null) return null; - var src = jo["src"].Value(); - return string.IsNullOrWhiteSpace(src) ? null : _mediaFileSystem.GetRelativePath(src); - }).WhereNotNull(); - } - /// /// Ensures any files associated are removed /// @@ -110,13 +88,47 @@ namespace Umbraco.Web.PropertyEditors internal IEnumerable ServiceDeleted(IEnumerable deletedEntities) { return deletedEntities.SelectMany(x => x.Properties) - .Where(x => IsCropperField(x, true)).Select(x => - { - var jo = GetJObject((string) x.GetValue(), true); - if (jo?["src"] == null) return null; - var src = jo["src"].Value(); - return string.IsNullOrWhiteSpace(src) ? null : _mediaFileSystem.GetRelativePath(src); - }).WhereNotNull(); + .Where(IsCropperField) + .SelectMany(GetFilePathsFromPropertyValues) + .Distinct(); + } + + /// + /// Look through all propery values stored against the property and resolve any file paths stored + /// + /// + /// + private IEnumerable GetFilePathsFromPropertyValues(Property prop) + { + //parses out the src from a json string + + foreach (var propertyValue in prop.Values) + { + //check if the published value contains data and return it + var src = GetFileSrcFromPropertyValue(propertyValue.PublishedValue, out var _); + if (src != null) yield return _mediaFileSystem.GetRelativePath(src); + + //check if the edited value contains data and return it + src = GetFileSrcFromPropertyValue(propertyValue.EditedValue, out var _); + if (src != null) yield return _mediaFileSystem.GetRelativePath(src); + } + } + + /// + /// Returns the "src" property from the json structure if the value is formatted correctly + /// + /// + /// The deserialized value + /// + private string GetFileSrcFromPropertyValue(object propVal, out JObject deserializedValue) + { + deserializedValue = null; + if (propVal == null || !(propVal is string str)) return null; + if (!str.DetectIsJson()) return null; + deserializedValue = GetJObject(str, true); + if (deserializedValue?["src"] == null) return null; + var src = deserializedValue["src"].Value(); + return _mediaFileSystem.GetRelativePath(src); } /// @@ -126,23 +138,25 @@ namespace Umbraco.Web.PropertyEditors /// The event arguments. public void ContentServiceCopied(IContentService sender, Core.Events.CopyEventArgs args) { - // get the image cropper field properties with a value - var properties = args.Original.Properties.Where(x => IsCropperField(x, true)); + // get the image cropper field properties + var properties = args.Original.Properties.Where(IsCropperField); // copy files var isUpdated = false; foreach (var property in properties) { - var jo = GetJObject((string) property.GetValue(), true); - - var src = jo?["src"]?.Value(); - if (string.IsNullOrWhiteSpace(src)) continue; - - var sourcePath = _mediaFileSystem.GetRelativePath(src); - var copyPath = _mediaFileSystem.CopyFile(args.Copy, property.PropertyType, sourcePath); - jo["src"] = _mediaFileSystem.GetUrl(copyPath); - args.Copy.SetValue(property.Alias, jo.ToString()); - isUpdated = true; + //copy each of the property values (variants, segments) to the destination by using the edited value + foreach (var propertyValue in property.Values) + { + var propVal = property.GetValue(propertyValue.LanguageId, propertyValue.Segment); + var src = GetFileSrcFromPropertyValue(propVal, out var jo); + if (src == null) continue; + var sourcePath = _mediaFileSystem.GetRelativePath(src); + var copyPath = _mediaFileSystem.CopyFile(args.Copy, property.PropertyType, sourcePath); + jo["src"] = _mediaFileSystem.GetUrl(copyPath); + args.Copy.SetValue(property.Alias, jo.ToString(), propertyValue.LanguageId, propertyValue.Segment); + isUpdated = true; + } } // if updated, re-save the copy with the updated value if (isUpdated) @@ -186,7 +200,7 @@ namespace Umbraco.Web.PropertyEditors /// private void AutoFillProperties(IContentBase model) { - var properties = model.Properties.Where(x => IsCropperField(x, false)); + var properties = model.Properties.Where(IsCropperField); foreach (var property in properties) { diff --git a/src/Umbraco.Web/PropertyEditors/LabelConfigurationEditor.cs b/src/Umbraco.Web/PropertyEditors/LabelConfigurationEditor.cs index 7b6063c538..c248eb1f71 100644 --- a/src/Umbraco.Web/PropertyEditors/LabelConfigurationEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/LabelConfigurationEditor.cs @@ -10,7 +10,7 @@ namespace Umbraco.Web.PropertyEditors public class LabelConfigurationEditor : ConfigurationEditor { /// - public override LabelConfiguration FromConfigurationEditor(Dictionary editorValues, LabelConfiguration configuration) + public override LabelConfiguration FromConfigurationEditor(IDictionary editorValues, LabelConfiguration configuration) { var newConfiguration = new LabelConfiguration(); diff --git a/src/Umbraco.Web/PropertyEditors/MediaPickerConfigurationEditor.cs b/src/Umbraco.Web/PropertyEditors/MediaPickerConfigurationEditor.cs index 53ae28c4a9..e810a65fb6 100644 --- a/src/Umbraco.Web/PropertyEditors/MediaPickerConfigurationEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/MediaPickerConfigurationEditor.cs @@ -20,7 +20,7 @@ namespace Umbraco.Web.PropertyEditors }; } - public override Dictionary ToValueEditor(object configuration) + public override IDictionary ToValueEditor(object configuration) { var d = base.ToValueEditor(configuration); d["idType"] = "udi"; diff --git a/src/Umbraco.Web/PropertyEditors/MultiNodePickerConfigurationEditor.cs b/src/Umbraco.Web/PropertyEditors/MultiNodePickerConfigurationEditor.cs index eb0849c3c6..48b0d7327a 100644 --- a/src/Umbraco.Web/PropertyEditors/MultiNodePickerConfigurationEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/MultiNodePickerConfigurationEditor.cs @@ -29,7 +29,7 @@ namespace Umbraco.Web.PropertyEditors } /// - public override Dictionary ToValueEditor(object configuration) + public override IDictionary ToValueEditor(object configuration) { var d = base.ToValueEditor(configuration); d["multiPicker"] = true; diff --git a/src/Umbraco.Web/PropertyEditors/MultipleTextStringConfigurationEditor.cs b/src/Umbraco.Web/PropertyEditors/MultipleTextStringConfigurationEditor.cs index a993b1c814..6a10a103ba 100644 --- a/src/Umbraco.Web/PropertyEditors/MultipleTextStringConfigurationEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/MultipleTextStringConfigurationEditor.cs @@ -32,7 +32,7 @@ namespace Umbraco.Web.PropertyEditors } /// - public override MultipleTestStringConfiguration FromConfigurationEditor(Dictionary editorValues, MultipleTestStringConfiguration configuration) + public override MultipleTestStringConfiguration FromConfigurationEditor(IDictionary editorValues, MultipleTestStringConfiguration configuration) { // fixme this isn't pretty //the values from the editor will be min/max fieds and we need to format to json in one field diff --git a/src/Umbraco.Web/PropertyEditors/PropertyEditorsComponent.cs b/src/Umbraco.Web/PropertyEditors/PropertyEditorsComponent.cs index 6c0233a7e3..c4f9f6be15 100644 --- a/src/Umbraco.Web/PropertyEditors/PropertyEditorsComponent.cs +++ b/src/Umbraco.Web/PropertyEditors/PropertyEditorsComponent.cs @@ -33,12 +33,8 @@ namespace Umbraco.Web.PropertyEditors MediaService.Deleted += (sender, args) => args.MediaFilesToDelete.AddRange(fileUpload.ServiceDeleted(args.DeletedEntities.Cast())); - MediaService.EmptiedRecycleBin += (sender, args) - => args.Files.AddRange(fileUpload.ServiceEmptiedRecycleBin(args.AllPropertyData)); ContentService.Deleted += (sender, args) => args.MediaFilesToDelete.AddRange(fileUpload.ServiceDeleted(args.DeletedEntities.Cast())); - ContentService.EmptiedRecycleBin += (sender, args) - => args.Files.AddRange(fileUpload.ServiceEmptiedRecycleBin(args.AllPropertyData)); MemberService.Deleted += (sender, args) => args.MediaFilesToDelete.AddRange(fileUpload.ServiceDeleted(args.DeletedEntities.Cast())); } @@ -51,12 +47,8 @@ namespace Umbraco.Web.PropertyEditors MediaService.Deleted += (sender, args) => args.MediaFilesToDelete.AddRange(imageCropper.ServiceDeleted(args.DeletedEntities.Cast())); - MediaService.EmptiedRecycleBin += (sender, args) - => args.Files.AddRange(imageCropper.ServiceEmptiedRecycleBin(args.AllPropertyData)); ContentService.Deleted += (sender, args) => args.MediaFilesToDelete.AddRange(imageCropper.ServiceDeleted(args.DeletedEntities.Cast())); - ContentService.EmptiedRecycleBin += (sender, args) - => args.Files.AddRange(imageCropper.ServiceEmptiedRecycleBin(args.AllPropertyData)); MemberService.Deleted += (sender, args) => args.MediaFilesToDelete.AddRange(imageCropper.ServiceDeleted(args.DeletedEntities.Cast())); } diff --git a/src/Umbraco.Web/PropertyEditors/RelatedLinksConfigurationEditor.cs b/src/Umbraco.Web/PropertyEditors/RelatedLinksConfigurationEditor.cs index 64d16f8f2a..07ff359a82 100644 --- a/src/Umbraco.Web/PropertyEditors/RelatedLinksConfigurationEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/RelatedLinksConfigurationEditor.cs @@ -8,7 +8,7 @@ namespace Umbraco.Web.PropertyEditors /// public class RelatedLinksConfigurationEditor : ConfigurationEditor { - public override Dictionary ToValueEditor(object configuration) + public override IDictionary ToValueEditor(object configuration) { var d = base.ToValueEditor(configuration); d["idType"] = "udi"; diff --git a/src/Umbraco.Web/PropertyEditors/TagConfigurationEditor.cs b/src/Umbraco.Web/PropertyEditors/TagConfigurationEditor.cs index 3a68c878b6..00ff2cf136 100644 --- a/src/Umbraco.Web/PropertyEditors/TagConfigurationEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/TagConfigurationEditor.cs @@ -46,7 +46,7 @@ namespace Umbraco.Web.PropertyEditors return dictionary; } - public override TagConfiguration FromConfigurationEditor(Dictionary editorValues, TagConfiguration configuration) + public override TagConfiguration FromConfigurationEditor(IDictionary editorValues, TagConfiguration configuration) { // the front-end editor retuns the string value of the storage type // pure Json could do with diff --git a/src/Umbraco.Web/PropertyEditors/ValueListConfigurationEditor.cs b/src/Umbraco.Web/PropertyEditors/ValueListConfigurationEditor.cs index a91103207c..d130fb5952 100644 --- a/src/Umbraco.Web/PropertyEditors/ValueListConfigurationEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/ValueListConfigurationEditor.cs @@ -64,7 +64,7 @@ namespace Umbraco.Web.PropertyEditors } /// - public override ValueListConfiguration FromConfigurationEditor(Dictionary editorValues, ValueListConfiguration configuration) + public override ValueListConfiguration FromConfigurationEditor(IDictionary editorValues, ValueListConfiguration configuration) { var output = new ValueListConfiguration();