Skip to content

Commit 75d0e27

Browse files
committed
Merge pull request apex-enterprise-patterns#74 from Autobat/master
apex-enterprise-patterns#18 - addition of afterUndelete within the fflib_SObjectDomain
2 parents 9a9a159 + 67f5ce2 commit 75d0e27

File tree

2 files changed

+55
-3
lines changed

2 files changed

+55
-3
lines changed

fflib/src/classes/fflib_SObjectDomain.cls

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,11 @@ public virtual with sharing class fflib_SObjectDomain
138138
**/
139139
public virtual void onAfterDelete() { }
140140

141+
/**
142+
* Override this to perform processing during the after undelete phase, this is called by the handleAfterDelete method
143+
**/
144+
public virtual void onAfterUndelete() { }
145+
141146
/**
142147
* Base handler for the Apex Trigger event Before Insert, calls the onApplyDefaults method, followed by onBeforeInsert
143148
**/
@@ -206,6 +211,19 @@ public virtual with sharing class fflib_SObjectDomain
206211
onAfterDelete();
207212
}
208213

214+
/**
215+
* Base handler for the Apex Trigger event After Undelete, checks object security and calls the onAfterUndelete method
216+
*
217+
* @throws DomainException if the current user context is not able to delete records
218+
**/
219+
public void handleAfterUndelete()
220+
{
221+
if(Configuration.EnforcingTriggerCRUDSecurity && !SObjectDescribe.isCreateable())
222+
throw new DomainException('Permission to create an ' + SObjectDescribe.getName() + ' denied.');
223+
224+
onAfterUndelete();
225+
}
226+
209227
/**
210228
* Returns the SObjectType this Domain class represents
211229
**/
@@ -274,6 +292,7 @@ public virtual with sharing class fflib_SObjectDomain
274292
Trigger.isInsert,
275293
Trigger.isUpdate,
276294
Trigger.isDelete,
295+
Trigger.isUnDelete,
277296
Trigger.new,
278297
Trigger.oldMap);
279298
}
@@ -282,7 +301,7 @@ public virtual with sharing class fflib_SObjectDomain
282301
/**
283302
* Calls the applicable override methods such as beforeInsert, beforeUpdate etc. based on a Trigger context
284303
**/
285-
private static void triggerHandler(Type domainClass, Boolean isBefore, Boolean isAfter, Boolean isInsert, Boolean isUpdate, Boolean isDelete, List<SObject> newRecords, Map<Id, SObject> oldRecordsMap)
304+
private static void triggerHandler(Type domainClass, Boolean isBefore, Boolean isAfter, Boolean isInsert, Boolean isUpdate, Boolean isDelete, Boolean isUndelete, List<SObject> newRecords, Map<Id, SObject> oldRecordsMap)
286305
{
287306
// After phase of trigger will reuse prior instance of domain class if ITriggerStateful implemented
288307
fflib_SObjectDomain domainObject = isBefore ? null : popTriggerInstance(domainClass, isDelete ? oldRecordsMap.values() : newRecords);
@@ -297,6 +316,7 @@ public virtual with sharing class fflib_SObjectDomain
297316
if(isInsert) domainObject = domainConstructor.construct(newRecords);
298317
else if(isUpdate) domainObject = domainConstructor.construct(newRecords);
299318
else if(isDelete) domainObject = domainConstructor.construct(oldRecordsMap.values());
319+
else if(isUndelete) domainObject = domainConstructor.construct(newRecords);
300320

301321
// Should this instance be reused on the next trigger invocation?
302322
if(domainObject.Configuration.TriggerStateEnabled)
@@ -316,6 +336,7 @@ public virtual with sharing class fflib_SObjectDomain
316336
if(isInsert) domainObject.handleAfterInsert();
317337
else if(isUpdate) domainObject.handleAfterUpdate(oldRecordsMap);
318338
else if(isDelete) domainObject.handleAfterDelete();
339+
else if(isUndelete) domainObject.handleAfterUndelete();
319340
}
320341
}
321342

