Skip to content

Instantly share code, notes, and snippets.

@Feldstrom
Last active November 3, 2021 19:45
Show Gist options
  • Save Feldstrom/1c9dd1cfaa3b49fbfb7ae3b44c8b9feb to your computer and use it in GitHub Desktop.
Save Feldstrom/1c9dd1cfaa3b49fbfb7ae3b44c8b9feb to your computer and use it in GitHub Desktop.
Apex script for pulling field names from specific page layout
//***
//this script is used for extracting labels from a given layout
//currently it will extract the following
//field labels, field help text, picklist field values,button & action names
//all input fields are required
//***
//uncomment for apex anon
// public String objectName = '';//example 'Case'
// public String layoutName = '';//example: 'Agent Layout'
// new LayoutDescriber().run(objectName,layoutName);
public without sharing class LayoutDescriber {
//inputs:
//objectName & layoutName should be commented when running apex anon
public String objectName = '';//example 'Case'
public String layoutName = '';//example: 'Agent Layout'
//update with preferred subject
public String subject = 'Your Salesforce export results';
//enter email in provided quotes
public String[] toAddresses = new String[]{'yourEmail'};
//run script method
public void run(String objectName, String layoutName){
String dt = String.valueOf(DateTime.now());
String fieldLabelsCSVName = dt +'_fieldLabels.csv';
String pickListValuesCSVName = dt + '_picklistValues.csv';
String helpTextCSVName = dt + '_helpText.csv';
String buttonCSVName = dt + '_buttonNames.csv';
List<Messaging.EmailFileAttachment> attchmentList = new List<Messaging.EmailFileAttachment>();
//get field api names and build field map
List<String> layoutFields = getFieldAPINames(objectName,layoutName);
Map<String, Schema.SObjectField> fieldMap = getFieldMap(layoutFields);
//extract field labels
List<String> fieldLabelList = getFieldLabels(fieldMap,layoutFields);
String fieldListCSV = buildCSVFromList('Field Labels', fieldLabelList);
attchmentList = buildAttachmentList(fieldLabelsCSVName, fieldListCSV);
//extract picklist values
Map<String, List<String>> picklistMap = getPicklistFields(fieldMap,layoutFields);
String picklistValuesCSV = buildCSVFromMap(picklistMap);
attchmentList.addAll(buildAttachmentList(pickListValuesCSVName, picklistValuesCSV));
//extract field help text
Map<String, List<String>> inlineHelpMap = getHelpText(fieldMap,layoutFields);
String inlineHelpMapCSV = buildCSVFromMap(inlineHelpMap);
attchmentList.addAll(buildAttachmentList(helpTextCSVName, inlineHelpMapCSV));
//extract buttons and actions
List<String> buttonNames = getActionNames(objectName, layoutName);
String buttonNamesCSV = buildCSVFromList('Button Names', buttonNames);
attchmentList.addAll(buildAttachmentList(buttonCSVName, buttonNamesCSV));
//email attachments
emailCSV(attchmentList);
}
//takes object & layout name then returns field API names
private List<String> getFieldAPINames(String objectName, String layoutName){
List<String> layoutFieldsAPI = new List<String>();
layoutName = objectName + '-' + layoutName;
List<Metadata.Metadata> layouts = Metadata.Operations.retrieve(Metadata.MetadataType.Layout, new List<String> {layoutName});
//System.debug('layouts ' + layouts);
Metadata.Layout layoutMd = (Metadata.Layout)layouts.get(0);
List<String> layoutFields = new List<String>();
for (Metadata.LayoutSection section : layoutMd.layoutSections) {
for (Metadata.LayoutColumn column : section.layoutColumns) {
if (column.layoutItems != null) {
for (Metadata.LayoutItem item : column.layoutItems) {
//System.debug('item ' + item);
if (item.field != null){
//System.debug('items. field ' + item.field);
layoutFieldsAPI.add(item.field);
//layoutFieldLabels.add(item.field);
}
}
}
}
}
return layoutFieldsAPI;
}
//takes list of fields and builds SObject map
private Map<String, Schema.SObjectField> getFieldMap(List<String> layoutFields){
SObjectType sObjectType = ((SObject)(Type.forName('Schema.'+ objectName).newInstance())).getSObjectType();
DescribeSObjectResult describeResult = sObjectType.getDescribe();
Map<String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe();
Schema.SObjectType objSchema = schemaMap.get(objectName);
Map<String, Schema.SObjectField> fieldMap = objSchema.getDescribe().fields.getMap();
return fieldMap;
}
//takes list of fields and returns field labels
private List<String> getFieldLabels(Map<String, Schema.SObjectField> fieldMap, List<String> layoutFields){
List<String> fieldLabels = new List<String>();
for (String fieldName : layoutFields) {
Schema.DisplayType fieldDataType = fieldMap.get(fieldName).getDescribe().getType();
Schema.DescribeFieldResult fieldResult = fieldMap.get(fieldName).getDescribe();
//System.debug('fieldResult.getLabel() ' + fieldResult.getLabel());
fieldLabels.add(fieldResult.getLabel());
}
return fieldLabels;
}
//takes list of fields and returns list of picklistfields mapped to their values
private Map<String, List<String>> getPicklistFields(Map<String, Schema.SObjectField> fieldMap, List<String> layoutFields){
Map<String, List<String>> pickListMap = new Map<String, List<String>>();
for (String fieldName : layoutFields) {
Schema.DisplayType fieldDataType = fieldMap.get(fieldName).getDescribe().getType();
if (fieldDataType == Schema.DisplayType.Picklist || fieldDataType == Schema.DisplayType.MultiPicklist){
Schema.DescribeFieldResult fieldResult = fieldMap.get(fieldName).getDescribe();
//System.debug('field Result ' + fieldResult.getPicklistValues());
List<Schema.PicklistEntry> ple = fieldResult.getPicklistValues();
for (Schema.PicklistEntry p : ple){
if (!pickListMap.containsKey(fieldName)){
pickListMap.put(fieldName, new List<String>());
pickListMap.get(fieldName).add(p.getValue());
} else {
pickListMap.get(fieldName).add(p.getValue());
}
}
}
}
return pickListMap;
}
//takes list of fields and returns the inline help text
private Map<String, List<String>> getHelpText(Map<String, Schema.SObjectField> fieldMap, List<String> layoutFields){
Map<String, List<String>> inlineHelpMap = new Map<String, List<String>>();
for (String fieldName : layoutFields) {
Schema.DescribeFieldResult fieldResult = fieldMap.get(fieldName).getDescribe();
if (fieldResult.getInlineHelpText() != null){
if (!inlineHelpMap.containsKey(fieldResult.getLabel())){
inlineHelpMap.put(fieldResult.getLabel(), new List<String>());
inlineHelpMap.get(fieldResult.getLabel()).add(fieldResult.getInlineHelpText());
} else {
inlineHelpMap.get(fieldResult.getLabel()).add(fieldResult.getInlineHelpText());
}
}
}
return inlineHelpMap;
}
//todo: extract layoutSections with:
//List<Metadata.Metadata> layouts = Metadata.Operations.retrieve(Metadata.MetadataType.Layout, new List<String> {layoutName});
//System.debug(layouts);
//takes object and layout names and returns a list of button & action labels
//for the given layout
private List<String> getActionNames(String objectName, String layoutName){
layoutName = objectName + '-' + layoutName;
List<String> buttonNameList = new List<String>();
List<String> actionNames = new List<String>();
List<String> actionLinkList = new List<String>();
List<String> customButtonList = new List<String>();
List<String> invocableActionList = new List<String>();
List<String> productivityActionList = new List<String>();
List<String> standardButtonList = new List<String>();
List<String> quickActionList = new List<String>();
List<Metadata.Metadata> layouts = Metadata.Operations.retrieve(Metadata.MetadataType.Layout, new List<String> {layoutName});
//System.debug(layouts);
Metadata.Layout layoutMd = (Metadata.Layout)layouts.get(0);
//System.debug('platformAction test ' + layoutMd.platformActionList.platformActionListItems);
List<Metadata.PlatformActionListItem> platformActionItems = layoutMd.platformActionList.platformActionListItems;
//System.debug(platformActionItems);
for (Metadata.PlatformActionListItem p : platformActionItems){
String s = p.actionName;
if (p.actionType == Metadata.PlatformActionTypeEnum.QuickAction){
quickActionList.add(s);
// System.debug('actionNames ' + s);
}
if (p.actionType == Metadata.PlatformActionTypeEnum.ActionLink){
actionLinkList.add(s);
// System.debug('actionLinkList ' + s);
}
if (p.actionType == Metadata.PlatformActionTypeEnum.CustomButton){
customButtonList.add(s);
// System.debug('customButtonList ' + s);
}
if (p.actionType == Metadata.PlatformActionTypeEnum.InvocableAction){
invocableActionList.add(s);
// System.debug('invocableActionList ' + s);
}
if (p.actionType == Metadata.PlatformActionTypeEnum.StandardButton){
standardButtonList.add(s);
// System.debug('standardButtonList ' + s);
}
}
// System.debug('QuickActions ' + quickActionList
// + ' ActionLinks ' + actionLinkList
// + ' CustomButtons ' + customButtonList
// + ' InvocableActions ' + invocableActionList
// + ' StandardButtons ' + standardButtonList);
//process quick actions
QuickAction.DescribeQuickActionResult[] result = QuickAction.describeQuickActions(quickActionList);
for (QuickAction.DescribeQuickActionResult r : result){
buttonNameList.add(r.getLabel());
}
//process custom buttons
if (!customButtonList.isEmpty() && customButtonList != null){
List<String> webLinkNames = new List<String>();
List<WebLink> webLinkList = [SELECT Id, Name, MasterLabel FROM WebLink WHERE Name IN: customButtonList];
for (Weblink w : webLinkList){
buttonNameList.add(w.MasterLabel);
}
}
return buttonNameList;
}
/* ***CSV and Email processing*** */
//builds a csv string from a given list
//set header row by passing in string
private String buildCSVFromList(String headerRows, List<String> fieldList){
String generatedCSVFile ='';
String fileRow = '';
generatedCSVFile += headerRows + '\n';
for (String s : fieldList){
fileRow = '';
fileRow = fileRow +','+ s;
fileRow = fileRow.replaceFirst(',','');
generatedCSVFile = generatedCSVFile + fileRow + '\n';
}
return generatedCSVFile;
}
//creates a csv string from a given map
//map key == header rows, values are list of string
private String buildCSVFromMap(Map<String, List<String>> mapForCSV) {
String generatedCSVFile = '';
List<String> columns = new List<String>(mapForCSV.keySet());
Integer maxRows = 0;
for (String col : columns) {
Integer colRowSize = mapForCSV.get(col).size();
if (colRowSize > maxRows) {
maxRows = colRowSize;
}
}
generatedCSVFile += String.join(columns, ',');
generatedCSVFile += '\n';
String fileRow = '';
for (Integer i = 0; i < maxRows; i++) {
fileRow = '';
for (String col : columns) {
fileRow += ',' + (mapForCSV.get(col).size() <= i
? ''
: mapForCSV.get(col).get(i)).escapeCSV();
}
fileRow = fileRow.replaceFirst(',', '');
generatedCSVFile += fileRow + '\n';
}
generatedCSVFile = generatedCSVFile.removeEnd('\n'); //remove the last empty line
return generatedCSVFile;
}
//builds list of attachments for emailing
private List<Messaging.EmailFileAttachment> buildAttachmentList(String csvName, String csvFile){
List<Messaging.EmailFileAttachment> attachmentList = new List<Messaging.EmailFileAttachment>();
if (String.isNotBlank(csvName) && String.isNotBlank(csvFile)){
Messaging.EmailFileAttachment csvAttachment = new Messaging.EmailFileAttachment();
Blob csvBlob = blob.valueOf(csvFile);
csvAttachment.setFileName(csvName);
csvAttachment.setBody(csvBlob);
attachmentList.add(csvAttachment);
}
return attachmentList;
}
//Sends email with all attachments
private void emailCSV(List<Messaging.EmailFileAttachment> csvAttachments){
Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
email.setSubject(subject);
email.setToAddresses(toAddresses);
email.setPlainTextBody(subject);
email.setFileAttachments(csvAttachments);
Messaging.SendEmailResult[] r = Messaging.sendEmail(new Messaging.SingleEmailMessage[]{email});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment