More in this section

Forums / Developing with Sitefinity / What is the proper method to programmatically create a copy of a sitefinity Image?

What is the proper method to programmatically create a copy of a sitefinity Image?

4 posts, 0 answered
  1. Rory
    Rory avatar
    44 posts
    Registered:
    22 Mar 2012
    07 May 2012
    Link to this post
    I am using sitefinity 5 and trying to programmatically copy an existing image to the default library but no matter what i try, the thumbnails don't seem to work properly after. my copy code is below.  'existingimage' is the master of the imge to be copied.

    public Telerik.Sitefinity.Libraries.Model.Image CopySitefinityImageToDefaultLibrary(string ImageTitle, Telerik.Sitefinity.Libraries.Model.Image existingimage)
            {
                Telerik.Sitefinity.Libraries.Model.Image newimage = null;
                if (existingimage != null && !String.IsNullOrEmpty(ImageTitle))
                {
                    LibrariesManager lman = LibrariesManager.GetManager();
                    Album defaultAlbum = FindAlbums("Default Library").FirstOrDefault();
     
                    if (defaultAlbum != null)
                    {
                        newimage = lman.CreateImage();
                        lman.Copy(existingimage, newimage);
                        lman.CopyThumbnails(existingimage, newimage );
                         
                        newimage.Title = ImageTitle;
                        newimage.Urls.Clear();
                        newimage.UrlName = Regex.Replace(ImageTitle.ToLower(), @"[^\w\-\!\$\'\(\)\=\@\d_]+", "-");
     
                        newimage.DateCreated = DateTime.UtcNow;
                        newimage.LastModified = DateTime.UtcNow;
                        newimage.InheritsPermissions = true;
                        newimage.Parent = defaultAlbum;
                         
                        try
                        {
                            lman.RecompileItemUrls<Telerik.Sitefinity.Libraries.Model.Image>(newimage);  
                            lman.SaveChanges();
     
                            var bag = new Dictionary<string, string>();
                            bag.Add("ContentType", typeof(Telerik.Sitefinity.Libraries.Model.Image).FullName);
                            WorkflowManager.MessageWorkflow(newimage.Id, typeof(Telerik.Sitefinity.Libraries.Model.Image), null, "Publish", false, bag);
                        }
                        catch { }
                    }
                }
                return newimage;
            }

    after this is run, the new image acts very strange.  SOMETIMES the image and thumbnail will show up but most of time i just get file not found and errors loading resources.  if i keep viewing the image and publishing it over and over again(manually) the image will show up every 4-5 publishes but disappears after again.

    so can anyone tell me what im missing or what the proper way to copy an image would be?

    please n thanks.
  2. Rory
    Rory avatar
    44 posts
    Registered:
    22 Mar 2012
    15 May 2012
    Link to this post
    UPDATE:
    The copy wouldn't work properly so i figured i would just go with moving an image from one library to another.  Sitefinity has a function called librarymanager.MoveItemToLibrary.  i tried that but still i get problems with the images afterwards.  so i started digging into the DB.

    turns out sitefinity is creating junk records in the sf_url_data table that dont have a content id and so dont point to an image.  so when i publish an image, it seems to look for a matching url in the sf_url_data table and the first one it finds is the one that it tries to display. which most of the time will be the one with a blank content id.

    here is my move image code:
    Image temp = lman.Lifecycle.CheckOut(imageMaster) as Image;
     
    temp.Album = album;
    temp.Parent = album;
    temp.Title = newLogoTitle;
    temp.FilePath = album.UrlName + "/" + newLogoTitle + imageMaster.Extension;
    temp.Urls.Clear();
    temp.UrlName = Regex.Replace(newLogoTitle.ToLower(), @"[^\w\-\!\$\'\(\)\=\@\d_]+", "-");
     
    lman.RecompileItemUrls<Telerik.Sitefinity.Libraries.Model.Image>(temp);
    imageMaster = lman.Lifecycle.CheckIn(temp) as Telerik.Sitefinity.Libraries.Model.Image;
    lman.SaveChanges();
     
    var bag = new Dictionary<string, string>();
    bag.Add("ContentType", typeof(Telerik.Sitefinity.Libraries.Model.Image).FullName);
    WorkflowManager.MessageWorkflow(imageMaster.Id, typeof(Telerik.Sitefinity.Libraries.Model.Image), null, "Publish", false, bag);

    so essentially to fix the problem i have to go in after my operations above and remove any newly created junk records.  anything with a blank contentid and matching url to the image i just moved.

    its very likely that this is happening because this is not the proper way to go about moving or copying an image but since the documentation is extremely limited there is no way to know, just keep guessing and trying until it seems to work.

    Also, the MoveItemToLibrary function doesn't actually 'move' the image.  it seems to just create new urls pointing to it in its old location.  file paths and urls still have to be changed manually.  kind of annoying. more junk records.

    so as always, if there is an official way to accomplish these simple tasks, i would love to hear about it.
  3. Boyan Barnev
    Boyan Barnev avatar
    1429 posts
    Registered:
    28 Aug 2017
    18 May 2012
    Link to this post
    Hello,

    Thank you for contacting Telerik Support.

    Actually we would recommend using MoveItemToLibrary, as this is the safest method that at the same time would ensure no duplicate records, since what it actually does is an internal call to ContentManagerBase.ChangeItemParent() and would not copy twice the actual media content, but just arrange additional URLs and Sitefinity Image representation in the desired library.
    For the user it would appear as if there are two separate images in both libraries, while actually there's two MediaContent Images (i.e. Sitefinity images) pointing to the same binary content in the database.

    You can even copy the image and set new properties to it,, for example you can easily change the title like this:
    protected void Page_Load(object sender, EventArgs e)
            {
                var manager = LibrariesManager.GetManager();
                 
                var originalAlbum = manager.GetAlbums().Where(al => al.Title == "Default Library").SingleOrDefault();
                var img = manager.GetImages().Where(im => im.Title == "Desert" && im.Status == ContentLifecycleStatus.Live && im.Parent.Id == originalAlbum.Id).SingleOrDefault();
                 
                if (img != null)
                {
                    var albumToCopy = manager.GetAlbums().Where(al => al.Title == "NewLIbrary").SingleOrDefault();
                    if (albumToCopy != null)
                    {
                        MoveImageToLibraryAndRename(manager.GetMaster(img), albumToCopy, "test");
                    }
                }
                manager.SaveChanges();
            }
     
            public bool MoveImageToLibraryAndRename(Telerik.Sitefinity.Libraries.Model.Image imageMaster, Album targetAlbum, string newLogoTitle)
            {
                bool success = true;
                var lman = LibrariesManager.GetManager();
                try
                {
                    lman.MoveItemToLibrary(imageMaster, targetAlbum);
                    lman.SaveChanges();
     
                    imageMaster.Title = newLogoTitle;
                    imageMaster.UrlName = Regex.Replace(newLogoTitle.ToLower(), @"[^\w\-\!\$\'\(\)\=\@\d_]+", "-");
                    lman.Lifecycle.Publish(imageMaster);
                    lman.SaveChanges();
                }
                catch { success = false; }
     
                return success;
            }

    Please do not hesitate to get back to me if you need some additional information, I'll be glad to help.

    Greetings,
    Boyan Barnev
    the Telerik team
    Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  4. Rory
    Rory avatar
    44 posts
    Registered:
    22 Mar 2012
    18 May 2012
    Link to this post
    Hello Boyan, thanks for your reply.  between this and my support ticket i think we have this figured out.

    my final move code looks like this:
    LibrariesManager lman = LibrariesManager.GetManager();
    lman.MoveItemToLibrary(imageMaster, album);
    lman.SaveChanges();
    if (!String.IsNullOrEmpty(newLogoTitle))
    {
        lman.ClearItemUrls<Telerik.Sitefinity.Libraries.Model.Image>(imageMaster);
        lman.SaveChanges(); 
        imageMaster.Title = newLogoTitle;
        imageMaster.UrlName = Regex.Replace(newLogoTitle.ToLower(), @"[^\w\-\!\$\'\(\)\=\@\d_]+", "-");
        imageMaster.FilePath = imageMaster.UrlName + "/" + newLogoTitle + imageMaster.Extension; 
        lman.RecompileItemUrls<Telerik.Sitefinity.Libraries.Model.Image>(imageMaster);
        lman.Lifecycle.Publish(imageMaster);
        lman.SaveChanges();
    }
    i added a couple lines to make sure the old urls get removed and the file path is updated.

    this seems to do everything i wanted it to do so thanks to the sitefinity guys for helping to get this straight.
4 posts, 0 answered