Merge pull request #14669 from civicrm/5.15
[civicrm-core.git] / CRM / Upgrade / Incremental / SmartGroups.php
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 and the CiviCRM Licensing Exception. |
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 and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
26 */
27
28 /**
29 *
30 * @package CRM
31 * @copyright CiviCRM LLC (c) 2004-2019
32 *
33 * Class to handled upgrading any saved searches with changed patterns.
34 */
35 class CRM_Upgrade_Incremental_SmartGroups {
36
37 /**
38 * Perform updates specified by upgrade function.
39 */
40 public function updateGroups($actions) {
41 foreach ($actions as $func => $fields) {
42 if ($func == 'renameField') {
43 foreach ($fields as $fieldConversion) {
44 $this->{$func}($fieldConversion['old'], $fieldConversion['new']);
45 }
46 }
47 else {
48 $this->{$func}($fields);
49 }
50 }
51 }
52
53 /**
54 * Convert any
55 * @param array $fields
56 */
57 public function datePickerConversion($fields) {
58 $fieldPossibilities = $relativeFieldNames = [];
59 foreach ($fields as $field) {
60 $fieldPossibilities[] = $field;
61 $fieldPossibilities[] = $field . '_high';
62 $fieldPossibilities[] = $field . '_low';
63 }
64 $relativeDateMappings = [
65 'activity_date_time' => 'activity',
66 'participant_register_date' => 'participant',
67 'receive_date' => 'contribution',
68 'contribution_cancel_date' => 'contribution_cancel',
69 ];
70
71 foreach ($fields as $field) {
72 foreach ($this->getSearchesWithField($field) as $savedSearch) {
73 $formValues = $savedSearch['form_values'];
74 $isRelative = $hasRelative = FALSE;
75 $relativeFieldName = $field . '_relative';
76
77 if (!empty($relativeDateMappings[$field]) && isset($formValues['relative_dates'])) {
78 if (!empty($formValues['relative_dates'][$relativeDateMappings[$field]])) {
79 $formValues[] = [$relativeFieldName, '=', $savedSearch['form_values']['relative_dates'][$relativeDateMappings[$field]]];
80 unset($formValues['relative_dates'][$relativeDateMappings[$field]]);
81 $isRelative = TRUE;
82 }
83 }
84 foreach ($formValues as $index => $formValue) {
85 if (!isset($formValue[0])) {
86 // Any actual criteria will have this key set but skip any weird lines
87 continue;
88 }
89 if ($formValue[0] === $relativeFieldName && empty($formValue[2])) {
90 unset($formValues[$index]);;
91 }
92 elseif (in_array($formValue[0], $fieldPossibilities)) {
93 if ($isRelative) {
94 unset($formValues[$index]);
95 }
96 else {
97 $isHigh = substr($formValue[0], -5, 5) === '_high';
98 $formValues[$index][2] = $this->getConvertedDateValue($formValue[2], $isHigh);
99 }
100 }
101 }
102 if (!$isRelative) {
103 if (!in_array($relativeFieldName, $relativeFieldNames)) {
104 $relativeFieldNames[] = $relativeFieldName;
105 $formValues[] = [$relativeFieldName, '=', 0];
106 }
107 }
108 if ($formValues !== $savedSearch['form_values']) {
109 civicrm_api3('SavedSearch', 'create', ['id' => $savedSearch['id'], 'form_values' => $formValues]);
110 }
111 }
112 }
113 }
114
115 /**
116 * Conversion routine for a form change change from = string to IN array.
117 *
118 * For example a checkbox expected [$fieldName, '=', 1]
119 * whereas select expects [$fieldName, 'IN', [1]]
120 *
121 * @param string $field
122 */
123 public function convertEqualsStringToInArray($field) {
124 foreach ($this->getSearchesWithField($field) as $savedSearch) {
125 $formValues = $savedSearch['form_values'];
126 foreach ($formValues as $index => $formValue) {
127 if ($formValue[0] === $field && !is_array($formValue[2]) && $formValue[1] === '=') {
128 $formValues[$index][1] = 'IN';
129 $formValues[$index][2] = [$formValue[2]];
130 }
131 }
132
133 if ($formValues !== $savedSearch['form_values']) {
134 civicrm_api3('SavedSearch', 'create', ['id' => $savedSearch['id'], 'form_values' => $formValues]);
135 }
136 }
137 }
138
139 /**
140 * Get converted date value.
141 *
142 * @param string $dateValue
143 * @param bool $isEndOfDay
144 * Is this the upper value in a search range? If so alter the time to
145 * get the end of day if none set.
146 *
147 * @return string
148 * $dateValue
149 */
150 protected function getConvertedDateValue($dateValue, $isEndOfDay) {
151 if (date('Y-m-d', strtotime($dateValue)) !== $dateValue
152 && date('Y-m-d H:i:s', strtotime($dateValue)) !== $dateValue
153 ) {
154 $dateValue = date('Y-m-d H:i:s', strtotime(CRM_Utils_Date::processDate($dateValue)));
155 if ($isEndOfDay) {
156 $dateValue = str_replace('00:00:00', '23:59:59', $dateValue);
157 }
158 }
159 return $dateValue;
160 }
161
162 /**
163 * Rename a smartgroup field.
164 *
165 * @param string $oldName
166 * @param string $newName
167 */
168 public function renameField($oldName, $newName) {
169 foreach ($this->getSearchesWithField($oldName) as $savedSearch) {
170 $formValues = $savedSearch['form_values'];
171 foreach ($formValues as $index => $formValue) {
172 if ($formValue[0] === $oldName) {
173 $formValues[$index][0] = $newName;
174 }
175 }
176
177 if ($formValues !== $savedSearch['form_values']) {
178 civicrm_api3('SavedSearch', 'create', ['id' => $savedSearch['id'], 'form_values' => $formValues]);
179 }
180 }
181 }
182
183 /**
184 * Rename pairs of fields
185 *
186 * @param array $pairs
187 * Array or arrays of pairs - e.g
188 * [
189 * ['old' => 'activity_date', 'new' => 'activity_date_time'],
190 * ['old' => 'activity_date_low', 'new' => 'activity_date_time_low'],
191 * ['old' => 'activity_date_high', 'new' => 'activity_date_time_high'],
192 * ['old' => 'activity_date_relative', 'new' => 'activity_date_time_relative'],
193 * ]
194 */
195 public function renameFields($pairs) {
196 foreach ($pairs as $pair) {
197 $this->renameField($pair['old'], $pair['new']);
198 }
199 }
200
201 /**
202 * @param $field
203 * @return mixed
204 */
205 protected function getSearchesWithField($field) {
206 $savedSearches = civicrm_api3('SavedSearch', 'get', [
207 'options' => ['limit' => 0],
208 'form_values' => ['LIKE' => "%{$field}%"],
209 ])['values'];
210 return $savedSearches;
211
212 }
213
214 }