private string ProcessFile(ContentPropertyData editorValue, ContentItemFile file, string currentPath, Guid cuid, Guid puid)
        {
            // process the file
            // no file, invalid file, reject change
            if (UploadFileTypeValidator.ValidateFileExtension(file.FileName) == false)
            {
                return(null);
            }

            // get the filepath
            // in case we are using the old path scheme, try to re-use numbers (bah...)
            var filepath = _mediaFileSystem.GetMediaPath(file.FileName, currentPath, cuid, puid); // fs-relative path

            using (var filestream = File.OpenRead(file.TempFilePath))
            {
                _mediaFileSystem.AddFile(filepath, filestream, true); // must overwrite!

                var ext = _mediaFileSystem.GetExtension(filepath);
                if (_mediaFileSystem.IsImageFile(ext))
                {
                    var preValues = editorValue.PreValues.FormatAsDictionary();
                    var sizes     = preValues.Any() ? preValues.First().Value.Value : string.Empty;
                    using (var image = Image.FromStream(filestream))
                        _mediaFileSystem.GenerateThumbnails(image, filepath, sizes);
                }

                // all related properties (auto-fill) are managed by ImageCropperPropertyEditor
                // when the content is saved (through event handlers)
            }

            return(filepath);
        }
        private string ProcessFile(ContentPropertyData editorValue, ContentItemFile file, string currentPath, Guid cuid, Guid puid)
        {
            // process the file
            // no file, invalid file, reject change
            if (UploadFileTypeValidator.ValidateFileExtension(file.FileName) == false)
            {
                return(null);
            }

            // get the filepath
            // in case we are using the old path scheme, try to re-use numbers (bah...)
            var filepath = _mediaFileSystem.GetMediaPath(file.FileName, currentPath, cuid, puid); // fs-relative path

            using (var filestream = File.OpenRead(file.TempFilePath))
            {
                _mediaFileSystem.AddFile(filepath, filestream, true); // must overwrite!

                var ext = _mediaFileSystem.GetExtension(filepath);
                if (_mediaFileSystem.IsImageFile(ext) && ext != ".svg")
                {
                    var preValues = editorValue.PreValues.FormatAsDictionary();
                    var sizes     = preValues.Any() ? preValues.First().Value.Value : string.Empty;
                    try
                    {
                        using (var image = Image.FromStream(filestream))
                            _mediaFileSystem.GenerateThumbnails(image, filepath, sizes);
                    }
                    catch (ArgumentException ex)
                    {
                        // send any argument errors caused by the thumbnail generation to the log instead of failing miserably
                        LogHelper.WarnWithException <ImageCropperPropertyValueEditor>("Could not extract image thumbnails.", ex);
                    }
                }

                // all related properties (auto-fill) are managed by ImageCropperPropertyEditor
                // when the content is saved (through event handlers)
            }

            return(filepath);
        }
Пример #3
0
        private string ProcessFile(ContentPropertyData editorValue, ContentPropertyFile file, string currentPath, Guid cuid, Guid puid)
        {
            // process the file
            // no file, invalid file, reject change
            if (UploadFileTypeValidator.ValidateFileExtension(file.FileName) == false)
            {
                return(null);
            }

            // get the filepath
            // in case we are using the old path scheme, try to re-use numbers (bah...)
            var filepath = _mediaFileSystem.GetMediaPath(file.FileName, currentPath, cuid, puid); // fs-relative path

            using (var filestream = File.OpenRead(file.TempFilePath))
            {
                // TODO: Here it would make sense to do the auto-fill properties stuff but the API doesn't allow us to do that right
                // since we'd need to be able to return values for other properties from these methods

                _mediaFileSystem.AddFile(filepath, filestream, true); // must overwrite!
            }

            return(filepath);
        }
