Commit | Line | Data |
---|---|---|
187fc9e9 C |
1 | <?php |
2 | /* | |
3 | +--------------------------------------------------------------------+ | |
4 | | CiviCRM version 5 | | |
5 | +--------------------------------------------------------------------+ | |
6 | | Copyright CiviCRM LLC (c) 2004-2019 | | |
7 | +--------------------------------------------------------------------+ | |
8 | | This file is a part of CiviCRM. | | |
9 | | | | |
10 | | CiviCRM is free software; you can copy, modify, and distribute it | | |
11 | | under the terms of the GNU Affero General Public License | | |
12 | | Version 3, 19 November 2007. | | |
13 | | | | |
14 | | CiviCRM is distributed in the hope that it will be useful, but | | |
15 | | WITHOUT ANY WARRANTY; without even the implied warranty of | | |
16 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | | |
17 | | See the GNU Affero General Public License for more details. | | |
18 | | | | |
19 | | You should have received a copy of the GNU Affero General Public | | |
20 | | License along with this program; if not, contact CiviCRM LLC | | |
21 | | at info[AT]civicrm[DOT]org. If you have questions about the | | |
22 | | GNU Affero General Public License or the licensing of CiviCRM, | | |
23 | | see the CiviCRM license FAQ at http://civicrm.org/licensing | | |
24 | +--------------------------------------------------------------------+ | |
25 | */ | |
26 | ||
27 | /** | |
28 | * Upgrade logic for FiveTwenty */ | |
29 | class CRM_Upgrade_Incremental_php_FiveTwenty extends CRM_Upgrade_Incremental_Base { | |
30 | ||
400db156 D |
31 | /** |
32 | * @var $relationshipTypes array | |
33 | * api call result keyed on relationship_type.id | |
34 | */ | |
35 | protected static $relationshipTypes; | |
36 | ||
187fc9e9 C |
37 | /** |
38 | * Compute any messages which should be displayed beforeupgrade. | |
39 | * | |
40 | * Note: This function is called iteratively for each upcoming | |
41 | * revision to the database. | |
42 | * | |
43 | * @param string $preUpgradeMessage | |
44 | * @param string $rev | |
45 | * a version number, e.g. '4.4.alpha1', '4.4.beta3', '4.4.0'. | |
46 | * @param null $currentVer | |
47 | */ | |
48 | public function setPreUpgradeMessage(&$preUpgradeMessage, $rev, $currentVer = NULL) { | |
49 | // Example: Generate a pre-upgrade message. | |
50 | // if ($rev == '5.12.34') { | |
51 | // $preUpgradeMessage .= '<p>' . ts('A new permission, "%1", has been added. This permission is now used to control access to the Manage Tags screen.', array(1 => ts('manage tags'))) . '</p>'; | |
52 | // } | |
81633334 TO |
53 | if ($rev == '5.20.alpha1') { |
54 | if (CRM_Core_DAO::checkTableExists('civicrm_persistent') && CRM_Core_DAO::checkTableHasData('civicrm_persistent')) { | |
55 | $preUpgradeMessage .= '<br/>' . ts("WARNING: The table \"<code>civicrm_persistent</code>\" is flagged for removal because all official records show it being unused. However, the upgrader has detected data in this copy of \"<code>civicrm_persistent</code>\". Please <a href='%1' target='_blank'>report</a> anything you can about the usage of this table. In the mean-time, the data will be preserved.", [ | |
56 | 1 => 'https://civicrm.org/bug-reporting', | |
57 | ]); | |
58 | } | |
59 | } | |
187fc9e9 C |
60 | } |
61 | ||
62 | /** | |
63 | * Compute any messages which should be displayed after upgrade. | |
64 | * | |
65 | * @param string $postUpgradeMessage | |
66 | * alterable. | |
67 | * @param string $rev | |
68 | * an intermediate version; note that setPostUpgradeMessage is called repeatedly with different $revs. | |
69 | */ | |
70 | public function setPostUpgradeMessage(&$postUpgradeMessage, $rev) { | |
71 | // Example: Generate a post-upgrade message. | |
72 | // if ($rev == '5.12.34') { | |
73 | // $postUpgradeMessage .= '<br /><br />' . ts("By default, CiviCRM now disables the ability to import directly from SQL. To use this feature, you must explicitly grant permission 'import SQL datasource'."); | |
74 | // } | |
75 | } | |
76 | ||
77 | /* | |
78 | * Important! All upgrade functions MUST add a 'runSql' task. | |
79 | * Uncomment and use the following template for a new upgrade version | |
80 | * (change the x in the function name): | |
81 | */ | |
82 | ||
187fc9e9 C |
83 | // public static function taskFoo(CRM_Queue_TaskContext $ctx, ...) { |
84 | // return TRUE; | |
85 | // } | |
86 | ||
6489e3de SL |
87 | /** |
88 | * Upgrade function. | |
89 | * | |
90 | * @param string $rev | |
91 | */ | |
92 | public function upgrade_5_20_alpha1($rev) { | |
93 | $this->addTask('Add frontend title column to contribution page table', 'addColumn', 'civicrm_contribution_page', | |
94 | 'frontend_title', "varchar(255) DEFAULT NULL COMMENT 'Contribution Page Public title'", TRUE, '5.20.alpha1'); | |
dc396835 AS |
95 | $this->addTask('Add is_template field to civicrm_contribution', 'addColumn', 'civicrm_contribution', 'is_template', |
96 | "tinyint(4) DEFAULT '0' COMMENT 'Shows this is a template for recurring contributions.'", FALSE, '5.20.alpha1'); | |
1f34d30a AS |
97 | $this->addTask('Add order_reference field to civicrm_financial_trxn', 'addColumn', 'civicrm_financial_trxn', 'order_reference', |
98 | "varchar(255) COMMENT 'Payment Processor external order reference'", FALSE, '5.20.alpha1'); | |
400db156 D |
99 | $config = CRM_Core_Config::singleton(); |
100 | if (in_array('CiviCase', $config->enableComponents)) { | |
101 | $this->addTask('Change direction of autoassignees in case type xml', 'changeCaseTypeAutoassignee'); | |
102 | } | |
6489e3de | 103 | $this->addTask(ts('Upgrade DB to %1: SQL', [1 => $rev]), 'runSql', $rev); |
f831ac20 | 104 | $this->addTask('Add "Template" contribution status', 'templateStatus'); |
7d832c0c SL |
105 | $this->addTask('Update smart groups to rename filters on case_from and case_to to case_start_date and case_end_date', 'updateSmartGroups', [ |
106 | 'renameField' => [ | |
107 | ['old' => 'case_from_relative', 'new' => 'case_start_date_relative'], | |
108 | ['old' => 'case_from_start_date_high', 'new' => 'case_start_date_high'], | |
109 | ['old' => 'case_from_start_date_low', 'new' => 'case_start_date_low'], | |
110 | ['old' => 'case_to_relative', 'new' => 'case_end_date_relative'], | |
111 | ['old' => 'case_to_end_date_high', 'new' => 'case_end_date_high'], | |
112 | ['old' => 'case_to_end_date_low', 'new' => 'case_end_date_low'], | |
0058ef3f SL |
113 | ['old' => 'mailing_date_relative', 'new' => 'mailing_job_start_date_relative'], |
114 | ['old' => 'mailing_date_high', 'new' => 'mailing_job_start_date_high'], | |
115 | ['old' => 'mailing_date_low', 'new' => 'mailing_job_start_date_low'], | |
41b8dd1d | 116 | ['old' => 'relation_start_date_low', 'new' => 'relationship_start_date_low'], |
117 | ['old' => 'relation_start_date_high', 'new' => 'relationship_start_date_high'], | |
118 | ['old' => 'relation_start_date_relative', 'new' => 'relationship_start_date_relative'], | |
119 | ['old' => 'relation_end_date_low', 'new' => 'relationship_end_date_low'], | |
120 | ['old' => 'relation_end_date_high', 'new' => 'relationship_end_date_high'], | |
121 | ['old' => 'relation_end_date_relative', 'new' => 'relationship_end_date_relative'], | |
c1436807 SL |
122 | ['old' => 'event_start_date_low', 'new' => 'event_low'], |
123 | ['old' => 'event_end_date_high', 'new' => 'event_high'], | |
7d832c0c SL |
124 | ], |
125 | ]); | |
70e0d21f SL |
126 | $this->addTask('Convert Log date searches to their final names either created date or modified date', 'updateSmartGroups', [ |
127 | 'renameLogFields' => [], | |
128 | ]); | |
7d832c0c SL |
129 | $this->addTask('Update smart groups where jcalendar fields have been converted to datepicker', 'updateSmartGroups', [ |
130 | 'datepickerConversion' => [ | |
bca2ad39 | 131 | 'birth_date', |
132 | 'deceased_date', | |
7d832c0c SL |
133 | 'case_start_date', |
134 | 'case_end_date', | |
0058ef3f | 135 | 'mailing_job_start_date', |
41b8dd1d | 136 | 'relationship_start_date', |
137 | 'relationship_end_date', | |
c1436807 SL |
138 | 'event', |
139 | 'relation_active_period_date', | |
70e0d21f SL |
140 | 'created_date', |
141 | 'modified_date', | |
7d832c0c SL |
142 | ], |
143 | ]); | |
81633334 | 144 | $this->addTask('Clean up unused table "civicrm_persistent"', 'dropTableIfEmpty', 'civicrm_persistent'); |
7f054690 SL |
145 | $this->addTask('Convert Custom data based smart groups from jcalendar to datepicker', 'updateSmartGroups', [ |
146 | 'convertCustomSmartGroups' => NULL, | |
147 | ]); | |
f831ac20 EE |
148 | } |
149 | ||
150 | public static function templateStatus(CRM_Queue_TaskContext $ctx) { | |
151 | CRM_Core_BAO_OptionValue::ensureOptionValueExists([ | |
152 | 'option_group_id' => 'contribution_status', | |
153 | 'name' => 'Template', | |
154 | 'label' => ts('Template'), | |
155 | 'is_active' => TRUE, | |
156 | 'component_id' => 'CiviContribute', | |
157 | ]); | |
158 | return TRUE; | |
6489e3de SL |
159 | } |
160 | ||
400db156 D |
161 | /** |
162 | * Change direction of activity autoassignees in case type xml for | |
163 | * bidirectional relationship types if they point the other way. This is | |
164 | * mostly a visual issue on the case type edit screen and doesn't affect | |
165 | * normal operation, but could lead to confusion and a future mixup. | |
166 | * (dev/core#1046) | |
167 | * ONLY for ones using database storage - don't want to "fork" case types | |
168 | * that aren't currently forked. | |
169 | * | |
170 | * Earlier iterations of this used the api and array manipulation | |
171 | * and then another iteration used SimpleXML manipulation, but both | |
172 | * suffered from weirdnesses in how conversion back and forth worked. | |
173 | * | |
174 | * Here we use SQL and a regex. The thing we're changing is pretty | |
175 | * well-defined and unique: | |
176 | * <default_assignee_relationship>N_b_a</default_assignee_relationship> | |
177 | * | |
178 | * @return bool | |
179 | */ | |
180 | public static function changeCaseTypeAutoassignee() { | |
181 | self::$relationshipTypes = civicrm_api3('RelationshipType', 'get', [ | |
182 | 'options' => ['limit' => 0], | |
183 | ])['values']; | |
184 | ||
185 | // Get all case types definitions that are using db storage | |
186 | $dao = CRM_Core_DAO::executeQuery("SELECT id, definition FROM civicrm_case_type WHERE definition IS NOT NULL AND definition <> ''"); | |
187 | while ($dao->fetch()) { | |
188 | self::processCaseTypeAutoassignee($dao->id, $dao->definition); | |
189 | } | |
190 | return TRUE; | |
191 | } | |
192 | ||
193 | /** | |
194 | * Process a single case type | |
195 | * | |
196 | * @param $caseTypeId int | |
197 | * @param $definition string | |
198 | * xml string | |
199 | */ | |
200 | public static function processCaseTypeAutoassignee($caseTypeId, $definition) { | |
201 | $isDirty = FALSE; | |
202 | // find the autoassignees | |
203 | preg_match_all('/<default_assignee_relationship>(.*?)<\/default_assignee_relationship>/', $definition, $matches); | |
204 | // $matches[1][n] has the text inside the xml tag, e.g. 2_a_b | |
205 | foreach ($matches[1] as $index => $match) { | |
206 | if (empty($match)) { | |
207 | continue; | |
208 | } | |
209 | // parse out existing id and direction | |
210 | list($relationshipTypeId, $direction1) = explode('_', $match); | |
211 | // we only care about ones that are b_a | |
212 | if ($direction1 === 'b') { | |
213 | // we only care about bidirectional | |
214 | if (self::isBidirectionalRelationship($relationshipTypeId)) { | |
215 | // flip it to be a_b | |
216 | // $matches[0][n] has the whole match including the xml tag | |
217 | $definition = str_replace($matches[0][$index], "<default_assignee_relationship>{$relationshipTypeId}_a_b</default_assignee_relationship>", $definition); | |
218 | $isDirty = TRUE; | |
219 | } | |
220 | } | |
221 | } | |
222 | ||
223 | if ($isDirty) { | |
224 | $sqlParams = [ | |
225 | 1 => [$definition, 'String'], | |
226 | 2 => [$caseTypeId, 'Integer'], | |
227 | ]; | |
228 | CRM_Core_DAO::executeQuery("UPDATE civicrm_case_type SET definition = %1 WHERE id = %2", $sqlParams); | |
229 | //echo "UPDATE civicrm_case_type SET definition = '" . CRM_Core_DAO::escapeString($sqlParams[1][0]) . "' WHERE id = {$sqlParams[2][0]}\n"; | |
230 | } | |
231 | } | |
232 | ||
233 | /** | |
234 | * Check if this is bidirectional, based on label. In the situation where | |
235 | * we're using this we don't care too much about the edge case where name | |
236 | * might not also be bidirectional. | |
237 | * | |
238 | * @param $relationshipTypeId int | |
239 | * | |
240 | * @return bool | |
241 | */ | |
242 | private static function isBidirectionalRelationship($relationshipTypeId) { | |
243 | if (isset(self::$relationshipTypes[$relationshipTypeId])) { | |
244 | if (self::$relationshipTypes[$relationshipTypeId]['label_a_b'] === self::$relationshipTypes[$relationshipTypeId]['label_b_a']) { | |
245 | return TRUE; | |
246 | } | |
247 | } | |
248 | return FALSE; | |
249 | } | |
250 | ||
187fc9e9 | 251 | } |