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 +--------------------------------------------------------------------+
15 * @copyright CiviCRM LLC https://civicrm.org/licensing
19 * This class generates form components for Payment-Instrument
21 class CRM_Member_Form_MembershipView
extends CRM_Core_Form
{
24 * The action links that we need to display for the browse screen.
28 public static $_links = NULL;
31 * The id of the membership being viewed.
35 private $membershipID;
45 * Add context information at the end of a link.
48 * extra query parameters
50 public function addContext() {
52 foreach (['context', 'selectedChild'] as $arg) {
53 if ($value = CRM_Utils_Request
::retrieve($arg, 'String', $this)) {
54 $extra .= "&{$arg}={$value}";
64 * (reference) of action links
66 public function &links() {
67 if (!(self
::$_links)) {
69 CRM_Core_Action
::DELETE
=> [
70 'name' => ts('Delete'),
71 'url' => 'civicrm/contact/view/membership',
72 'qs' => 'action=view&id=%%id%%&cid=%%cid%%&relAction=delete&mid=%%mid%%&reset=1' . $this->addContext(),
73 'title' => ts('Cancel Related Membership'),
75 CRM_Core_Action
::ADD
=> [
76 'name' => ts('Create'),
77 'url' => 'civicrm/contact/view/membership',
78 'qs' => 'action=view&id=%%id%%&cid=%%cid%%&relAction=create&rid=%%rid%%&reset=1' . $this->addContext(),
79 'title' => ts('Create Related Membership'),
87 * Perform create or delete action on related memberships.
89 * @param string $action
92 * Primary membership info (membership_id, contact_id, membership_type ...).
94 * @throws \CRM_Core_Exception
95 * @throws \CiviCRM_API3_Exception
97 public function relAction($action, $owner) {
100 $id = CRM_Utils_Request
::retrieve('mid', 'Positive', $this);
101 $relatedContactId = CRM_Utils_Request
::retrieve('cid', 'Positive', $this);
102 $relatedDisplayName = CRM_Contact_BAO_Contact
::displayName($relatedContactId);
103 CRM_Member_BAO_Membership
::del($id);
104 CRM_Core_Session
::setStatus(ts('Related membership for %1 has been deleted.', [1 => $relatedDisplayName]),
105 ts('Membership Deleted'), 'success');
110 'contact_id' => CRM_Utils_Request
::retrieve('rid', 'Positive', $this),
111 'membership_type_id' => $owner['membership_type_id'],
112 'owner_membership_id' => $owner['id'],
113 'join_date' => CRM_Utils_Date
::processDate($owner['join_date'], NULL, TRUE, 'Ymd'),
114 'start_date' => CRM_Utils_Date
::processDate($owner['start_date'], NULL, TRUE, 'Ymd'),
115 'end_date' => CRM_Utils_Date
::processDate($owner['end_date'], NULL, TRUE, 'Ymd'),
116 'source' => ts('Manual Assignment of Related Membership'),
117 'is_test' => $owner['is_test'],
118 'campaign_id' => $owner['campaign_id'] ??
NULL,
119 'status_id' => $owner['status_id'],
120 'skipStatusCal' => TRUE,
121 'createActivity' => TRUE,
123 CRM_Member_BAO_Membership
::create($params);
124 $relatedDisplayName = CRM_Contact_BAO_Contact
::displayName($params['contact_id']);
125 CRM_Core_Session
::setStatus(ts('Related membership for %1 has been created.', [1 => $relatedDisplayName]),
126 ts('Membership Added'), 'success');
130 throw new CRM_Core_Exception(ts('Invalid action specified in URL'));
133 // Redirect back to membership view page for the owner, without the relAction parameters
134 CRM_Utils_System
::redirect(
135 CRM_Utils_System
::url(
136 'civicrm/contact/view/membership',
137 "action=view&reset=1&id={$owner['membership_id']}&cid={$owner['contact_id']}" . $this->addContext()
143 * Set variables up before form is built.
147 public function preProcess() {
149 $this->membershipID
= CRM_Utils_Request
::retrieve('id', 'Positive', $this);
150 $this->contactID
= CRM_Utils_Request
::retrieve('cid', 'Positive', $this);
152 // Make sure context is assigned to template for condition where we come here view civicrm/membership/view
153 $context = CRM_Utils_Request
::retrieve('context', 'Alphanumeric', $this);
154 $this->assign('context', $context);
156 if ($this->membershipID
) {
157 $values = \Civi\Api4\Membership
::get()
158 ->addSelect('*', 'status_id:label', 'membership_type_id:label', 'membership_type_id.financial_type_id', 'status_id.is_current_member')
159 ->addWhere('id', '=', $this->membershipID
)
163 // Ensure keys expected by MembershipView.tpl are set correctly
164 // Some of these defaults are overwritten dependant on context below
165 $values['financialTypeId'] = $values['membership_type_id.financial_type_id'];
166 $values['membership_type'] = $values['membership_type_id:label'];
167 $values['status'] = $values['status_id:label'];
168 $values['active'] = $values['status_id.is_current_member'];
169 $values['owner_contact_id'] = FALSE;
170 $values['owner_display_name'] = FALSE;
171 $values['campaign'] = FALSE;
173 if (CRM_Financial_BAO_FinancialType
::isACLFinancialTypeStatus()) {
174 $finTypeId = CRM_Core_DAO
::getFieldValue('CRM_Member_DAO_MembershipType', $values['membership_type_id'], 'financial_type_id');
175 $finType = CRM_Contribute_PseudoConstant
::financialType($finTypeId);
176 if (!CRM_Core_Permission
::check('view contributions of type ' . $finType)) {
177 CRM_Core_Error
::statusBounce(ts('You do not have permission to access this page.'));
181 $this->assign('noACL', TRUE);
183 $membershipType = CRM_Member_BAO_MembershipType
::getMembershipTypeDetails($values['membership_type_id']);
185 // Do the action on related Membership if needed
186 $relAction = CRM_Utils_Request
::retrieve('relAction', 'String', $this);
188 $this->relAction($relAction, $values);
191 // build associated contributions
192 $this->assign('accessContribution', FALSE);
193 if (CRM_Core_Permission
::access('CiviContribute')) {
194 $this->assign('accessContribution', TRUE);
195 CRM_Member_Page_Tab
::associatedContribution($values['contact_id'], $this->membershipID
);
198 //Provide information about membership source when it is the result of a relationship (CRM-1901)
199 $values['owner_membership_id'] = CRM_Core_DAO
::getFieldValue('CRM_Member_DAO_Membership',
201 'owner_membership_id'
204 if (isset($values['owner_membership_id'])) {
205 $values['owner_contact_id'] = CRM_Core_DAO
::getFieldValue('CRM_Member_DAO_Membership',
206 $values['owner_membership_id'],
211 $values['owner_display_name'] = CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Contact',
212 $values['owner_contact_id'],
217 $direction = strrev($membershipType['relationship_direction']);
218 // To display relationship type in view membership page
219 $relTypeIds = str_replace(CRM_Core_DAO
::VALUE_SEPARATOR
, ",", $membershipType['relationship_type_id']);
221 SELECT relationship_type_id,
223 WHEN contact_id_a = {$values['owner_contact_id']} AND contact_id_b = {$values['contact_id']} THEN 'b_a'
224 WHEN contact_id_b = {$values['owner_contact_id']} AND contact_id_a = {$values['contact_id']} THEN 'a_b'
226 FROM civicrm_relationship
227 WHERE relationship_type_id IN ($relTypeIds)";
228 $dao = CRM_Core_DAO
::executeQuery($sql);
229 $values['relationship'] = NULL;
230 while ($dao->fetch()) {
231 $typeId = $dao->relationship_type_id
;
232 $direction = $dao->relType
;
233 if ($direction && $typeId) {
234 if ($values['relationship']) {
235 $values['relationship'] .= ',';
237 $values['relationship'] .= CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_RelationshipType',
246 $this->assign('has_related', FALSE);
247 // if membership can be granted, and we are the owner of the membership
248 if (!empty($membershipType['relationship_type_id']) && empty($values['owner_membership_id'])) {
249 // display related contacts/membership block
250 $this->assign('has_related', TRUE);
251 $this->assign('max_related', CRM_Utils_Array
::value('max_related', $values, ts('Unlimited')));
252 // split the relations in 2 arrays based on direction
253 $relTypeId = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $membershipType['relationship_type_id']);
254 $relDirection = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $membershipType['relationship_direction']);
255 foreach ($relTypeId as $rid) {
256 $relTypeDir[substr($relDirection[0], 0, 1)][] = $rid;
258 // build query in 2 parts with a UNION if necessary
259 // _x and _y are replaced with _a and _b first, then vice-versa
260 // comment is a qualifier for the relationship - now just job_title
262 SELECT r.id, c.id as cid, c.display_name as name, c.job_title as comment,
263 rt.name_x_y as relation, r.start_date, r.end_date,
264 m.id as mid, ms.is_current_member, ms.label as status
265 FROM civicrm_relationship r
266 LEFT JOIN civicrm_relationship_type rt ON rt.id = r.relationship_type_id
267 LEFT JOIN civicrm_contact c ON c.id = r.contact_id_x
268 LEFT JOIN civicrm_membership m ON (m.owner_membership_id = {$values['id']}
269 AND m.contact_id = r.contact_id_x AND m.is_test = 0)
270 LEFT JOIN civicrm_membership_status ms ON ms.id = m.status_id
271 WHERE r.contact_id_y = {$values['contact_id']} AND r.is_active = 1 AND c.is_deleted = 0";
273 foreach (['a', 'b'] as $dir) {
274 if (isset($relTypeDir[$dir])) {
275 $query .= ($query ?
' UNION ' : '')
276 . str_replace('_y', '_' . $dir, str_replace('_x', '_' . ($dir == 'a' ?
'b' : 'a'), $select))
277 . ' AND r.relationship_type_id IN (' . implode(',', $relTypeDir[$dir]) . ')';
280 $query .= " ORDER BY is_current_member DESC";
281 $dao = CRM_Core_DAO
::executeQuery($query);
283 $relatedRemaining = CRM_Utils_Array
::value('max_related', $values, PHP_INT_MAX
);
297 while ($dao->fetch()) {
299 foreach ($rowElememts as $field) {
300 $row[$field] = $dao->$field;
302 if ($row['mid'] && ($row['is_current_member'] == 1)) {
304 $row['action'] = CRM_Core_Action
::formLink(self
::links(), CRM_Core_Action
::DELETE
,
306 'id' => CRM_Utils_Request
::retrieve('id', 'Positive', $this),
307 'cid' => $row['cid'],
308 'mid' => $row['mid'],
312 'membership.relationship.action',
314 CRM_Utils_Request
::retrieve('id', 'Positive', $this)
318 if ($relatedRemaining > 0) {
319 $row['action'] = CRM_Core_Action
::formLink(self
::links(), CRM_Core_Action
::ADD
,
321 'id' => CRM_Utils_Request
::retrieve('id', 'Positive', $this),
322 'cid' => $row['cid'],
323 'rid' => $row['cid'],
327 'membership.relationship.action',
329 CRM_Utils_Request
::retrieve('id', 'Positive', $this)
335 $this->assign('related', $related);
336 if ($relatedRemaining <= 0) {
337 $this->assign('related_text', ts('None available'));
340 if ($relatedRemaining < 100000) {
341 $this->assign('related_text', ts('%1 available', [1 => $relatedRemaining]));
344 $this->assign('related_text', ts('Unlimited', [1 => $relatedRemaining]));
349 $displayName = CRM_Contact_BAO_Contact
::displayName($values['contact_id']);
350 $this->assign('displayName', $displayName);
352 // Check if this is default domain contact CRM-10482
353 if (CRM_Contact_BAO_Contact
::checkDomainContact($values['contact_id'])) {
354 $displayName .= ' (' . ts('default organization') . ')';
357 // omitting contactImage from title for now since the summary overlay css doesn't work outside crm-container
358 $this->setTitle(ts('View Membership for') . ' ' . $displayName);
360 // add viewed membership to recent items list
361 $recentTitle = $displayName . ' - ' . ts('Membership Type:') . ' ' . $values['membership_type'];
362 $url = CRM_Utils_System
::url('civicrm/contact/view/membership',
363 "action=view&reset=1&id={$values['id']}&cid={$values['contact_id']}&context=home"
367 if (CRM_Core_Permission
::checkActionPermission('CiviMember', CRM_Core_Action
::UPDATE
)) {
368 $recentOther['editUrl'] = CRM_Utils_System
::url('civicrm/contact/view/membership',
369 "action=update&reset=1&id={$values['id']}&cid={$values['contact_id']}&context=home"
372 if (CRM_Core_Permission
::checkActionPermission('CiviMember', CRM_Core_Action
::DELETE
)) {
373 $recentOther['deleteUrl'] = CRM_Utils_System
::url('civicrm/contact/view/membership',
374 "action=delete&reset=1&id={$values['id']}&cid={$values['contact_id']}&context=home"
377 CRM_Utils_Recent
::add($recentTitle,
381 $values['contact_id'],
386 CRM_Member_Page_Tab
::setContext($this, $values['contact_id']);
388 $memType = CRM_Core_DAO
::getFieldValue("CRM_Member_DAO_Membership", $this->membershipID
, "membership_type_id");
390 $groupTree = CRM_Core_BAO_CustomGroup
::getTree('Membership', NULL, $this->membershipID
, 0, $memType, NULL,
391 TRUE, NULL, FALSE, CRM_Core_Permission
::VIEW
);
392 CRM_Core_BAO_CustomGroup
::buildCustomDataView($this, $groupTree, FALSE, NULL, NULL, NULL, $this->membershipID
);
394 $isRecur = CRM_Core_DAO
::getFieldValue('CRM_Member_DAO_Membership', $this->membershipID
, 'contribution_recur_id');
396 $autoRenew = (bool) $isRecur;
399 if (!empty($values['is_test'])) {
400 $values['membership_type'] = CRM_Core_TestEntity
::appendTestText($values['membership_type']);
403 $subscriptionCancelled = CRM_Member_BAO_Membership
::isSubscriptionCancelled($this->membershipID
);
404 $values['auto_renew'] = ($autoRenew && !$subscriptionCancelled) ?
'Yes' : 'No';
406 //do check for campaigns
407 if ($campaignId = CRM_Utils_Array
::value('campaign_id', $values)) {
408 $campaigns = CRM_Campaign_BAO_Campaign
::getCampaigns($campaignId);
409 $values['campaign'] = $campaigns[$campaignId];
412 $this->assign($values);
416 * Build the form object.
420 public function buildQuickForm() {
424 'name' => ts('Done'),
425 'spacing' => ' ',