Пример #4
0
        /// <summary>
        /// Converts the value received from the editor into the value can be stored in the database.
        /// </summary>
        /// <param name="editorValue">The value received from the editor.</param>
        /// <param name="currentValue">The current value of the property</param>
        /// <returns>The converted value.</returns>
        /// <remarks>
        /// <para>The <paramref name="currentValue"/> is used to re-use the folder, if possible.</para>
        /// <para>The <paramref name="editorValue"/> is value passed in from the editor. We normally don't care what
        /// the editorValue.Value is set to because we are more interested in the files collection associated with it,
        /// however we do care about the value if we are clearing files. By default the editorValue.Value will just
        /// be set to the name of the file - but again, we just ignore this and deal with the file collection in
        /// editorValue.AdditionalData.ContainsKey("files")</para>
        /// <para>We only process ONE file. We understand that the current value may contain more than one file,
        /// and that more than one file may be uploaded, so we take care of them all, but we only store ONE file.
        /// Other places (FileUploadPropertyEditor...) do NOT deal with multiple files, and our logic for reusing
        /// folders would NOT work, etc.</para>
        /// </remarks>
        public override object ConvertEditorToDb(ContentPropertyData editorValue, object currentValue)
        {
            currentValue = currentValue ?? string.Empty;

            // at that point,
            // currentValue is either empty or "/media/path/to/img.jpg"
            // editorValue.Value is { "clearFiles": true } or { "selectedFiles": "img1.jpg,img2.jpg" }
            // comparing them makes little sense

            // check the editorValue value to see whether we need to clear files
            var editorJsonValue = editorValue.Value as JObject;
            var clears          = editorJsonValue != null && editorJsonValue["clearFiles"] != null && editorJsonValue["clearFiles"].Value <bool>();
            var uploads         = editorValue.AdditionalData.ContainsKey("files") && editorValue.AdditionalData["files"] is IEnumerable <ContentItemFile>;

            // nothing = no changes, return what we have already (leave existing files intact)
            if (clears == false && uploads == false)
            {
                return(currentValue);
            }

            // get the current file paths
            var currentPaths = currentValue.ToString()
                               .Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
                               .Select(x => _mediaFileSystem.GetRelativePath(x)) // get the fs-relative path
                               .ToArray();

            // if clearing, remove these files and return
            if (clears)
            {
                foreach (var pathToRemove in currentPaths)
                {
                    _mediaFileSystem.DeleteFile(pathToRemove, true);
                }
                return(string.Empty); // no more files
            }

            // ensure we have the required guids
            if (editorValue.AdditionalData.ContainsKey("cuid") == false || // for the content item
                editorValue.AdditionalData.ContainsKey("puid") == false)    // and the property type
            {
                throw new Exception("Missing cuid/puid additional data.");
            }
            var cuido = editorValue.AdditionalData["cuid"];
            var puido = editorValue.AdditionalData["puid"];

            if ((cuido is Guid) == false || (puido is Guid) == false)
            {
                throw new Exception("Invalid cuid/puid additional data.");
            }
            var cuid = (Guid)cuido;
            var puid = (Guid)puido;

            if (cuid == Guid.Empty || puid == Guid.Empty)
            {
                throw new Exception("Invalid cuid/puid additional data.");
            }

            // process the files
            var files = ((IEnumerable <ContentItemFile>)editorValue.AdditionalData["files"]).ToArray();

            var       newPaths  = new List <string>();
            const int maxLength = 1; // we only process ONE file

            for (var i = 0; i < maxLength /*files.Length*/; i++)
            {
                var file = files[i];

                // skip invalid files
                if (UploadFileTypeValidator.ValidateFileExtension(file.FileName) == false)
                {
                    continue;
                }

                // get the filepath
                // in case we are using the old path scheme, try to re-use numbers (bah...)
                var reuse    = i < currentPaths.Length ? currentPaths[i] : null;                // this would be WRONG with many files
                var filepath = _mediaFileSystem.GetMediaPath(file.FileName, reuse, cuid, puid); // fs-relative path

                using (var filestream = File.OpenRead(file.TempFilePath))
                {
                    _mediaFileSystem.AddFile(filepath, filestream, true); // must overwrite!

                    var ext = _mediaFileSystem.GetExtension(filepath);
                    if (_mediaFileSystem.IsImageFile(ext) && ext != ".svg")
                    {
                        var preValues = editorValue.PreValues.FormatAsDictionary();
                        var sizes     = preValues.Any() ? preValues.First().Value.Value : string.Empty;
                        using (var image = Image.FromStream(filestream))
                            _mediaFileSystem.GenerateThumbnails(image, filepath, sizes);
                    }

                    // all related properties (auto-fill) are managed by FileUploadPropertyEditor
                    // when the content is saved (through event handlers)

                    newPaths.Add(filepath);
                }
            }

            // remove all temp files
            foreach (var file in files)
            {
                File.Delete(file.TempFilePath);
            }

            // remove files that are not there anymore
            foreach (var pathToRemove in currentPaths.Except(newPaths))
            {
                _mediaFileSystem.DeleteFile(pathToRemove, true);
            }


            return(string.Join(",", newPaths.Select(x => _mediaFileSystem.GetUrl(x))));
        }
        /// <summary>
        /// Overrides the deserialize value so that we can save the file accordingly
        /// </summary>
        /// <param name="editorValue">
        /// This is value passed in from the editor. We normally don't care what the editorValue.Value is set to because
        /// we are more interested in the files collection associated with it, however we do care about the value if we
        /// are clearing files. By default the editorValue.Value will just be set to the name of the file (but again, we
        /// just ignore this and deal with the file collection in editorValue.AdditionalData.ContainsKey("files") )
        /// </param>
        /// <param name="currentValue">
        /// The current value persisted for this property. This will allow us to determine if we want to create a new
        /// file path or use the existing file path.
        /// </param>
        /// <returns></returns>
        public override object ConvertEditorToDb(ContentPropertyData editorValue, object currentValue)
        {
            string  oldFile = string.Empty;
            string  newFile = string.Empty;
            JObject newJson = null;
            JObject oldJson = null;

            //get the old src path
            if (currentValue != null && string.IsNullOrEmpty(currentValue.ToString()) == false)
            {
                try
                {
                    oldJson = JObject.Parse(currentValue.ToString());
                }
                catch (Exception ex)
                {
                    //for some reason the value is invalid so continue as if there was no value there
                    LogHelper.WarnWithException <ImageCropperPropertyValueEditor>("Could not parse current db value to a JObject", ex);
                }

                if (oldJson != null && oldJson["src"] != null)
                {
                    oldFile = oldJson["src"].Value <string>();
                }
            }

            //get the new src path
            if (editorValue.Value != null)
            {
                newJson = editorValue.Value as JObject;
                if (newJson != null && newJson["src"] != null)
                {
                    newFile = newJson["src"].Value <string>();
                }
            }

            //compare old and new src path
            //if not alike, that means we have a new file, or delete the current one...
            if (string.IsNullOrEmpty(newFile) || editorValue.AdditionalData.ContainsKey("files"))
            {
                var fs = FileSystemProviderManager.Current.GetFileSystemProvider <MediaFileSystem>();

                //if we have an existing file, delete it
                if (string.IsNullOrEmpty(oldFile) == false)
                {
                    fs.DeleteFile(fs.GetRelativePath(oldFile), true);
                }
                else
                {
                    oldFile = string.Empty;
                }

                //if we have a new file, add it to the media folder and set .src

                if (editorValue.AdditionalData.ContainsKey("files"))
                {
                    var files = editorValue.AdditionalData["files"] as IEnumerable <ContentItemFile>;
                    if (files != null && files.Any())
                    {
                        var file = files.First();

                        if (UploadFileTypeValidator.ValidateFileExtension(file.FileName))
                        {
                            //create name and folder number
                            var name = IOHelper.SafeFileName(file.FileName.Substring(file.FileName.LastIndexOf(IOHelper.DirSepChar) + 1, file.FileName.Length - file.FileName.LastIndexOf(IOHelper.DirSepChar) - 1).ToLower());

                            //try to reuse the folder number from the current file
                            var subfolder = UmbracoConfig.For.UmbracoSettings().Content.UploadAllowDirectories
                                                ? oldFile.Replace(fs.GetUrl("/"), "").Split('/')[0]
                                                : oldFile.Substring(oldFile.LastIndexOf("/", StringComparison.Ordinal) + 1).Split('-')[0];

                            //if we dont find one, create a new one
                            int subfolderId;
                            var numberedFolder = int.TryParse(subfolder, out subfolderId)
                                                     ? subfolderId.ToString(CultureInfo.InvariantCulture)
                                                     : MediaSubfolderCounter.Current.Increment().ToString(CultureInfo.InvariantCulture);

                            //set a file name or full path
                            var fileName = UmbracoConfig.For.UmbracoSettings().Content.UploadAllowDirectories
                                               ? Path.Combine(numberedFolder, name)
                                               : numberedFolder + "-" + name;

                            //save file and assign to the json
                            using (var fileStream = System.IO.File.OpenRead(file.TempFilePath))
                            {
                                var umbracoFile = UmbracoMediaFile.Save(fileStream, fileName);
                                newJson["src"] = umbracoFile.Url;

                                return(newJson.ToString());
                            }
                        }
                    }
                }
            }

            //incase we submit nothing back
            if (editorValue.Value == null)
            {
                return(null);
            }

            return(editorValue.Value.ToString());
        }
