-
-
Save Feldstrom/1c9dd1cfaa3b49fbfb7ae3b44c8b9feb to your computer and use it in GitHub Desktop.
Apex script for pulling field names from specific page layout
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//*** | |
//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