Fixes for Activity import
[civicrm-core.git] / CRM / Upgrade / Incremental / php / FiveFiftyOne.php
CommitLineData
99ee6241
C
1<?php
2/*
3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
5 | |
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9 +--------------------------------------------------------------------+
10 */
11
73edfc10
EM
12use Civi\Api4\MappingField;
13
99ee6241
C
14/**
15 * Upgrade logic for the 5.51.x series.
16 *
17 * Each minor version in the series is handled by either a `5.51.x.mysql.tpl` file,
18 * or a function in this class named `upgrade_5_51_x`.
19 * If only a .tpl file exists for a version, it will be run automatically.
20 * If the function exists, it must explicitly add the 'runSql' task if there is a corresponding .mysql.tpl.
21 *
22 * This class may also implement `setPreUpgradeMessage()` and `setPostUpgradeMessage()` functions.
23 */
24class CRM_Upgrade_Incremental_php_FiveFiftyOne extends CRM_Upgrade_Incremental_Base {
25
26 /**
27 * Upgrade step; adds tasks including 'runSql'.
28 *
29 * @param string $rev
30 * The version number matching this function name
31 */
32 public function upgrade_5_51_alpha1($rev): void {
33 $this->addTask(ts('Upgrade DB to %1: SQL', [1 => $rev]), 'runSql', $rev);
73edfc10 34 $this->addTask(ts('Convert import mappings to use names'), 'convertMappingFieldLabelsToNames', $rev);
0ea8ff07
TO
35 $this->addTask('Add column "civicrm_queue.status"', 'addColumn', 'civicrm_queue',
36 'status', "varchar(16) NULL DEFAULT 'active' COMMENT 'Execution status'");
37 $this->addTask('Add column "civicrm_queue.error"', 'addColumn', 'civicrm_queue',
38 'error', "varchar(16) NULL COMMENT 'Fallback behavior for unhandled errors'");
52374db3
TO
39 $this->addTask('Backfill "civicrm_queue.status" and "civicrm_queue.error")', 'fillQueueColumns');
40 }
41
42 public static function fillQueueColumns($ctx): bool {
43 // Generally, anything we do here is nonsensical because there shouldn't be much real world data,
44 // and the goal is to require something specific going forward (for anything that has an automatic runner).
45 // But this ensures that satisfy the invariant.
46 //
47 // What default value of "error" should apply to pre-existing queues (if they somehow exist)?
48 // Go back to our heuristic "short-term/finite queue <=> abort" vs "long-term/infinite queue <=> log".
49 // We don't have adequate data to differentiate these, so some will be wrong/suboptimal.
50 // What's the impact of getting it wrong?
51 // - For a finite/short-term queue, work has finished already (or will finish soon), so there is
57fe3ccf 52 // very limited impact to wrongly setting `error=delete`.
52374db3
TO
53 // - For an infinite/long-term queue, work will continue indefinitely into the future. The impact
54 // of wrongly setting `error=abort` would continue indefinitely to the future.
55 // Therefore, backfilling `error=log` is less-problematic than backfilling `error=abort`.
56 CRM_Core_DAO::executeQuery('UPDATE civicrm_queue SET error = "delete" WHERE runner IS NOT NULL AND error IS NULL');
57 CRM_Core_DAO::executeQuery('UPDATE civicrm_queue SET status = IF(runner IS NULL, NULL, "active")');
58 return TRUE;
73edfc10
EM
59 }
60
61 /**
62 * Convert saved mapping fields for contribution imports to use name rather than
63 * label.
64 *
65 * Currently the 'name' column in civicrm_mapping_field holds names like
66 * 'First Name' or, more tragically 'Contact ID (match to contact)'.
67 *
68 * This updates them to hold the name - eg. 'total_amount'.
69 *
70 * @return bool
71 * @throws \API_Exception
72 */
73 public static function convertMappingFieldLabelsToNames(): bool {
638a0140 74 // Contribution fields....
73edfc10
EM
75 $mappings = MappingField::get(FALSE)
76 ->setSelect(['id', 'name'])
77 ->addWhere('mapping_id.mapping_type_id:name', '=', 'Import Contribution')
78 ->execute();
79 $fields = CRM_Contribute_BAO_Contribution::importableFields('All', FALSE);
80 $fieldMap = [];
81 foreach ($fields as $fieldName => $field) {
82 $fieldMap[$field['title']] = $fieldName;
638a0140
EM
83 if (!empty($field['html']['label'])) {
84 $fieldMap[$field['html']['label']] = $fieldName;
85 }
73edfc10
EM
86 }
87 $fieldMap[ts('Soft Credit')] = 'soft_credit';
88 $fieldMap[ts('Pledge Payment')] = 'pledge_payment';
89 $fieldMap[ts(ts('Pledge ID'))] = 'pledge_id';
cbc11a37
EM
90 $fieldMap[ts(ts('Financial Type'))] = 'financial_type_id';
91 $fieldMap[ts(ts('Payment Method'))] = 'payment_instrument_id';
638a0140 92 $fieldMap[ts('- do not import -')] = 'do_not_import';
73edfc10 93
209cedd9 94 // Membership fields
73edfc10
EM
95 foreach ($mappings as $mapping) {
96 if (!empty($fieldMap[$mapping['name']])) {
97 MappingField::update(FALSE)
98 ->addWhere('id', '=', $mapping['id'])
99 ->addValue('name', $fieldMap[$mapping['name']])
100 ->execute();
101 }
102 }
209cedd9
EM
103
104 // Membership fields...
105 // Yes - I know they could be combined - but it's also less confusing this way.
106 $mappings = MappingField::get(FALSE)
107 ->setSelect(['id', 'name'])
108 ->addWhere('mapping_id.mapping_type_id:name', '=', 'Import Membership')
109 ->execute();
110 $fields = CRM_Member_BAO_Membership::importableFields('All', FALSE);;
111 $fieldMap = [];
112 foreach ($fields as $fieldName => $field) {
113 $fieldMap[$field['title']] = $fieldName;
114 if (!empty($field['html']['label'])) {
115 $fieldMap[$field['html']['label']] = $fieldName;
116 }
117 }
118 $fieldMap[ts('- do not import -')] = 'do_not_import';
119
120 foreach ($mappings as $mapping) {
121 if (!empty($fieldMap[$mapping['name']])) {
122 MappingField::update(FALSE)
123 ->addWhere('id', '=', $mapping['id'])
124 ->addValue('name', $fieldMap[$mapping['name']])
125 ->execute();
126 }
127 }
128
99308da4
EM
129 // Participant fields...
130 // Yes - I know they could be combined - but it's also less confusing this way.
131 $mappings = MappingField::get(FALSE)
132 ->setSelect(['id', 'name'])
133 ->addWhere('mapping_id.mapping_type_id:name', '=', 'Import Participant')
134 ->execute();
135
136 $fields = CRM_Event_BAO_Participant::importableFields('All', FALSE);
137 $fields['event_id']['title'] = 'Event ID';
138 $eventfields = CRM_Event_BAO_Event::fields();
139 $fields['event_title'] = $eventfields['event_title'];
140
141 $fieldMap = [];
142 foreach ($fields as $fieldName => $field) {
143 $fieldMap[$field['title']] = $fieldName;
144 if (!empty($field['html']['label'])) {
145 $fieldMap[$field['html']['label']] = $fieldName;
146 }
147 }
148 $fieldMap[ts('- do not import -')] = 'do_not_import';
149 $fieldMap[ts('Participant Status')] = 'participant_status_id';
150 $fieldMap[ts('Participant Role')] = 'participant_role_id';
151 $fieldMap[ts('Event Title')] = 'event_id';
152
153 foreach ($mappings as $mapping) {
154 if (!empty($fieldMap[$mapping['name']])) {
155 MappingField::update(FALSE)
156 ->addWhere('id', '=', $mapping['id'])
157 ->addValue('name', $fieldMap[$mapping['name']])
158 ->execute();
159 }
160 }
161
7eebbdaa
EM
162 // Activity fields...
163 // Yes - I know they could be combined - but it's also less confusing this way.
164 $mappings = MappingField::get(FALSE)
165 ->setSelect(['id', 'name'])
166 ->addWhere('mapping_id.mapping_type_id:name', '=', 'Import Activity')
167 ->execute();
168
169 $activityContact = CRM_Activity_BAO_ActivityContact::import();
170 $activityTarget['target_contact_id'] = $activityContact['contact_id'];
171 $fields = array_merge(CRM_Activity_BAO_Activity::importableFields(),
172 $activityTarget
173 );
174
175 $fields = array_merge($fields, [
176 'source_contact_id' => [
177 'title' => ts('Source Contact'),
178 'headerPattern' => '/Source.Contact?/i',
179 ],
180 ]);
181
182 $fieldMap = [];
183 foreach ($fields as $fieldName => $field) {
184 $fieldMap[$field['title']] = $fieldName;
185 if (!empty($field['html']['label'])) {
186 $fieldMap[$field['html']['label']] = $fieldName;
187 }
188 }
189 $fieldMap[ts('- do not import -')] = 'do_not_import';
190 $fieldMap[ts('Activity Type Label')] = 'activity_type_id';
191
192 foreach ($mappings as $mapping) {
193 if (!empty($fieldMap[$mapping['name']])) {
194 MappingField::update(FALSE)
195 ->addWhere('id', '=', $mapping['id'])
196 ->addValue('name', $fieldMap[$mapping['name']])
197 ->execute();
198 }
199 }
200
73edfc10 201 return TRUE;
99ee6241
C
202 }
203
204}