7

I am currently using VisualForce to display a table at the top of one of my forms. It is displaying data to users who do not have access to the object which it is displaying so it is therefore invisible to those people. I would like to make it visible to everybody so I need to use the withoutsharing extension to accomplish that. My problem is that I don't understand what all code needs to go into that extension since all of the rest of the (properly functioning) code is already in VF.

I guess ideally I would be able to write a simple 5 line class which would just be called up in the VF, and would supply that withoutsharing functionality. How would I do this ? I don't want to have to re-write everything that is in VF in Apex if I don't have to do that. Can anybody give me help on this ? I would be soooo grateful.

Here is the VF page.

<apex:page standardController="Invoice_Overview__c" > 
  <apex:form >
   <apex:pageBlock title="Invoice Terms"> 
     <apex:pageBlockTable value="{!Invoice_Overview__c.New_Invoice_Terms__r}" var="con"> 
      <apex:column width="43%" headerValue="Invoice Terms">
        <apex:facet name="header"> Invoice Name</apex:facet>              
        <apex:outputtext value="{!con.Name}"/>         
      </apex:column>
      <apex:column width="30%">
        <apex:facet name="header"> Record Type</apex:facet>
        <apex:outputtext value="{!con.RecordType.Name}"/>
      </apex:column>          
      <apex:column width="20%">
        <apex:facet name="header"> End Date</apex:facet>
        <apex:outputText value="{0,date,dd'/'MM'/'yyyy}">
          <apex:param value="{!con.Invoice_End_Date__c}"/>
        </apex:outputText>        
      </apex:column>     
      <apex:column width="30%">
        <apex:facet name="header"> Owner</apex:facet>
        <apex:outputtext value="{!con.Owner.Alias}"/>
      </apex:column>
    </apex:pageblocktable>         
  </apex:pageBlock>
 </apex:form> 
 <apex:detail relatedList="True"/>
 <apex:relatedList list="New_Invoice_Terms__r"/>
</apex:page>
3
  • 2
    Welcome to the community! This is a well-written first post and thank you posting the code sample; it will be helpful with eliciting answers.
    – Mike Chale
    Commented Mar 1, 2013 at 15:21
  • Any reason you wouldn't be able to just give Read permission to the users in question?
    – JCD
    Commented Mar 1, 2013 at 15:25
  • Mike - Thanks - I'm trying ! JCD - I can't give read permission to the users in question because I don't want them to report on (or see) the rest of the data in that Invoice_Terms object. I just want to display those several fields in a table on this form\page.
    – user2428
    Commented Mar 1, 2013 at 16:20

1 Answer 1

3

I would suggest against using without sharing as it can have unintended consequences at time. You are bypassing your security model by using without sharing. With that said, from the comments on your original question, it sounds like you may be able to Field Level Security with the Read Permission on the Invoice_Terms__c object. If everyone in the organization can have access to this object, your sharing model should reflect this. Just hide the values they should not be able to see with FLS.


If you are adamant about using without sharing, try using something like:

public without sharing class InvoiceOverviewControllerExtension {
    public Invoice_Overview__c invoiceOverview {get;set;}
    public InvoiceOverviewControllerExtension(ApexPages.StandardController stdController) {
        Invoice_Overview__c temp = (Invoice_Overview__c) stdController.getRecord();
        invoiceOverview = [SELECT
                               Id, (SELECT
                                        Id
                                    FROM
                                        New_Invoice_Terms__r)
                           FROM
                               Invoice_Overview__c
                           WHERE
                               Id = :temp.Id
        ];
    }
}

You would then need to replace all of the references to Invoice_Overview__c in your controller to use invoiceOverview instead. The reason for loading the data into the separate object is to get the related list populated. It will also let you query whatever fields you want from either of them. Change up your page declaration to:

<apex:page standardController="Invoice_Overview__c" extensions="InvoiceOverviewControllerExtension"> 
  <apex:form >
   <apex:pageBlock title="Invoice Terms"> 
     <apex:pageBlockTable value="{!invoiceOverview.New_Invoice_Terms__r}" var="con"> 
      <apex:column width="43%" headerValue="Invoice Terms">
        <apex:facet name="header"> Invoice Name</apex:facet>              
        <apex:outputtext value="{!con.Name}"/>         
      </apex:column>
      <apex:column width="30%">
        <apex:facet name="header"> Record Type</apex:facet>
        <apex:outputtext value="{!con.RecordType.Name}"/>
      </apex:column>          
      <apex:column width="20%">
        <apex:facet name="header"> End Date</apex:facet>
        <apex:outputText value="{0,date,dd'/'MM'/'yyyy}">
          <apex:param value="{!con.Invoice_End_Date__c}"/>
        </apex:outputText>        
      </apex:column>     
      <apex:column width="30%">
        <apex:facet name="header"> Owner</apex:facet>
        <apex:outputtext value="{!con.Owner.Alias}"/>
      </apex:column>
    </apex:pageblocktable>         
  </apex:pageBlock>
 </apex:form> 
 <apex:detail relatedList="True"/>
 <apex:relatedList subject="{!invoiceOverview}" list="New_Invoice_Terms__r"/>
</apex:page>

I'll let you write your own unit test for it.

11
  • Shouldn't the 'without sharing' only affect the VF page which is calling the extension at the time ? Invoice_Overview__c is the object which the table will be displayed on, not the object which is restricted. That's Invoice_Terms__c. (I don't know if that's what you meant, but I'm just making sure). So, doing FLS on Invoice_Overview__c wouldn't really do any good. Do you know how to implement 'without sharing' for this type of case ? I'd like to at least test it against a bunch of different profiles. Thank you very much for your response.
    – user2428
    Commented Mar 1, 2013 at 19:24
  • Is Invoice_Terms__c a master-detail object on the Invoice_Overview__c object? Commented Mar 1, 2013 at 19:31
  • No - Invoice_Terms__c has a lookup relationship w/ Invoice_Overview__c, not a Master\Detail one.
    – user2428
    Commented Mar 1, 2013 at 20:18
  • 1
    You need to query each field specifically. The code I wrote above was just a quick template, not a complete example of what you need. I was just trying to give you a starting point. Check out the SOQL documentation - salesforce.com/us/developer/docs/api/Content/… - Essentially, you need to specify each field in your SELECT statement that you are going to be accessing on your Visualforce page - salesforce.com/us/developer/docs/pages/Content/… Commented Mar 4, 2013 at 15:51
  • 1
    You need to query for RecordType.Name and Owner.Name to be able to reference them. Same as before, the workbench should be able to tell you the relationships you want. Also, if you this answers your question, please take a second to upvote and mark this as the answer. This allows other users to find answers easier in the future. Commented Mar 4, 2013 at 18:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .