Wednesday 16 May 2012

Working with Content in Apex

So, it's been a long while since I last posted here an this one is going to be a short one for the techies amongst us. I recently had some work to do around Content and using a trigger to take the latest version of a template and create a copy linked to a custom object and also share it in a different workspace as a specific piece of documentation. Now, if you haev been around Salesforce long enough, you'll know that when Content first came out it was completely untouchable with Apex and today, I am happy to say, this has now changed. Onto the solution... I first created a custom setting which would hold the Ids of the Workspace(s) I would be using (to get around the hard coding issue and depolyment from sandbox to production) and wrote some very simple code to retreive this:
 public static CPM_Documentation_Settings__c getWorkspaceIds() {
     // Retrieve the custom setting and get the Id of the workspace
     CPM_Documentation_Settings__c documentSettings = [SELECT Document_Template_Workspace_Id__c, Document_Workspace_Id__c FROM CPM_Documentation_Settings__c][0];
     return documentSettings;
     
    }
Whilst not very robust or defensive it met the immediate need to get the Ids back that I needed. The next job was the meat of the issue, how to pick up the latest version of any templates and create new versions in the documentation workspace and link them to the custom object. The First thing I needed to do was get all the latest versions of the templates:
    // Get the Workspace
        CPM_Documentation_Settings__c settings = ProjectTriggerUtilities.getWorkspaceIds();
        
     ContentWorkspace templatesWorkspace = [SELECT Id FROM ContentWorkspace WHERE Id = :settings.Document_Template_Workspace_Id__c];
     ContentWorkspace projectWorkspace = [SELECT Id FROM ContentWorkspace WHERE Id = :settings.Document_Workspace_Id__c];
        
        // Get the list of document templates and their current published version Ids
        List templates = [SELECT ContentDocumentId FROM ContentWorkspaceDoc WHERE ContentWorkspaceId = :templatesWorkspace.Id];
        List templateIds = new List();
        for (ContentWorkspaceDoc doc : templates) {
         templateIds.add(doc.ContentDocumentId);
        }
        List contentDocuments = [SELECT LatestPublishedVersionId FROM ContentDocument WHERE Id in :templateIds];
        
        List latestVersionTemplateIds = new List();
        for (ContentDocument cs : contentDocuments) {
         latestVersionTemplateIds.add(cs.LatestPublishedVersionId);
        }
Now that I had a collection of all the latest versions of templates I simply needed to create the new versions linked to the custom object:
//loop through all the templates and pull back the latest published version of each of them
        List latestVersionOfTemplate = [SELECT c.VersionData, c.Title, c.Supplier_Brand__c, c.Relevant_Sector__c, c.Reference__c, c.PublishStatus, c.Printed_Version_Available__c, 
                                                               c.Printed_Format__c, c.PositiveRatingCount, c.PathOnClient, c.Origin, c.NegativeRatingCount, c.Industry_Sector__c, c.Id, c.FirstPublishLocationId, 
                                                               c.FileType, c.FeaturedContentDate, c.FeaturedContentBoost, c.Description, c.Customer_Facing__c, c.ContentDocumentId, c.Classification__c, 
                                                               c.Brand_Relevance__c 
                    FROM ContentVersion c
                    WHERE ID in :latestVersionTemplateIds];
        for (Project__c p : projects) {                    
         //create the new documents from the templates
         List newProjectDocuments = latestVersionOfTemplate.deepClone();
         for (ContentVersion cv : newProjectDocuments) {
          cv.FirstPublishLocationId = settings.Document_Workspace_Id__c;
          cv.project__c = p.Id;
          cv.ContentDocumentId = null;
          cv.Title = p.Project_Name__c + '_' + cv.Title;
          cv.Description = '';
         }
         insert newProjectDocuments;
        }
And there you have it, we now have the ability to create new content based on existing templates that exist in SFDC content. There is still some fun to be had unit testing and there are still some gotchas in there they are easy to workthough. If you have any questions please let me know by commenting and I'll do my best to steer you in the right direction.

1 comment:

  1. Hey Chris,

    I found your Blog on Salesforce and wanted to reach out to you to see if you know of anyone in the California/Los Angeles area who is a certified salesforce.com developer? I am working on a full time direct hire opportunity with the worlds leading media and entertainment company and see that you are a thought leader in the industry.

    If you have a few minutes, Id like to speak with you via phone/skype and see if you might know of anyone who might be interested in this exciting opportunity? Also, I would like to ask you some questions about salesforce!

    Let me know if you might be available, and I hope to hear from you soon.

    Happy Holidays!

    Randy

    Randy J. Stark, MBA

    Recruiter
    Talent & Acquisition, LLC
    T: 646-801-3551
    C: 570-814-9156
    E: rstark@talentandacquisition.com

    ReplyDelete