File Upload Validation


Certainly, let’s consider the two use cases:

  1. Uploading a new file.
  2. Relinking an existing file.

Now, let’s delve into a specific scenario. Suppose we want to restrict users from uploading a file in a Contact record if the ‘Level__c’ is set to ‘Primary’.

To comprehend the file handling in Salesforce:

In Salesforce, the ContentDocumentLink is an object that signifies the link between a ContentDocument and a Salesforce record. It essentially associates a Salesforce record with a document in Salesforce CRM Content or a file in Salesforce Files. This linkage enables users with access to the record to also access the associated document, determining the document’s sharing settings.

The ContentDocument represents a document uploaded to a library in Salesforce CRM Content or to a file in Salesforce Files, containing details such as title, type, and other properties.

The ContentDocumentLink object is utilized to share documents with users, groups, records, and Salesforce CRM Content libraries, and it determines the document’s visibility within the organization.

By linking the ContentDocument to records through ContentDocumentLink, users can conveniently access and share documents related to specific records within Salesforce.

When a user uploads a new version of a document, a new record is generated in the ContentVersion object, maintaining the version history of the document. Each version is associated with a ContentDocument record representing the document.

ContentVersion is closely linked to ContentDocument, with each ContentVersion record linked to a single ContentDocument. The ContentDocument acts as the parent record for one or more ContentVersion records, representing different versions of the same document.

Users can view version details, download specific versions, and track the document’s version history. ContentVersion streamlines document version management, facilitating collaboration and sharing within the Salesforce platform.

To implement the restriction mentioned, a trigger needs to be written on ContentDocumentLink, comparing the field of the parent record using the LinkedEntityId field.

Here is a sample code for reference:

trigger ContentDocumentLinkTrigger on ContentDocumentLink (before insert) {
    set<Id> parentIds = new set<Id>();
    map<Id, Contact> contactMap;
     
    //get the parent ids
    for (ContentDocumentLink content : Trigger.new) {
        if(content.LinkedEntityId!=null){
            parentIds.add(content.LinkedEntityId);
        }
    }
     
    //now build the parent record map and check the Level value
    if(!parentIds.isEmpty()){
        getContactDetails(parentIds);
        for (ContentDocumentLink content : Trigger.new) {
            if(contactMap.get(content.LinkedEntityId).Level__c == 'Primary'){
                content.addError('You can not upload file.');
            }
        }
    }
     
    //Method return map of parent record
    public static void getContactDetails (set<Id> conSet){
        contactMap = new map<Id, Contact>( [select Id,Level__c 
                                            from Contact 
                                            where Id IN: conSet]);
    }    
}