Take the 2-minute tour ×
Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. It's 100% free, no registration required.

I have one checkbox on my vf page.when i select this i want that the class to which this VF page is referring should work in with sharing mode and when i deselect it class should work in without sharing mode.Any suggestions how can i implement this functionality?

share|improve this question

3 Answers 3

This is little tricky. So what can you do is keep the logic that needs to be executed in a Util Class. Say

public class Util{
    public static void process(){

    }
}

Now define two more classes

public with sharing class withSharing(){
    public static void runCode(){
        Util.process();
    }
}


public without sharing class withoutSharing(){
    public static void runCode(){
        Util.process();
    }
}

Now define your controller and from controller depending on the checkbox checked call the corresponding class

public class controller{
    public void process(){
      if(isChecked == true){
        withSharing.runCode();
      }
     else{
         withoutSharing.runCode();
     }
    }
}

PS: The code is written in Notepad my not actually compile. Please feel free to make changes

UPDATE : Just realized you dont even need the second class(without sharing) just call the util class directly from the controller.

share|improve this answer

The following solution does not work:

Put the functionality in a separate virtual class (with sharing), and create a subclass which is annotated "without sharing". You would choose which one to instantiate in your controller.

It appears that in a class hierarchy, the platform respects the sharing annotation of the class in which the method is defined, and not necessarily the class that is instantiated. For example:

public virtual with sharing class AccountSelector
{
    public virtual List<Account> selectAccounts(String criteria)
    {
        return [select Name from Account where Name like :criteria+'%'];
    }
}

public without sharing class AccountSelectorWithoutSharing extends AccountSelector {}

If I construct an instance of AccountSelectorWithoutSharing, and call selectAccounts(String), the method is executed "with sharing" because of the annotation in the class where the method is defined (AccountSelector).

The fact that the class I have instantiated, AccountSelectorWithoutSharing, is "without sharing" has no influence.

share|improve this answer
    
Yep, but doesn't need to be extended - just delegation (i.e. calling) to a non-sharing-specified class will continue to enforce the current sharing policy. –  jkraybill Feb 27 '13 at 16:33
    
@jkraybill but extending / implementing a common interface will make the code harder to break ;) And there probably will be huge amounts of code that can be reused, a method in base class sounds like a good choice. –  eyescream Feb 27 '13 at 16:36
    
Actually, yes, you would not need to extend it twice, only once: the base implementation might be "without sharing", and add a single "with sharing" extension. Main thing I was aiming for was to have only 1 implementation of the logic. –  Stephen Willcock Feb 27 '13 at 16:42
    
@jkraybill take your point - delegation would work, and the logic would be implemented in one place, but if there are multiple methods being called from the controller then I think extension would be neater –  Stephen Willcock Feb 27 '13 at 17:01
    
A fun note that might make this less work for utility methods: if you leave off the with/without sharing declaration then any methods in that class inherit the sharing settings of their caller. –  ca_peterson Feb 27 '13 at 18:09

I've found the simplest way to do this is to have the parent class run in with sharing mode and then use a util class to perform certain tasks in system mode.

Example Parent Class

public with sharing class ParentController() {

  private List<Contact> queryContacts() {
    String query = 'select id from Contact';
    if(respectSharing) {
      return Database.query(query);
    } else {
      return SudoHelper.sudoQuery(query);
    }
  }

}

My Sudo Helper class looks like this

public without sharing class SudoHelper {

    /* Query */

    public static List<sObject> doQuery(String query) {
        return Database.query(query);
    }

    /* Inserts */

    public static Database.SaveResult doInsert(sObject recordToInsert) {
        return doInsert(new sObject[] { recordToInsert })[0];
    }
    public static Database.SaveResult doInsert(sObject recordToInsert, Boolean opt_allOrNone) {
        return doInsert(new sObject[] { recordToInsert }, opt_allOrNone)[0];
    }
    public static List<Database.SaveResult> doInsert(List<sObject> recordsToInsert) {
        return doInsert(recordsToInsert, true);
    }
    public static List<Database.SaveResult> doInsert(List<sObject> recordsToInsert, Boolean opt_allOrNone) {
        return Database.insert(recordsToInsert, opt_allOrNone);
    }

    /* Updates */

    public static Database.SaveResult doUpdate(sObject recordToUpdate) {
        return doUpdate(new sObject[] { recordToUpdate })[0];
    }
    public static Database.SaveResult doUpdate(sObject recordToUpdate, Boolean opt_allOrNone) {
        return doUpdate(new sObject[] { recordToUpdate }, opt_allOrNone)[0];
    }
    public static List<Database.SaveResult> doUpdate(List<sObject> recordsToUpdate) {
        return doUpdate(recordsToUpdate, true);
    }
    public static List<Database.SaveResult> doUpdate(List<sObject> recordsToUpdate, Boolean opt_allOrNone) {
        return Database.update(recordsToUpdate, opt_allOrNone);
    }

}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.