View Any Record Page

Common case is when admin/developer need to view additional data in production.
Some common approaches:
-Add the data in the page layout.
-Use developer console query.
-Create list view.
I think the first method is the most common. If the admin uses the same page layouts as regular users then this might expose to users data that they should see, if they have different page layouts then there is no issue for adding the data only this require maintain more page layouts.
The latest 2 approaches- writing a query in console or creating the list view-  also can be used, but are more time consuming.

At last, I decided to use different simple and generic solution. It does require me to write code, but it is done once and then I can reused it.
The functionality is quite simple - user will select the object type, will search single record either by Id or by Name, and will be able to view/update any field.
Of course, that the access for this page should be highly restricted as it provide access to all the data.




Controller:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
public class ViewRecord{

    public String objectType {get; set;}
    public String recordName {get; set;}
    public String recordId {get; set;}
    public map <String, Schema.SObjectType> schemaMap ;
    
    public list<String> l_objects {get ;set;}
    public list<String> l_fields {get; set;}
    public list<String> l_values {get; set;}
    public sObject record {get;set;}
    
    public SelectOption[] selectedFields { get; set; }
    public SelectOption[] allFields { get; set; }
    
    public list<SelectOption> objectoptions{
    get{
        list<SelectOption> pOptions = new list<SelectOption>(); 
        
        pOptions.add(new SelectOption('none', 'Select Object'));
        
        for(String obj: l_objects){
            
            pOptions.add(new SelectOption(obj,obj));
        }
        
        return pOptions;
    }
    set;
    }
    
    public ViewRecord(){
        schemaMap = Schema.getGlobalDescribe();
        l_objects = new list<string>();
        
        selectedFields = new list<SelectOption>();
        allFields = new list<SelectOption>();
        
        for(Schema.SObjectType schemaType : schemaMap.values()){
            
            Schema.DescribeSObjectResult ds = schemaType.getDescribe();
            
            if(ds.isCreateable())
                l_objects.add(ds.getName());
        }
        
        l_objects.sort();
    }
    
    public PageReference fillOptions(){
        selectedFields.clear();
        allFields.clear();
        
        if(objectType != 'none'){
            for(Schema.SObjectField field : schemaMap.get(objectType).getDescribe().fields.getMap().values()){
                Schema.DescribeFieldResult dr  = field.getDescribe();
            
                if(dr.isUpdateable()){
                    allFields.add(new SelectOption(dr.getName(), dr.getName()));
                }
            }
        }
        
        return  Apexpages.currentPage();
    }
    
    public PageReference showRecord(){
    
    try{
    
        if(objectType != 'none'){
            l_fields = new list<String>();
            l_values = new list<String>();
        
            String sql = 'select ';
            
            if(selectedFields.isEmpty()){
                for(Schema.SObjectField field : schemaMap.get(objectType).getDescribe().fields.getMap().values()){
                    Schema.DescribeFieldResult dr  = field.getDescribe();
                
                    if(dr.isUpdateable()){
                        sql += dr.getName() + ',';
                   
                        l_fields.add(dr.getName());
                    }
                }
            }
            else{
                for(SelectOption option : selectedFields){
                    sql += option.getValue() + ',';
                
                    l_fields.add(option.getValue());
                }
            }
            
            l_fields.sort();
            
            sql = sql.subString(0, sql.length()-1) + ' from ' +objectType;
            
            if(!String.isEmpty(recordId))
                sql += ' where id = \'' + recordId + '\'';
            else if(!String.isEmpty(recordName))
                sql += ' where name = \'' + recordName + '\'';
            else{
                ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'Add Filter!'));
                return null;
            }
            
            
            system.debug('####'+ sql);
        
            list<sObject> l_obj = database.query(sql);
        
            if(l_obj.size() > 0){
                //for(String field: l_fields){
                 //   l_values.add((String)l_obj.get(0).get(field));
               // }
                
                record = l_obj.get(0);
            
            }
        }
        
     }catch(Exception ex){
         ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'Bad thing happen...' + ex.getMessage() + ' : ' + ex.getStackTraceString()));
            return null;
     }
    
        return null;
    }
    
    
    
    public PageReference updateRecord(){
        try{
            if(record!=null)
                update record;
                
     ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.INFO, 'Done'));
        }
        catch(Exception ex){
            ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'Bad thing happen...' + ex.getMessage() + ' : ' + ex.getStackTraceString()));
            return null;
        }
        return null;
    }
    
    
    
}




Page
1:  <apex:page controller="ViewRecord">  
2:  <apex:form id="formId">  
3:    <apex:pageMessages />   
4:    <apex:pageblock id="blockId">  
5:     <apex:pageblockSection id="pbSection">  
6:       <apex:pageblockSectionItem id="pbsi">  
7:         <apex:outputLabel value="Select Object" for="objectTypeId" />  
8:         <apex:selectList multiselect="false" id="objectTypeId" value="{!objectType}" size="1">  
9:           <apex:selectoptions value="{!objectoptions}" />  
10:           <apex:actionSupport event="onchange" reRender="formId,blockId,pbSection,pbsi,fieldsId"/>  
11:           <apex:actionSupport event="onchange" action="{!fillOptions}"/>  
12:         </apex:selectList>  
13:       </apex:pageblockSectionItem>  
14:        <apex:pageblockSectionItem />  
15:       <apex:pageblockSectionItem >  
16:         <apex:outputLabel value="Search by Id" />  
17:         <apex:inputText value="{!recordId}"/>  
18:       </apex:pageblockSectionItem>  
19:       <apex:pageblockSectionItem />  
20:       <apex:pageblockSectionItem >  
21:         <apex:outputLabel value="Search by name" />  
22:         <apex:inputText value="{!recordName}"/>  
23:       </apex:pageblockSectionItem>  
24:     </apex:pageblockSection>  
25:     <apex:pageBlockButtons location="top">    
26:       <apex:commandButton value="Show Record" action="{!showRecord}"/>  
27:     </apex:pageBlockButtons>  
28:   </apex:pageblock>  
29:   <apex:pageBlock rendered="{!Not ISBlank(record)}">  
30:     <apex:pageBlockButtons location="top">    
31:       <apex:commandButton value="Update" action="{!updateRecord}" rendered="{!Not ISBlank(record)}"/>  
32:     </apex:pageBlockButtons>  
33:     <apex:pageblockSection >  
34:       <apex:repeat value="{!l_fields}" var="field">  
35:          <apex:pageblockSectionItem >  
36:             <apex:outputLabel value="{!field}" />  
37:             <apex:inputField value="{!record[field]}"/>  
38:          </apex:pageblockSectionItem>  
39:          <apex:pageblockSectionItem />  
40:       </apex:repeat>  
41:     </apex:pageblockSection>  
42:   </apex:pageBlock>  
43:  </apex:form>  
44:  </apex:page>  



Retire of Permission on Profiles

If you are working as a Salesforce admin/developer you've probably heard somewhere that Salesforce is planning to make a significant cha...