Merge pull request #15796 from seamuslee001/dev_core_183_requirements
[civicrm-core.git] / CRM / Member / BAO / MembershipStatus.php
CommitLineData
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
TO
16 * $Id$
17 *
18 */
19class CRM_Member_BAO_MembershipStatus extends CRM_Member_DAO_MembershipStatus {
20
21 /**
fe482240 22 * Static holder for the default LT.
971e129b 23 * @var int
6a488035 24 */
971e129b 25 public static $_defaultMembershipStatus = NULL;
6a488035
TO
26
27 /**
fe482240 28 * Class constructor.
6a488035 29 */
00be9182 30 public function __construct() {
6a488035
TO
31 parent::__construct();
32 }
33
34 /**
fe482240 35 * Fetch object based on array of properties.
6a488035 36 *
b2363ea8
TO
37 * @param array $params
38 * (reference ) an assoc array of name/value pairs.
39 * @param array $defaults
40 * (reference ) an assoc array to hold the flattened values.
6a488035 41 *
16b10e64 42 * @return CRM_Member_BAO_MembershipStatus
6a488035 43 */
00be9182 44 public static function retrieve(&$params, &$defaults) {
6a488035
TO
45 $membershipStatus = new CRM_Member_DAO_MembershipStatus();
46 $membershipStatus->copyValues($params);
47 if ($membershipStatus->find(TRUE)) {
48 CRM_Core_DAO::storeValues($membershipStatus, $defaults);
49 return $membershipStatus;
50 }
51 return NULL;
52 }
53
54 /**
fe482240 55 * Update the is_active flag in the db.
6a488035 56 *
b2363ea8
TO
57 * @param int $id
58 * Id of the database record.
59 * @param bool $is_active
60 * Value we want to set the is_active field.
6a488035 61 *
8a4fede3 62 * @return bool
63 * true if we found and updated the object, else false
6a488035 64 */
00be9182 65 public static function setIsActive($id, $is_active) {
6a488035
TO
66 return CRM_Core_DAO::setFieldValue('CRM_Member_DAO_MembershipStatus', $id, 'is_active', $is_active);
67 }
68
69 /**
fe482240 70 * Takes an associative array and creates a membership Status object.
6a488035 71 * See http://wiki.civicrm.org/confluence/display/CRM/Database+layer
6a488035 72 *
b2363ea8
TO
73 * @param array $params
74 * (reference ) an assoc array of name/value pairs.
d9f93da9
EM
75 *
76 * @throws Exception
16b10e64 77 * @return CRM_Member_BAO_MembershipStatus
6a488035 78 */
9b873358 79 public static function create($params) {
be2fb01f 80 $ids = [];
9b873358 81 if (!empty($params['id'])) {
353ffa53 82 $ids['membershipStatus'] = $params['id'];
6a488035 83 }
92e4c2a5 84 else {
6a488035
TO
85 //don't allow duplicate names - if id not set
86 $status = new CRM_Member_DAO_MembershipStatus();
87 $status->name = $params['name'];
88 if ($status->find(TRUE)) {
89 throw new Exception('A membership status with this name already exists.');
90 }
91 }
92 $membershipStatusBAO = CRM_Member_BAO_MembershipStatus::add($params, $ids);
93 return $membershipStatusBAO;
94 }
353ffa53 95
6a488035 96 /**
fe482240 97 * Add the membership types.
6a488035 98 *
b2363ea8
TO
99 * @param array $params
100 * Reference array contains the values submitted by the form.
101 * @param array $ids
102 * Array contains the id - this param is deprecated.
6a488035 103 *
6a488035
TO
104 *
105 * @return object
106 */
be2fb01f 107 public static function add(&$params, $ids = []) {
8df1a020 108 $id = $params['id'] ?? $ids['membershipStatus'] ?? NULL;
64d24a64
EM
109 if (!$id) {
110 CRM_Core_DAO::setCreateDefaults($params, self::getDefaults());
111 //copy name to label when not passed.
112 if (empty($params['label']) && !empty($params['name'])) {
113 $params['label'] = $params['name'];
114 }
115
116 if (empty($params['name']) && !empty($params['label'])) {
117 $params['name'] = $params['label'];
118 }
119 }
6a488035
TO
120
121 // set all other defaults to false.
64d24a64 122 if (!empty($params['is_default'])) {
6a488035 123 $query = "UPDATE civicrm_membership_status SET is_default = 0";
e03e1641 124 CRM_Core_DAO::executeQuery($query);
6a488035
TO
125 }
126
6a488035
TO
127 // action is taken depending upon the mode
128 $membershipStatus = new CRM_Member_DAO_MembershipStatus();
129 $membershipStatus->copyValues($params);
130
64d24a64 131 $membershipStatus->id = $id;
6a488035
TO
132
133 $membershipStatus->save();
9d4d481e 134 CRM_Member_PseudoConstant::flush('membershipStatus');
6a488035
TO
135 return $membershipStatus;
136 }
137
64d24a64 138 /**
fe482240 139 * Get defaults for new entity.
64d24a64
EM
140 * @return array
141 */
00be9182 142 public static function getDefaults() {
be2fb01f 143 return [
64d24a64
EM
144 'is_active' => FALSE,
145 'is_current_member' => FALSE,
146 'is_admin' => FALSE,
147 'is_default' => FALSE,
be2fb01f 148 ];
64d24a64
EM
149 }
150
6a488035 151 /**
fe482240 152 * Get membership status.
6a488035
TO
153 *
154 * @param int $membershipStatusId
d9f93da9
EM
155 *
156 * @return array
6a488035
TO
157 */
158 public static function getMembershipStatus($membershipStatusId) {
be2fb01f 159 $statusDetails = [];
6a488035
TO
160 $membershipStatus = new CRM_Member_DAO_MembershipStatus();
161 $membershipStatus->id = $membershipStatusId;
162 if ($membershipStatus->find(TRUE)) {
163 CRM_Core_DAO::storeValues($membershipStatus, $statusDetails);
164 }
165 return $statusDetails;
166 }
167
168 /**
fe482240 169 * Delete membership Types.
6a488035
TO
170 *
171 * @param int $membershipStatusId
77b97be7
EM
172 *
173 * @throws CRM_Core_Exception
6a488035 174 */
00be9182 175 public static function del($membershipStatusId) {
6a488035
TO
176 //check dependencies
177 //checking if membership status is present in some other table
178 $check = FALSE;
179
be2fb01f 180 $dependency = ['Membership', 'MembershipLog'];
b44e3f84 181 foreach ($dependency as $name) {
4d5c2eb5 182 $baoString = 'CRM_Member_BAO_' . $name;
183 $dao = new $baoString();
6a488035
TO
184 $dao->status_id = $membershipStatusId;
185 if ($dao->find(TRUE)) {
dcc4f6a7 186 throw new CRM_Core_Exception(ts('This membership status cannot be deleted as memberships exist with this status'));
6a488035
TO
187 }
188 }
dcc4f6a7 189 CRM_Utils_Weight::delWeight('CRM_Member_DAO_MembershipStatus', $membershipStatusId);
6a488035
TO
190 //delete from membership Type table
191 $membershipStatus = new CRM_Member_DAO_MembershipStatus();
192 $membershipStatus->id = $membershipStatusId;
a60c0bc8
SL
193 if (!$membershipStatus->find()) {
194 throw new CRM_Core_Exception(ts('Cannot delete membership status ' . $membershipStatusId));
195 }
6a488035 196 $membershipStatus->delete();
9d4d481e 197 CRM_Member_PseudoConstant::flush('membershipStatus');
6a488035
TO
198 }
199
200 /**
100fef9d 201 * Find the membership status based on start date, end date, join date & status date.
6a488035 202 *
b2363ea8
TO
203 * @param string $startDate
204 * Start date of the member whose membership status is to be calculated.
205 * @param string $endDate
206 * End date of the member whose membership status is to be calculated.
207 * @param string $joinDate
208 * Join date of the member whose membership status is to be calculated.
da6b46f4 209 * @param \date|string $statusDate status date of the member whose membership status is to be calculated.
acb1052e 210 * @param bool $excludeIsAdmin the statuses those having is_admin = 1.
b2363ea8 211 * Exclude the statuses those having is_admin = 1.
c490a46a 212 * @param int $membershipTypeID
b2363ea8
TO
213 * @param array $membership
214 * Membership params as available to calling function - passed to the hook.
6a488035 215 *
da6b46f4 216 * @return array
6a488035 217 */
acb1052e 218 public static function getMembershipStatusByDate(
500cfe81 219 $startDate, $endDate, $joinDate,
be2fb01f 220 $statusDate = 'today', $excludeIsAdmin = FALSE, $membershipTypeID, $membership = []
6a488035 221 ) {
be2fb01f 222 $membershipDetails = [];
5f11bbcc 223
6a488035 224 if (!$statusDate || $statusDate == 'today') {
b09fe5ed 225 $statusDate = getdate();
6a488035
TO
226 $statusDate = date('Ymd',
227 mktime($statusDate['hours'],
228 $statusDate['minutes'],
229 $statusDate['seconds'],
230 $statusDate['mon'],
231 $statusDate['mday'],
232 $statusDate['year']
233 )
234 );
235 }
236 else {
237 $statusDate = CRM_Utils_Date::customFormat($statusDate, '%Y%m%d');
238 }
239
be2fb01f
CW
240 $dates = ['start', 'end', 'join'];
241 $events = ['start', 'end'];
6a488035
TO
242
243 foreach ($dates as $dat) {
a0713e70 244 if (${$dat . 'Date'} && ${$dat . 'Date'} != "null") {
245 ${$dat . 'Date'} = CRM_Utils_Date::customFormat(${$dat . 'Date'}, '%Y%m%d');
246
6a488035
TO
247 ${$dat . 'Year'} = substr(${$dat . 'Date'}, 0, 4);
248
249 ${$dat . 'Month'} = substr(${$dat . 'Date'}, 4, 2);
250
251 ${$dat . 'Day'} = substr(${$dat . 'Date'}, 6, 2);
252 }
a0713e70 253 else {
254 ${$dat . 'Date'} = '';
255 }
6a488035
TO
256 }
257
258 //fix for CRM-3570, if we have statuses with is_admin=1,
259 //exclude these statuses from calculatation during import.
260 $where = "is_active = 1";
261 if ($excludeIsAdmin) {
262 $where .= " AND is_admin != 1";
263 }
264
265 $query = "
266 SELECT *
267 FROM civicrm_membership_status
268 WHERE {$where}
269 ORDER BY weight ASC";
270
33621c4f 271 $membershipStatus = CRM_Core_DAO::executeQuery($query);
6a488035
TO
272 $hour = $minute = $second = 0;
273
274 while ($membershipStatus->fetch()) {
275 $startEvent = NULL;
276 $endEvent = NULL;
277 foreach ($events as $eve) {
278 foreach ($dates as $dat) {
279 // calculate start-event/date and end-event/date
280 if (($membershipStatus->{$eve . '_event'} == $dat . '_date') &&
281 ${$dat . 'Date'}
282 ) {
283 if ($membershipStatus->{$eve . '_event_adjust_unit'} &&
284 $membershipStatus->{$eve . '_event_adjust_interval'}
285 ) {
286 // add in months
287 if ($membershipStatus->{$eve . '_event_adjust_unit'} == 'month') {
288 ${$eve . 'Event'} = date('Ymd', mktime($hour, $minute, $second,
353ffa53
TO
289 ${$dat . 'Month'} + $membershipStatus->{$eve . '_event_adjust_interval'},
290 ${$dat . 'Day'},
291 ${$dat . 'Year'}
b09fe5ed 292 ));
6a488035
TO
293 }
294 // add in days
295 if ($membershipStatus->{$eve . '_event_adjust_unit'} == 'day') {
296 ${$eve . 'Event'} = date('Ymd', mktime($hour, $minute, $second,
353ffa53
TO
297 ${$dat . 'Month'},
298 ${$dat . 'Day'} + $membershipStatus->{$eve . '_event_adjust_interval'},
299 ${$dat . 'Year'}
b09fe5ed 300 ));
6a488035
TO
301 }
302 // add in years
303 if ($membershipStatus->{$eve . '_event_adjust_unit'} == 'year') {
304 ${$eve . 'Event'} = date('Ymd', mktime($hour, $minute, $second,
353ffa53
TO
305 ${$dat . 'Month'},
306 ${$dat . 'Day'},
307 ${$dat . 'Year'} + $membershipStatus->{$eve . '_event_adjust_interval'}
b09fe5ed 308 ));
6a488035
TO
309 }
310 // if no interval and unit, present
311 }
312 else {
313 ${$eve . 'Event'} = ${$dat . 'Date'};
314 }
315 }
316 }
317 }
318
319 // check if statusDate is in the range of start & end events.
320 if ($startEvent && $endEvent) {
321 if (($statusDate >= $startEvent) && ($statusDate <= $endEvent)) {
322 $membershipDetails['id'] = $membershipStatus->id;
323 $membershipDetails['name'] = $membershipStatus->name;
324 }
325 }
326 elseif ($startEvent) {
327 if ($statusDate >= $startEvent) {
328 $membershipDetails['id'] = $membershipStatus->id;
329 $membershipDetails['name'] = $membershipStatus->name;
330 }
331 }
332 elseif ($endEvent) {
333 if ($statusDate <= $endEvent) {
334 $membershipDetails['id'] = $membershipStatus->id;
335 $membershipDetails['name'] = $membershipStatus->name;
336 }
337 }
338
339 // returns FIRST status record for which status_date is in range.
340 if ($membershipDetails) {
5f11bbcc 341 break;
6a488035
TO
342 }
343 }
344 //end fetch
345
5f11bbcc
EM
346 //we bundle the arguments into an array as we can't pass 8 variables to the hook otherwise
347 // the membership array might contain the pre-altered settings so we don't want to merge this
be2fb01f 348 $arguments = [
5f11bbcc
EM
349 'start_date' => $startDate,
350 'end_date' => $endDate,
351 'join_date' => $joinDate,
352 'status_date' => $statusDate,
353 'exclude_is_admin' => $endDate,
354 'membership_type_id' => $membershipTypeID,
355 'start_event' => $startEvent,
356 'end_event' => $endEvent,
be2fb01f 357 ];
5f11bbcc 358 CRM_Utils_Hook::alterCalculatedMembershipStatus($membershipDetails, $arguments, $membership);
6a488035
TO
359 return $membershipDetails;
360 }
361
362 /**
fe482240 363 * Function that return the status ids whose is_current_member is set.
6a488035 364 *
77b97be7 365 * @return array
6a488035
TO
366 */
367 public static function getMembershipStatusCurrent() {
be2fb01f 368 $statusIds = [];
6a488035
TO
369 $membershipStatus = new CRM_Member_DAO_MembershipStatus();
370 $membershipStatus->is_current_member = 1;
371 $membershipStatus->find();
372 $membershipStatus->selectAdd();
373 $membershipStatus->selectAdd('id');
374 while ($membershipStatus->fetch()) {
375 $statusIds[] = $membershipStatus->id;
376 }
6a488035
TO
377 return $statusIds;
378 }
96025800 379
6a488035 380}