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