@@ -560,6 +581,7 @@ public virtual with sharing class fflib_SObjectDomain
560581
private Boolean isInsert = false;
561582
private Boolean isUpdate = false;
562583
private Boolean isDelete = false;
584+
private Boolean isUndelete = false;
563585
private List<SObject> records = new List<SObject>();
564586
private Map<Id, SObject> oldRecords = new Map<Id, SObject>();
565587

@@ -571,17 +593,18 @@ public virtual with sharing class fflib_SObjectDomain
571593
private void testTriggerHandler(Type domainClass)
572594
{
573595
// Mock Before
574-
triggerHandler(domainClass, true, false, isInsert, isUpdate, isDelete, records, oldRecords);
596+
triggerHandler(domainClass, true, false, isInsert, isUpdate, isDelete, isUndelete, records, oldRecords);
575597

576598
// Mock After
577-
triggerHandler(domainClass, false, true, isInsert, isUpdate, isDelete, records, oldRecords);
599+
triggerHandler(domainClass, false, true, isInsert, isUpdate, isDelete, isUndelete, records, oldRecords);
578600
}
579601

580602
public void onInsert(List<SObject> records)
581603
{
582604
this.isInsert = true;
583605
this.isUpdate = false;
584606
this.isDelete = false;
607+
this.isUndelete = false;
585608
this.records = records;
586609
}
587610

@@ -591,6 +614,7 @@ public virtual with sharing class fflib_SObjectDomain
591614
this.isUpdate = true;
592615
this.isDelete = false;
593616
this.records = records;
617+
this.isUndelete = false;
594618
this.oldRecords = oldRecords;
595619
}
596620

@@ -599,9 +623,19 @@ public virtual with sharing class fflib_SObjectDomain
599623
this.isInsert = false;
600624
this.isUpdate = false;
601625
this.isDelete = true;
626+
this.isUndelete = false;
602627
this.oldRecords = records;
603628
}
604629

630+
public void onUndelete(List<SObject> records)
631+
{
632+
this.isInsert = false;
633+
this.isUpdate = false;
634+
this.isDelete = false;
635+
this.isUndelete = true;
636+
this.records = records;
637+
}
638+
605639
public Boolean hasRecords()
606640
{
607641
return records!=null && records.size()>0 || oldRecords!=null && oldRecords.size()>0;
@@ -676,6 +710,12 @@ public virtual with sharing class fflib_SObjectDomain
676710
}
677711
}
678712

713+
public override void onAfterUndelete()
714+
{
715+
// Not required in production code
716+
super.onAfterUndelete();
717+
}
718+
679719
public override void onBeforeInsert()
680720
{
681721
// Assert this variable is null in the after insert (since this domain class is stateless)

fflib/src/classes/fflib_SObjectDomainTest.cls

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,18 @@ private with sharing class fflib_SObjectDomainTest
8282
System.assertEquals('You cannot delete this Opportunity.', fflib_SObjectDomain.Errors.getAll()[0].message);
8383
}
8484

85+
@IsTest
86+
private static void testOnAfterUndeleteWithoutDML()
87+
{
88+
Opportunity opp = (Opportunity) Opportunity.sObjectType.newSObject('006E0000006mkRQ');
89+
opp.Name = 'Test';
90+
opp.Type = 'Existing Account';
91+
System.assertEquals(false, fflib_SObjectDomain.Test.Database.hasRecords());
92+
fflib_SObjectDomain.Test.Database.onUndelete(new list<Opportunity> { opp } );
93+
System.assertEquals(true, fflib_SObjectDomain.Test.Database.hasRecords());
94+
fflib_SObjectDomain.triggerHandler(fflib_SObjectDomain.TestSObjectDomainConstructor.class);
95+
}
96+
8597
@IsTest
8698
private static void testObjectSecurity()
8799
{

0 commit comments

Comments
 (0)