3 class CRM_Export_Utils
{
6 * This transforms the lists of fields for each contact type & component
7 * into a single unified list suitable for select2.
9 * The return values of CRM_Core_BAO_Mapping::getBasicFields contain a separate field list
10 * for every contact type and sub-type. This is extremely redundant as 90%+ of the fields
11 * in each list are the same. To avoid sending bloated data to the client-side, we turn
12 * it into a single list where fields not shared by every contact type get a contact_type
13 * attribute so they can be filtered appropriately by the selector.
15 * We also sort fields into optgroup categories, and add component fields appropriate to this export.
19 * @throws CiviCRM_API3_Exception
21 public static function getExportFields($exportMode) {
22 $fieldGroups = CRM_Core_BAO_Mapping
::getBasicFields('Export');
25 'contact' => ['text' => ts('Contact Fields'), 'is_contact' => TRUE],
26 'address' => ['text' => ts('Address Fields'), 'is_contact' => TRUE],
27 'communication' => ['text' => ts('Communication Fields'), 'is_contact' => TRUE],
30 'civicrm_website' => 'website_type_id',
31 'civicrm_phone' => 'phone_type_id',
32 'civicrm_im' => 'im_provider_id',
34 // Whitelist of field properties we actually care about; others will be discarded
35 $fieldProps = ['id', 'text', 'has_location', 'option_list', 'relationship_type_id', 'related_contact_type'];
36 $relTypes = civicrm_api3('RelationshipType', 'get', ['options' => ['limit' => 0]])['values'];
38 // Add component fields
40 $compLabels = CRM_Core_BAO_Mapping
::addComponentFields($compFields, 'Export', $exportMode);
41 foreach ($compLabels as $comp => $label) {
42 $categories[$comp] = ['text' => $label];
43 foreach ($compFields[$comp] as $key => $field) {
44 $field['text'] = $field['title'];
46 $categories[$comp]['children'][] = array_intersect_key($field, array_flip($fieldProps));
50 // Unset groups, tags, notes for component export
51 if ($exportMode != CRM_Export_Form_Select
::CONTACT_EXPORT
) {
52 foreach (array_keys($fieldGroups) as $contactType) {
53 CRM_Utils_Array
::remove($fieldGroups[$contactType], 'groups', 'tags', 'notes');
57 // Now combine all those redundant lists of fields into a single list with categories
58 foreach ($fieldGroups as $contactType => $fields) {
59 // 'related' was like a poor-mans optgroup.
60 unset($fields['related']);
61 foreach ($fields as $key => $field) {
63 $field['text'] = $field['title'];
65 $field['has_location'] = !empty($field['hasLocationType']);
66 if (isset($field['table_name']) && isset($optionMap[$field['table_name']])) {
67 $field['option_list'] = $optionMap[$field['table_name']];
68 $group = 'communication';
70 elseif (!empty($field['has_location'])) {
73 if ($key == 'email') {
74 $group = 'communication';
76 if (!empty($field['custom_group_id'])) {
77 $group = $field['custom_group_id'];
78 $categories[$group]['text'] = $field['groupTitle'];
79 $categories[$group]['is_contact'] = TRUE;
81 if (!empty($field['related'])) {
83 $categories[$group]['text'] = ts('Related Contact Info');
84 list($type, , $dir) = explode('_', $key);
85 $field['related_contact_type'] = $relTypes[$type]["contact_sub_type_$dir"] ??
$relTypes[$type]["contact_type_$dir"] ??
'*';
86 // Skip relationship types targeting disabled contacts
87 if ($field['related_contact_type'] != '*' && !isset($fieldGroups[$field['related_contact_type']])) {
91 if (empty($categories[$group]['children'][$key])) {
92 // Discard unwanted field props to save space
93 $categories[$group]['children'][$key] = array_intersect_key($field, array_flip($fieldProps));
95 // Set contact_type, which gets added to on every iteration
96 $categories[$group]['children'][$key]['contact_type'][] = $contactType;
97 // If a field applies to every contact type, remove the contact_type flag as it's redundant
98 if (count($fieldGroups) == count($categories[$group]['children'][$key]['contact_type'])) {
99 unset($categories[$group]['children'][$key]['contact_type']);
103 // We needed meaningful keys while organizing fields but if we send them client-side they'll just be in the way
104 foreach ($categories as &$category) {
105 $category['children'] = array_values($category['children']);
107 return array_values($categories);