From a673babfb7d8fc8e3145b93485c2d311db9b45c1 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 4 Apr 2018 13:11:12 +1000 Subject: [PATCH] Fixes Content List View installation, removes unecessary properties from the RecycleBinEventArgs, updates both the upload and image cropper property editors to properly remove all files including any associated with variants, updates several other places to deal with variants and Property.GetValue(langId), adds notes, ensures we are returning the corect IDictionary instead of Dictionary for some interfaces --- .../Events/RecycleBinEventArgs.cs | 115 ++---------------- .../Migrations/Install/DatabaseDataCreator.cs | 3 +- src/Umbraco.Core/Models/MediaExtensions.cs | 1 + src/Umbraco.Core/Models/Property.cs | 2 +- .../Models/PropertyTagsExtensions.cs | 3 + .../Repositories/IDocumentRepository.cs | 9 +- .../Implement/ContentRepositoryBase.cs | 1 + .../PropertyEditors/ConfigurationEditor.cs | 8 +- .../ConfigurationEditorOfTConfiguration.cs | 9 +- .../PropertyEditors/IConfigurationEditor.cs | 8 +- src/Umbraco.Core/Services/IContentService.cs | 2 +- src/Umbraco.Core/Services/IMediaService.cs | 2 +- .../Services/Implement/ContentService.cs | 12 +- .../Services/Implement/MediaService.cs | 8 +- .../Services/Implement/NotificationService.cs | 2 + src/Umbraco.Core/StringExtensions.cs | 1 + .../Cache/CacheRefresherComponentTests.cs | 4 +- .../common/services/listviewhelper.service.js | 12 +- src/Umbraco.Web/Editors/ImagesController.cs | 2 + .../Mapping/TabsAndPropertiesResolver.cs | 23 +++- .../ColorPickerConfigurationEditor.cs | 2 +- .../ContentPickerConfigurationEditor.cs | 4 +- .../DateConfigurationEditor.cs | 2 +- .../DateTimeConfigurationEditor.cs | 2 +- .../DropDownFlexibleConfigurationEditor.cs | 2 +- .../FileUploadPropertyEditor.cs | 70 ++++++----- .../ImageCropperConfigurationEditor.cs | 2 +- .../ImageCropperPropertyEditor.cs | 104 +++++++++------- .../LabelConfigurationEditor.cs | 2 +- .../MediaPickerConfigurationEditor.cs | 2 +- .../MultiNodePickerConfigurationEditor.cs | 2 +- .../MultipleTextStringConfigurationEditor.cs | 2 +- .../PropertyEditorsComponent.cs | 8 -- .../RelatedLinksConfigurationEditor.cs | 2 +- .../PropertyEditors/TagConfigurationEditor.cs | 2 +- .../ValueListConfigurationEditor.cs | 2 +- 36 files changed, 189 insertions(+), 248 deletions(-) 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();