diff --git a/src/Umbraco.Web/Templates/TemplateUtilities.cs b/src/Umbraco.Web/Templates/TemplateUtilities.cs index edccbcc9d4..7134d088a6 100644 --- a/src/Umbraco.Web/Templates/TemplateUtilities.cs +++ b/src/Umbraco.Web/Templates/TemplateUtilities.cs @@ -1,5 +1,6 @@ using HtmlAgilityPack; using System; +using System.Collections.Generic; using System.IO; using System.Text.RegularExpressions; using Umbraco.Core; @@ -201,7 +202,11 @@ namespace Umbraco.Web.Templates var tmpImages = htmlDoc.DocumentNode.SelectNodes($"//img[@{TemporaryImageDataAttribute}]"); if (tmpImages == null || tmpImages.Count == 0) return html; - + + // An array to contain a list of URLs that + // we have already processed to avoid dupes + var uploadedImages = new Dictionary(); + foreach (var img in tmpImages) { // The data attribute contains the path to the tmp img to persist as a media item @@ -209,55 +214,70 @@ namespace Umbraco.Web.Templates if (string.IsNullOrEmpty(tmpImgPath)) continue; - + var absoluteTempImagePath = IOHelper.MapPath(tmpImgPath); var fileName = Path.GetFileName(absoluteTempImagePath); var safeFileName = fileName.ToSafeFileName(); var mediaItemName = safeFileName.ToFriendlyName(); IMedia mediaFile; + GuidUdi udi; - if(mediaParentFolder == Guid.Empty) - mediaFile = mediaService.CreateMedia(mediaItemName, Constants.System.Root, Constants.Conventions.MediaTypes.Image, userId); - else - mediaFile = mediaService.CreateMedia(mediaItemName, mediaParentFolder, Constants.Conventions.MediaTypes.Image, userId); - - var fileInfo = new FileInfo(absoluteTempImagePath); - - var fileStream = fileInfo.OpenReadWithRetry(); - if (fileStream == null) throw new InvalidOperationException("Could not acquire file stream"); - using (fileStream) + if (uploadedImages.ContainsKey(tmpImgPath) == false) { - mediaFile.SetValue(contentTypeBaseServiceProvider, Constants.Conventions.Media.File, safeFileName, fileStream); - } + if (mediaParentFolder == Guid.Empty) + mediaFile = mediaService.CreateMedia(mediaItemName, Constants.System.Root, Constants.Conventions.MediaTypes.Image, userId); + else + mediaFile = mediaService.CreateMedia(mediaItemName, mediaParentFolder, Constants.Conventions.MediaTypes.Image, userId); - mediaService.Save(mediaFile, userId); + var fileInfo = new FileInfo(absoluteTempImagePath); + + var fileStream = fileInfo.OpenReadWithRetry(); + if (fileStream == null) throw new InvalidOperationException("Could not acquire file stream"); + using (fileStream) + { + mediaFile.SetValue(contentTypeBaseServiceProvider, Constants.Conventions.Media.File, safeFileName, fileStream); + } + + mediaService.Save(mediaFile, userId); + + udi = mediaFile.GetUdi(); + } + else + { + // Already been uploaded & we have it's UDI + udi = uploadedImages[tmpImgPath]; + } // Add the UDI to the img element as new data attribute - var udi = mediaFile.GetUdi(); img.SetAttributeValue("data-udi", udi.ToString()); //Get the new persisted image url - var mediaTyped = Current.UmbracoHelper.Media(mediaFile.Id); + var mediaTyped = Current.UmbracoHelper.Media(udi.Guid); var location = mediaTyped.Url; img.SetAttributeValue("src", location); // Remove the data attribute (so we do not re-process this) img.Attributes.Remove(TemporaryImageDataAttribute); - // Delete folder & image now its saved in media - // The folder should contain one image - as a unique guid folder created - // for each image uploaded from TinyMceController - var folderName = Path.GetDirectoryName(absoluteTempImagePath); - try - { - Directory.Delete(folderName, true); - } - catch (Exception ex) + // Add to the dictionary to avoid dupes + if(uploadedImages.ContainsKey(tmpImgPath) == false) { - logger.Error(typeof(TemplateUtilities), ex, "Could not delete temp file or folder {FileName}", absoluteTempImagePath); + uploadedImages.Add(tmpImgPath, udi); + + // Delete folder & image now its saved in media + // The folder should contain one image - as a unique guid folder created + // for each image uploaded from TinyMceController + var folderName = Path.GetDirectoryName(absoluteTempImagePath); + try + { + Directory.Delete(folderName, true); + } + catch (Exception ex) + { + logger.Error(typeof(TemplateUtilities), ex, "Could not delete temp file or folder {FileName}", absoluteTempImagePath); + } } - } return htmlDoc.DocumentNode.OuterHtml;