Our company relies on having files (formerly attachments) visible to customer community users, and we need a way to have "Customer Access" checked off by default, rather than requiring a manual change by our user.
How can Files be set to be automatically visible to Customer Community users?
In the salesforce Idea page files not visible to community users when sharing set to "set by record" (https://success.salesforce.com/ideaView?id=0873A000000E7mrQAC), Neil Hayek (https://success.salesforce.com/profile?u=00530000003SpRmAAK) demos a solution using Apex. His model is effective and can be viewed at the link above.
If Neil's comment is moved/not accessible, I have posted my modified version of Neil's solution below. Please note that I am following a Trigger-Handler-Utility model, rather than hosting everything on the Trigger.Apex Trigger:
trigger ContentDocumentLinkTrigger on ContentDocumentLink (after delete, after insert, after undelete, after update, before delete, before insert, before update) {
ContentDocumentLinkHandler.ProcessContentDocumentLinks();
}
Apex Handler Class:
global with sharing class ContentDocumentLinkHandler {
// Debug walkthrough indicator
static String showDebugs = 'walkthrough';
// Change value to 'walkthrough' to view high-level debugs steps in Log,
// 'fine' to include all debugs, and 'None' to exclude debugs
global static void ProcessContentDocumentLinks() {
// All trigger requests enter here. Provide routing to the correct
// method for processing.
IF (!Trigger.isExecuting) {
system.debug('ContentDocumentLinkHandler > ProcessContentDocumentLinks > '
+ ' Error: The ProcessContentDocumentLink() Trigger Handler method was'
+ ' just called with no active ContentDocumentLink Trigger in process. '
+ ' The ProcessContentDocumentLink() method may ONLY be called during a'
+ ' Trigger Context. Other methods can be called '
+ ' at any time, but not this Trigger Traffic Cop method.');
}
else {
if(showDebugs != 'none') system.debug('ContentDocumentLinkHandler > ProcessContentDocumentLinks > Trigger Size is: ' + Trigger.size);
if(showDebugs == 'fine') system.debug('ContentDocumentLinkHandler > ProcessContentDocumentLinks > Trigger.new: '+Trigger.new);
if(Trigger.isBefore){
if(Trigger.isInsert){
BeforeInsert(Trigger.new, Trigger.newMap);
}
}
// Unused conditional criteria commented-out, but left
// here for ease of use in case of future development
/*
if(Trigger.isAfter){
if(Trigger.isInsert){
AfterInsert(Trigger.old, Trigger.new, Trigger.oldMap, Trigger.newMap);
}
if(Trigger.isUpdate){
AfterUpdate(Trigger.old, Trigger.new, Trigger.oldMap, Trigger.newMap);
}
if(Trigger.isDelete){
AfterDelete(Trigger.old, Trigger.new, Trigger.oldMap, Trigger.newMap);
}
if(Trigger.isUndelete){
AfterUndelete(Trigger.old, Trigger.new, Trigger.oldMap, Trigger.newMap);
}
}
*/
}
}
return;
}
public static void BeforeInsert(List<sObject> newContentDocumentLinks, Map<Id, sObject> newContentDocumentLinkMap){
ContentDocumentLinkUtil.BeforeInsertActions(newContentDocumentLinks);
}
}
Apex Utility Class
public without sharing class ContentDocumentLinkUtil {
// Debug walkthrough indicator
static String showDebugs = 'Fine';
// Change value to 'walkthrough' to view high-level debugs steps in Log,
// 'fine' to include all debugs, and 'None' to exclude debugs
public static void BeforeInsertActions(List<SObject> newContentDocumentLinks){
if(showDebugs != 'None') system.debug('ContentDocumentLinkUtil > ' +
'beginning convertShareTypeToViewer');
// Convert all ContentDocumentLink Visibility to 'AllUsers' to allow
// Customer Community User access by default.
for(Integer i = 0, j = newContentDocumentLinks.size(); i < j; i++){
newContentDocumentLinks[i].put('Visibility','AllUsers');
}
}
}
Note that in the Apex Utility Class, you could apply conditional logic to only have the Customer Community access be on certain objects. As an example:
for(Integer i = 0, j = newContentDocumentLinks.size(); i < j; i++){
if(newContentDocumentLinks[i].LinkedEntityId.getSObjectType().getDescribe().getName() == 'Case'){
newContentDocumentLinks[i].put('Visibility','AllUsers');
}
}
Note: The code provided was slightly modified from its original state, so some compile errors may occur if copying-and-pasting.