-
Notifications
You must be signed in to change notification settings - Fork 57
Expand file tree
/
Copy pathqsyd_ContentDocumentTriggerHandler.cls
More file actions
189 lines (160 loc) · 7.3 KB
/
Copy pathqsyd_ContentDocumentTriggerHandler.cls
File metadata and controls
189 lines (160 loc) · 7.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
/*
* Copyright (c) 2020, salesforce.com, inc.
* All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
/**
Author: Paul Lucas
Company: Salesforce
Description: qsyd_ContentDocumentTriggerHandler
Date: 05-May-2020
TODO:
*/
public without sharing class qsyd_ContentDocumentTriggerHandler extends TriggerHandler {
public final String SHARE_TYPE_VIEWER = 'V';
public final String SHARE_TYPE_COLLABORATOR = 'C';
public final String SHARE_TYPE_INFERRED = 'I';
public final String VISIBILITY_ALLUSERS = 'AllUsers';
public final String VISIBILITY_INTERNALUSERS = 'InternalUsers';
public final String VISIBILITY_SHAREDUSERS = 'SharedUsers';
private List<ContentDocument> contentDocumentOldList;
private Map<Id, ContentDocument> contentDocumentOldMap;
private List<ContentDocument> contentDocumentNewList;
private Map<Id, ContentDocument> contentDocumentNewMap;
//private static qsyd_FileExplorerCommon common = new qsyd_FileExplorerCommon();
private SObjectAccessDecision accessDecision;
/**
* @description Constructor
*/
public qsyd_ContentDocumentTriggerHandler() {
this.contentDocumentOldList = (List<ContentDocument>) Trigger.old;
this.contentDocumentOldMap = (Map<Id, ContentDocument>) Trigger.oldMap;
this.contentDocumentNewList = (List<ContentDocument>) Trigger.new;
this.contentDocumentNewMap = (Map<Id, ContentDocument>) Trigger.newMap;
}
/**
* @description After update, associate content document to file explorer
*/
public override void afterUpdate() {
// If Lightning File Explorer has not been enabled or the user has not been assigned the file explorer permissionset, return
if (!qsyd_FileExplorerCommon.isFileExplorerEnabled() || !qsyd_FileExplorerCommon.checkForPermission()) {
return;
}
Id linkedEntityId;
ContentDocument cd = this.contentDocumentNewList.get(0);
FileExplorerFile__c file = new FileExplorerFile__c();
List<ContentDocumentLink> cdlList = [
SELECT LinkedEntityId
FROM ContentDocumentLink
WHERE ContentDocumentId IN :this.contentDocumentNewMap.keySet()
WITH SECURITY_ENFORCED
];
this.accessDecision = Security.stripInaccessible(AccessType.READABLE, cdlList);
cdlList = (List<ContentDocumentLink>) this.accessDecision.getRecords();
if (!cdlList.isEmpty()) {
switch on cdlList.size() {
// Files uploaded to the user record
when 1 {
linkedEntityId = cdlList.get(0).LinkedEntityId;
}
// Files uploaded to a record
when else {
for (ContentDocumentLink cdl : cdlList) {
if (cdl.LinkedEntityId.getSobjectType() != Schema.User.SObjectType) {
linkedEntityId = cdl.LinkedEntityId;
}
}
}
}
}
// Transpose the EmailMessage id to its related object id and share with the related record
if (linkedEntityId.getSobjectType() == Schema.EmailMessage.SObjectType) {
list<EmailMessage> emailMessage = [
SELECT RelatedToId
FROM EmailMessage
WHERE Id = :linkedEntityId
];
this.accessDecision = Security.stripInaccessible(AccessType.READABLE, emailMessage);
emailMessage = (List<EmailMessage>) this.accessDecision.getRecords();
linkedEntityId = emailMessage[0]?.RelatedToId;
// Add a ContentDocumentLink entry for the EmailMessage related object, removing the degree of separation
shareFile(cd.Id, linkedEntityId, SHARE_TYPE_INFERRED, VISIBILITY_ALLUSERS);
}
// Check if a file explorer file exists
List<FileExplorerFile__c> fileList = [
SELECT ContentDocumentId__c,
LinkedEntityId__c,
Label__c,
FileType__c,
FileExtension__c,
FileOwner__c,
ContentSize__c
FROM FileExplorerFile__c
WHERE ContentDocumentId__c = :cd.Id
WITH SECURITY_ENFORCED
];
this.accessDecision = Security.stripInaccessible(AccessType.READABLE, fileList);
if (!fileList.isEmpty()) {
file = (FileExplorerFile__c) this.accessDecision.getRecords().get(0);
}
// TODO: Check for changes before updating
file.ContentDocumentId__c = cd.Id;
file.LinkedEntityId__c = linkedEntityId;
file.Label__c = cd.Title;
file.FileType__c = cd.FileType;
file.FileExtension__c = cd.FileExtension;
file.FileOwner__c = cd.OwnerId;
file.ContentSize__c = cd.ContentSize;
this.accessDecision = Security.stripInaccessible(AccessType.UPSERTABLE,
new List<FileExplorerFile__c>{
file
});
try {
UPSERT this.accessDecision.getRecords();
} catch (Exception e) {
System.debug(LoggingLevel.ERROR, e.getMessage());
System.debug(LoggingLevel.ERROR, e.getStackTraceString());
}
}
/**
* @description After delete, remove any associated file explorer files
*/
public override void afterDelete() {
Set<Id> contentDocumentIds = (new Map<Id, SObject>(this.contentDocumentOldList)).keySet();
// If Lightning File Explorer has not been enabled or the user has not been assigned the file explorer permissionset, return
if (!qsyd_FileExplorerCommon.isFileExplorerEnabled() || !qsyd_FileExplorerCommon.checkForPermission()) {
return;
}
List<FileExplorerFile__c> files = [
SELECT Id
FROM FileExplorerFile__c
WHERE ContentDocumentId__c IN :contentDocumentIds
WITH SECURITY_ENFORCED
];
this.accessDecision = Security.stripInaccessible(AccessType.READABLE, files);
try {
if (Schema.SObjectType.FileExplorerFile__c.isDeletable()) {
DELETE files;
}
} catch (Exception e) {
System.debug(LoggingLevel.ERROR, e.getMessage());
System.debug(LoggingLevel.ERROR, e.getStackTraceString());
}
}
/**
* @description Share a file with another entity
*/
private void shareFile(String contentDocumentId, String linkedEntityId, String shareType, String visibility) {
ContentDocumentLink cdl = new ContentDocumentLink(ContentDocumentId = contentDocumentId, LinkedEntityId = linkedEntityId, ShareType = shareType, Visibility = visibility);
this.accessDecision = Security.stripInaccessible(AccessType.CREATABLE, new list<ContentDocumentLink>{
cdl
});
try {
INSERT this.accessDecision.getRecords();
} catch (Exception e) {
System.debug(LoggingLevel.ERROR, e.getMessage());
System.debug(LoggingLevel.ERROR, e.getStackTraceString());
}
}
}