Commit | Line | Data |
---|---|---|
6a488035 TO |
1 | <?php |
2 | /* | |
3 | +--------------------------------------------------------------------+ | |
bc77d7c0 | 4 | | Copyright CiviCRM LLC. All rights reserved. | |
6a488035 | 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 | | |
6a488035 | 9 | +--------------------------------------------------------------------+ |
d25dd0ee | 10 | */ |
6a488035 TO |
11 | |
12 | /** | |
13 | * | |
14 | * @package CRM | |
ca5cec67 | 15 | * @copyright CiviCRM LLC https://civicrm.org/licensing |
6a488035 | 16 | */ |
23de8776 | 17 | class CRM_Member_BAO_MembershipStatus extends CRM_Member_DAO_MembershipStatus implements \Civi\Test\HookInterface { |
6a488035 | 18 | |
6a488035 | 19 | /** |
4f940304 | 20 | * Retrieve DB object and copy to defaults array. |
6a488035 | 21 | * |
b2363ea8 | 22 | * @param array $params |
4f940304 | 23 | * Array of criteria values. |
b2363ea8 | 24 | * @param array $defaults |
4f940304 | 25 | * Array to be populated with found values. |
6a488035 | 26 | * |
4f940304 CW |
27 | * @return self|null |
28 | * The DAO object, if found. | |
29 | * | |
30 | * @deprecated | |
6a488035 | 31 | */ |
4f940304 CW |
32 | public static function retrieve($params, &$defaults) { |
33 | return self::commonRetrieve(self::class, $params, $defaults); | |
6a488035 TO |
34 | } |
35 | ||
36 | /** | |
fe482240 | 37 | * Update the is_active flag in the db. |
6a488035 | 38 | * |
b2363ea8 TO |
39 | * @param int $id |
40 | * Id of the database record. | |
41 | * @param bool $is_active | |
42 | * Value we want to set the is_active field. | |
6a488035 | 43 | * |
8a4fede3 | 44 | * @return bool |
45 | * true if we found and updated the object, else false | |
6a488035 | 46 | */ |
00be9182 | 47 | public static function setIsActive($id, $is_active) { |
6a488035 TO |
48 | return CRM_Core_DAO::setFieldValue('CRM_Member_DAO_MembershipStatus', $id, 'is_active', $is_active); |
49 | } | |
50 | ||
51 | /** | |
c07ec0f4 | 52 | * Takes an associative array and creates a membership status object. |
6a488035 | 53 | * |
b2363ea8 | 54 | * @param array $params |
e021e985 | 55 | * Array of name/value pairs. |
d9f93da9 | 56 | * |
e021e985 | 57 | * @throws CRM_Core_Exception |
58 | * @return CRM_Member_DAO_MembershipStatus | |
6a488035 | 59 | */ |
9b873358 | 60 | public static function create($params) { |
e021e985 | 61 | if (empty($params['id'])) { |
6a488035 TO |
62 | //don't allow duplicate names - if id not set |
63 | $status = new CRM_Member_DAO_MembershipStatus(); | |
64 | $status->name = $params['name']; | |
65 | if ($status->find(TRUE)) { | |
e021e985 | 66 | throw new CRM_Core_Exception('A membership status with this name already exists.'); |
6a488035 TO |
67 | } |
68 | } | |
e021e985 | 69 | return self::add($params); |
6a488035 | 70 | } |
353ffa53 | 71 | |
6a488035 | 72 | /** |
c07ec0f4 | 73 | * Add the membership status. |
6a488035 | 74 | * |
b2363ea8 TO |
75 | * @param array $params |
76 | * Reference array contains the values submitted by the form. | |
77 | * @param array $ids | |
78 | * Array contains the id - this param is deprecated. | |
6a488035 | 79 | * |
e021e985 | 80 | * @return CRM_Member_DAO_MembershipStatus |
6a488035 | 81 | */ |
be2fb01f | 82 | public static function add(&$params, $ids = []) { |
e021e985 | 83 | if (!empty($ids)) { |
84 | CRM_Core_Error::deprecatedFunctionWarning('ids is a deprecated parameter'); | |
85 | } | |
8df1a020 | 86 | $id = $params['id'] ?? $ids['membershipStatus'] ?? NULL; |
64d24a64 EM |
87 | if (!$id) { |
88 | CRM_Core_DAO::setCreateDefaults($params, self::getDefaults()); | |
89 | //copy name to label when not passed. | |
90 | if (empty($params['label']) && !empty($params['name'])) { | |
91 | $params['label'] = $params['name']; | |
92 | } | |
93 | ||
94 | if (empty($params['name']) && !empty($params['label'])) { | |
95 | $params['name'] = $params['label']; | |
96 | } | |
97 | } | |
6a488035 TO |
98 | |
99 | // set all other defaults to false. | |
64d24a64 | 100 | if (!empty($params['is_default'])) { |
6a488035 | 101 | $query = "UPDATE civicrm_membership_status SET is_default = 0"; |
e03e1641 | 102 | CRM_Core_DAO::executeQuery($query); |
6a488035 TO |
103 | } |
104 | ||
6a488035 TO |
105 | // action is taken depending upon the mode |
106 | $membershipStatus = new CRM_Member_DAO_MembershipStatus(); | |
107 | $membershipStatus->copyValues($params); | |
108 | ||
64d24a64 | 109 | $membershipStatus->id = $id; |
6a488035 TO |
110 | |
111 | $membershipStatus->save(); | |
9d4d481e | 112 | CRM_Member_PseudoConstant::flush('membershipStatus'); |
6a488035 TO |
113 | return $membershipStatus; |
114 | } | |
115 | ||
64d24a64 | 116 | /** |
fe482240 | 117 | * Get defaults for new entity. |
64d24a64 EM |
118 | * @return array |
119 | */ | |
00be9182 | 120 | public static function getDefaults() { |
be2fb01f | 121 | return [ |
64d24a64 EM |
122 | 'is_active' => FALSE, |
123 | 'is_current_member' => FALSE, | |
124 | 'is_admin' => FALSE, | |
125 | 'is_default' => FALSE, | |
be2fb01f | 126 | ]; |
64d24a64 EM |
127 | } |
128 | ||
6a488035 | 129 | /** |
c07ec0f4 | 130 | * Get membership status. |
6a488035 TO |
131 | * |
132 | * @param int $membershipStatusId | |
d9f93da9 EM |
133 | * |
134 | * @return array | |
6a488035 TO |
135 | */ |
136 | public static function getMembershipStatus($membershipStatusId) { | |
be2fb01f | 137 | $statusDetails = []; |
6a488035 TO |
138 | $membershipStatus = new CRM_Member_DAO_MembershipStatus(); |
139 | $membershipStatus->id = $membershipStatusId; | |
140 | if ($membershipStatus->find(TRUE)) { | |
141 | CRM_Core_DAO::storeValues($membershipStatus, $statusDetails); | |
142 | } | |
143 | return $statusDetails; | |
144 | } | |
145 | ||
146 | /** | |
c07ec0f4 | 147 | * Delete membership status. |
6a488035 TO |
148 | * |
149 | * @param int $membershipStatusId | |
23de8776 | 150 | * @deprecated |
77b97be7 | 151 | * @throws CRM_Core_Exception |
6a488035 | 152 | */ |
00be9182 | 153 | public static function del($membershipStatusId) { |
23de8776 CW |
154 | static::deleteRecord(['id' => $membershipStatusId]); |
155 | } | |
156 | ||
157 | /** | |
158 | * Callback for hook_civicrm_pre(). | |
159 | * @param \Civi\Core\Event\PreEvent $event | |
160 | * @throws CRM_Core_Exception | |
161 | */ | |
162 | public static function self_hook_civicrm_pre(\Civi\Core\Event\PreEvent $event) { | |
163 | if ($event->action === 'delete') { | |
164 | // Check if any membership records are assigned this membership status | |
165 | $dependency = ['Membership']; | |
166 | foreach ($dependency as $name) { | |
167 | $baoString = 'CRM_Member_BAO_' . $name; | |
168 | $dao = new $baoString(); | |
169 | $dao->status_id = $event->id; | |
170 | if ($dao->find(TRUE)) { | |
171 | throw new CRM_Core_Exception(ts('This membership status cannot be deleted. Memberships exist with this status.')); | |
172 | } | |
6a488035 | 173 | } |
23de8776 CW |
174 | CRM_Utils_Weight::delWeight('CRM_Member_DAO_MembershipStatus', $event->id); |
175 | CRM_Member_PseudoConstant::flush('membershipStatus'); | |
6a488035 | 176 | } |
6a488035 TO |
177 | } |
178 | ||
179 | /** | |
100fef9d | 180 | * Find the membership status based on start date, end date, join date & status date. |
6a488035 | 181 | * |
04bc93fa | 182 | * Loop through all the membership status definitions, ordered by their |
183 | * weight. For each, we loop through all possible variations of the given | |
184 | * start, end, and join dates and adjust the starts and ends based on that | |
185 | * membership status's rules, where the last computed set of adjusted start | |
186 | * and end becomes a candidate. Then we compare that candidate to either | |
187 | * "today" or some other given date, and if it falls between the adjusted | |
188 | * start and end we have a match and we stop looping through status | |
189 | * definitions. Then we call a hook in case that wasn't enough loops. | |
190 | * | |
b2363ea8 TO |
191 | * @param string $startDate |
192 | * Start date of the member whose membership status is to be calculated. | |
193 | * @param string $endDate | |
194 | * End date of the member whose membership status is to be calculated. | |
195 | * @param string $joinDate | |
196 | * Join date of the member whose membership status is to be calculated. | |
04bc93fa | 197 | * @param string $statusDate |
198 | * Either the string "today" or a date against which we compare the adjusted start and end based on the status rules. | |
199 | * @param bool $excludeIsAdmin | |
200 | * Exclude the statuses having is_admin = 1. | |
c490a46a | 201 | * @param int $membershipTypeID |
04bc93fa | 202 | * Not used directly but gets passed to the hook. |
b2363ea8 | 203 | * @param array $membership |
04bc93fa | 204 | * Membership params as available to calling function - not used directly but passed to the hook. |
6a488035 | 205 | * |
da6b46f4 | 206 | * @return array |
6a488035 | 207 | */ |
acb1052e | 208 | public static function getMembershipStatusByDate( |
500cfe81 | 209 | $startDate, $endDate, $joinDate, |
2cb64970 | 210 | $statusDate = 'now', $excludeIsAdmin = FALSE, $membershipTypeID = NULL, $membership = [] |
6a488035 | 211 | ) { |
be2fb01f | 212 | $membershipDetails = []; |
5f11bbcc | 213 | |
2cb64970 | 214 | if (!$statusDate || $statusDate === 'today') { |
215 | $statusDate = 'now'; | |
216 | CRM_Core_Error::deprecatedFunctionWarning('pass now rather than today in'); | |
6a488035 TO |
217 | } |
218 | ||
ccd459b8 | 219 | $statusDate = date('Ymd', CRM_Utils_Time::strtotime($statusDate)); |
2cb64970 | 220 | |
6a488035 TO |
221 | //fix for CRM-3570, if we have statuses with is_admin=1, |
222 | //exclude these statuses from calculatation during import. | |
223 | $where = "is_active = 1"; | |
224 | if ($excludeIsAdmin) { | |
225 | $where .= " AND is_admin != 1"; | |
226 | } | |
227 | ||
228 | $query = " | |
229 | SELECT * | |
230 | FROM civicrm_membership_status | |
231 | WHERE {$where} | |
232 | ORDER BY weight ASC"; | |
233 | ||
33621c4f | 234 | $membershipStatus = CRM_Core_DAO::executeQuery($query); |
6a488035 | 235 | |
7438fb00 | 236 | $dates = [ |
ccd459b8 TO |
237 | 'start' => ($startDate && $startDate !== 'null') ? date('Ymd', CRM_Utils_Time::strtotime($startDate)) : '', |
238 | 'end' => ($endDate && $endDate !== 'null') ? date('Ymd', CRM_Utils_Time::strtotime($endDate)) : '', | |
239 | 'join' => ($joinDate && $joinDate !== 'null') ? date('Ymd', CRM_Utils_Time::strtotime($joinDate)) : '', | |
7438fb00 | 240 | ]; |
241 | ||
6a488035 TO |
242 | while ($membershipStatus->fetch()) { |
243 | $startEvent = NULL; | |
244 | $endEvent = NULL; | |
7438fb00 | 245 | foreach (['start', 'end'] as $eve) { |
246 | foreach ($dates as $dat => $date) { | |
6a488035 | 247 | // calculate start-event/date and end-event/date |
7438fb00 | 248 | if (($membershipStatus->{$eve . '_event'} === $dat . '_date') && |
249 | $date | |
6a488035 TO |
250 | ) { |
251 | if ($membershipStatus->{$eve . '_event_adjust_unit'} && | |
252 | $membershipStatus->{$eve . '_event_adjust_interval'} | |
253 | ) { | |
ccd459b8 TO |
254 | $month = date('m', CRM_Utils_Time::strtotime($date)); |
255 | $day = date('d', CRM_Utils_Time::strtotime($date)); | |
256 | $year = date('Y', CRM_Utils_Time::strtotime($date)); | |
6a488035 | 257 | // add in months |
5872a4b7 | 258 | if ($membershipStatus->{$eve . '_event_adjust_unit'} === 'month') { |
259 | ${$eve . 'Event'} = date('Ymd', mktime(0, 0, 0, | |
260 | $month + $membershipStatus->{$eve . '_event_adjust_interval'}, | |
261 | $day, | |
262 | $year | |
b09fe5ed | 263 | )); |
6a488035 TO |
264 | } |
265 | // add in days | |
5872a4b7 | 266 | if ($membershipStatus->{$eve . '_event_adjust_unit'} === 'day') { |
267 | ${$eve . 'Event'} = date('Ymd', mktime(0, 0, 0, | |
268 | $month, | |
269 | $day + $membershipStatus->{$eve . '_event_adjust_interval'}, | |
270 | $year | |
b09fe5ed | 271 | )); |
6a488035 TO |
272 | } |
273 | // add in years | |
5872a4b7 | 274 | if ($membershipStatus->{$eve . '_event_adjust_unit'} === 'year') { |
275 | ${$eve . 'Event'} = date('Ymd', mktime(0, 0, 0, | |
276 | $month, | |
277 | $day, | |
278 | $year + $membershipStatus->{$eve . '_event_adjust_interval'} | |
b09fe5ed | 279 | )); |
6a488035 TO |
280 | } |
281 | // if no interval and unit, present | |
282 | } | |
283 | else { | |
7438fb00 | 284 | ${$eve . 'Event'} = $date; |
6a488035 TO |
285 | } |
286 | } | |
287 | } | |
288 | } | |
289 | ||
290 | // check if statusDate is in the range of start & end events. | |
291 | if ($startEvent && $endEvent) { | |
292 | if (($statusDate >= $startEvent) && ($statusDate <= $endEvent)) { | |
293 | $membershipDetails['id'] = $membershipStatus->id; | |
294 | $membershipDetails['name'] = $membershipStatus->name; | |
295 | } | |
296 | } | |
297 | elseif ($startEvent) { | |
298 | if ($statusDate >= $startEvent) { | |
299 | $membershipDetails['id'] = $membershipStatus->id; | |
300 | $membershipDetails['name'] = $membershipStatus->name; | |
301 | } | |
302 | } | |
303 | elseif ($endEvent) { | |
304 | if ($statusDate <= $endEvent) { | |
305 | $membershipDetails['id'] = $membershipStatus->id; | |
306 | $membershipDetails['name'] = $membershipStatus->name; | |
307 | } | |
308 | } | |
309 | ||
310 | // returns FIRST status record for which status_date is in range. | |
311 | if ($membershipDetails) { | |
5f11bbcc | 312 | break; |
6a488035 TO |
313 | } |
314 | } | |
315 | //end fetch | |
316 | ||
5f11bbcc EM |
317 | //we bundle the arguments into an array as we can't pass 8 variables to the hook otherwise |
318 | // the membership array might contain the pre-altered settings so we don't want to merge this | |
be2fb01f | 319 | $arguments = [ |
5f11bbcc EM |
320 | 'start_date' => $startDate, |
321 | 'end_date' => $endDate, | |
322 | 'join_date' => $joinDate, | |
323 | 'status_date' => $statusDate, | |
324 | 'exclude_is_admin' => $endDate, | |
325 | 'membership_type_id' => $membershipTypeID, | |
326 | 'start_event' => $startEvent, | |
327 | 'end_event' => $endEvent, | |
be2fb01f | 328 | ]; |
5f11bbcc | 329 | CRM_Utils_Hook::alterCalculatedMembershipStatus($membershipDetails, $arguments, $membership); |
6a488035 TO |
330 | return $membershipDetails; |
331 | } | |
332 | ||
333 | /** | |
fe482240 | 334 | * Function that return the status ids whose is_current_member is set. |
6a488035 | 335 | * |
77b97be7 | 336 | * @return array |
6a488035 TO |
337 | */ |
338 | public static function getMembershipStatusCurrent() { | |
be2fb01f | 339 | $statusIds = []; |
6a488035 TO |
340 | $membershipStatus = new CRM_Member_DAO_MembershipStatus(); |
341 | $membershipStatus->is_current_member = 1; | |
342 | $membershipStatus->find(); | |
343 | $membershipStatus->selectAdd(); | |
344 | $membershipStatus->selectAdd('id'); | |
345 | while ($membershipStatus->fetch()) { | |
346 | $statusIds[] = $membershipStatus->id; | |
347 | } | |
6a488035 TO |
348 | return $statusIds; |
349 | } | |
96025800 | 350 | |
6a488035 | 351 | } |