diff --git a/src/Umbraco.Core/IO/MediaFileSystem.cs b/src/Umbraco.Core/IO/MediaFileSystem.cs index e3d8f489c6..de795303af 100644 --- a/src/Umbraco.Core/IO/MediaFileSystem.cs +++ b/src/Umbraco.Core/IO/MediaFileSystem.cs @@ -1,8 +1,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Text; -using Umbraco.Core.CodeAnnotations; using Umbraco.Core.Configuration; namespace Umbraco.Core.IO @@ -27,6 +25,15 @@ namespace Umbraco.Core.IO return propertyId.ToString() + seperator + fileName; } + public string GetRelativePath(string subfolder, string fileName) + { + var seperator = UmbracoSettings.UploadAllowDirectories + ? Path.DirectorySeparatorChar + : '-'; + + return subfolder + seperator + fileName; + } + public IEnumerable GetThumbnails(string path) { var parentDirectory = System.IO.Path.GetDirectoryName(path); diff --git a/src/Umbraco.Core/Media/MediaSubFolders.cs b/src/Umbraco.Core/Media/MediaSubfolderCounter.cs similarity index 65% rename from src/Umbraco.Core/Media/MediaSubFolders.cs rename to src/Umbraco.Core/Media/MediaSubfolderCounter.cs index ab5e994e73..6f0142cacf 100644 --- a/src/Umbraco.Core/Media/MediaSubFolders.cs +++ b/src/Umbraco.Core/Media/MediaSubfolderCounter.cs @@ -12,34 +12,32 @@ namespace Umbraco.Core.Media /// which will be the start point for the naming of the next subfolders. If no subfolders exists /// then the starting point will be 1000, ie. /media/1000/koala.jpg /// - internal class MediaSubFolders + internal class MediaSubfolderCounter { #region Singleton private long _numberedFolder = 1000;//Default starting point private static readonly ReaderWriterLockSlim ClearLock = new ReaderWriterLockSlim(); - private static readonly Lazy Lazy = new Lazy(() => new MediaSubFolders()); + private static readonly Lazy Lazy = new Lazy(() => new MediaSubfolderCounter()); - public static MediaSubFolders Current { get { return Lazy.Value; } } + public static MediaSubfolderCounter Current { get { return Lazy.Value; } } - private MediaSubFolders() + private MediaSubfolderCounter() { var folders = new List(); var fs = FileSystemProviderManager.Current.GetFileSystemProvider(); - var directories = fs.GetDirectories("/"); - if (directories.Any()) + var directories = fs.GetDirectories(""); + foreach (var directory in directories) { - foreach (var directory in directories) + long dirNum; + if (long.TryParse(directory, out dirNum)) { - long dirNum; - if (long.TryParse(directory, out dirNum)) - { - folders.Add(dirNum); - } + folders.Add(dirNum); } - long last = folders.OrderBy(x => x).Last(); - _numberedFolder = last; } + var last = folders.OrderBy(x => x).LastOrDefault(); + if(last != default(long)) + _numberedFolder = last; } #endregion @@ -52,7 +50,7 @@ namespace Umbraco.Core.Media { using (new ReadLock(ClearLock)) { - _numberedFolder++; + _numberedFolder = _numberedFolder + 1; return _numberedFolder; } } diff --git a/src/Umbraco.Core/Models/ContentExtensions.cs b/src/Umbraco.Core/Models/ContentExtensions.cs index 2aca92d857..1ad73191f3 100644 --- a/src/Umbraco.Core/Models/ContentExtensions.cs +++ b/src/Umbraco.Core/Models/ContentExtensions.cs @@ -58,16 +58,22 @@ namespace Umbraco.Core.Models /// /// Sets and uploads the file from a HttpPostedFileBase object as the property value /// - /// to add property value to + /// to add property value to /// Alias of the property to save the value on /// The containing the file that will be uploaded public static void SetValue(this IContentBase content, string propertyTypeAlias, HttpPostedFileBase value) { + // Ensure we get the filename without the path in IE in intranet mode + // http://stackoverflow.com/questions/382464/httppostedfile-filename-different-from-ie + var fileName = value.FileName; + if (fileName.LastIndexOf(@"\") > 0) + fileName = fileName.Substring(fileName.LastIndexOf(@"\") + 1); + var name = IOHelper.SafeFileName( - value.FileName.Substring(value.FileName.LastIndexOf(IOHelper.DirSepChar) + 1, - value.FileName.Length - value.FileName.LastIndexOf(IOHelper.DirSepChar) - 1) - .ToLower()); + fileName.Substring(fileName.LastIndexOf(IOHelper.DirSepChar) + 1, + fileName.Length - fileName.LastIndexOf(IOHelper.DirSepChar) - 1) + .ToLower()); if (string.IsNullOrEmpty(name) == false) SetFileOnContent(content, propertyTypeAlias, name, value.InputStream); @@ -76,16 +82,22 @@ namespace Umbraco.Core.Models /// /// Sets and uploads the file from a HttpPostedFile object as the property value /// - /// to add property value to + /// to add property value to /// Alias of the property to save the value on /// The containing the file that will be uploaded public static void SetValue(this IContentBase content, string propertyTypeAlias, HttpPostedFile value) { + // Ensure we get the filename without the path in IE in intranet mode + // http://stackoverflow.com/questions/382464/httppostedfile-filename-different-from-ie + var fileName = value.FileName; + if (fileName.LastIndexOf(@"\") > 0) + fileName = fileName.Substring(fileName.LastIndexOf(@"\") + 1); + var name = IOHelper.SafeFileName( - value.FileName.Substring(value.FileName.LastIndexOf(IOHelper.DirSepChar) + 1, - value.FileName.Length - value.FileName.LastIndexOf(IOHelper.DirSepChar) - 1) - .ToLower()); + fileName.Substring(fileName.LastIndexOf(IOHelper.DirSepChar) + 1, + fileName.Length - fileName.LastIndexOf(IOHelper.DirSepChar) - 1) + .ToLower()); if (string.IsNullOrEmpty(name) == false) SetFileOnContent(content, propertyTypeAlias, name, value.InputStream); @@ -94,13 +106,33 @@ namespace Umbraco.Core.Models /// /// Sets and uploads the file from a HttpPostedFileWrapper object as the property value /// - /// to add property value to + /// to add property value to /// Alias of the property to save the value on /// The containing the file that will be uploaded public static void SetValue(this IContentBase content, string propertyTypeAlias, HttpPostedFileWrapper value) { - if (string.IsNullOrEmpty(value.FileName) == false) - SetFileOnContent(content, propertyTypeAlias, value.FileName, value.InputStream); + // Ensure we get the filename without the path in IE in intranet mode + // http://stackoverflow.com/questions/382464/httppostedfile-filename-different-from-ie + var fileName = value.FileName; + if (fileName.LastIndexOf(@"\") > 0) + fileName = fileName.Substring(fileName.LastIndexOf(@"\") + 1); + + if (string.IsNullOrEmpty(fileName) == false) + SetFileOnContent(content, propertyTypeAlias, fileName, value.InputStream); + } + + /// + /// Sets and uploads the file from a as the property value + /// + /// to add property value to + /// Alias of the property to save the value on + /// Name of the file + /// to save to disk + public static void SetValue(this IContentBase content, string propertyTypeAlias, string fileName, + Stream fileStream) + { + if (string.IsNullOrEmpty(fileName) == false && fileStream != null) + SetFileOnContent(content, propertyTypeAlias, fileName, fileStream); } private static void SetFileOnContent(IContentBase content, string propertyTypeAlias, string name, Stream fileStream) @@ -110,11 +142,12 @@ namespace Umbraco.Core.Models return; bool supportsResizing = false; - var numberedFolder = MediaSubFolders.Current.Increment(); + var numberedFolder = MediaSubfolderCounter.Current.Increment(); string fileName = UmbracoSettings.UploadAllowDirectories ? Path.Combine(numberedFolder.ToString(CultureInfo.InvariantCulture), name) : numberedFolder + "-" + name; - string extension = Path.GetExtension(name); + + string extension = Path.GetExtension(name).Substring(1).ToLowerInvariant(); var fs = FileSystemProviderManager.Current.GetFileSystemProvider(); fs.AddFile(fileName, fileStream); diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index a915caf4e4..2af4f04820 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -139,7 +139,7 @@ - + diff --git a/src/umbraco.cms/businesslogic/datatype/FileHandlerData.cs b/src/umbraco.cms/businesslogic/datatype/FileHandlerData.cs index 854abd2d77..481b9b7cb0 100644 --- a/src/umbraco.cms/businesslogic/datatype/FileHandlerData.cs +++ b/src/umbraco.cms/businesslogic/datatype/FileHandlerData.cs @@ -57,7 +57,7 @@ namespace umbraco.cms.businesslogic.datatype // handle upload if (name != String.Empty) { - var numberedFolder = MediaSubFolders.Current.Increment(); + var numberedFolder = MediaSubfolderCounter.Current.Increment(); string fileName = UmbracoSettings.UploadAllowDirectories ? Path.Combine(numberedFolder.ToString(CultureInfo.InvariantCulture), name) : numberedFolder + "-" + name; diff --git a/src/umbraco.cms/businesslogic/media/UmbracoImageMediaFactory.cs b/src/umbraco.cms/businesslogic/media/UmbracoImageMediaFactory.cs index 3c77e0cb5c..e4bd16d704 100644 --- a/src/umbraco.cms/businesslogic/media/UmbracoImageMediaFactory.cs +++ b/src/umbraco.cms/businesslogic/media/UmbracoImageMediaFactory.cs @@ -1,15 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Drawing.Drawing2D; -using System.Drawing.Imaging; -using System.IO; -using System.Linq; -using System.Web; -using Umbraco.Core.Logging; -using umbraco.BasePages; +using System.Collections.Generic; +using Umbraco.Core.Models; using umbraco.BusinessLogic; -using umbraco.cms.businesslogic.datatype; namespace umbraco.cms.businesslogic.media { @@ -27,146 +18,17 @@ namespace umbraco.cms.businesslogic.media public override void DoHandleMedia(Media media, PostedMediaFile postedFile, User user) { - // Get Image object, width and height - var image = Image.FromStream(postedFile.InputStream); - var fileWidth = image.Width; - var fileHeight = image.Height; + // Set media property to upload the file as well as set all related properties + media.MediaItem.SetValue("umbracoFile", postedFile.FileName, postedFile.InputStream); - // Get umbracoFile property - var propertyId = media.getProperty("umbracoFile").Id; + // Copy back the values from the internal IMedia to ensure that the values are persisted when saved + foreach (var property in media.MediaItem.Properties) + { + media.getProperty(property.Alias).Value = property.Value; + } - // Get paths - var destFilePath = FileSystem.GetRelativePath(propertyId, postedFile.FileName); - var ext = Path.GetExtension(destFilePath).Substring(1); - - // Set media properties - media.getProperty("umbracoFile").Value = FileSystem.GetUrl(destFilePath); - - if (media.getProperty("umbracoWidth") != null) - media.getProperty("umbracoWidth").Value = fileWidth; - - if (media.getProperty("umbracoHeight") != null) - media.getProperty("umbracoHeight").Value = fileHeight; - - if (media.getProperty("umbracoBytes") != null) - media.getProperty("umbracoBytes").Value = postedFile.ContentLength; - - if (media.getProperty("umbracoExtension") != null) - media.getProperty("umbracoExtension").Value = ext; - - if (media.getProperty("umbracoExtensio") != null) - media.getProperty("umbracoExtensio").Value = ext; - - // Generate thumbnail - var thumbDestFilePath = Path.Combine(Path.GetDirectoryName(destFilePath), Path.GetFileNameWithoutExtension(destFilePath) + "_thumb"); - GenerateThumbnail(image, 100, fileWidth, fileHeight, ext, thumbDestFilePath + ".jpg"); - - // Generate additional thumbnails based on PreValues set in DataTypeDefinition uploadField - GenerateAdditionalThumbnails(image, fileWidth, fileHeight, ext, thumbDestFilePath); - - image.Dispose(); - - FileSystem.AddFile(destFilePath, postedFile.InputStream, postedFile.ReplaceExisting); - - // Save media + // Save media (using legacy media object to ensure the usage of the legacy events). media.Save(); } - - private void GenerateAdditionalThumbnails(Image image, int fileWidth, int fileHeight, string ext, string destFilePath) - { - var uploadFieldDataTypeId = new Guid("5032a6e6-69e3-491d-bb28-cd31cd11086c"); - - DataTypeDefinition dataTypeDef = null; - - try - { - // Get DataTypeDefinition of upload field - dataTypeDef = DataTypeDefinition.GetByDataTypeId(uploadFieldDataTypeId); - } - catch (Exception e) - { - LogHelper.Error("Could get Upload Field datatype definition", e); - } - - if (dataTypeDef != null) - { - // Get PreValues - var preValues = PreValues.GetPreValues(dataTypeDef.Id); - - var thumbnails = ""; - if (preValues.Count > 0) - thumbnails = ((PreValue)preValues[0]).Value; - - if (thumbnails != "") - { - var thumbnailSizes = thumbnails.Split(";".ToCharArray()); - foreach (var thumb in thumbnailSizes.Where(thumb => thumb != "")) - { - GenerateThumbnail(image, int.Parse(thumb), fileWidth, fileHeight, ext, destFilePath + "_" + thumb + ".jpg"); - } - } - } - } - - private void GenerateThumbnail(Image image, int maxWidthHeight, int fileWidth, int fileHeight, string ext, string thumbnailFileName) - { - // Generate thumbnailee - var fx = (float)fileWidth / maxWidthHeight; - var fy = (float)fileHeight / maxWidthHeight; - - // must fit in thumbnail size - var f = Math.Max(fx, fy); //if (f < 1) f = 1; - var widthTh = (int)Math.Round(fileWidth / f); - var heightTh = (int)Math.Round(fileHeight / f); - - // fixes for empty width or height - if (widthTh == 0) - widthTh = 1; - - if (heightTh == 0) - heightTh = 1; - - // Create new image with best quality settings - var bp = new Bitmap(widthTh, heightTh); - var g = Graphics.FromImage(bp); - g.SmoothingMode = SmoothingMode.HighQuality; - g.InterpolationMode = InterpolationMode.HighQualityBicubic; - g.PixelOffsetMode = PixelOffsetMode.HighQuality; - - // Copy the old image to the new and resized - var rect = new Rectangle(0, 0, widthTh, heightTh); - g.DrawImage(image, rect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel); - - // Copy metadata - var codecs = ImageCodecInfo.GetImageEncoders(); - - var codec = ext.ToLower() == "png" || ext.ToLower() == "gif" - ? codecs.Single(t => t.MimeType.Equals("image/png")) - : codecs.Single(t => t.MimeType.Equals("image/jpeg")); - - // Set compresion ratio to 90% - var ep = new EncoderParameters(); - ep.Param[0] = new EncoderParameter(Encoder.Quality, 90L); - - // Save the new image - if (codec != null) - { - var ms = new MemoryStream(); - bp.Save(ms, codec, ep); - ms.Seek(0, 0); - - FileSystem.AddFile(thumbnailFileName, ms); - - ms.Close(); - } - else - { - // Log error - LogHelper.Warn("Multiple file upload: Can't find appropriate codec"); - } - - bp.Dispose(); - g.Dispose(); - } } }