3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
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 +--------------------------------------------------------------------+
15 * @copyright CiviCRM LLC https://civicrm.org/licensing
16 * Class to handled upgrading any saved searches with changed patterns.
18 class CRM_Upgrade_Incremental_SmartGroups
{
21 * Perform updates specified by upgrade function.
23 public function updateGroups($actions) {
24 foreach ($actions as $func => $fields) {
25 if ($func == 'renameField') {
26 foreach ($fields as $fieldConversion) {
27 $this->{$func}($fieldConversion['old'], $fieldConversion['new']);
31 $this->{$func}($fields);
38 * @param array $fields
40 public function datePickerConversion($fields) {
41 $fieldPossibilities = $relativeFieldNames = [];
42 $relativeDateMappings = [
43 'activity_date_time' => 'activity',
44 'participant_register_date' => 'participant',
45 'receive_date' => 'contribution',
46 'contribution_cancel_date' => 'contribution_cancel',
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',
54 'case_start_date' => 'case_from',
55 'case_end_date' => 'case_to',
56 'mailing_job_start_date' => 'mailing_date',
57 'relationship_start_date' => 'relation_start',
58 'relationship_end_date' => 'relation_end',
60 'created_date' => 'log',
61 'modified_date' => 'log',
64 foreach ($fields as $field) {
65 foreach ($this->getSearchesWithField($field) as $savedSearch) {
66 // Only populate field possibilities as we go to convert each field
67 $fieldPossibilities[] = $field;
68 $fieldPossibilities[] = $field . '_high';
69 $fieldPossibilities[] = $field . '_low';
70 $formValues = $savedSearch['form_values'];
71 $isRelative = $hasRelative = FALSE;
72 $relativeFieldName = $field . '_relative';
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]]);
81 foreach ($formValues as $index => $formValue) {
82 if (!is_array($formValue)) {
83 if ($index === $relativeFieldName) {
85 if (!empty($formValue)) {
90 elseif ($index === 'event_low' ||
$index === 'event_high') {
91 if ($isRelative ||
(!$isRelative && $formValue === '')) {
92 unset($formValues[$index]);
95 $isHigh = substr($index, -5, 5) === '_high';
96 $formValues[$index] = $this->getConvertedDateValue($formValue, $isHigh);
101 if (!isset($formValue[0])) {
102 // Any actual criteria will have this key set but skip any weird lines
105 if ($formValue[0] === $relativeFieldName && !empty($formValue[2])) {
108 if ($formValue[0] === $relativeFieldName && empty($formValue[2])) {
109 unset($formValues[$index]);
111 elseif (in_array($formValue[0], $fieldPossibilities)) {
113 unset($formValues[$index]);
116 $isHigh = substr($formValue[0], -5, 5) === '_high';
117 $formValues[$index][2] = $this->getConvertedDateValue($formValue[2], $isHigh);
122 if (!in_array($relativeFieldName, $relativeFieldNames)) {
123 $relativeFieldNames[] = $relativeFieldName;
124 $formValues[] = [$relativeFieldName, '=', 0];
126 elseif (!$hasRelative) {
127 $formValues[] = [$relativeFieldName, '=', 0];
130 if ($formValues !== $savedSearch['form_values']) {
131 civicrm_api3('SavedSearch', 'create', ['id' => $savedSearch['id'], 'form_values' => $formValues]);
138 * Conversion routine for a form change change from = string to IN array.
140 * For example a checkbox expected [$fieldName, '=', 1]
141 * whereas select expects [$fieldName, 'IN', [1]]
143 * @param string $field
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]];
155 if ($formValues !== $savedSearch['form_values']) {
156 civicrm_api3('SavedSearch', 'create', ['id' => $savedSearch['id'], 'form_values' => $formValues]);
162 * Get converted date value.
164 * @param string $dateValue
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.
172 protected function getConvertedDateValue($dateValue, $isEndOfDay) {
173 if (date('Y-m-d', strtotime($dateValue)) !== $dateValue
174 && date('Y-m-d H:i:s', strtotime($dateValue)) !== $dateValue
176 $dateValue = date('Y-m-d H:i:s', strtotime(CRM_Utils_Date
::processDate($dateValue)));
178 $dateValue = str_replace('00:00:00', '23:59:59', $dateValue);
185 * Rename a smartgroup field.
187 * @param string $oldName
188 * @param string $newName
190 public function renameField($oldName, $newName) {
191 foreach ($this->getSearchesWithField($oldName) as $savedSearch) {
192 $formValues = $savedSearch['form_values'];
193 foreach ($formValues as $index => $formValue) {
194 if (is_array($formValue)) {
195 if (isset($formValue[0]) && $formValue[0] === $oldName) {
196 $formValues[$index][0] = $newName;
199 elseif ($index === $oldName) {
200 $formValues[$newName] = $formValue;
201 unset($formValues[$oldName]);
205 if ($formValues !== $savedSearch['form_values']) {
206 civicrm_api3('SavedSearch', 'create', ['id' => $savedSearch['id'], 'form_values' => $formValues]);
212 * Rename pairs of fields
214 * @param array $pairs
215 * Array or arrays of pairs - e.g
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'],
223 public function renameFields($pairs) {
224 foreach ($pairs as $pair) {
225 $this->renameField($pair['old'], $pair['new']);
233 protected function getSearchesWithField($field) {
234 return civicrm_api3('SavedSearch', 'get', [
235 'options' => ['limit' => 0],
236 'form_values' => ['LIKE' => "%{$field}%"],
237 'return' => ['id', 'form_values'],
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
245 public function renameLogFields() {
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') {
251 if ($formValue[2] == 2) {
255 if (isset($formValue[0]) && ($formValue[0] === 'log_date_high' ||
$formValue[0] === 'log_date_low')) {
256 $isHigh = substr($index, -5, 5) === '_high';
258 $fieldName = 'created_date';
261 $fieldName = 'modified_date';
264 $fieldName .= '_high';
267 $fieldName .= '_low';
269 $formValues[$index][0] = $fieldName;
272 if ($formValues !== $savedSearch['form_values']) {
273 civicrm_api3('SavedSearch', 'create', ['id' => $savedSearch['id'], 'form_values' => $formValues]);
279 * Convert Custom date fields in smart groups
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) {
288 if (isset($formValues[0]) && $formValues[0] === 'custom_' . $custom_date_fields->id
&& is_array($formValues[2])) {
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)];
292 unset($form_values[$index]);
294 if (isset($formValues[2]['>='])) {
295 $form_values[] = ['custom_' . $custom_date_fields->id
. '_low', '=', $this->getConvertedDateValue($formValues[2]['>='], FALSE)];
296 unset($form_values[$index]);
298 if (isset($formValues[2]['<='])) {
299 $form_values[] = ['custom_' . $custom_date_fields->id
. '_high', '=', $this->getConvertedDateValue($formValues[2]['<='], TRUE)];
300 unset($form_values[$index]);
304 if ($form_values !== $savedSearch['form_values']) {
305 civicrm_api3('SavedSearch', 'create', ['id' => $savedSearch['id'], 'form_values' => $form_values]);