+ Start a Discussion
Ron WildRon Wild 

Setting custom settings in a hierarchy

We've done some testing with the hierarchical custom settings feature and have run into what appears to be limitation when managing individual user settings from Apex (hopefully not).

 

We created a custom setting object and simple checkbox field (let's call it UI_Settings__c.Show_Feature__c) and would like our apex code to be able to store individual user settings for that value.  Something like this:

 

 

public PageReference saveUISettings() { UI_Settings__c userInstance = UI_Settings__c.getValues(UserInfo.getUserId()); userInstance.Show_Feature__c = this.showFeature; update userInstance; // save changes to UI preferences.

return null; }

 

 This works fine if we have manually configured a custom setting instance for each user through the Salesforce UI.  But it looks like we can't store user-level settings if the custom setting instance hasn't been created for a user.  And there appears to be no way to create that custom setting instance from Apex.

 

Is this true?

 

Thanks,

Ron

 

Best Answer chosen by Admin (Salesforce Developers) 
mtbclimbermtbclimber

No, you can certainly create user-level custom settings in apex.

 

Here's a sample for you that allows the user to override the org value for themselves, toggle that setting and revert to the org default ("Reset" ).  This example assumes an instance has been created at the org level and I already had a hierarchy setting defined with a boolean for a separate example so in my case it's "My_Setting__c.Enabled__c" but the same logic applies:

 

PAGE:

 

 

<apex:page controller="usersettingcon">
<apex:form>
<apex:commandButton value="{!buttonLabel}" action="{!toggle}"/>
<apex:commandButton value="Reset" action="{!reset}" rendered="{!useroverridden}"/>
<apex:pageMessages/>
</apex:form>
</apex:page>

 

 

 

CONTROLLER:

 

 

public class usersettingcon {

public String getButtonLabel() {

String l;

/* Get the values for the running user. */
My_Setting__c s = My_Setting__c.getValues(UserInfo.getUserId());

if(s == null) {
/* If the instance was null defer to the org value for the label.
This assumes there is no profile level in play. */
s = My_Setting__c.getOrgDefaults();
if(s.enabled__c) { l = 'Disable (override org value)'; }
else { l = 'Enable (override org value)'; }

} else {
/* If non-null then use the current setting value to drive the button label. */
if(s.enabled__c) { l = 'Disable'; }
else { l = 'Enable'; }
}

return l;
}

public Boolean getUserOverridden() {
/* return the existence of the user level value for control of the reset button display. */
return My_Setting__c.getValues(UserInfo.getUserId()) != null;
}

/* Changes the setting for the user or establishes the override as appropriate. */
public void toggle() {

My_Setting__c s = My_Setting__c.getValues(UserInfo.getUserId());
Boolean isEnabled = My_Setting__c.getInstance().enabled__c;

if(s == null) {
s = new My_Setting__c(setupownerid = UserInfo.getUserId(), enabled__c = !isEnabled);
} else {
s.enabled__c = !isEnabled;
}

try {
Database.UpsertResult result = Database.upsert(s);
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.CONFIRM,'User level setting ' + (result.isCreated() ? ' inserted' : ' updated')));
} catch(System.DMLException e) {
ApexPages.addMessages(e);
}
}

/* Deletes the user level setting, reverting the behavior back to the
org level defaults. */
public void reset() {
try {
Database.delete(My_Setting__c.getInstance(UserInfo.getUserId()));
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.CONFIRM,'User level setting deleted.'));
} catch(System.DMLException e) {
ApexPages.addMessages(e);
}
}
}

 


 

Message Edited by mtbclimber on 02-19-2010 03:10 PM

All Answers

mtbclimbermtbclimber

No, you can certainly create user-level custom settings in apex.

 

Here's a sample for you that allows the user to override the org value for themselves, toggle that setting and revert to the org default ("Reset" ).  This example assumes an instance has been created at the org level and I already had a hierarchy setting defined with a boolean for a separate example so in my case it's "My_Setting__c.Enabled__c" but the same logic applies:

 

PAGE:

 

 

<apex:page controller="usersettingcon">
<apex:form>
<apex:commandButton value="{!buttonLabel}" action="{!toggle}"/>
<apex:commandButton value="Reset" action="{!reset}" rendered="{!useroverridden}"/>
<apex:pageMessages/>
</apex:form>
</apex:page>

 

 

 

CONTROLLER:

 

 

public class usersettingcon {

public String getButtonLabel() {

String l;

/* Get the values for the running user. */
My_Setting__c s = My_Setting__c.getValues(UserInfo.getUserId());

if(s == null) {
/* If the instance was null defer to the org value for the label.
This assumes there is no profile level in play. */
s = My_Setting__c.getOrgDefaults();
if(s.enabled__c) { l = 'Disable (override org value)'; }
else { l = 'Enable (override org value)'; }

} else {
/* If non-null then use the current setting value to drive the button label. */
if(s.enabled__c) { l = 'Disable'; }
else { l = 'Enable'; }
}

return l;
}

public Boolean getUserOverridden() {
/* return the existence of the user level value for control of the reset button display. */
return My_Setting__c.getValues(UserInfo.getUserId()) != null;
}

/* Changes the setting for the user or establishes the override as appropriate. */
public void toggle() {

My_Setting__c s = My_Setting__c.getValues(UserInfo.getUserId());
Boolean isEnabled = My_Setting__c.getInstance().enabled__c;

if(s == null) {
s = new My_Setting__c(setupownerid = UserInfo.getUserId(), enabled__c = !isEnabled);
} else {
s.enabled__c = !isEnabled;
}

try {
Database.UpsertResult result = Database.upsert(s);
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.CONFIRM,'User level setting ' + (result.isCreated() ? ' inserted' : ' updated')));
} catch(System.DMLException e) {
ApexPages.addMessages(e);
}
}

/* Deletes the user level setting, reverting the behavior back to the
org level defaults. */
public void reset() {
try {
Database.delete(My_Setting__c.getInstance(UserInfo.getUserId()));
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.CONFIRM,'User level setting deleted.'));
} catch(System.DMLException e) {
ApexPages.addMessages(e);
}
}
}

 


 

Message Edited by mtbclimber on 02-19-2010 03:10 PM
This was selected as the best answer
Ron WildRon Wild

Andrew -

 

I had tried creating new instance, but didn't know about the setup ownerid parameter ...

setupownerid = UserInfo.getUserId()


... that was all we needed.  Thanks!!

 

- Ron

 

jwilkinsonjwilkinson

I just ran up against testing a VFExtension that uses Custom Setting for extra security.  This was exacly what I was looking for and I wanted just to say thanks for the post.