diff --git a/src/Umbraco.Core/Services/ContentService.cs b/src/Umbraco.Core/Services/ContentService.cs index 1bba084108..846498a3fb 100644 --- a/src/Umbraco.Core/Services/ContentService.cs +++ b/src/Umbraco.Core/Services/ContentService.cs @@ -1159,47 +1159,6 @@ namespace Umbraco.Core.Services repository.AddOrUpdatePreviewXml(copy, c => _entitySerializer.Serialize(this, _dataTypeService, c)); uow.Commit(); - //Special case for the Upload DataType - //TODO: Should we handle this with events? - //TODO: This really shouldn't be here! What about the cropper in v7, we'll have the same issue. - - if (content.Properties.Any(x => x.PropertyType.PropertyEditorAlias == Constants.PropertyEditors.UploadFieldAlias)) - { - bool isUpdated = false; - var fs = FileSystemProviderManager.Current.GetFileSystemProvider(); - - //Loop through properties to check if the content contains media that should be deleted - foreach (var property in content.Properties.Where(x => x.PropertyType.PropertyEditorAlias == Constants.PropertyEditors.UploadFieldAlias - && string.IsNullOrEmpty(x.Value.ToString()) == false)) - { - if (fs.FileExists(IOHelper.MapPath(property.Value.ToString()))) - { - var currentPath = fs.GetRelativePath(property.Value.ToString()); - var propertyId = copy.Properties.First(x => x.Alias == property.Alias).Id; - var newPath = fs.GetRelativePath(propertyId, System.IO.Path.GetFileName(currentPath)); - - fs.CopyFile(currentPath, newPath); - copy.SetValue(property.Alias, fs.GetUrl(newPath)); - - //Copy thumbnails - foreach (var thumbPath in fs.GetThumbnails(currentPath)) - { - var newThumbPath = fs.GetRelativePath(propertyId, System.IO.Path.GetFileName(thumbPath)); - fs.CopyFile(thumbPath, newThumbPath); - } - isUpdated = true; - } - } - - if (isUpdated) - { - repository.AddOrUpdate(copy); - //add or update a preview - repository.AddOrUpdatePreviewXml(copy, c => _entitySerializer.Serialize(this, _dataTypeService, c)); - uow.Commit(); - } - } - //TODO: Move this to the repository layer in a single transaction! //Special case for the associated tags var tags = uow.Database.Fetch("WHERE nodeId = @Id", new { Id = content.Id }); @@ -1210,7 +1169,7 @@ namespace Umbraco.Core.Services } //NOTE This 'Relation' part should eventually be delegated to a RelationService - //TODO: This should be party of a single commit + //TODO: This should be part of a single commit if (relateToOriginal) { IRelationType relationType = null; diff --git a/src/Umbraco.Web/PropertyEditors/FileUploadPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/FileUploadPropertyEditor.cs index efbeb0644e..4934a457d8 100644 --- a/src/Umbraco.Web/PropertyEditors/FileUploadPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/FileUploadPropertyEditor.cs @@ -31,9 +31,13 @@ namespace Umbraco.Web.PropertyEditors static FileUploadPropertyEditor() { MediaService.Saving += MediaServiceSaving; - MediaService.Creating += MediaServiceCreating; + MediaService.Created += MediaServiceCreating; + + ContentService.Copied += ContentServiceCopied; } + + /// /// Creates our custom value editor /// @@ -50,6 +54,50 @@ namespace Umbraco.Web.PropertyEditors return new FileUploadPreValueEditor(); } + /// + /// After the content is copied we need to check if there are files that also need to be copied + /// + /// + /// + static void ContentServiceCopied(IContentService sender, Core.Events.CopyEventArgs e) + { + if (e.Original.Properties.Any(x => x.PropertyType.PropertyEditorAlias == Constants.PropertyEditors.UploadFieldAlias)) + { + bool isUpdated = false; + var fs = FileSystemProviderManager.Current.GetFileSystemProvider(); + + //Loop through properties to check if the content contains media that should be deleted + foreach (var property in e.Original.Properties.Where(x => x.PropertyType.PropertyEditorAlias == Constants.PropertyEditors.UploadFieldAlias + && x.Value != null + && string.IsNullOrEmpty(x.Value.ToString()) == false)) + { + if (fs.FileExists(IOHelper.MapPath(property.Value.ToString()))) + { + var currentPath = fs.GetRelativePath(property.Value.ToString()); + var propertyId = e.Copy.Properties.First(x => x.Alias == property.Alias).Id; + var newPath = fs.GetRelativePath(propertyId, System.IO.Path.GetFileName(currentPath)); + + fs.CopyFile(currentPath, newPath); + e.Copy.SetValue(property.Alias, fs.GetUrl(newPath)); + + //Copy thumbnails + foreach (var thumbPath in fs.GetThumbnails(currentPath)) + { + var newThumbPath = fs.GetRelativePath(propertyId, System.IO.Path.GetFileName(thumbPath)); + fs.CopyFile(thumbPath, newThumbPath); + } + isUpdated = true; + } + } + + if (isUpdated) + { + //need to re-save the copy with the updated path value + sender.Save(e.Copy); + } + } + } + static void MediaServiceCreating(IMediaService sender, Core.Events.NewEventArgs e) { AutoFillProperties(e.Entity); diff --git a/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyEditor.cs index dc0352d464..bb6aff2e95 100644 --- a/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyEditor.cs @@ -18,10 +18,20 @@ namespace Umbraco.Web.PropertyEditors [PropertyEditor(Constants.PropertyEditors.ImageCropperAlias, "Image Cropper", "imagecropper", ValueType = "JSON", HideLabel = false)] public class ImageCropperPropertyEditor : PropertyEditor { + + /// + /// We're going to bind to the MediaService Saving event so that we can populate the umbracoFile size, type, etc... label fields + /// if we find any attached to the current media item. + /// + /// + /// I think this kind of logic belongs on this property editor, I guess it could exist elsewhere but it all has to do with the cropper. + /// static ImageCropperPropertyEditor() { MediaService.Saving += MediaServiceSaving; MediaService.Created += MediaServiceCreated; + + ContentService.Copied += ContentServiceCopied; } /// @@ -49,6 +59,67 @@ namespace Umbraco.Web.PropertyEditors }; } + /// + /// After the content is copied we need to check if there are files that also need to be copied + /// + /// + /// + static void ContentServiceCopied(IContentService sender, Core.Events.CopyEventArgs e) + { + if (e.Original.Properties.Any(x => x.PropertyType.PropertyEditorAlias == Constants.PropertyEditors.ImageCropperAlias)) + { + bool isUpdated = false; + var fs = FileSystemProviderManager.Current.GetFileSystemProvider(); + + //Loop through properties to check if the content contains media that should be deleted + foreach (var property in e.Original.Properties.Where(x => x.PropertyType.PropertyEditorAlias == Constants.PropertyEditors.ImageCropperAlias + && x.Value != null + && string.IsNullOrEmpty(x.Value.ToString()) == false)) + { + JObject json; + try + { + json = JsonConvert.DeserializeObject(property.Value.ToString()); + } + catch (Exception ex) + { + LogHelper.Error("An error occurred parsing the value stored in the image cropper value: " + property.Value.ToString(), ex); + continue; + } + + if (json["src"] != null && json["src"].ToString().IsNullOrWhiteSpace() == false) + { + if (fs.FileExists(IOHelper.MapPath(json["src"].ToString()))) + { + var currentPath = fs.GetRelativePath(json["src"].ToString()); + var propertyId = e.Copy.Properties.First(x => x.Alias == property.Alias).Id; + var newPath = fs.GetRelativePath(propertyId, System.IO.Path.GetFileName(currentPath)); + + fs.CopyFile(currentPath, newPath); + json["src"] = fs.GetUrl(newPath); + e.Copy.SetValue(property.Alias, json.ToString()); + + //Copy thumbnails + foreach (var thumbPath in fs.GetThumbnails(currentPath)) + { + var newThumbPath = fs.GetRelativePath(propertyId, System.IO.Path.GetFileName(thumbPath)); + fs.CopyFile(thumbPath, newThumbPath); + } + isUpdated = true; + } + } + + + } + + if (isUpdated) + { + //need to re-save the copy with the updated path value + sender.Save(e.Copy); + } + } + } + static void MediaServiceCreated(IMediaService sender, Core.Events.NewEventArgs e) { AutoFillProperties(e.Entity);