Example #1
0
        /// <summary>
        /// Save the kraked image to a specific Umbraco Media node
        /// </summary>
        /// <param name="imKrakTarget">Target media node</param>
        /// <param name="keepOriginal">Save the original image in Umbraco? Pass NULL to use global settings</param>
        /// <param name="hasChanged">Has a new image been selected for the media node just now?</param>
        /// <returns>Success status</returns>
        internal bool Save(Media mKrakTarget, bool?keepOriginal = null, bool hasChanged = false)
        {
            umbraco.cms.businesslogic.property.Property p;
            // Validate parameters
            var status = GetKrakStatus(mKrakTarget);

            if (status == EnmIsKrakable.Unkrakable || status == EnmIsKrakable.Original || String.IsNullOrEmpty(kraked_url))
            {
                // This image is unkrakable, do not proceed
                return(false);
            }

            // Determine the path and the name of the image
            var    relativeFilepath  = mKrakTarget.getProperty(Constants.UmbracoPropertyAliasFile).Value.ToString();
            var    relativeDirectory = System.IO.Path.GetDirectoryName(relativeFilepath);
            var    absoluteDirectory = System.Web.Hosting.HostingEnvironment.MapPath("~" + relativeDirectory);
            string filename          = Path.GetFileName(relativeFilepath);

            if (keepOriginal == null)
            {
                keepOriginal = Configuration.Settings.KeepOriginal;
            }

            // Has this media node already been Kraked before?
            int originalSize = 0;

            if (status == EnmIsKrakable.Kraked)
            {
                p = mKrakTarget.getProperty(Constants.UmbracoPropertyAliasOriginalSize);
                if (p != null && p.Value != null)
                {
                    int.TryParse(p.Value.ToString(), out originalSize);
                }
            }
            if (originalSize == 0)
            {
                originalSize = original_size;
            }

            var compressionRate = (((decimal)(originalSize - kraked_size)) / originalSize).ToString("p2");

            // The following might seem redundant, but Umbraco's "SetValue" extension method used below actually does a lot of magic for us.
            // However, Umbraco will also create a new media folder for us to contain the new image which we do NOT want (the url to the image has to remain unchanged).
            // So some extra efforts are required to make sure the compressed image will be switched in the place of the original image.

            var originalUmbracoFilePropertyData = mKrakTarget.getProperty(Constants.UmbracoPropertyAliasFile).Value.ToString(); // Get the original property data

            if (!mKrakTarget.AddFile(kraked_url, filename))
            {
                return(false); // Krak failed
            }
            // Extract the absolute directory path
            var newRelativeFilepath  = mKrakTarget.getProperty(Constants.UmbracoPropertyAliasFile).Value.ToString(); // Retrieve the relative filepath to the new image location
            var newRelativeDirectory = System.IO.Path.GetDirectoryName(newRelativeFilepath);                         // Extract the relative directoryname
            var newAbsoluteDirectory = System.Web.Hosting.HostingEnvironment.MapPath("~" + newRelativeDirectory);    // Convert to it's absolute variant

            mKrakTarget.getProperty(Constants.UmbracoPropertyAliasFile).Value = originalUmbracoFilePropertyData;     // Put the original property data back in place

            // If an "original" media node is already present under the current node, then save our original data to that node.
            // Else we will keep creating new nodes under the current node each time we save, and we never want more then 1 original node!
            var mOriginal = mKrakTarget.Children.FirstOrDefault(x => x.Text == EnmKrakStatus.Original.ToString() && x.getProperty(Constants.UmbracoPropertyAliasStatus) != null && x.getProperty(Constants.UmbracoPropertyAliasStatus).Value as String == "Original");

            // Does the original media node already exist?
            bool originalExists = mOriginal != null;

            // Do we need to keep a backup of the originally kraked image?
            if (keepOriginal.Value)
            {
                if (!originalExists)
                {
                    // No. Simply create a new "Original" media node under the current node, which will be used to store our "backup"
                    mOriginal = Media.MakeNew(EnmKrakStatus.Original.ToString(), MediaType.GetByAlias(mKrakTarget.ContentType.Alias), mKrakTarget.User, mKrakTarget.Id);
                }

                // We are only allowed to MODIFY the ORIGINAL media node if the FILE has CHANGED! If the original file has not been modified, then we are ONLY allowed to create a NEW media node (aka it didn't exist before)
                if (hasChanged || !originalExists)
                {
                    // Copy all properties of the current media node to the original (aka: BACKUP)
                    foreach (var p2 in mOriginal.GenericProperties)
                    {
                        p2.Value = mKrakTarget.getProperty(p2.PropertyType.Alias).Value;
                    }

                    // The image has been modified during the saving proces before, so correct that by specifying the correct original imag
                    p = mOriginal.getProperty(Constants.UmbracoPropertyAliasFile);
                    if (p != null)
                    {
                        // Save the original data, but replace the old relative filepath with the new one
                        p.Value = originalUmbracoFilePropertyData.Replace(relativeFilepath, newRelativeFilepath);
                    }

                    // The same for filesize
                    p = mOriginal.getProperty(Constants.UmbracoPropertyAliasSize);
                    if (p != null)
                    {
                        p.Value = originalSize;
                    }

                    // Set the "status" of the original image to "Original", so we know in the future this is the original image
                    p = mOriginal.getProperty(Constants.UmbracoPropertyAliasStatus);
                    if (p != null)
                    {
                        p.Value = EnmKrakStatus.Original.ToString();
                    }

                    // Save the original node. It will be placed directly underneath the current media node
                    mOriginal.Save();

                    // Now swap the folders so everything is correct again
                    string tmpFolder = absoluteDirectory + "_tmp";
                    System.IO.Directory.Move(absoluteDirectory, tmpFolder);
                    System.IO.Directory.Move(newAbsoluteDirectory, absoluteDirectory);
                    System.IO.Directory.Move(tmpFolder, newAbsoluteDirectory);
                }
                else
                {
                    // Leave the original alone! So just replace the target folder with the compressed version
                    if (System.IO.Directory.Exists(absoluteDirectory))
                    {
                        System.IO.Directory.Delete(absoluteDirectory, true);
                    }
                    System.IO.Directory.Move(newAbsoluteDirectory, absoluteDirectory);
                }
            }
            else
            {
                if (originalExists)
                {
                    var originalFilePath          = mOriginal.getProperty(Constants.UmbracoPropertyAliasFile).Value.ToString();
                    var originalRelativeDirectory = System.IO.Path.GetDirectoryName(originalFilePath);
                    var originalAbsoluteDirectory = System.Web.Hosting.HostingEnvironment.MapPath("~" + originalRelativeDirectory);
                    mOriginal.delete(true);
                    if (System.IO.Directory.Exists(originalAbsoluteDirectory))
                    {
                        System.IO.Directory.Delete(originalAbsoluteDirectory, true);
                    }
                }
                if (System.IO.Directory.Exists(absoluteDirectory))
                {
                    System.IO.Directory.Delete(absoluteDirectory, true);
                }
                System.IO.Directory.Move(newAbsoluteDirectory, absoluteDirectory);
            }


            // Show the original size
            p = mKrakTarget.getProperty(Constants.UmbracoPropertyAliasOriginalSize);
            if (p != null)
            {
                p.Value = originalSize;
            }

            // Show the kraked status
            p = mKrakTarget.getProperty(Constants.UmbracoPropertyAliasStatus);
            if (p != null)
            {
                p.Value = EnmKrakStatus.Compressed.ToString();
            }

            // Show the kraked date
            p = mKrakTarget.getProperty(Constants.UmbracoPropertyAliasCompressionDate);
            if (p != null)
            {
                p.Value = DateTime.Now.ToString();
            }

            // Show how many bytes we by kraking the image
            p = mKrakTarget.getProperty(Constants.UmbracoPropertyAliasSaved);
            if (p != null)
            {
                p.Value = compressionRate;
            }

            // Save the newly (kraked) media item
            mKrakTarget.Save();

            // Clean up the cache
            HttpRuntime.Cache.Remove("kraken_" + id);
            HttpRuntime.Cache.Remove("kraken_" + id + "_user");

            // W 8-1-2016: Obsolete as the media URL should never change in the first place
            // Refresh the Umbraco Media cache (else you might end up getting the old media node URL when fetching the filename)
            //Umbraco.Web.Cache.DistributedCache.Instance.Refresh(new Guid(Umbraco.Web.Cache.DistributedCache.MediaCacheRefresherId), imKrakTarget.Id);

            return(true);
        }