Пример #6
0
        /// <summary>
        /// Overrides the deserialize value so that we can save the file accordingly
        /// </summary>
        /// <param name="editorValue">
        /// This is value passed in from the editor. We normally don't care what the editorValue.Value is set to because
        /// we are more interested in the files collection associated with it, however we do care about the value if we
        /// are clearing files. By default the editorValue.Value will just be set to the name of the file (but again, we
        /// just ignore this and deal with the file collection in editorValue.AdditionalData.ContainsKey("files") )
        /// </param>
        /// <param name="currentValue">
        /// The current value persisted for this property. This will allow us to determine if we want to create a new
        /// file path or use the existing file path.
        /// </param>
        /// <returns></returns>
        public override object ConvertEditorToDb(ContentPropertyData editorValue, object currentValue)
        {
            if (currentValue == null)
            {
                currentValue = string.Empty;
            }

            //if the value is the same then just return the current value so we don't re-process everything
            if (string.IsNullOrEmpty(currentValue.ToString()) == false && editorValue.Value == currentValue.ToString())
            {
                return(currentValue);
            }

            //check the editorValue value to see if we need to clear the files or not.
            var clear = false;
            var json  = editorValue.Value as JObject;

            if (json != null && json["clearFiles"] != null && json["clearFiles"].Value <bool>())
            {
                clear = json["clearFiles"].Value <bool>();
            }

            var currentPersistedValues = new string[] {};

            if (string.IsNullOrEmpty(currentValue.ToString()) == false)
            {
                currentPersistedValues = currentValue.ToString().Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            }

            var newValue = new List <string>();

            var fs = FileSystemProviderManager.Current.GetFileSystemProvider <MediaFileSystem>();

            if (clear)
            {
                //Remove any files that are saved for this item
                foreach (var toRemove in currentPersistedValues)
                {
                    fs.DeleteFile(fs.GetRelativePath(toRemove), true);
                }
                return("");
            }

            //check for any files
            if (editorValue.AdditionalData.ContainsKey("files"))
            {
                var files = editorValue.AdditionalData["files"] as IEnumerable <ContentItemFile>;
                if (files != null)
                {
                    //now we just need to move the files to where they should be
                    var filesAsArray = files.ToArray();
                    //a list of all of the newly saved files so we can compare with the current saved files and remove the old ones
                    var savedFilePaths = new List <string>();
                    for (var i = 0; i < filesAsArray.Length; i++)
                    {
                        var file = filesAsArray[i];

                        //don't continue if this is not allowed!
                        if (UploadFileTypeValidator.ValidateFileExtension(file.FileName) == false)
                        {
                            continue;
                        }

                        //TODO: ALl of this naming logic needs to be put into the ImageHelper and then we need to change ContentExtensions to do the same!

                        var currentPersistedFile = currentPersistedValues.Length >= (i + 1)
                                                       ? currentPersistedValues[i]
                                                       : "";

                        var name = IOHelper.SafeFileName(file.FileName.Substring(file.FileName.LastIndexOf(IOHelper.DirSepChar) + 1, file.FileName.Length - file.FileName.LastIndexOf(IOHelper.DirSepChar) - 1).ToLower());

                        var subfolder = UmbracoConfig.For.UmbracoSettings().Content.UploadAllowDirectories
                                            ? currentPersistedFile.Replace(fs.GetUrl("/"), "").Split('/')[0]
                                            : currentPersistedFile.Substring(currentPersistedFile.LastIndexOf("/", StringComparison.Ordinal) + 1).Split('-')[0];

                        int subfolderId;
                        var numberedFolder = int.TryParse(subfolder, out subfolderId)
                                                 ? subfolderId.ToString(CultureInfo.InvariantCulture)
                                                 : MediaSubfolderCounter.Current.Increment().ToString(CultureInfo.InvariantCulture);

                        var fileName = UmbracoConfig.For.UmbracoSettings().Content.UploadAllowDirectories
                                           ? Path.Combine(numberedFolder, name)
                                           : numberedFolder + "-" + name;

                        using (var fileStream = File.OpenRead(file.TempFilePath))
                        {
                            var umbracoFile = UmbracoMediaFile.Save(fileStream, fileName);

                            if (umbracoFile.SupportsResizing)
                            {
                                var additionalSizes = new List <int>();
                                //get the pre-vals value
                                var thumbs = editorValue.PreValues.FormatAsDictionary();
                                if (thumbs.Any())
                                {
                                    var thumbnailSizes = thumbs.First().Value.Value;
                                    // additional thumbnails configured as prevalues on the DataType
                                    foreach (var thumb in thumbnailSizes.Split(new[] { ";", "," }, StringSplitOptions.RemoveEmptyEntries))
                                    {
                                        int thumbSize;
                                        if (thumb == "" || int.TryParse(thumb, out thumbSize) == false)
                                        {
                                            continue;
                                        }
                                        additionalSizes.Add(thumbSize);
                                    }
                                }

                                using (var image = Image.FromStream(fileStream))
                                {
                                    ImageHelper.GenerateMediaThumbnails(fs, fileName, umbracoFile.Extension, image, additionalSizes);
                                }
                            }
                            newValue.Add(umbracoFile.Url);
                            //add to the saved paths
                            savedFilePaths.Add(umbracoFile.Url);
                        }
                        //now remove the temp file
                        File.Delete(file.TempFilePath);
                    }

                    //Remove any files that are no longer saved for this item
                    foreach (var toRemove in currentPersistedValues.Except(savedFilePaths))
                    {
                        fs.DeleteFile(fs.GetRelativePath(toRemove), true);
                    }


                    return(string.Join(",", newValue));
                }
            }

            //if we've made it here, we had no files to save and we were not clearing anything so just persist the same value we had before
            return(currentValue);
        }