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