3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
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 |
9 +--------------------------------------------------------------------+
13 * Class CRM_Member_Utils_RelationshipProcessor
15 class CRM_Member_Utils_RelationshipProcessor
{
18 * Contact IDs to process.
22 protected $contactIDs = [];
25 * Memberships for related contacts.
29 protected $memberships = [];
32 * Is the relationship being enabled.
39 * CRM_Member_Utils_RelationshipProcessor constructor.
41 * @param [int] $contactIDs
44 * @throws \CiviCRM_API3_Exception
46 public function __construct($contactIDs, $active) {
47 $this->contactIDs
= $contactIDs;
48 $this->active
= $active;
49 $this->setMemberships();
53 * Get memberships for contact of potentially inheritable types.
55 * @param int $contactID
59 public function getRelationshipMembershipsForContact(int $contactID):array {
61 foreach ($this->memberships
as $id => $membership) {
62 if ((int) $membership['contact_id'] === $contactID) {
63 $memberships[$id] = $membership;
70 * Set the relevant memberships on the class.
72 * We are looking at relationships that are potentially inheritable
73 * so we can filter out membership types with NULL relationship_type_id
75 * @throws \CiviCRM_API3_Exception
77 protected function setMemberships() {
78 $return = array_keys(civicrm_api3('Membership', 'getfields', [])['values']);
79 $return[] = 'owner_membership_id.contact_id';
80 $return[] = 'membership_type_id.relationship_type_id';
81 $return[] = 'membership_type_id.relationship_direction';
82 $memberships = civicrm_api3('Membership', 'get', [
83 'contact_id' => ['IN' => $this->contactIDs
],
84 'status_id' => ['IN' => $this->getInheritableMembershipStatusIDs()],
85 'membership_type_id.relationship_type_id' => ['IS NOT NULL' => TRUE],
87 'options' => ['limit' => 0],
89 foreach ($memberships as $id => $membership) {
90 if (!isset($memberships[$id]['inheriting_membership_ids'])) {
91 $memberships[$id]['inheriting_membership_ids'] = [];
92 $memberships[$id]['inheriting_contact_ids'] = [];
94 if (!empty($membership['owner_membership_id']) && isset($memberships[$membership['owner_membership_id']])) {
95 $memberships[$membership['owner_membership_id']]['inheriting_membership_ids'][] = (int) $membership['id'];
96 $memberships[$membership['owner_membership_id']]['inheriting_contact_ids'][] = (int) $membership['contact_id'];
97 $membership['owner_membership_id.contact_id'] = (int) $membership['owner_membership_id.contact_id'];
99 // Just for the sake of having an easier parameter to access.
100 $memberships[$id]['owner_contact_id'] = $membership['owner_membership_id.contact_id'] ??
NULL;
102 // Ensure it is an array & use an easier parameter name.
103 $memberships[$id]['relationship_type_ids'] = (array) $membership['membership_type_id.relationship_type_id'];
104 $memberships[$id]['relationship_type_directions'] = (array) $membership['membership_type_id.relationship_direction'];
106 foreach ($memberships[$id]['relationship_type_ids'] as $index => $relationshipType) {
107 $memberships[$id]['relationship_type_keys'][] = $relationshipType . '_' . $memberships[$id]['relationship_type_directions'][$index];
110 $this->memberships
= $memberships;
114 * Get membership statuses that could be inherited.
118 protected function getInheritableMembershipStatusIDs() {
119 // @todo - clean this up - was legacy code that got moved.
120 $membershipStatusRecordIds = [];
122 // If we're looking for active memberships we must consider pending (id: 5) ones too.
123 // Hence we can't just call CRM_Member_BAO_Membership::getValues below with the active flag, is it would completely miss pending relatioships.
124 // As suggested by @davecivicrm, the pending status id is fetched using the CRM_Member_PseudoConstant::membershipStatus() class and method, since these ids differ from system to system.
125 $pendingStatusId = array_search('Pending', CRM_Member_PseudoConstant
::membershipStatus());
127 $query = 'SELECT * FROM `civicrm_membership_status`';
129 $query .= ' WHERE `is_current_member` = 1 OR `id` = %1 ';
132 $dao = CRM_Core_DAO
::executeQuery($query, [1 => [$pendingStatusId, 'Integer']]);
134 while ($dao->fetch()) {
135 $membershipStatusRecordIds[$dao->id
] = $dao->id
;
137 return $membershipStatusRecordIds;