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