Merge pull request #22886 from demeritcowboy/contributionview-notice3
[civicrm-core.git] / CRM / Upgrade / Incremental / php / FiveFortySeven.php
CommitLineData
9ea6ff40
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
12/**
13 * Upgrade logic for the 5.47.x series.
14 *
15 * Each minor version in the series is handled by either a `5.47.x.mysql.tpl` file,
16 * or a function in this class named `upgrade_5_47_x`.
17 * If only a .tpl file exists for a version, it will be run automatically.
18 * If the function exists, it must explicitly add the 'runSql' task if there is a corresponding .mysql.tpl.
19 *
68cc0e2e 20 * This class may also implement `setPreUpgradeMessage()` and `setPostUpgradeMessage()` functions.
9ea6ff40
C
21 */
22class CRM_Upgrade_Incremental_php_FiveFortySeven extends CRM_Upgrade_Incremental_Base {
23
fe8c33a3
EM
24 /**
25 * Compute any messages which should be displayed before upgrade.
26 *
27 * Note: This function is called iteratively for each incremental upgrade step.
28 * There must be a concrete step (eg 'X.Y.Z.mysql.tpl' or 'upgrade_X_Y_Z()').
29 *
30 * @param string $preUpgradeMessage
31 * @param string $rev
32 * a version number, e.g. '4.4.alpha1', '4.4.beta3', '4.4.0'.
33 * @param null $currentVer
34 */
35 public function setPreUpgradeMessage(&$preUpgradeMessage, $rev, $currentVer = NULL): void {
36 if ($rev === '5.47.alpha1') {
37 $count = CRM_Core_DAO::singleValueQuery('SELECT count(*) FROM civicrm_contact WHERE preferred_mail_format != "Both"');
38 if ($count) {
39 $preUpgradeMessage .= '<p>' . ts('The contact field preferred mail format is being phased out. Modern email clients can handle receiving both formats so CiviCRM is moving towards always sending both and the field will be incrementally removed from the UI.')
40 . ' <a href="https://lab.civicrm.org/dev/core/-/issues/2866">' . ts('See the issue for more detail') . '</a></p>';
41 }
79b6ac2b
CW
42 // Check for custom groups with duplicate names
43 $dupes = CRM_Core_DAO::singleValueQuery('SELECT COUNT(g1.id) FROM civicrm_custom_group g1, civicrm_custom_group g2 WHERE g1.name = g2.name AND g1.id > g2.id');
44 if ($dupes) {
45 $preUpgradeMessage .= '<p>' .
46 ts('Your system has custom field groups with duplicate internal names. To ensure data integrity, the internal names will be automatically changed; user-facing titles will not be affected. Please review any custom code you may be using which relies on custom field group names.') .
47 '</p>';
48 }
fe8c33a3
EM
49 }
50 }
51
9ea6ff40
C
52 /**
53 * Upgrade step; adds tasks including 'runSql'.
54 *
55 * @param string $rev
56 * The version number matching this function name
57 */
58 public function upgrade_5_47_alpha1($rev): void {
59 $this->addTask(ts('Upgrade DB to %1: SQL', [1 => $rev]), 'runSql', $rev);
df014828 60 $this->addTask('Migrate CiviGrant component to an extension', 'migrateCiviGrant');
d4a9b736 61 if (CRM_Core_Component::isEnabled('CiviGrant')) {
458e2d8e 62 $this->addExtensionTask('Enable CiviGrant extension', ['civigrant']);
d4a9b736 63 }
a0efcd4d
EM
64 $this->addTask('Add created_date to civicrm_relationship', 'addColumn', 'civicrm_relationship', 'created_date',
65 "timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Relationship created date'"
66 );
67 $this->addTask('Add modified_date column to civicrm_relationship', 'addColumn',
68 'civicrm_relationship', 'modified_date',
69 "timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'Relationship last modified.'"
70 );
71 $this->addTask('Set initial value for relationship created_date and modified_date to start_date', 'updateRelationshipDates');
f61cf6ab
FW
72 $this->addTask('core-issue#2122 - Add timezone column to Events', 'addColumn',
73 'civicrm_event', 'event_tz', "text NULL DEFAULT NULL COMMENT 'Event\'s native time zone'"
74 );
75 $this->addTask('core-issue#2122 - Set the timezone to the default for existing Events', 'setEventTZDefault');
79b6ac2b
CW
76 $this->addTask('Drop CustomGroup UI_name_extends index', 'dropIndex', 'civicrm_custom_group', 'UI_name_extends');
77 $this->addTask('Add CustomGroup UI_name index', 'addIndex', 'civicrm_custom_group', ['name'], 'UI');
448a357e
TO
78 if (CRM_Core_DAO::checkTableExists('civicrm_search_display')) {
79 $this->addTask('Add SearchDisplay.acl_bypass', 'addColumn',
80 'civicrm_search_display', 'acl_bypass',
81 "tinyint DEFAULT 0 COMMENT 'Skip permission checks and ACLs when running this display.'"
82 );
83 }
df014828
CW
84 }
85
86 /**
87 * @param \CRM_Queue_TaskContext $ctx
a0efcd4d
EM
88 *
89 * @return bool
90 */
91 public static function updateRelationshipDates(CRM_Queue_TaskContext $ctx): bool {
92 CRM_Core_DAO::executeQuery('
93 UPDATE civicrm_relationship SET created_date = start_date, modified_date = start_date
94 WHERE start_date IS NOT NULL AND start_date > "1970-01-01"
95 ');
96 return TRUE;
97 }
98
99 /**
100 * @param \CRM_Queue_TaskContext $ctx
101 *
df014828 102 * @return bool
a0efcd4d
EM
103 * @throws \API_Exception
104 * @throws \CRM_Core_Exception
105 * @throws \Civi\API\Exception\NotImplementedException
df014828
CW
106 */
107 public static function migrateCiviGrant(CRM_Queue_TaskContext $ctx): bool {
e46f73c7 108 $civiGrantEnabled = CRM_Core_Component::isEnabled('CiviGrant');
df014828
CW
109 if ($civiGrantEnabled) {
110 CRM_Core_BAO_ConfigSetting::disableComponent('CiviGrant');
111 }
112 $civiGrantId = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_Component', 'CiviGrant', 'id', 'name');
113 if ($civiGrantId) {
114 foreach (['civicrm_menu', 'civicrm_option_value'] as $table) {
115 CRM_Core_DAO::executeQuery("UPDATE $table SET component_id = NULL WHERE component_id = $civiGrantId", [], TRUE, NULL, FALSE, FALSE);
116 }
117 CRM_Core_DAO::executeQuery("DELETE FROM civicrm_component WHERE name = 'CiviGrant'", [], TRUE, NULL, FALSE, FALSE);
118 }
458e2d8e
TO
119
120 // There are existing records which should be managed by `civigrant`. To assign ownership, we need
121 // placeholders in `civicrm_extension` and `civicrm_managed`.
df014828
CW
122 $ext = new CRM_Core_DAO_Extension();
123 $ext->full_name = 'civigrant';
124 if (!$ext->find(TRUE)) {
125 $ext->type = 'module';
126 $ext->name = 'CiviGrant';
127 $ext->label = ts('CiviGrant');
128 $ext->file = 'civigrant';
458e2d8e 129 $ext->is_active = 0; /* Not active _yet_. If site uses CiviGrant, we will re-activate once the core-schema has been revised. */
df014828 130 $ext->save();
458e2d8e 131 CRM_Extension_System::singleton()->getManager()->refresh();
df014828
CW
132
133 $managedItems = [
134 'OptionGroup_advanced_search_options_OptionValue_CiviGrant' => [
135 'entity' => 'OptionValue',
136 'values' => [
137 'option_group_id:name' => 'advanced_search_options',
138 'name' => 'CiviGrant',
139 ],
140 ],
141 'OptionGroup_contact_view_options_OptionValue_CiviGrant' => [
142 'entity' => 'OptionValue',
143 'values' => [
144 'option_group_id:name' => 'contact_view_options',
145 'name' => 'CiviGrant',
146 ],
147 ],
148 'OptionGroup_mapping_type_OptionValue_Export Grant' => [
149 'entity' => 'OptionValue',
150 'values' => [
151 'option_group_id:name' => 'mapping_type',
152 'name' => 'Export Grant',
153 ],
154 ],
155 'OptionGroup_grant_status' => [
156 'entity' => 'OptionGroup',
157 'values' => [
158 'name' => 'grant_status',
159 ],
160 ],
161 'OptionGroup_grant_status_OptionValue_Submitted' => [
162 'entity' => 'OptionValue',
163 'values' => [
164 'option_group_id:name' => 'grant_status',
165 'name' => 'Submitted',
166 ],
167 ],
168 'OptionGroup_grant_status_OptionValue_Eligible' => [
169 'entity' => 'OptionValue',
170 'values' => [
171 'option_group_id:name' => 'grant_status',
172 'name' => 'Eligible',
173 ],
174 ],
175 'OptionGroup_grant_status_OptionValue_Ineligible' => [
176 'entity' => 'OptionValue',
177 'values' => [
178 'option_group_id:name' => 'grant_status',
179 'name' => 'Ineligible',
180 ],
181 ],
182 'OptionGroup_grant_status_OptionValue_Paid' => [
183 'entity' => 'OptionValue',
184 'values' => [
185 'option_group_id:name' => 'grant_status',
186 'name' => 'Paid',
187 ],
188 ],
189 'OptionGroup_grant_status_OptionValue_Awaiting Information' => [
190 'entity' => 'OptionValue',
191 'values' => [
192 'option_group_id:name' => 'grant_status',
193 'name' => 'Awaiting Information',
194 ],
195 ],
196 'OptionGroup_grant_status_OptionValue_Withdrawn' => [
197 'entity' => 'OptionValue',
198 'values' => [
199 'option_group_id:name' => 'grant_status',
200 'name' => 'Withdrawn',
201 ],
202 ],
203 'OptionGroup_grant_status_OptionValue_Approved for Payment' => [
204 'entity' => 'OptionValue',
205 'values' => [
206 'option_group_id:name' => 'grant_status',
207 'name' => 'Approved for Payment',
208 ],
209 ],
210 'OptionGroup_grant_type' => [
211 'entity' => 'OptionGroup',
212 'values' => [
213 'name' => 'grant_type',
214 ],
215 ],
df014828
CW
216 'OptionGroup_report_template_OptionValue_CRM_Report_Form_Grant_Detail' => [
217 'entity' => 'OptionValue',
218 'values' => [
219 'option_group_id:name' => 'report_template',
220 'name' => 'CRM_Report_Form_Grant_Detail',
221 ],
222 ],
223 'OptionGroup_report_template_OptionValue_CRM_Report_Form_Grant_Statistics' => [
224 'entity' => 'OptionValue',
225 'values' => [
226 'option_group_id:name' => 'report_template',
227 'name' => 'CRM_Report_Form_Grant_Statistics',
228 ],
229 ],
230 'Navigation_Grants' => [
231 'entity' => 'Navigation',
232 'values' => [
233 'name' => 'Grants',
234 'domain_id' => 'current_domain',
235 ],
236 ],
237 'Navigation_Grants_Navigation_Dashboard' => [
238 'entity' => 'Navigation',
239 'values' => [
240 'name' => 'Dashboard',
241 'url' => 'civicrm/grant?reset=1',
242 'domain_id' => 'current_domain',
243 ],
244 ],
245 'Navigation_Grants_Navigation_New_Grant' => [
246 'entity' => 'Navigation',
247 'values' => [
248 'name' => 'New Grant',
249 'url' => 'civicrm/grant/add?reset=1&action=add&context=standalone',
250 'domain_id' => 'current_domain',
251 ],
252 ],
253 'Navigation_Grants_Navigation_Find_Grants' => [
254 'entity' => 'Navigation',
255 'values' => [
256 'name' => 'Find Grants',
257 'url' => 'civicrm/grant/search?reset=1',
258 'domain_id' => 'current_domain',
259 ],
260 ],
261 'Navigation_CiviGrant' => [
262 'entity' => 'Navigation',
263 'values' => [
264 'name' => 'CiviGrant',
265 'domain_id' => 'current_domain',
266 ],
267 ],
268 'Navigation_CiviGrant_Navigation_Grant_Types' => [
269 'entity' => 'Navigation',
270 'values' => [
271 'name' => 'Grant Types',
272 'domain_id' => 'current_domain',
273 ],
274 ],
275 'Navigation_CiviGrant_Navigation_Grant_Status' => [
276 'entity' => 'Navigation',
277 'values' => [
278 'name' => 'Grant Status',
279 'domain_id' => 'current_domain',
280 ],
281 ],
df014828
CW
282 ];
283 // Create an entry in civicrm_managed for each existing record that will be managed by the extension
284 foreach ($managedItems as $name => $item) {
285 $params = ['checkPermissions' => FALSE];
286 foreach ($item['values'] as $k => $v) {
287 $params['where'][] = [$k, '=', $v];
288 }
289 $record = civicrm_api4($item['entity'], 'get', $params)->first();
290 if ($record) {
291 $mgd = new CRM_Core_DAO_Managed();
292 $mgd->name = $name;
293 $mgd->module = 'civigrant';
294 $mgd->entity_type = $item['entity'];
295 if (!$mgd->find(TRUE)) {
296 $mgd->entity_id = $record['id'];
297 $mgd->cleanup = 'unused';
298 $mgd->save();
299 }
300 // Disable record if CiviGrant disabled
301 if (!$civiGrantEnabled && !empty($record['is_active'])) {
302 civicrm_api4($item['entity'], 'update', [
303 'checkPermissions' => FALSE,
304 'values' => ['id' => $record['id'], 'is_active' => FALSE],
305 ]);
306 }
307 }
308 }
309 }
310 return TRUE;
9ea6ff40
C
311 }
312
f61cf6ab
FW
313 /**
314 * Set the timezone to the default for existing Events.
315 *
316 * @param \CRM_Queue_TaskContext $ctx
317 * @return bool
318 */
319 public static function setEventTZDefault(CRM_Queue_TaskContext $ctx) {
320 // Set default for CiviCRM Events to user system timezone (most reasonable default);
321 $defaultTZ = CRM_Core_Config::singleton()->userSystem->getTimeZoneString();
322 CRM_Core_DAO::executeQuery('UPDATE `civicrm_event` SET `event_tz` = %1 WHERE `event_tz` IS NULL;', [1 => [$defaultTZ, 'String']]);
323 return TRUE;
324 }
325
9ea6ff40 326}