6345c936 |
1 | <?php |
2 | /* |
3 | +--------------------------------------------------------------------+ |
4 | | CiviCRM version 5 | |
5 | +--------------------------------------------------------------------+ |
f299f7db |
6 | | Copyright CiviCRM LLC (c) 2004-2020 | |
6345c936 |
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 | * Class CRM_Member_Utils_RelationshipProcessor |
30 | */ |
31 | class CRM_Member_Utils_RelationshipProcessor { |
32 | |
33 | /** |
34 | * Contact IDs to process. |
35 | * |
36 | * @var [int] |
37 | */ |
38 | protected $contactIDs = []; |
39 | |
40 | /** |
41 | * Memberships for related contacts. |
42 | * |
43 | * @var array |
44 | */ |
45 | protected $memberships = []; |
46 | |
47 | /** |
48 | * Is the relationship being enabled. |
49 | * |
50 | * @var bool |
51 | */ |
52 | protected $active; |
53 | |
54 | /** |
55 | * CRM_Member_Utils_RelationshipProcessor constructor. |
56 | * |
57 | * @param [int] $contactIDs |
58 | * @param bool $active |
59 | * |
60 | * @throws \CiviCRM_API3_Exception |
61 | */ |
62 | public function __construct($contactIDs, $active) { |
63 | $this->contactIDs = $contactIDs; |
64 | $this->active = $active; |
65 | $this->setMemberships(); |
66 | } |
67 | |
68 | /** |
69 | * Get memberships for contact of potentially inheritable types. |
70 | * |
71 | * @param int $contactID |
72 | * |
73 | * @return array |
74 | */ |
75 | public function getRelationshipMembershipsForContact(int $contactID):array { |
76 | $memberships = []; |
77 | foreach ($this->memberships as $id => $membership) { |
78 | if ((int) $membership['contact_id'] === $contactID) { |
79 | $memberships[$id] = $membership; |
80 | } |
81 | } |
82 | return $memberships; |
83 | } |
84 | |
85 | /** |
86 | * Set the relevant memberships on the class. |
87 | * |
88 | * We are looking at relationships that are potentially inheritable |
89 | * so we can filter out membership types with NULL relationship_type_id |
90 | * |
91 | * @throws \CiviCRM_API3_Exception |
92 | */ |
93 | protected function setMemberships() { |
94 | $return = array_keys(civicrm_api3('Membership', 'getfields', [])['values']); |
95 | $return[] = 'owner_membership_id.contact_id'; |
96 | $return[] = 'membership_type_id.relationship_type_id'; |
97 | $return[] = 'membership_type_id.relationship_direction'; |
98 | $memberships = civicrm_api3('Membership', 'get', [ |
99 | 'contact_id' => ['IN' => $this->contactIDs], |
100 | 'status_id' => ['IN' => $this->getInheritableMembershipStatusIDs()], |
101 | 'membership_type_id.relationship_type_id' => ['IS NOT NULL' => TRUE], |
102 | 'return' => $return, |
103 | 'options' => ['limit' => 0], |
104 | ])['values']; |
105 | foreach ($memberships as $id => $membership) { |
106 | if (!isset($membership['inheriting_membership_ids'])) { |
107 | $memberships[$id]['inheriting_membership_ids'] = []; |
108 | $memberships[$id]['inheriting_contact_ids'] = []; |
109 | } |
110 | if (!empty($membership['owner_membership_id']) && isset($memberships[$membership['owner_membership_id']])) { |
111 | $memberships[$membership['owner_membership_id']]['inheriting_membership_ids'][] = (int) $membership['id']; |
112 | $memberships[$membership['owner_membership_id']]['inheriting_contact_ids'][] = (int) $membership['contact_id']; |
113 | $membership['owner_membership_id.contact_id'] = (int) $membership['owner_membership_id.contact_id']; |
114 | } |
115 | // Just for the sake of having an easier parameter to access. |
116 | $memberships[$id]['owner_contact_id'] = $membership['owner_membership_id.contact_id'] ?? NULL; |
117 | |
118 | // Ensure it is an array & use an easier parameter name. |
119 | $memberships[$id]['relationship_type_ids'] = (array) $membership['membership_type_id.relationship_type_id']; |
120 | $memberships[$id]['relationship_type_directions'] = (array) $membership['membership_type_id.relationship_direction']; |
121 | |
122 | foreach ($memberships[$id]['relationship_type_ids'] as $index => $relationshipType) { |
123 | $memberships[$id]['relationship_type_keys'][] = $relationshipType . '_' . $memberships[$id]['relationship_type_directions'][$index]; |
124 | } |
125 | } |
126 | $this->memberships = $memberships; |
127 | } |
128 | |
129 | /** |
130 | * Get membership statuses that could be inherited. |
131 | * |
132 | * @return array |
133 | */ |
134 | protected function getInheritableMembershipStatusIDs() { |
135 | // @todo - clean this up - was legacy code that got moved. |
136 | $membershipStatusRecordIds = []; |
137 | // CRM-15829 UPDATES |
138 | // If we're looking for active memberships we must consider pending (id: 5) ones too. |
139 | // Hence we can't just call CRM_Member_BAO_Membership::getValues below with the active flag, is it would completely miss pending relatioships. |
140 | // 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. |
141 | $pendingStatusId = array_search('Pending', CRM_Member_PseudoConstant::membershipStatus()); |
142 | |
143 | $query = 'SELECT * FROM `civicrm_membership_status`'; |
144 | if ($this->active) { |
145 | $query .= ' WHERE `is_current_member` = 1 OR `id` = %1 '; |
146 | } |
147 | |
148 | $dao = CRM_Core_DAO::executeQuery($query, [1 => [$pendingStatusId, 'Integer']]); |
149 | |
150 | while ($dao->fetch()) { |
151 | $membershipStatusRecordIds[$dao->id] = $dao->id; |
152 | } |
153 | return $membershipStatusRecordIds; |
154 | } |
155 | |
156 | } |