4
votes

I want to be able to create/update media items in code and also use language versioning. Here are more specifics. I have a Product content item. When that item is saved I want to be able to generate a PDF version of that item and save it to the media library. If the PDF version already exists in the media library I need to be able to update it. In addition this is a multi-language site. So if someone saves the French version of the Product content item I need to be able to generate the French version of the PDF and only save/update the French version of the associated PDF in the media library - not touch any of the other language versions of the PDF. I can't seem to figure out how to do this. The code that I have currently does the following: if I save the English version of the Product then it creates and English version of the PDF. But then if I save the French version of the Product, it creates a French version of the PDF and removes the English version of the PDF.

Anyone know how to do this?

    public static Item AddMediaItem(byte[] fileBuffer, string fullMediaPath, string fileNameWithExtension, string title, Language language)
    {
        try
        {
            var db = Sitecore.Configuration.Factory.GetDatabase("master");
            var options = new MediaCreatorOptions();
            options.FileBased = false;
            options.IncludeExtensionInItemName = false;
            options.KeepExisting = false;
            options.Versioned = true;
            options.Destination = fullMediaPath;
            options.Database = db;
            options.Language = language;

            var creator = new MediaCreator();
            var fileStream = new MemoryStream(fileBuffer);

            var pdfItem = db.GetItem(fullMediaPath, language);
            if (pdfItem != null)
            {
                var updatedItem = creator.AttachStreamToMediaItem(fileStream, fullMediaPath, fileNameWithExtension,
                    options);
                updatedItem.Editing.BeginEdit();
                updatedItem.Fields["Title"].Value = title;
                updatedItem.Editing.EndEdit();
                return updatedItem;
            }
            else
            {
                //Create a new item
                var newItem = creator.CreateFromStream(fileStream, fileNameWithExtension, options);
                newItem.Editing.BeginEdit();
                newItem.Fields["Title"].Value = title;
                newItem.Editing.EndEdit();
                return newItem;
            }
        }
        catch (Exception ex)
        {
            return null;
        }
    }
2
There are Unversioned and Versioned Media templates, be sure you use the Versioned one. Else the media is a Shared Field.Jan Bluemink
Well, in my code I don't specify the template at all. I am using the MediaCreator and if you see in the options I am specifying options.Versioned = true. So I assume that is correct. And I do notice that the item that gets created does use the Versioned Media template for PDFs. So I think that part is correct.Corey Burnett
Thanks so much @JanBluemink for pointing me to that post. I was able to modify my code and now it is working the way I need it to!Corey Burnett
One of my ongoing frustrations with Sitecore is that it is always difficult to find the "proper" way of doing something in code. The documentation of their API leaves a lot to be desired. Usually you have to hunt through blog posts or Stack Overflow to find what you need.Corey Burnett

2 Answers

2
votes

Thanks to @JanBluemink for pointing me in the right direction. I found the right approach in the following article: Sitecore.Resources.Media.MediaCreator deletes versions of media. I just had to modify the code to use MediaManager instead of MediaCreator when updating.

    public static Item AddMediaItem(byte[] fileBuffer, string fullMediaPath, string fileNameWithExtension, string title, Language language)
    {
        try
        {
            var db = Sitecore.Configuration.Factory.GetDatabase("master");
            var options = new MediaCreatorOptions();
            options.FileBased = false;
            options.IncludeExtensionInItemName = false;
            options.KeepExisting = false;
            options.Versioned = true;
            options.Destination = fullMediaPath;
            options.Database = db;
            options.Language = language;

            var creator = new MediaCreator();
            var fileStream = new MemoryStream(fileBuffer);

            var pdfItem = db.GetItem(fullMediaPath, language);
            if (pdfItem != null)
            {
                var mediaItem = new MediaItem(pdfItem);
                var media = MediaManager.GetMedia(mediaItem);
                media.SetStream(fileStream, "pdf");

                pdfItem.Editing.BeginEdit();
                pdfItem.Fields["Title"].Value = title;
                pdfItem.Editing.EndEdit();
                return pdfItem;
            }
            else
            {
                //Create a new item
                var newItem = creator.CreateFromStream(fileStream, fileNameWithExtension, options);
                newItem.Editing.BeginEdit();
                newItem.Fields["Title"].Value = title;
                newItem.Editing.EndEdit();
                return newItem;
            }
        }
        catch (Exception ex)
        {
            return null;
        }
    }
0
votes

I had to add couple of more lines for updating media item stored in File System with versioning.

if (mediaItem.FileBased)
        {
            string uniqueFilename = FileUtil.GetUniqueFilename(FileUtil.MakePath(Settings.Media.FileFolder, MediaManager.Creator.GetMediaStorageFolder(mediaItem.ID, fileshortname)));
            using (new Sitecore.SecurityModel.SecurityDisabler())
            {
                mediaItem.BeginEdit();
                mediaItem.FilePath = uniqueFilename;
                mediaItem.EndEdit();
            }
        }
        Media media = MediaManager.GetMedia(mediaItem);
        using (FileStream stream = new FileStream(fileName, FileMode.Open))
        {
            media.SetStream(stream, FileUtil.GetExtension(fileshortname));
        }`