Adding Contact matching to Communities Self Registration
Note: This update can only occur within sandbox and then perform a change set to production to save those changes. For additional information, please see the Salesforce Help & Training article Deploy change sets from sandbox to production.
Communities is an unmanaged package. You have two options to apply these changes:
- Option 1: If you HAVE customizations on your Community, use this option and complete all steps.
- Option 2: If you DO NOT HAVE customizations on your Community, replace the contents of TX_CommunitiesSelfRegController with the code listed below.
Option 1
- Navigate to Setup and search for Apex Classes.
- Locate TX_CommunitiesSelfRegController and select Edit.
- On line 4, replace “with” with “without” to allow matching to existing contact:

- On line 44, remove the lines from “Contact[] cs;“ through “else{” (see Screenshot below):

and replace with the following text by copying from here:
// match existing contact
Contact[] cs = [select id, accountid, account.ownerid, account.owner.userRoleId from Contact where email = :email];
if(String.isNotBlank(accountId)){
for (Account a : [select Id, Owner.UserRoleId from Account where Id = :accountId]) {
if(a.Owner.UserRoleId == null) {
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'Account Owner Missing Role'));
return null;
}
}
}
- It should look similar to this:

- Starting at line 56, paste these lines by copying from here:
// move contact to selected account if it's not the original and not default
if (!cs.isEmpty() && cs[0].AccountId != defaultAccountId && cs[0].AccountId != accountId) {
update new Contact(Id=cs[0].Id, AccountId=accountId);
}
Note:AccountId=accountIdshould be removed if your institution is not using the school picker and/or not using EDA Administrative Accounts.
- It should look similar to this:

- On line 73 insert the following by copying from here:
if(!cs.isEmpty()){
u.ContactId = cs[0].Id;
}
- Save your changes.
Option 2
If you DO NOT HAVE customizations on your Community, replace the contents of TX_CommunitiesSelfRegController with the code below [v 1912.7] or by copying from here and Save your changes.
/**
* An apex page controller that supports self registration of users in communities that allow self registration
*/
public without sharing class TX_CommunitiesSelfRegController {
public String defaultAccountId {get; private set;}
public String accountId {get;set;}
public String firstName {get; set;}
public String lastName {get; set;}
public String email {get; set;}
public String password {get; set {password = value == null ? value : value.trim(); } }
public String confirmPassword {get; set { confirmPassword = value == null ? value : value.trim(); } }
public String communityNickname {get; set { communityNickname = value == null ? value : value.trim(); } }
public Boolean isCaptchaEnabled {get; set;}
public String tokenValue {get; set;}
public TX_CommunitiesSelfRegController(TargetX_Base.TX_CommunitiesBase controller) {
defaultAccountId = null; // To be filled in by customer. (if school picker is on page this will default the value)
accountid = defaultAccountId;
}
public TX_CommunitiesSelfRegController() {}
private boolean isValidPassword() {
return password == confirmPassword;
}
public PageReference registerUser() {
if(isCaptchaEnabled != null && isCaptchaEnabled){
ApexPages.Message msg = new ApexPages.Message(ApexPages.Severity.ERROR, 'Invalid recaptcha response.');
if(String.isNotBlank(tokenValue)){
String response = TargetX_Base.CaptchaController.captchaVerify(tokenValue);
if(response != 'true'){
ApexPages.addMessage(msg);
return null;
}
}
else {
ApexPages.addMessage(msg);
return null;
}
}
SavePoint sp = Database.setSavePoint();
try{
//Uncomment below to make school picker required
/*
if (String.isBlank(accountId)) {
ApexPages.Message msg = new ApexPages.Message(ApexPages.Severity.ERROR, 'Please Select A School');
ApexPages.addMessage(msg);
return null;
}
*/
if (!isValidPassword()) {
ApexPages.Message msg = new ApexPages.Message(ApexPages.Severity.ERROR, Label.site.passwords_dont_match);
ApexPages.addMessage(msg);
return null;
}
String profileId = null; // To be filled in by customer.
String roleEnum = null; // To be filled in by customer.
// match existing contact
Contact[] cs = [select id, accountid, account.ownerid, account.owner.userRoleId from Contact where email = :email];
// Uncomment the following line if you want to use HEDA's administrative accounts.
// NOTE: You will also need to make sure you have some way for account to be set to an owner with a role
// on creation. By default, accounts will be created by the guest user and fail.
//if(cs.size() == 0 && !hasDuplicateUser(email)) cs = insertContactFirst() ;
if(String.isNotBlank(accountId)){
for (Account a : [select Id, Owner.UserRoleId from Account where Id = :accountId]) {
if(a.Owner.UserRoleId == null) {
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'Account Owner Missing Role'));
return null;
}
}
}
// move contact to selected account if it's not the original and not default
if (String.isNotBlank(accountId) && !cs.isEmpty() && cs[0].AccountId != defaultAccountId && cs[0].AccountId != accountId) {
update new Contact(Id=cs[0].Id, AccountId=accountId);
}
if(!hasDuplicateUser(email)){
String userName = email;
User u = new User();
u.Username = userName;
u.Email = email;
u.FirstName = firstName;
u.LastName = lastName;
u.CommunityNickname = getCommunityNickname();
u.ProfileId = profileId;
if(!cs.isEmpty()){
u.ContactId = cs[0].Id;
accountId = String.isBlank(accountId) ? cs[0].AccountId : accountId;
}
String userId = Site.createPortalUser(u, String.isBlank(accountId) ? null : accountId, password);
if (userId != null) {
if (password != null && password.length() > 1) {
return Site.login(userName, password, ApexPages.currentPage().getParameters().get('startURL'));
}
else {
PageReference page = System.Page.TX_CommunitiesSelfRegConfirm;
page.setRedirect(true);
return page;
}
}
}
}
catch(Exception ex){
ApexPages.addMessages(ex);
}
Database.rollback(sp);
return null;
}
private static Boolean hasDuplicateUser(String email){
Boolean hasDupe = [SELECT Count() FROM User WHERE UserName = :email] > 0;
if(hasDupe){
ApexPages.Message msg = new ApexPages.Message(ApexPages.Severity.ERROR, Label.Duplicate_User_Exists);
ApexPages.addMessage(msg);
}
return hasDupe;
}
private string getCommunityNickname() {
// Perhaps make this query the database at some point
return (communityNickname == null || communityNickname == '') ? (firstName.substring(0,1) + lastName + randomNumber()).toLowerCase() : communityNickname;
}
private string randomNumber() {
Integer i1 = Math.abs(Crypto.getRandomInteger());
Integer i2 = Math.abs(Crypto.getRandomInteger());
Integer i3 = Math.abs(Crypto.getRandomInteger());
return (String.valueOf(i1) + String.valueOf(i2) + String.valueOf(i3)).substring(0,3);
}
public Contact[] insertContactFirst() {
Contact c = new Contact() ;
c.FirstName = firstName ;
c.LastName = lastName ;
c.Email = email ;
if(TX_FLSChk.getInstance().isFieldsCreatable(c, Contact.sObjectType)){
insert c ;
}
return [SELECT Id, AccountId, Account.OwnerId, Account.Owner.UserRoleId FROM Contact WHERE Id = :c.Id] ;
}
}
Note:AccountId=accountIdshould be removed from the update new Contact method if your institution is not using the school picker and/or not using EDA Administrative Accounts.
