Merge pull request #18424 from eileenmcnaughton/dep
[civicrm-core.git] / CRM / Member / Utils / RelationshipProcessor.php
CommitLineData
6345c936 1<?php
2/*
3 +--------------------------------------------------------------------+
bc77d7c0 4 | Copyright CiviCRM LLC. All rights reserved. |
6345c936 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 |
6345c936 9 +--------------------------------------------------------------------+
10 */
11
12/**
13 * Class CRM_Member_Utils_RelationshipProcessor
14 */
15class CRM_Member_Utils_RelationshipProcessor {
16
17 /**
18 * Contact IDs to process.
19 *
20 * @var [int]
21 */
22 protected $contactIDs = [];
23
24 /**
25 * Memberships for related contacts.
26 *
27 * @var array
28 */
29 protected $memberships = [];
30
31 /**
32 * Is the relationship being enabled.
33 *
34 * @var bool
35 */
36 protected $active;
37
38 /**
39 * CRM_Member_Utils_RelationshipProcessor constructor.
40 *
41 * @param [int] $contactIDs
42 * @param bool $active
43 *
44 * @throws \CiviCRM_API3_Exception
45 */
46 public function __construct($contactIDs, $active) {
47 $this->contactIDs = $contactIDs;
48 $this->active = $active;
49 $this->setMemberships();
50 }
51
52 /**
53 * Get memberships for contact of potentially inheritable types.
54 *
55 * @param int $contactID
56 *
57 * @return array
58 */
59 public function getRelationshipMembershipsForContact(int $contactID):array {
60 $memberships = [];
61 foreach ($this->memberships as $id => $membership) {
62 if ((int) $membership['contact_id'] === $contactID) {
63 $memberships[$id] = $membership;
64 }
65 }
66 return $memberships;
67 }
68
69 /**
70 * Set the relevant memberships on the class.
71 *
72 * We are looking at relationships that are potentially inheritable
73 * so we can filter out membership types with NULL relationship_type_id
74 *
75 * @throws \CiviCRM_API3_Exception
76 */
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],
86 'return' => $return,
87 'options' => ['limit' => 0],
88 ])['values'];
89 foreach ($memberships as $id => $membership) {
0cd30c83 90 if (!isset($memberships[$id]['inheriting_membership_ids'])) {
6345c936 91 $memberships[$id]['inheriting_membership_ids'] = [];
92 $memberships[$id]['inheriting_contact_ids'] = [];
93 }
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'];
98 }
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;
101
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'];
105
106 foreach ($memberships[$id]['relationship_type_ids'] as $index => $relationshipType) {
107 $memberships[$id]['relationship_type_keys'][] = $relationshipType . '_' . $memberships[$id]['relationship_type_directions'][$index];
108 }
109 }
110 $this->memberships = $memberships;
111 }
112
113 /**
114 * Get membership statuses that could be inherited.
115 *
116 * @return array
117 */
118 protected function getInheritableMembershipStatusIDs() {
119 // @todo - clean this up - was legacy code that got moved.
120 $membershipStatusRecordIds = [];
121 // CRM-15829 UPDATES
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());
126
127 $query = 'SELECT * FROM `civicrm_membership_status`';
128 if ($this->active) {
129 $query .= ' WHERE `is_current_member` = 1 OR `id` = %1 ';
130 }
131
132 $dao = CRM_Core_DAO::executeQuery($query, [1 => [$pendingStatusId, 'Integer']]);
133
134 while ($dao->fetch()) {
135 $membershipStatusRecordIds[$dao->id] = $dao->id;
136 }
137 return $membershipStatusRecordIds;
138 }
139
140}