/// <summary>
        /// Populates the properties.
        /// </summary>
        /// <param name="media">The image media.</param>
        /// <param name="userService">The user service.</param>
        /// <param name="includeChildrenDetails">if set to <c>true</c> [include children details].</param>
        private void PopulateProperties(IMedia media, IUserService userService, bool includeChildrenDetails)
        {
            Id                     = media.Id;
            Name                   = media.Name;
            Path                   = media.Path;
            CreatorName            = media.GetCreatorProfile(userService).Name;
            IncludeChildrenDetails = includeChildrenDetails;

            if (includeChildrenDetails)
            {
                NumberOfFolders = media.Children().Where(p => p.ContentType.Alias == MediaTypeAlias.Folder).Count();
                NumberOfImages  = media.Children().Where(p => p.ContentType.Alias == MediaTypeAlias.Image).Count();
            }
        }
Пример #2
0
        /// <summary>
        /// Function to return existing media file.
        /// </summary>
        /// <returns>Media file.</returns>
        private IList <IMedia> GetExistingMediaFiles(string ticketTemplatesFolderName)
        {
            IMedia uploadsMediaFolder = this.MediaService.GetRootMedia().Where(m => m.Name.Equals(ticketTemplatesFolderName)).FirstOrDefault();

            if (uploadsMediaFolder != null)
            {
                if (uploadsMediaFolder.Children().Count() > 0)
                {
                    return(uploadsMediaFolder.Children().ToList());
                }
            }

            return(null);
        }
        private bool CopyMedia(IMedia mediaToCopy, int destinationId, bool copyChildren)
        {
            //Copy the first media then we will determine if/how to copy the children.
            IMedia freshlyCopiedMedia = CopyMediaPropertiesAndSave(mediaToCopy, destinationId);

            if (freshlyCopiedMedia == null)
            {
                return(false);
            }

            this._lastCopiedNodePath = freshlyCopiedMedia.Path;

            if (copyChildren)
            {
                foreach (IMedia childMediaToCopy in mediaToCopy.Children())
                {
                    bool allSuccessfull = CopyMedia(childMediaToCopy, freshlyCopiedMedia.Id, copyChildren);

                    if (!allSuccessfull)
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
        private IMedia SaveImage(HttpPostedFileBase file, MemberModel member)
        {
            IMedia peopleFolder = _umbracoMediaService.GetRootMedia().FirstOrDefault(x => x.Name == "People");

            IMedia chapterFolder = peopleFolder.Children().FirstOrDefault(x => x.Name == member.Chapter.Name);

            if (chapterFolder == null)
            {
                chapterFolder = _umbracoMediaService.CreateMedia(member.Chapter.Name, peopleFolder, "Folder");
            }

            string key      = member.FullName;
            IMedia existing = chapterFolder.Children().FirstOrDefault(x => x.Name == member.FullName);

            if (existing != null)
            {
                existing.Name = member.FullName + "-deleted";
                _umbracoMediaService.Save(existing);
            }

            IMedia memberImage = _umbracoMediaService.CreateMedia(member.FullName, chapterFolder, "Image");

            memberImage.SetValue("umbracoFile", file);

            _umbracoMediaService.Save(memberImage);

            if (existing != null)
            {
                _umbracoMediaService.Delete(existing);
            }

            return(memberImage);
        }
Пример #5
0
        private bool CopyMedia(IMedia media, int destinationId, bool copyChildren = false)
        {
            if (media == null)
            {
                return(false);
            }

            var copiedMedia = _mediaService.CreateMediaWithIdentity(
                $"{media.Name}{_textService?.Localize("mediaCopy/copySuffix")}",
                destinationId,
                media.ContentType.Alias);

            if (copiedMedia == null)
            {
                return(false);
            }

            for (int i = 0; i < media.Properties.Count; ++i)
            {
                copiedMedia.Properties[i].Value = media.Properties[i]?.Value;
            }

            if (media.ContentType.Alias != FolderAlias)
            {
                CopyUploadedFile(media, copiedMedia);
            }

            _nodePath = copiedMedia.Path;

            _mediaService.Save(copiedMedia);

            if (media.Children()?.Any() ?? false)
            {
                foreach (IMedia childMedia in media.Children())
                {
                    if (!CopyMedia(childMedia, copiedMedia.Id, copyChildren))
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
Пример #6
0
        /// <summary>
        /// Adds the folder if contains new images.
        /// </summary>
        /// <param name="media">The media.</param>
        /// <param name="mediaContainer">The media container.</param>
        /// <param name="date">The date.</param>
        public static void AddFolderIfContainsNewImages(this IMedia media, ConcurrentBag <IMedia> mediaContainer, Nullable <DateTime> date)
        {
            bool hasAnyNewMedia = media.Children()
                                  .Any(p => p.ContentType.Alias == MediaTypeAlias.Image && p.UpdateDate >= date.Value);

            if (hasAnyNewMedia)
            {
                mediaContainer.Add(media);
            }
        }
Пример #7
0
        public void SeedMedia(MediaSeed media, IMedia parent = null, int userId = 0, bool raiseEventsOnCreate = false)
        {
            var content = (parent?.Children().Where(x => string.Equals(x.Name, media.NodeName, StringComparison.InvariantCultureIgnoreCase))
                           ??
                           _mediaService.GetRootMedia().Where(x => string.Equals(x.Name, media.NodeName, StringComparison.InvariantCultureIgnoreCase))).FirstOrDefault();
            var contentExisted = content == null;

            if (!contentExisted)
            {
                media.Content.NodeDetails.Name = media.NodeName;
                media.Content.Persist(parent?.Id ?? -1, userId, raiseEventsOnCreate);
                content = media.Content.NodeDetails.Content;
            }

            if (!SkipChildrenIfParentExists || !contentExisted)
            {
                foreach (var child in media.Children)
                {
                    SeedMedia(child, content, userId, raiseEventsOnCreate);
                }
            }
        }
        public bool Execute(string packageName, XmlNode xmlData)
        {
            IMediaService       mediaService       = ApplicationContext.Current.Services.MediaService;
            IContentService     contentService     = UmbracoContext.Current.Application.Services.ContentService;
            IContentTypeService contentTypeService = ApplicationContext.Current.Services.ContentTypeService;
            IFileService        fileService        = ApplicationContext.Current.Services.FileService;
            //ApplicationContext.Current.Services.DataTypeService.
            IDataTypeService dataTypeService = UmbracoContext.Current.Application.Services.DataTypeService;

            #region Create media
            List <int>    productImageIds = new List <int>();
            List <IMedia> productImages   = new List <IMedia>();
            try {
                //Create image files
                const string productImagesFolderName = "Product images";
                string[]     mediaInstallImages      = Directory.GetFiles(HostingEnvironment.MapPath("~/Assets/InstallMedia"));
                IMedia       productImagesFolder     = mediaService.GetByLevel(1).FirstOrDefault(m => m.Name == productImagesFolderName);
                if (productImagesFolder == null)
                {
                    productImagesFolder = mediaService.CreateMedia(productImagesFolderName, -1, "Folder");
                    mediaService.Save(productImagesFolder);
                }

                if (!productImagesFolder.Children().Any())
                {
                    foreach (string mediaInstallImage in mediaInstallImages)
                    {
                        string fileName     = Path.GetFileName(mediaInstallImage);
                        IMedia productImage = mediaService.CreateMedia(fileName, productImagesFolder.Id, "Image");
                        byte[] buffer       = File.ReadAllBytes(Path.GetFullPath(mediaInstallImage));
                        using (MemoryStream strm = new MemoryStream(buffer)) {
                            productImage.SetValue("umbracoFile", fileName, strm);
                            mediaService.Save(productImage);
                            productImages.Add(productImage);
                            productImageIds.Add(productImage.Id);
                        }
                    }
                }
                else
                {
                    productImageIds = productImagesFolder.Children().Select(c => c.Id).ToList();
                }

                Directory.Delete(HostingEnvironment.MapPath("~/Assets/InstallMedia"), true);
            } catch (Exception ex) {
                LogHelper.Error <TeaCommerceStarterKitInstall>("Create media failed", ex);
            }
            #endregion

            #region Set up Tea Commerce
            Store store = null;
            try {
                //Get store or create it
                IReadOnlyList <Store> stores = StoreService.Instance.GetAll().ToList();
                store = stores.FirstOrDefault();
                if (store == null)
                {
                    store = new Store("Starter Kit Store");
                }

                store.ProductSettings.ProductVariantPropertyAlias = "variants";
                store.Save();

                foreach (PaymentMethod paymentMethod in PaymentMethodService.Instance.GetAll(store.Id).Where(p => p.Alias == "invoicing"))
                {
                    PaymentMethodSetting setting = paymentMethod.Settings.FirstOrDefault(s => s.Key == "acceptUrl");
                    if (setting != null)
                    {
                        setting.Value = "/cart-content/confirmation/";
                    }
                    paymentMethod.Save();
                }
            } catch (Exception ex) {
                LogHelper.Error <TeaCommerceStarterKitInstall>("Setting up Tea Commerce failed", ex);
            }
            #endregion

            #region Create Templates
            List <ITemplate> templates = new List <ITemplate>();
            try {
                string[] templateFiles = Directory.GetFiles(HostingEnvironment.MapPath("~/views"));
                foreach (string templateFile in templateFiles)
                {
                    string fileName    = Path.GetFileNameWithoutExtension(templateFile);
                    string fileContent = File.ReadAllText(templateFile);
                    templates.Add(fileService.CreateTemplateWithIdentity(fileName, fileContent));
                }
            } catch (Exception ex) {
                LogHelper.Error <TeaCommerceStarterKitInstall>("Create templates failed", ex);
            }
            #endregion

            #region Set up content types

            IEnumerable <IDataTypeDefinition> allDataTypeDefinitions = dataTypeService.GetAllDataTypeDefinitions();
            try {
                IDataTypeDefinition variantEditorDataTypeDefinition = allDataTypeDefinitions.FirstOrDefault(d => d.Name.ToLowerInvariant().Contains("variant editor"));
                variantEditorDataTypeDefinition.DatabaseType = DataTypeDatabaseType.Ntext;

                var preValDictionary = new Dictionary <string, object> {
                    { "xpathOrNode", "{\"showXPath\": true,\"query\": \"$current/ancestor-or-self::frontpage/attributes\"}" },
                    { "variantDocumentType", "variant" },
                    { "extraListInformation", "sku,priceJMD" },
                    { "hideLabel", "1" },
                };
                var currVal = dataTypeService.GetPreValuesCollectionByDataTypeId(variantEditorDataTypeDefinition.Id);

                //we need to allow for the property editor to deserialize the prevalues
                PropertyEditor pe           = PropertyEditorResolver.Current.PropertyEditors.SingleOrDefault(x => x.Alias == "TeaCommerce.VariantEditor");
                var            formattedVal = pe.PreValueEditor.ConvertEditorToDb(preValDictionary, currVal);
                dataTypeService.SaveDataTypeAndPreValues(variantEditorDataTypeDefinition, formattedVal);
                //dataTypeService.Save( variantEditorDataTypeDefinition );
                variantEditorDataTypeDefinition = dataTypeService.GetDataTypeDefinitionById(variantEditorDataTypeDefinition.Id);
            } catch (Exception ex) {
                LogHelper.Error <TeaCommerceStarterKitInstall>("Set up content types failed", ex);
            }
            #endregion

            #region Create Document types
            ContentType attributeContentType      = null,
                        attributeGroupContentType = null,
                        attributesContentType     = null,
                        cartStepContentType       = null,
                        cartContentType           = null,
                        variantContentType        = null,
                        productContentType        = null,
                        productListContentType    = null,
                        frontpageContentType      = null;
            try {
                attributeContentType       = new ContentType(-1);
                attributeContentType.Alias = "attribute";
                attributeContentType.Name  = "Attribute";
                attributeContentType.Icon  = "icon-t-shirt";
                contentTypeService.Save(attributeContentType);

                attributeGroupContentType       = new ContentType(-1);
                attributeGroupContentType.Alias = "attributeGroup";
                attributeGroupContentType.Name  = "Attribute group";
                attributeGroupContentType.Icon  = "icon-t-shirt color-orange";
                attributeGroupContentType.AllowedContentTypes = new List <ContentTypeSort>()
                {
                    new ContentTypeSort(attributeContentType.Id, 0)
                };
                contentTypeService.Save(attributeGroupContentType);

                attributesContentType       = new ContentType(-1);
                attributesContentType.Alias = "attributes";
                attributesContentType.Name  = "Attributes";
                attributesContentType.Icon  = "icon-t-shirt";
                attributesContentType.AllowedContentTypes = new List <ContentTypeSort>()
                {
                    new ContentTypeSort(attributeGroupContentType.Id, 0)
                };
                contentTypeService.Save(attributesContentType);

                cartStepContentType                  = new ContentType(-1);
                cartStepContentType.Alias            = "cartStep";
                cartStepContentType.Name             = "Cart step";
                cartStepContentType.Icon             = "icon-shopping-basket-alt-2 color-orange";
                cartStepContentType.AllowedTemplates = templates.Where(t => t.Alias.ToLowerInvariant().Contains("cartstep") && !t.Alias.ToLowerInvariant().Contains("master"));
                contentTypeService.Save(cartStepContentType);

                cartContentType       = new ContentType(-1);
                cartContentType.Alias = "cart";
                cartContentType.Name  = "Cart";
                cartContentType.Icon  = "icon-shopping-basket-alt-2";
                cartContentType.AllowedContentTypes = new List <ContentTypeSort>()
                {
                    new ContentTypeSort(cartStepContentType.Id, 0)
                };
                cartContentType.AllowedTemplates = templates.Where(t => t.Alias.ToLowerInvariant().Contains("cartstep1"));
                contentTypeService.Save(cartContentType);

                variantContentType = CreateVariantContentType(allDataTypeDefinitions, contentTypeService);
                productContentType = CreateProductContentType(allDataTypeDefinitions, contentTypeService, templates);

                productListContentType       = new ContentType(-1);
                productListContentType.Alias = "productList";
                productListContentType.Name  = "Product list";
                productListContentType.Icon  = "icon-tags";
                productListContentType.AllowedContentTypes = new List <ContentTypeSort>()
                {
                    new ContentTypeSort(productContentType.Id, 0)
                };
                productListContentType.AllowedTemplates = templates.Where(t => t.Alias.ToLowerInvariant().Contains("productlist"));
                contentTypeService.Save(productListContentType);

                frontpageContentType = CreateFrontpageContentType(allDataTypeDefinitions, contentTypeService, templates);
            } catch (Exception ex) {
                LogHelper.Error <TeaCommerceStarterKitInstall>("Create templates failed", ex);
            }
            #endregion

            #region Create content
            try {
                Content frontPageContent = new Content("Home", -1, frontpageContentType);
                frontPageContent.Template = frontpageContentType.AllowedTemplates.First();
                frontPageContent.SetValue("slider", string.Join(",", productImages.Select(p => "umb://media/" + p.Key.ToString().Replace("-", ""))));
                frontPageContent.SetValue("store", store.Id);
                contentService.SaveAndPublishWithStatus(frontPageContent, raiseEvents: false);

                #region Create Cart
                Content cartContent = new Content("Cart content", frontPageContent.Id, cartContentType);
                cartContent.Template = cartContentType.AllowedTemplates.First();
                contentService.SaveAndPublishWithStatus(cartContent, raiseEvents: false);
                Content informationContent = new Content("Information", cartContent.Id, cartStepContentType);
                informationContent.Template = templates.First(t => t.Alias.ToLowerInvariant() == "cartstep2");
                contentService.SaveAndPublishWithStatus(informationContent, raiseEvents: false);
                Content shippingPaymentContent = new Content("Shipping/Payment", cartContent.Id, cartStepContentType);
                shippingPaymentContent.Template = templates.First(t => t.Alias.ToLowerInvariant() == "cartstep3");
                contentService.SaveAndPublishWithStatus(shippingPaymentContent, raiseEvents: false);
                Content acceptContent = new Content("Accept", cartContent.Id, cartStepContentType);
                acceptContent.Template = templates.First(t => t.Alias.ToLowerInvariant() == "cartstep4");
                contentService.SaveAndPublishWithStatus(acceptContent, raiseEvents: false);
                Content paymentContent = new Content("Payment", cartContent.Id, cartStepContentType);
                contentService.SaveAndPublishWithStatus(paymentContent);
                Content confirmationContent = new Content("Confirmation", cartContent.Id, cartStepContentType);
                confirmationContent.Template = templates.First(t => t.Alias.ToLowerInvariant() == "cartstep6");
                contentService.SaveAndPublishWithStatus(confirmationContent, raiseEvents: false);
                #endregion

                #region Create Attributes
                Content variantAttributesContent = new Content("Variant attributes", frontPageContent.Id, attributesContentType);
                contentService.SaveAndPublishWithStatus(variantAttributesContent, raiseEvents: false);
                Content colorContent = new Content("Color", variantAttributesContent.Id, attributeGroupContentType);
                contentService.SaveAndPublishWithStatus(colorContent, raiseEvents: false);
                Content sizeContent = new Content("Size", variantAttributesContent.Id, attributeGroupContentType);
                contentService.SaveAndPublishWithStatus(sizeContent, raiseEvents: false);
                Content blackContent = new Content("Black", colorContent.Id, attributeContentType);
                contentService.SaveAndPublishWithStatus(blackContent, raiseEvents: false);
                Content whiteContent = new Content("White", colorContent.Id, attributeContentType);
                contentService.SaveAndPublishWithStatus(whiteContent, raiseEvents: false);
                Content blueContent = new Content("Blue", colorContent.Id, attributeContentType);
                contentService.SaveAndPublishWithStatus(blueContent, raiseEvents: false);
                Content largeContent = new Content("Large", sizeContent.Id, attributeContentType);
                contentService.SaveAndPublishWithStatus(largeContent, raiseEvents: false);
                Content mediumContent = new Content("Medium", sizeContent.Id, attributeContentType);
                contentService.SaveAndPublishWithStatus(mediumContent, raiseEvents: false);
                Content smallContent = new Content("Small", sizeContent.Id, attributeContentType);
                contentService.SaveAndPublishWithStatus(smallContent, raiseEvents: false);
                #endregion

                #region Create Products
                Content expensiveYachtsContent = new Content("Expensive Yachts", frontPageContent.Id, productListContentType);
                expensiveYachtsContent.Template = productListContentType.AllowedTemplates.First();
                contentService.SaveAndPublishWithStatus(expensiveYachtsContent, raiseEvents: false);
                Content veryAxpensiveYachtsContent = new Content("Very expensive Yachts", frontPageContent.Id, productListContentType);
                veryAxpensiveYachtsContent.Template = productListContentType.AllowedTemplates.First();
                contentService.SaveAndPublishWithStatus(veryAxpensiveYachtsContent, raiseEvents: false);
                Content summerYachtContent = new Content("Summer Yacht", expensiveYachtsContent, productContentType);
                summerYachtContent.Template = productContentType.AllowedTemplates.First();
                summerYachtContent.SetValue("image", "umb://media/" + productImages[0].Key.ToString().Replace("-", ""));
                summerYachtContent.SetValue("productName", "Summer Yacht");
                summerYachtContent.SetValue("sku", "p0001");
                summerYachtContent.SetValue("priceJMD", "500");
                summerYachtContent.SetValue("description", "<p>This is the product description.</p>");
                summerYachtContent.SetValue("variants", "{\"variants\": [],\"variantGroupsOpen\":{}}");
                contentService.SaveAndPublishWithStatus(summerYachtContent, raiseEvents: false);
                Content yachtWithSailsContent = new Content("Yacht with sails", expensiveYachtsContent, productContentType);
                yachtWithSailsContent.Template = productContentType.AllowedTemplates.First();
                yachtWithSailsContent.SetValue("image", "umb://media/" + productImages[1].Key.ToString().Replace("-", ""));
                yachtWithSailsContent.SetValue("productName", "Yacht with sails");
                yachtWithSailsContent.SetValue("sku", "p0002");
                yachtWithSailsContent.SetValue("priceJMD", "1000");
                yachtWithSailsContent.SetValue("description", "<p>This is the product description.</p>");
                yachtWithSailsContent.SetValue("variants", "{\"variants\": [],\"variantGroupsOpen\":{}}");
                contentService.SaveAndPublishWithStatus(yachtWithSailsContent, raiseEvents: false);
                Content motorDrivenYachtContent = new Content("Motor driven Yacht", veryAxpensiveYachtsContent, productContentType);
                motorDrivenYachtContent.Template = productContentType.AllowedTemplates.First();
                motorDrivenYachtContent.SetValue("image", "umb://media/" + productImages[2].Key.ToString().Replace("-", ""));
                motorDrivenYachtContent.SetValue("productName", "Motor driven Yacht");
                motorDrivenYachtContent.SetValue("sku", "p0003");
                motorDrivenYachtContent.SetValue("priceJMD", "1500");
                motorDrivenYachtContent.SetValue("description", "<p>This is the product description.</p>");
                motorDrivenYachtContent.SetValue("variants", "{\"variants\": [],\"variantGroupsOpen\":{}}");
                contentService.SaveAndPublishWithStatus(motorDrivenYachtContent, raiseEvents: false);
                Content oneMastedYachtContent = new Content("One masted yacht", veryAxpensiveYachtsContent, productContentType);
                oneMastedYachtContent.Template = productContentType.AllowedTemplates.First();
                oneMastedYachtContent.SetValue("image", "umb://media/" + productImages[3].Key.ToString().Replace("-", ""));
                oneMastedYachtContent.SetValue("productName", "One masted yacht");
                oneMastedYachtContent.SetValue("sku", "p0004");
                oneMastedYachtContent.SetValue("priceJMD", "2000");
                oneMastedYachtContent.SetValue("description", "<p>This is the product description.</p>");
                oneMastedYachtContent.SetValue("variants", "{\"variants\": [],\"variantGroupsOpen\":{}}");


                contentService.SaveAndPublishWithStatus(oneMastedYachtContent, raiseEvents: false);


                #endregion
                frontPageContent.SetValue("featuredProducts", string.Join(",", new List <string> {
                    "umb://document/" + summerYachtContent.Key.ToString().Replace("-", ""),
                    "umb://document/" + yachtWithSailsContent.Key.ToString().Replace("-", ""),
                    "umb://document/" + motorDrivenYachtContent.Key.ToString().Replace("-", ""),
                    "umb://document/" + oneMastedYachtContent.Key.ToString().Replace("-", ""),
                }));
                contentService.SaveAndPublishWithStatus(frontPageContent, raiseEvents: false);
            } catch (Exception ex) {
                LogHelper.Error <TeaCommerceStarterKitInstall>("Create content failed", ex);
            }

            #endregion


            return(true);
        }
Пример #9
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(IMedia imKrakTarget, bool?keepOriginal = null, bool hasChanged = false)
        {
            // Validate parameters
            var status = GetKrakStatus(imKrakTarget);

            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  = GetImage(imKrakTarget);
            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)
            {
                var propertyValue = imKrakTarget.GetValue(Constants.UmbracoPropertyAliasOriginalSize);
                if (propertyValue is int)
                {
                    originalSize = (int)propertyValue;
                }
                else
                {
                    int.TryParse(propertyValue as String, out originalSize);
                }
            }
            if (originalSize == 0)
            {
                originalSize = original_size;
            }

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

            // Download the image from kraken.io
            var image = Helper.DownloadFile(kraked_url);

            // The following might seem redundant, but Umbraco's "SetValue" extension method used below actually does a lot of magic for us.
            // Umbraco will create a new media folder us to store the new image. However the Original URL has to remain unchanged.
            // After we have called SetValue, we will read the location of the new image, and then restore the imKrakTarget to the original file.

            var originalUmbracoFilePropertyData = imKrakTarget.GetValue <String>(Constants.UmbracoPropertyAliasFile); // Get the original property data

            imKrakTarget.SetValue(Constants.UmbracoPropertyAliasFile, filename, image);                               // Save the image and let Umbraco do some magic here

            // Extract the absolute directory path
            var newRelativeFilepath  = GetImage(imKrakTarget);                                                    // 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

            // Revert changes so the media node remains unchanged (remember, we don't want the file location to change!). So we will manually swap the underlying file in a moment.
            imKrakTarget.SetValue(Constants.UmbracoPropertyAliasFile, originalUmbracoFilePropertyData);

            // 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!
            IMedia imOriginal = imKrakTarget.Children().FirstOrDefault(x => x.Name == EnmKrakStatus.Original.ToString() && x.HasProperty(Constants.UmbracoPropertyAliasStatus) && x.GetValue <String>(Constants.UmbracoPropertyAliasStatus) == "Original");

            // Does the original media node already exist?
            bool originalExists = imOriginal != 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"
                    imOriginal = ms.CreateMedia(EnmKrakStatus.Original.ToString(), imKrakTarget.Id, imKrakTarget.ContentType.Alias, imKrakTarget.CreatorId);
                }

                // 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 p in imOriginal.Properties)
                    {
                        p.Value = imKrakTarget.GetValue(p.Alias);
                    }

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

                    // The same for filesize
                    if (imOriginal.HasProperty(Constants.UmbracoPropertyAliasSize))
                    {
                        imOriginal.SetValue(Constants.UmbracoPropertyAliasSize, originalSize);
                    }

                    // Set the "status" of the original image to "Original", so we know in the future this is the original image
                    if (imOriginal.HasProperty(Constants.UmbracoPropertyAliasStatus))
                    {
                        imOriginal.SetValue(Constants.UmbracoPropertyAliasStatus, EnmKrakStatus.Original.ToString());
                    }

                    // Save the original node. It will be placed directly underneath the current media node
                    ms.Save(imOriginal, UmbracoUserId, false);

                    // 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          = GetImage(imOriginal);
                    var originalRelativeDirectory = System.IO.Path.GetDirectoryName(originalFilePath);
                    var originalAbsoluteDirectory = System.Web.Hosting.HostingEnvironment.MapPath("~" + originalRelativeDirectory);
                    ms.Delete(imOriginal);
                    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
            if (imKrakTarget.HasProperty(Constants.UmbracoPropertyAliasOriginalSize))
            {
                imKrakTarget.SetValue(Constants.UmbracoPropertyAliasOriginalSize, originalSize);
            }

            // Show the kraked status
            if (imKrakTarget.HasProperty(Constants.UmbracoPropertyAliasStatus))
            {
                imKrakTarget.SetValue(Constants.UmbracoPropertyAliasStatus, EnmKrakStatus.Compressed.ToString());
            }

            // Show the kraked date
            if (imKrakTarget.HasProperty(Constants.UmbracoPropertyAliasCompressionDate))
            {
                imKrakTarget.SetValue(Constants.UmbracoPropertyAliasCompressionDate, DateTime.Now.ToString());
            }

            // Show how many bytes we by kraking the image
            if (imKrakTarget.HasProperty(Constants.UmbracoPropertyAliasSaved))
            {
                imKrakTarget.SetValue(Constants.UmbracoPropertyAliasSaved, compressionRate);
            }

            // Save the newly (kraked) media item
            ms.Save(imKrakTarget, UmbracoUserId, false);

            // 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);
        }