/** * Create memberships for related contacts, taking into account the maximum related memberships. * * @param array $params * Array of key - value pairs. * @param CRM_Core_DAO $dao * Membership object. * * @param bool $reset * * @return array|null * Membership details, if created. * * @throws \CRM_Core_Exception */ public static function createRelatedMemberships(&$params, &$dao, $reset = FALSE) { static $relatedContactIds = array(); if ($reset) { // not sure why a static var is in use here - we need a way to reset it from the test suite $relatedContactIds = array(); return FALSE; } $membership = new CRM_Member_DAO_Membership(); $membership->id = $dao->id; // required since create method doesn't return all the // parameters in the returned membership object if (!$membership->find(TRUE)) { return; } $deceasedStatusId = array_search('Deceased', CRM_Member_PseudoConstant::membershipStatus()); // FIXME : While updating/ renewing the // membership, if the relationship is PAST then // the membership of the related contact must be // expired. // For that, getting Membership Status for which // is_current_member is 0. It works for the // generated data as there is only one membership // status having is_current_member = 0. // But this wont work exactly if there will be // more than one status having is_current_member = 0. $membershipStatus = new CRM_Member_DAO_MembershipStatus(); $membershipStatus->is_current_member = 0; if ($membershipStatus->find(TRUE)) { $expiredStatusId = $membershipStatus->id; } else { $expiredStatusId = array_search('Expired', CRM_Member_PseudoConstant::membershipStatus()); } $allRelatedContacts = array(); $relatedContacts = array(); if (!is_a($membership, 'CRM_Core_Error')) { $allRelatedContacts = CRM_Member_BAO_Membership::checkMembershipRelationship($membership->id, $membership->contact_id, CRM_Utils_Array::value('action', $params)); } // check for loops. CRM-4213 // remove repeated related contacts, which already inherited membership. $relatedContactIds[$membership->contact_id] = TRUE; foreach ($allRelatedContacts as $cid => $status) { if (empty($relatedContactIds[$cid])) { $relatedContactIds[$cid] = TRUE; //don't create membership again for owner contact. $nestedRelationship = FALSE; if ($membership->owner_membership_id) { $nestedRelMembership = new CRM_Member_DAO_Membership(); $nestedRelMembership->id = $membership->owner_membership_id; $nestedRelMembership->contact_id = $cid; $nestedRelationship = $nestedRelMembership->find(TRUE); $nestedRelMembership->free(); } if (!$nestedRelationship) { $relatedContacts[$cid] = $status; } } } //lets cleanup related membership if any. if (empty($relatedContacts)) { self::deleteRelatedMemberships($membership->id); } else { // Edit the params array unset($params['id']); // Reminder should be sent only to the direct membership unset($params['reminder_date']); // unset the custom value ids if (is_array(CRM_Utils_Array::value('custom', $params))) { foreach ($params['custom'] as $k => $v) { unset($params['custom'][$k]['id']); } } if (!isset($params['membership_type_id'])) { $params['membership_type_id'] = $membership->membership_type_id; } // max_related should be set in the parent membership unset($params['max_related']); // Number of inherited memberships available - NULL is interpreted as unlimited, '0' as none $available = $membership->max_related == NULL ? PHP_INT_MAX : $membership->max_related; // will be used to queue potential memberships to be created. $queue = array(); foreach ($relatedContacts as $contactId => $relationshipStatus) { //use existing membership record. $relMembership = new CRM_Member_DAO_Membership(); $relMembership->contact_id = $contactId; $relMembership->owner_membership_id = $membership->id; $relMemIds = array(); if ($relMembership->find(TRUE)) { $params['id'] = $relMemIds['membership'] = $relMembership->id; } $params['contact_id'] = $contactId; $params['owner_membership_id'] = $membership->id; // set status_id as it might have been changed for // past relationship $params['status_id'] = $membership->status_id; if ($deceasedStatusId && CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $contactId, 'is_deceased')) { $params['status_id'] = $deceasedStatusId; } elseif (CRM_Utils_Array::value('action', $params) & CRM_Core_Action::UPDATE && $relationshipStatus == CRM_Contact_BAO_Relationship::PAST) { $params['status_id'] = $expiredStatusId; } //don't calculate status again in create( ); $params['skipStatusCal'] = TRUE; //do create activity if we changed status. if ($params['status_id'] != $relMembership->status_id) { $params['createActivity'] = TRUE; } // we should not created contribution record for related contacts, CRM-3371 unset($params['contribution_status_id']); //CRM-16857: Do not create multiple line-items for inherited membership through priceset. unset($params['lineItems']); unset($params['line_item']); if ($params['status_id'] == $deceasedStatusId || $params['status_id'] == $expiredStatusId) { // related membership is not active so does not count towards maximum CRM_Member_BAO_Membership::create($params, $relMemIds); } else { // related membership already exists, so this is just an update if (isset($params['id'])) { if ($available > 0) { CRM_Member_BAO_Membership::create($params, $relMemIds); $available--; } else { // we have run out of inherited memberships, so delete extras self::deleteMembership($params['id']); } // we need to first check if there will remain inherited memberships, so queue it up } else { $queue[] = $params; } } } // now go over the queue and create any available related memberships reset($queue); while ($available > 0 && ($params = each($queue))) { CRM_Member_BAO_Membership::create($params['value'], $relMemIds); $available--; } } }
/** * function to create memberships for related contacts * * @param array $params array of key - value pairs * @param object $membership membership object * * @return null|relatedMembership array of memberships if created * @static * @access public */ static function createRelatedMemberships(&$params, &$membership) { static $relatedContactIds = array(); // required since create method doesn't return all the // parameters in the returned membership object if (!$membership->find(true)) { return; } $allRelatedContacts = array(); $relatedContacts = array(); if (!is_a($membership, 'CRM_Core_Error')) { $allRelatedContacts = CRM_Member_BAO_Membership::checkMembershipRelationship($membership->id, $membership->contact_id, CRM_Utils_Array::value('action', $params)); } // check for loops. CRM-4213 // remove repeated related contacts, which already inherited membership. $relatedContactIds[$membership->contact_id] = true; foreach ($allRelatedContacts as $cid => $status) { if (!CRM_Utils_Array::value($cid, $relatedContactIds)) { $relatedContacts[$cid] = $status; $relatedContactIds[$cid] = true; } } if (!empty($relatedContacts)) { // delete all the related membership records before creating CRM_Member_BAO_Membership::deleteRelatedMemberships($membership->id); // Edit the params array unset($params['id']); // Reminder should be sent only to the direct membership unset($params['reminder_date']); // unset the custom value ids if (is_array(CRM_Utils_Array::value('custom', $params))) { foreach ($params['custom'] as $k => $v) { unset($params['custom'][$k]['id']); } } if (!isset($params['membership_type_id'])) { $params['membership_type_id'] = $membership->membership_type_id; } foreach ($relatedContacts as $contactId => $relationshipStatus) { $params['contact_id'] = $contactId; $params['owner_membership_id'] = $membership->id; // set status_id as it might have been changed for // past relationship $params['status_id'] = $membership->status_id; if (CRM_Utils_Array::value('action', $params) & CRM_Core_Action::UPDATE && $relationshipStatus == CRM_Contact_BAO_Relationship::PAST) { // FIXME : While updating/ renewing the // membership, if the relationship is PAST then // the membership of the related contact must be // expired. // For that, getting Membership Status for which // is_current_member is 0. It works for the // generated data as there is only one membership // status having is_current_member = 0. // But this wont work exactly if there will be // more than one status having is_current_member = 0. require_once 'CRM/Member/DAO/MembershipStatus.php'; $membership = new CRM_Member_DAO_MembershipStatus(); $membership->is_current_member = 0; if ($membership->find(true)) { $params['status_id'] = $membership->id; } } // we should not created contribution record for related contacts, CRM-3371 unset($params['contribution_status_id']); CRM_Member_BAO_Membership::create($params, CRM_Core_DAO::$_nullArray); } } }
/** * function to create memberships for related contacts * * @param array $params array of key - value pairs * @param object $membership membership object * * @return null|relatedMembership array of memberships if created * @static * @access public */ static function createRelatedMemberships(&$params, &$membership) { static $relatedContactIds = array(); // required since create method doesn't return all the // parameters in the returned membership object if (!$membership->find(true)) { return; } require_once 'CRM/Member/PseudoConstant.php'; $deceasedStatusId = array_search('Deceased', CRM_Member_PseudoConstant::membershipStatus()); $allRelatedContacts = array(); $relatedContacts = array(); if (!is_a($membership, 'CRM_Core_Error')) { $allRelatedContacts = CRM_Member_BAO_Membership::checkMembershipRelationship($membership->id, $membership->contact_id, CRM_Utils_Array::value('action', $params)); } // check for loops. CRM-4213 // remove repeated related contacts, which already inherited membership. $relatedContactIds[$membership->contact_id] = true; foreach ($allRelatedContacts as $cid => $status) { if (!CRM_Utils_Array::value($cid, $relatedContactIds)) { $relatedContactIds[$cid] = true; //don't create membership again for owner contact. $nestedRelationship = false; if ($membership->owner_membership_id) { $nestedRelMembership = new CRM_Member_DAO_Membership(); $nestedRelMembership->id = $membership->owner_membership_id; $nestedRelMembership->contact_id = $cid; $nestedRelationship = $nestedRelMembership->find(true); $nestedRelMembership->free(); } if (!$nestedRelationship) { $relatedContacts[$cid] = $status; } } } //lets cleanup related membership if any. if (empty($relatedContacts)) { require_once 'CRM/Member/BAO/Membership.php'; CRM_Member_BAO_Membership::deleteRelatedMemberships($membership->id); } else { // Edit the params array unset($params['id']); // Reminder should be sent only to the direct membership unset($params['reminder_date']); // unset the custom value ids if (is_array(CRM_Utils_Array::value('custom', $params))) { foreach ($params['custom'] as $k => $v) { unset($params['custom'][$k]['id']); } } if (!isset($params['membership_type_id'])) { $params['membership_type_id'] = $membership->membership_type_id; } foreach ($relatedContacts as $contactId => $relationshipStatus) { //use existing membership record. $relMembership = new CRM_Member_DAO_Membership(); $relMembership->contact_id = $contactId; $relMembership->owner_membership_id = $membership->id; $relMemIds = array(); if ($relMembership->find(true)) { $params['id'] = $relMemIds['membership'] = $relMembership->id; } $params['contact_id'] = $contactId; $params['owner_membership_id'] = $membership->id; // set status_id as it might have been changed for // past relationship $params['status_id'] = $membership->status_id; if ($deceasedStatusId && CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $contactId, 'is_deceased')) { $params['status_id'] = $deceasedStatusId; } else { if (CRM_Utils_Array::value('action', $params) & CRM_Core_Action::UPDATE && $relationshipStatus == CRM_Contact_BAO_Relationship::PAST) { // FIXME : While updating/ renewing the // membership, if the relationship is PAST then // the membership of the related contact must be // expired. // For that, getting Membership Status for which // is_current_member is 0. It works for the // generated data as there is only one membership // status having is_current_member = 0. // But this wont work exactly if there will be // more than one status having is_current_member = 0. require_once 'CRM/Member/DAO/MembershipStatus.php'; $membershipStatus = new CRM_Member_DAO_MembershipStatus(); $membershipStatus->is_current_member = 0; if ($membershipStatus->find(true)) { $params['status_id'] = $membershipStatus->id; } } } //don't calculate status again in create( ); $params['skipStatusCal'] = true; //do create activity if we changed status. if ($params['status_id'] != $relMembership->status_id) { $params['createActivity'] = true; } // we should not created contribution record for related contacts, CRM-3371 unset($params['contribution_status_id']); CRM_Member_BAO_Membership::create($params, $relMemIds); } } }
/** * Update an existing contact membership * * This api is used for updating an existing contact membership. * Required parrmeters : id of a membership * * @param Array $params an associative array of name/value property values of civicrm_membership * * @return array of updated membership property values * @access public */ function crm_update_contact_membership($params) { _crm_initialize(); if (!is_array($params)) { return _crm_error('Params is not an array'); } if (!isset($params['id'])) { return _crm_error('Required parameter missing'); } $changeFields = array('membership_start_date' => 'start_date', 'membership_end_date' => 'end_date', 'membership_source' => 'source'); foreach ($changeFields as $field => $requiredField) { if (array_key_exists($field, $params)) { $params[$requiredField] = $params[$field]; unset($params[$field]); } } require_once 'CRM/Member/BAO/Membership.php'; $membershipBAO =& new CRM_Member_BAO_Membership(); $membershipBAO->id = $params['id']; $membershipBAO->find(true); $oldStatusID = $membershipBAO->status_id; $membershipBAO->copyValues($params); $datefields = array('start_date', 'end_date', 'join_date', 'reminder_date'); //fix the dates foreach ($datefields as $value) { $membershipBAO->{$value} = CRM_Utils_Date::customFormat($membershipBAO->{$value}, '%Y%m%d'); // Handle resetting date to 'null' (which is converted to 00000 by customFormat) if ($membershipBAO->{$value} == '00000') { $membershipBAO->{$value} = 'null'; } $params[$value] = $membershipBAO->{$value}; } $membershipBAO->save(); require_once "CRM/Core/Action.php"; // Check and add membership for related contacts $relatedContacts = CRM_Member_BAO_Membership::checkMembershipRelationship($membershipBAO->id, (int) $membershipBAO->contact_id, CRM_Core_Action::UPDATE); //delete all the related membership records before creating CRM_Member_BAO_Membership::deleteRelatedMemberships($membershipBAO->id); $params['membership_type_id'] = $membershipBAO->membership_type_id; foreach ($relatedContacts as $contactId => $relationshipStatus) { if ($relationshipStatus & CRM_Contact_BAO_Relationship::CURRENT) { $params['contact_id'] = $contactId; $params['owner_membership_id'] = $membershipBAO->id; unset($params['id']); CRM_Member_BAO_Membership::create($params, CRM_Core_DAO::$_nullArray); } } // Create activity history record. require_once "CRM/Member/PseudoConstant.php"; $membershipType = CRM_Member_PseudoConstant::membershipType($membershipBAO->membership_type_id); if (!$membershipType) { $membershipType = ts('Membership'); } $activitySummary = $membershipType; if ($membershipBAO->source != 'null') { $activitySummary .= " - {$membershipBAO->source}"; } if ($membershipBAO->owner_membership_id) { $cid = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_Membership', $membershipBAO->owner_membership_id, 'contact_id'); $displayName = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $cid, 'display_name'); $activitySummary .= " (by {$displayName})"; } // create activity record only if there is change in the statusID (CRM-2521). if ($oldStatusID != $membershipBAO->status_id) { $activityParams = array('source_contact_id' => $membershipBAO->contact_id, 'source_record_id' => $membershipBAO->id, 'activity_type_id' => array_search('Membership Signup', CRM_Core_PseudoConstant::activityType()), 'subject' => $activitySummary, 'activity_date_time' => $params['join_date'], 'is_test' => $membershipBAO->is_test, 'status_id' => 2); require_once 'api/v2/Activity.php'; if (is_a(civicrm_activity_create($activityParams), 'CRM_Core_Error')) { return false; } } $membership = array(); _crm_object_to_array($membershipBAO, $membership); $membershipBAO->free(); return $membership; }