
Hello there!
Hope you are safe and doing well.
In this article, we are going to see how we can upload/share a file (ContentDocument) across multiple records/users/groups using Apex.
Here is the scenario: Whenever someone uploads a file on the event object the same file should automatically upload or rather be shared with its parent records (Account/Opportunity, etc…)
First let’s see how actually Salesforce stores the files:
Content Document: This object represents the actual documents that have been uploaded to the library in Salesforce content/files. It gets automatically created when we create a ContentVersion (Child of ContentDocument) record.
Content Version: It represents a version of a specific file or Salesforce CRM content. The maximum number of versions we can publish in 24 hrs is 200,000.

Content Document Link: This object represents a link between Salesforce files and where it is shared. A Salesforce file can be shared across users, groups, records, and content libraries.
We can create multiple records of ContentDocumentLink to share a file across multiple records (Opportunities, Accounts, Users, etc…)
As we discussed in the scenario above I am going to demonstrate how event files can be shared automatically with the Account(Parent) object.
When we insert the file order of trigger execution of content documents objects will be like this:
First ContentVersion object trigger will fire, the next ContentDocument object trigger will fire and the last ContentDocumentLink object trigger will fire.
LinkedEntityId (parent record I’d) establishes links between file and Record ( Account, Opportunity, Users, Group, etc…)
ContentDocumentLink_Trigger
trigger ContentDocumentLink_Trigger on ContentDocumentLink (after insert) { | |
if(Trigger.isAfter && Trigger.isInsert){ | |
Set<ID> contentDocIds = new Set<ID>(); | |
for(ContentDocumentLink cdl: Trigger.new){ | |
contentDocIds.add(cdl.ContentDocumentId); | |
} | |
Set<Id> eventIds = new Set<Id>(); | |
Map<String,String> eventMap = new Map<String,String>(); | |
for(ContentDocumentLink cdlObj: Trigger.new) | |
{ | |
if(String.valueOf(cdlObj.LinkedEntityId).startsWith('00U')){ //Check if file is uploaded on event object | |
eventIds.add(cdlObj.LinkedEntityId); | |
} | |
} | |
for(Event e:[select id,whatId from Event where Id IN:eventIds]){ | |
eventMap.put(e.Id, e.whatId); | |
} | |
Map<String,String> parentRecMap = new Map<String,String>(); | |
for(ContentDocumentLink cdl: Trigger.new){ | |
if(String.valueOf(cdl.LinkedEntityId).startsWith('00U')){ //Check if file is uploaded on event object | |
if(String.valueOf(eventMap.get(cdl.LinkedEntityId)).startsWith('001')) //Check if event parent is Account | |
parentRecMap.put(cdl.ContentDocumentId, eventMap.get(cdl.LinkedEntityId)); //Map<ContentDocumentId,AccountId> | |
} | |
} | |
List<ContentDocumentLink> cdl_List = new List<ContentDocumentLink>(); | |
if(ContentDocumentLink_TriggerHelper.Flag == true){ | |
ContentDocumentLink_TriggerHelper.Flag = false; | |
for(String str: parentRecMap.keySet()){ | |
ContentDocumentLink cdl = new ContentDocumentLink(); // Content Document Link to share the file with Account(Parent) record | |
cdl.LinkedEntityId = parentRecMap.get(str); // Account ID | |
cdl.ContentDocumentId = str; //Content Dcoument ID | |
cdl.ShareType = 'V'; | |
cdl.Visibility = 'InternalUsers'; | |
cdl_List.add(cdl); | |
} | |
} | |
system.debug('Size : '+ cdl_List); | |
if(cdl_List.size()>0) | |
ContentDocumentLink_TriggerHelper.shareFile(cdl_List);// Insert Content Document Link to share the file with Account | |
} | |
} |
ContentDocumentLink_TriggerHelper
public class ContentDocumentLink_TriggerHelper { | |
public static Boolean flag = true; | |
public static void shareFile(List<ContentDocumentLink> cdlLink){ | |
try{ | |
insert cdlLink; | |
} | |
catch(Exception e){ | |
system.debug('Exception has occured ! ' +e.getMessage()); | |
} | |
} | |
} |
Output: Upload any file on the Event object associated with any Account. After upload, you can see the same file attached in the Account’s files related list.
References:
https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sforce_api_objects_contentversion.htm
Good Explanation
LikeLike