diff --git a/CRM/Contribute/Page/Tab.php b/CRM/Contribute/Page/Tab.php
index f0caa917d24f..2d75e2096c0c 100644
--- a/CRM/Contribute/Page/Tab.php
+++ b/CRM/Contribute/Page/Tab.php
@@ -94,6 +94,87 @@ public static function recurLinks(int $recurID, $context = 'contribution') {
return $links;
}
+ /**
+ * Get the recur links to return for self service.
+ *
+ * These are the links to present to a logged in user wishing
+ * to service their own
+ *
+ * @param int $recurID
+ *
+ * @return array|array[]
+ * @throws \CRM_Core_Exception
+ * @throws \CiviCRM_API3_Exception
+ */
+ public static function selfServiceRecurLinks(int $recurID): array {
+ $links = [];
+ $paymentProcessorObj = Civi\Payment\System::singleton()->getById(CRM_Contribute_BAO_ContributionRecur::getPaymentProcessorID($recurID));
+ if ($paymentProcessorObj->supports('cancelRecurring')
+ && $paymentProcessorObj->subscriptionURL($recurID, 'recur', 'cancel')
+ ) {
+ $url = $paymentProcessorObj->subscriptionURL($recurID, 'recur', 'cancel');
+ $links[CRM_Core_Action::DISABLE] = [
+ 'url' => $url,
+ 'name' => ts('Cancel'),
+ 'title' => ts('Cancel'),
+ // Only display on-site links in a popup.
+ 'class' => (stripos($url, 'http') !== FALSE) ? 'no-popup' : '',
+ ];
+ }
+
+ if ($paymentProcessorObj->supports('UpdateSubscriptionBillingInfo')
+ && $paymentProcessorObj->subscriptionURL($recurID, 'recur', 'billing')
+ ) {
+ $url = $paymentProcessorObj->subscriptionURL($recurID, 'recur', 'billing');
+ $links[CRM_Core_Action::RENEW] = [
+ 'name' => ts('Change Billing Details'),
+ 'title' => ts('Change Billing Details'),
+ 'url' => $url,
+ // Only display on-site links in a popup.
+ 'class' => (stripos($url, 'http') !== FALSE) ? 'no-popup' : '',
+ ];
+ }
+
+ if (($paymentProcessorObj->supports('ChangeSubscriptionAmount')
+ || $paymentProcessorObj->supports('EditRecurringContribution'))
+ && $paymentProcessorObj->subscriptionURL($recurID, 'recur', 'update')
+ ) {
+ $url = $paymentProcessorObj->subscriptionURL($recurID, 'recur', 'update');
+ $links[CRM_Core_Action::UPDATE] = [
+ 'name' => ts('Edit'),
+ 'title' => ts('Edit Recurring Payment'),
+ 'url' => $url,
+ // Only display on-site links in a popup.
+ 'class' => (stripos($url, 'http') !== FALSE) ? 'no-popup' : '',
+ ];
+ }
+ return $links;
+ }
+
+ /**
+ * Get recurring links appropriate to viewing a user dashboard.
+ *
+ * A contact should be able to see links appropriate to them (e.g
+ * payment processor cancel page) if viewing their own dashboard and
+ * links appropriate to the contact they are viewing, if they have
+ * permission, if viewing another user.
+ *
+ * @param int $recurID
+ * @param int $contactID
+ *
+ * @return array|array[]
+ * @throws \CRM_Core_Exception
+ * @throws \CiviCRM_API3_Exception
+ */
+ public static function dashboardRecurLinks(int $recurID, int $contactID): array {
+ $links = [];
+ if ($contactID && $contactID === CRM_Core_Session::getLoggedInContactID()) {
+ $links = self::selfServiceRecurLinks($recurID);
+ }
+ $links += self::recurLinks($recurID, 'dashboard');
+ return $links;
+ }
+
/**
* called when action is browse.
*
diff --git a/CRM/Contribute/Page/UserDashboard.php b/CRM/Contribute/Page/UserDashboard.php
index cad2bc4aa468..11adcd89e3a2 100644
--- a/CRM/Contribute/Page/UserDashboard.php
+++ b/CRM/Contribute/Page/UserDashboard.php
@@ -98,7 +98,7 @@ public function listContribution() {
$values['recur_status'] = $recurStatus[$values['contribution_status_id']];
$recurRow[$values['id']] = $values;
- $action = array_sum(array_keys(CRM_Contribute_Page_Tab::recurLinks((int) $recur->id, 'dashboard')));
+ $action = array_sum(array_keys(CRM_Contribute_Page_Tab::dashboardRecurLinks((int) $recur->id, (int) $recur->contact_id)));
$details = CRM_Contribute_BAO_ContributionRecur::getSubscriptionDetails($recur->id, 'recur');
$hideUpdate = $details->membership_id & $details->auto_renew;
@@ -107,7 +107,7 @@ public function listContribution() {
$action -= CRM_Core_Action::UPDATE;
}
- $recurRow[$values['id']]['action'] = CRM_Core_Action::formLink(CRM_Contribute_Page_Tab::recurLinks((int) $recur->id, 'dashboard'),
+ $recurRow[$values['id']]['action'] = CRM_Core_Action::formLink(CRM_Contribute_Page_Tab::dashboardRecurLinks((int) $recur->id, (int) $this->_contactId),
$action, [
'cid' => $this->_contactId,
'crid' => $values['id'],
diff --git a/CRM/Core/Session.php b/CRM/Core/Session.php
index 698b25eb9ddf..dcbe3a7823c0 100644
--- a/CRM/Core/Session.php
+++ b/CRM/Core/Session.php
@@ -563,7 +563,7 @@ public static function getLoggedInContactID() {
if (!is_numeric($session->get('userID'))) {
return NULL;
}
- return $session->get('userID');
+ return (int) $session->get('userID');
}
/**
diff --git a/CRM/Member/Page/RecurringContributions.php b/CRM/Member/Page/RecurringContributions.php
index 3a497b748ab9..44c9c1062b25 100644
--- a/CRM/Member/Page/RecurringContributions.php
+++ b/CRM/Member/Page/RecurringContributions.php
@@ -125,7 +125,7 @@ private function setActionsForRecurringContribution(int $recurID, &$recurringCon
}
$recurringContribution['action'] = CRM_Core_Action::formLink(
- CRM_Contribute_Page_Tab::recurLinks($recurID, 'contribution'),
+ CRM_Contribute_Page_Tab::recurLinks($recurID),
$action,
[
'cid' => $this->contactID,
diff --git a/tests/phpunit/CRM/Contribute/Page/TabTest.php b/tests/phpunit/CRM/Contribute/Page/TabTest.php
index f06faf1f5d39..a32f323c43ab 100644
--- a/tests/phpunit/CRM/Contribute/Page/TabTest.php
+++ b/tests/phpunit/CRM/Contribute/Page/TabTest.php
@@ -60,10 +60,12 @@ public function testLinksPaypalStandard(): void {
$page = new CRM_Contribute_Page_UserDashboard();
$page->run();
- $expected = 'ViewEditmore';
+ $expected = ''
+ . 'View'
+ . 'more';
$this->assertEquals(
$expected,
- $this->getActionHtml()
+ $this->getDashboardActionHtml()
);
}
@@ -116,4 +118,14 @@ protected function getActionHtml(): string {
->get_template_vars()['activeRecurRows'][1]['action'];
}
+ /**
+ * Get the html assigned as actions.
+ *
+ * @return string
+ */
+ protected function getDashboardActionHtml(): string {
+ return CRM_Core_Smarty::singleton()
+ ->get_template_vars()['recurRows'][1]['action'];
+ }
+
}