Merge pull request #23587 from civicrm/5.50
[civicrm-core.git] / CRM / Upgrade / Incremental / SmartGroups.php
CommitLineData
7015248a 1<?php
2/*
3 +--------------------------------------------------------------------+
bc77d7c0 4 | Copyright CiviCRM LLC. All rights reserved. |
7015248a 5 | |
bc77d7c0
TO
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 |
7015248a 9 +--------------------------------------------------------------------+
10 */
11
12/**
13 *
14 * @package CRM
ca5cec67 15 * @copyright CiviCRM LLC https://civicrm.org/licensing
7015248a 16 * Class to handled upgrading any saved searches with changed patterns.
17 */
18class CRM_Upgrade_Incremental_SmartGroups {
19
20 /**
ac241c34 21 * Perform updates specified by upgrade function.
7015248a 22 */
ac241c34
CW
23 public function updateGroups($actions) {
24 foreach ($actions as $func => $fields) {
6e7cc0f5
SL
25 if ($func == 'renameField') {
26 foreach ($fields as $fieldConversion) {
27 $this->{$func}($fieldConversion['old'], $fieldConversion['new']);
28 }
29 }
30 else {
31 $this->{$func}($fields);
32 }
ac241c34 33 }
7015248a 34 }
35
36 /**
37 * Convert any
38 * @param array $fields
39 */
40 public function datePickerConversion($fields) {
929d5a15 41 $fieldPossibilities = $relativeFieldNames = [];
30898ee8 42 $relativeDateMappings = [
43 'activity_date_time' => 'activity',
44 'participant_register_date' => 'participant',
6e7cc0f5
SL
45 'receive_date' => 'contribution',
46 'contribution_cancel_date' => 'contribution_cancel',
1915f8d2
SL
47 'membership_join_date' => 'member_join',
48 'membership_start_date' => 'member_start',
49 'membership_end_date' => 'member_end',
50 'pledge_payment_scheduled_date' => 'pledge_payment',
51 'pledge_create_date' => 'pledge_create',
52 'pledge_end_date' => 'pledge_end',
53 'pledge_start_date' => 'pledge_start',
7d832c0c
SL
54 'case_start_date' => 'case_from',
55 'case_end_date' => 'case_to',
0058ef3f 56 'mailing_job_start_date' => 'mailing_date',
0d679de5
SL
57 'relationship_start_date' => 'relation_start',
58 'relationship_end_date' => 'relation_end',
c1436807 59 'event' => 'event',
70e0d21f
SL
60 'created_date' => 'log',
61 'modified_date' => 'log',
30898ee8 62 ];
7015248a 63
64 foreach ($fields as $field) {
b4d67eb2 65 foreach ($this->getSearchesWithField($field) as $savedSearch) {
1915f8d2
SL
66 // Only populate field possibilities as we go to convert each field
67 $fieldPossibilities[] = $field;
68 $fieldPossibilities[] = $field . '_high';
69 $fieldPossibilities[] = $field . '_low';
7015248a 70 $formValues = $savedSearch['form_values'];
929d5a15 71 $isRelative = $hasRelative = FALSE;
72 $relativeFieldName = $field . '_relative';
73
74 if (!empty($relativeDateMappings[$field]) && isset($formValues['relative_dates'])) {
75 if (!empty($formValues['relative_dates'][$relativeDateMappings[$field]])) {
76 $formValues[] = [$relativeFieldName, '=', $savedSearch['form_values']['relative_dates'][$relativeDateMappings[$field]]];
77 unset($formValues['relative_dates'][$relativeDateMappings[$field]]);
78 $isRelative = TRUE;
79 }
80 }
7015248a 81 foreach ($formValues as $index => $formValue) {
c1436807
SL
82 if (!is_array($formValue)) {
83 if ($index === $relativeFieldName) {
84 $hasRelative = TRUE;
85 if (!empty($formValue)) {
86 $isRelative = TRUE;
87 }
88 continue;
89 }
90 elseif ($index === 'event_low' || $index === 'event_high') {
91 if ($isRelative || (!$isRelative && $formValue === '')) {
92 unset($formValues[$index]);
93 }
94 else {
95 $isHigh = substr($index, -5, 5) === '_high';
96 $formValues[$index] = $this->getConvertedDateValue($formValue, $isHigh);
97 }
98 }
99 continue;
100 }
8e80025c 101 if (!isset($formValue[0])) {
102 // Any actual criteria will have this key set but skip any weird lines
103 continue;
104 }
c1436807
SL
105 if ($formValue[0] === $relativeFieldName && !empty($formValue[2])) {
106 $hasRelative = TRUE;
107 }
30898ee8 108 if ($formValue[0] === $relativeFieldName && empty($formValue[2])) {
fe7f4414 109 unset($formValues[$index]);
30898ee8 110 }
111 elseif (in_array($formValue[0], $fieldPossibilities)) {
929d5a15 112 if ($isRelative) {
113 unset($formValues[$index]);
114 }
115 else {
116 $isHigh = substr($formValue[0], -5, 5) === '_high';
117 $formValues[$index][2] = $this->getConvertedDateValue($formValue[2], $isHigh);
118 }
119 }
120 }
121 if (!$isRelative) {
122 if (!in_array($relativeFieldName, $relativeFieldNames)) {
123 $relativeFieldNames[] = $relativeFieldName;
124 $formValues[] = [$relativeFieldName, '=', 0];
7015248a 125 }
c1436807
SL
126 elseif (!$hasRelative) {
127 $formValues[] = [$relativeFieldName, '=', 0];
128 }
7015248a 129 }
130 if ($formValues !== $savedSearch['form_values']) {
131 civicrm_api3('SavedSearch', 'create', ['id' => $savedSearch['id'], 'form_values' => $formValues]);
132 }
133 }
134 }
135 }
136
b4d67eb2 137 /**
138 * Conversion routine for a form change change from = string to IN array.
139 *
140 * For example a checkbox expected [$fieldName, '=', 1]
141 * whereas select expects [$fieldName, 'IN', [1]]
142 *
143 * @param string $field
144 */
145 public function convertEqualsStringToInArray($field) {
146 foreach ($this->getSearchesWithField($field) as $savedSearch) {
147 $formValues = $savedSearch['form_values'];
148 foreach ($formValues as $index => $formValue) {
149 if ($formValue[0] === $field && !is_array($formValue[2]) && $formValue[1] === '=') {
150 $formValues[$index][1] = 'IN';
151 $formValues[$index][2] = [$formValue[2]];
152 }
153 }
154
155 if ($formValues !== $savedSearch['form_values']) {
156 civicrm_api3('SavedSearch', 'create', ['id' => $savedSearch['id'], 'form_values' => $formValues]);
157 }
158 }
159 }
160
7015248a 161 /**
162 * Get converted date value.
163 *
164 * @param string $dateValue
929d5a15 165 * @param bool $isEndOfDay
166 * Is this the upper value in a search range? If so alter the time to
167 * get the end of day if none set.
7015248a 168 *
169 * @return string
170 * $dateValue
171 */
929d5a15 172 protected function getConvertedDateValue($dateValue, $isEndOfDay) {
7015248a 173 if (date('Y-m-d', strtotime($dateValue)) !== $dateValue
174 && date('Y-m-d H:i:s', strtotime($dateValue)) !== $dateValue
175 ) {
176 $dateValue = date('Y-m-d H:i:s', strtotime(CRM_Utils_Date::processDate($dateValue)));
929d5a15 177 if ($isEndOfDay) {
178 $dateValue = str_replace('00:00:00', '23:59:59', $dateValue);
179 }
7015248a 180 }
181 return $dateValue;
182 }
183
7bab3351 184 /**
185 * Rename a smartgroup field.
186 *
187 * @param string $oldName
188 * @param string $newName
189 */
190 public function renameField($oldName, $newName) {
191 foreach ($this->getSearchesWithField($oldName) as $savedSearch) {
192 $formValues = $savedSearch['form_values'];
193 foreach ($formValues as $index => $formValue) {
c1436807
SL
194 if (is_array($formValue)) {
195 if (isset($formValue[0]) && $formValue[0] === $oldName) {
196 $formValues[$index][0] = $newName;
197 }
198 }
199 elseif ($index === $oldName) {
200 $formValues[$newName] = $formValue;
201 unset($formValues[$oldName]);
7bab3351 202 }
203 }
204
205 if ($formValues !== $savedSearch['form_values']) {
206 civicrm_api3('SavedSearch', 'create', ['id' => $savedSearch['id'], 'form_values' => $formValues]);
207 }
208 }
209 }
210
211 /**
212 * Rename pairs of fields
213 *
214 * @param array $pairs
215 * Array or arrays of pairs - e.g
216 * [
217 * ['old' => 'activity_date', 'new' => 'activity_date_time'],
218 * ['old' => 'activity_date_low', 'new' => 'activity_date_time_low'],
219 * ['old' => 'activity_date_high', 'new' => 'activity_date_time_high'],
220 * ['old' => 'activity_date_relative', 'new' => 'activity_date_time_relative'],
221 * ]
222 */
223 public function renameFields($pairs) {
224 foreach ($pairs as $pair) {
225 $this->renameField($pair['old'], $pair['new']);
226 }
227 }
228
b4d67eb2 229 /**
230 * @param $field
231 * @return mixed
232 */
233 protected function getSearchesWithField($field) {
47cef480 234 return civicrm_api3('SavedSearch', 'get', [
b4d67eb2 235 'options' => ['limit' => 0],
236 'form_values' => ['LIKE' => "%{$field}%"],
47cef480 237 'return' => ['id', 'form_values'],
b4d67eb2 238 ])['values'];
b4d67eb2 239 }
240
3a431eaa
SL
241 /**
242 * Convert the log_date saved search date fields to their correct name
243 * default to switching to created_date as that is what the code did originally
244 */
70e0d21f 245 public function renameLogFields() {
3a431eaa 246 $addedDate = TRUE;
70e0d21f
SL
247 foreach ($this->getSearchesWithField('log_date') as $savedSearch) {
248 $formValues = $savedSearch['form_values'];
249 foreach ($formValues as $index => $formValue) {
250 if (isset($formValue[0]) && $formValue[0] === 'log_date') {
3a431eaa 251 if ($formValue[2] == 2) {
70e0d21f
SL
252 $addedDate = FALSE;
253 }
254 }
255 if (isset($formValue[0]) && ($formValue[0] === 'log_date_high' || $formValue[0] === 'log_date_low')) {
256 $isHigh = substr($index, -5, 5) === '_high';
257 if ($addedDate) {
258 $fieldName = 'created_date';
259 }
260 else {
261 $fieldName = 'modified_date';
262 }
263 if ($isHigh) {
264 $fieldName .= '_high';
265 }
266 else {
267 $fieldName .= '_low';
268 }
269 $formValues[$index][0] = $fieldName;
270 }
271 }
272 if ($formValues !== $savedSearch['form_values']) {
273 civicrm_api3('SavedSearch', 'create', ['id' => $savedSearch['id'], 'form_values' => $formValues]);
274 }
275 }
276 }
277
7f054690
SL
278 /**
279 * Convert Custom date fields in smart groups
280 */
281 public function convertCustomSmartGroups() {
282 $custom_date_fields = CRM_Core_DAO::executeQuery("SELECT id FROM civicrm_custom_field WHERE data_type = 'Date' AND is_search_range = 1");
283 while ($custom_date_fields->fetch()) {
284 $savedSearches = $this->getSearchesWithField('custom_' . $custom_date_fields->id);
285 foreach ($savedSearches as $savedSearch) {
286 $form_values = $savedSearch['form_values'];
287 foreach ($form_values as $index => $formValues) {
45586ae8 288 if (isset($formValues[0]) && $formValues[0] === 'custom_' . $custom_date_fields->id && is_array($formValues[2])) {
7f054690
SL
289 if (isset($formValues[2]['BETWEEN'])) {
290 $form_values[] = ['custom_' . $custom_date_fields->id . '_low', '=', $this->getConvertedDateValue($formValues[2]['BETWEEN'][0], FALSE)];
291 $form_values[] = ['custom_' . $custom_date_fields->id . '_high', '=', $this->getConvertedDateValue($formValues[2]['BETWEEN'][1], TRUE)];
ff77d525 292 unset($form_values[$index]);
7f054690
SL
293 }
294 if (isset($formValues[2]['>='])) {
295 $form_values[] = ['custom_' . $custom_date_fields->id . '_low', '=', $this->getConvertedDateValue($formValues[2]['>='], FALSE)];
ff77d525 296 unset($form_values[$index]);
7f054690
SL
297 }
298 if (isset($formValues[2]['<='])) {
299 $form_values[] = ['custom_' . $custom_date_fields->id . '_high', '=', $this->getConvertedDateValue($formValues[2]['<='], TRUE)];
ff77d525 300 unset($form_values[$index]);
7f054690
SL
301 }
302 }
303 }
304 if ($form_values !== $savedSearch['form_values']) {
305 civicrm_api3('SavedSearch', 'create', ['id' => $savedSearch['id'], 'form_values' => $form_values]);
306 }
307 }
308 }
309 }
310
7015248a 311}