Commit | Line | Data |
---|---|---|
33044927 CW |
1 | <?php |
2 | ||
3 | class CRM_Export_Utils { | |
4 | ||
5 | /** | |
6 | * This transforms the lists of fields for each contact type & component | |
7 | * into a single unified list suitable for select2. | |
8 | * | |
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. | |
14 | * | |
15 | * We also sort fields into optgroup categories, and add component fields appropriate to this export. | |
16 | * | |
17 | * @param $exportMode | |
18 | * @return array | |
19 | * @throws CiviCRM_API3_Exception | |
20 | */ | |
21 | public static function getExportFields($exportMode) { | |
22 | $fieldGroups = CRM_Core_BAO_Mapping::getBasicFields('Export'); | |
23 | ||
24 | $categories = [ | |
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], | |
28 | ]; | |
29 | $optionMap = [ | |
30 | 'civicrm_website' => 'website_type_id', | |
31 | 'civicrm_phone' => 'phone_type_id', | |
32 | 'civicrm_im' => 'im_provider_id', | |
33 | ]; | |
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']; | |
37 | ||
38 | // Add component fields | |
39 | $compFields = []; | |
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']; | |
45 | $field['id'] = $key; | |
46 | $categories[$comp]['children'][] = array_intersect_key($field, array_flip($fieldProps)); | |
47 | } | |
48 | } | |
49 | ||
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'); | |
54 | } | |
55 | } | |
56 | ||
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) { | |
62 | $group = 'contact'; | |
63 | $field['text'] = $field['title']; | |
64 | $field['id'] = $key; | |
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'; | |
69 | } | |
70 | elseif (!empty($field['has_location'])) { | |
71 | $group = 'address'; | |
72 | } | |
73 | if ($key == 'email') { | |
74 | $group = 'communication'; | |
75 | } | |
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; | |
80 | } | |
81 | if (!empty($field['related'])) { | |
82 | $group = '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']])) { | |
88 | continue; | |
89 | } | |
90 | } | |
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)); | |
94 | } | |
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']); | |
100 | } | |
101 | } | |
102 | } | |
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']); | |
106 | } | |
107 | return array_values($categories); | |
108 | } | |
109 | ||
110 | } |