From 6268a61af4735a749e49ec48bda626ba0150f035 Mon Sep 17 00:00:00 2001 From: Matthew Wire Date: Sat, 28 Apr 2018 16:15:45 +0100 Subject: [PATCH 1/2] Remove usage of deprecated function from paypal --- CRM/Core/Payment/PayPalImpl.php | 105 ++++++++++++++++++++++++-------- 1 file changed, 78 insertions(+), 27 deletions(-) diff --git a/CRM/Core/Payment/PayPalImpl.php b/CRM/Core/Payment/PayPalImpl.php index 3fde78c1bbfd..6f7ac6d8d8e4 100644 --- a/CRM/Core/Payment/PayPalImpl.php +++ b/CRM/Core/Payment/PayPalImpl.php @@ -39,6 +39,10 @@ class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment { const CHARSET = 'iso-8859-1'; + const PAYPAL_PRO = 'PayPal'; + const PAYPAL_STANDARD = 'PayPal_Standard'; + const PAYPAL_EXPRESS = 'PayPal_Express'; + protected $_mode = NULL; /** @@ -50,21 +54,50 @@ class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment { * @param CRM_Core_Payment $paymentProcessor * * @return \CRM_Core_Payment_PayPalImpl + * @throws \Civi\Payment\Exception\PaymentProcessorException */ public function __construct($mode, &$paymentProcessor) { $this->_mode = $mode; $this->_paymentProcessor = $paymentProcessor; - $this->_processorName = ts('PayPal Pro'); - $paymentProcessorType = CRM_Core_PseudoConstant::paymentProcessorType(FALSE, NULL, 'name'); - if ($this->_paymentProcessor['payment_processor_type_id'] == CRM_Utils_Array::key('PayPal_Standard', $paymentProcessorType)) { + if ($this->isPayPalType($this::PAYPAL_STANDARD)) { $this->_processorName = ts('PayPal Standard'); - return; } - elseif ($this->_paymentProcessor['payment_processor_type_id'] == CRM_Utils_Array::key('PayPal_Express', $paymentProcessorType)) { + elseif ($this->isPayPalType($this::PAYPAL_EXPRESS)) { $this->_processorName = ts('PayPal Express'); } + elseif ($this->isPayPalType($this::PAYPAL_PRO)) { + $this->_processorName = ts('PayPal Pro'); + } + else { + throw new PaymentProcessorException('CRM_Core_Payment_PayPalImpl: Payment processor type is not defined!'); + } + } + /** + * Helper function to check which payment processor type is being used. + * + * @param $typeName + * + * @return bool + * @throws \Civi\Payment\Exception\PaymentProcessorException + */ + public function isPayPalType($typeName) { + // Historically payment_processor_type may have been set to the name of the processor but newer versions of CiviCRM use the id set in payment_processor_type_id + if (empty($this->_paymentProcessor['payment_processor_type_id']) && empty($this->_paymentProcessor['payment_processor_type'])) { + // We need one of them to be set! + throw new PaymentProcessorException('CRM_Core_Payment_PayPalImpl: Payment processor type is not defined!'); + } + if (empty($this->_paymentProcessor['payment_processor_type_id']) && !empty($this->_paymentProcessor['payment_processor_type'])) { + // Handle legacy case where payment_processor_type was set, but payment_processor_type_id was not. + $this->_paymentProcessor['payment_processor_type_id'] + = CRM_Core_PseudoConstant::getKey('CRM_Financial_BAO_PaymentProcessor', 'payment_processor_type_id', $this->_paymentProcessor['payment_processor_type']); + } + if ((int) $this->_paymentProcessor['payment_processor_type_id'] === + CRM_Core_PseudoConstant::getKey('CRM_Financial_BAO_PaymentProcessor', 'payment_processor_type_id', $typeName)) { + return TRUE; + } + return FALSE; } /** @@ -74,9 +107,10 @@ public function __construct($mode, &$paymentProcessor) { * with someone else's login. * * @return bool + * @throws \Civi\Payment\Exception\PaymentProcessorException */ protected function supportsBackOffice() { - if ($this->_processorName == ts('PayPal Pro')) { + if ($this->isPayPalType($this::PAYPAL_PRO)) { return TRUE; } return FALSE; @@ -92,9 +126,10 @@ protected function supportsBackOffice() { * 'notify' flow a key difference is that in the notify flow they don't have to return but in this flow they do. * * @return bool + * @throws \Civi\Payment\Exception\PaymentProcessorException */ protected function supportsPreApproval() { - if ($this->_processorName == ts('PayPal Express') || $this->_processorName == ts('PayPal Pro')) { + if ($this->isPayPalType($this::PAYPAL_EXPRESS) || $this->isPayPalType($this::PAYPAL_PRO)) { return TRUE; } return FALSE; @@ -107,17 +142,18 @@ protected function supportsPreApproval() { * * @return bool * Should form building stop at this point? + * @throws \Civi\Payment\Exception\PaymentProcessorException */ public function buildForm(&$form) { if ($this->supportsPreApproval()) { $this->addPaypalExpressCode($form); - if ($this->_processorName == ts('PayPal Express')) { + if ($this->isPayPalType($this::PAYPAL_EXPRESS)) { CRM_Core_Region::instance('billing-block-post')->add(array( 'template' => 'CRM/Financial/Form/PaypalExpress.tpl', 'name' => 'paypal_express', )); } - if ($this->_processorName == ts('PayPal Pro')) { + if ($this->isPayPalType($this::PAYPAL_PRO)) { CRM_Core_Region::instance('billing-block-pre')->add(array( 'template' => 'CRM/Financial/Form/PaypalPro.tpl', )); @@ -186,9 +222,11 @@ protected function supportsRecurContributionsForPledges() { * * @param array $values * @param array $errors + * + * @throws \Civi\Payment\Exception\PaymentProcessorException */ public function validatePaymentInstrument($values, &$errors) { - if ($this->_paymentProcessor['payment_processor_type'] == 'PayPal' && !$this->isPaypalExpress($values)) { + if ($this->isPayPalType($this::PAYPAL_PRO) && !$this->isPaypalExpress($values)) { CRM_Core_Payment_Form::validateCreditCard($values, $errors, $this->_paymentProcessor['id']); CRM_Core_Form::validateMandatoryFields($this->getMandatoryFields(), $values, $errors); } @@ -251,6 +289,7 @@ protected function setExpressCheckOut(&$params) { * @param array $storedDetails * * @return array + * @throws \Civi\Payment\Exception\PaymentProcessorException */ public function getPreApprovalDetails($storedDetails) { return empty($storedDetails['token']) ? array() : $this->getExpressCheckoutDetails($storedDetails['token']); @@ -266,6 +305,7 @@ public function getPreApprovalDetails($storedDetails) { * * @return array * the result in an nice formatted array (or an error object) + * @throws \Civi\Payment\Exception\PaymentProcessorException */ public function getExpressCheckoutDetails($token) { $args = array(); @@ -365,6 +405,7 @@ public function doExpressCheckout(&$params) { * @param array $params * * @return mixed + * @throws \Exception */ public function createRecurringPayments(&$params) { $args = array(); @@ -461,9 +502,7 @@ public function initialize(&$args, $method) { * @throws \Civi\Payment\Exception\PaymentProcessorException */ public function doPayment(&$params, $component = 'contribute') { - if ($this->_paymentProcessor['payment_processor_type'] == 'PayPal_Express' - || ($this->_paymentProcessor['payment_processor_type'] == 'PayPal' && !empty($params['token'])) - ) { + if ($this->isPayPalType($this::PAYPAL_EXPRESS) || ($this->isPayPalType($this::PAYPAL_STANDARD) && !empty($params['token']))) { $this->_component = $component; return $this->doExpressCheckout($params); @@ -481,6 +520,7 @@ public function doPayment(&$params, $component = 'contribute') { * @param string $component * @return array * the result in an nice formatted array (or an error object) + * @throws \Civi\Payment\Exception\PaymentProcessorException */ public function doDirectPayment(&$params, $component = 'contribute') { $args = array(); @@ -538,7 +578,7 @@ public function doDirectPayment(&$params, $component = 'contribute') { $result = $this->invokeAPI($args); - //WAG + // WAG if (is_a($result, 'CRM_Core_Error')) { return $result; } @@ -597,14 +637,14 @@ public function doQuery($params) { /** * This function checks to see if we have the right config values. * - * @return string + * @return null|string * the error message if any + * @throws \Civi\Payment\Exception\PaymentProcessorException */ public function checkConfig() { $error = array(); - $paymentProcessorType = CRM_Core_PseudoConstant::paymentProcessorType(FALSE, NULL, 'name'); - if ($this->_paymentProcessor['payment_processor_type_id'] != CRM_Utils_Array::key('PayPal_Standard', $paymentProcessorType)) { + if (!$this->isPayPalType($this::PAYPAL_STANDARD)) { if (empty($this->_paymentProcessor['signature'])) { $error[] = ts('Signature is not set in the Administer » System Settings » Payment Processors.'); } @@ -627,9 +667,10 @@ public function checkConfig() { /** * @return null|string + * @throws \Civi\Payment\Exception\PaymentProcessorException */ public function cancelSubscriptionURL() { - if ($this->_paymentProcessor['payment_processor_type'] == 'PayPal_Standard') { + if ($this->isPayPalType($this::PAYPAL_STANDARD)) { return "{$this->_paymentProcessor['url_site']}cgi-bin/webscr?cmd=_subscr-find&alias=" . urlencode($this->_paymentProcessor['user_name']); } else { @@ -644,14 +685,15 @@ public function cancelSubscriptionURL() { * Method to check for. * * @return bool + * @throws \Civi\Payment\Exception\PaymentProcessorException */ public function isSupported($method) { - if ($this->_paymentProcessor['payment_processor_type'] != 'PayPal') { + if (!$this->isPayPalType($this::PAYPAL_PRO)) { // since subscription methods like cancelSubscription or updateBilling is not yet implemented / supported // by standard or express. return FALSE; } - return parent::isSupported($method); + return $this->_paymentProcessor->supports($method); } /** @@ -659,9 +701,10 @@ public function isSupported($method) { * * @return bool * Should the form button by suppressed? + * @throws \Civi\Payment\Exception\PaymentProcessorException */ public function isSuppressSubmitButtons() { - if ($this->_paymentProcessor['payment_processor_type'] == 'PayPal_Express') { + if ($this->isPayPalType($this::PAYPAL_EXPRESS)) { return TRUE; } return FALSE; @@ -672,9 +715,10 @@ public function isSuppressSubmitButtons() { * @param array $params * * @return array|bool|object + * @throws \Civi\Payment\Exception\PaymentProcessorException */ public function cancelSubscription(&$message = '', $params = array()) { - if ($this->_paymentProcessor['payment_processor_type'] == 'PayPal') { + if ($this->isPayPalType($this::PAYPAL_PRO)) { $args = array(); $this->initialize($args, 'ManageRecurringPaymentsProfileStatus'); @@ -694,6 +738,9 @@ public function cancelSubscription(&$message = '', $params = array()) { /** * Process incoming notification. + * + * @throws \CRM_Core_Exception + * @throws \CiviCRM_API3_Exception */ static public function handlePaymentNotification() { $params = array_merge($_GET, $_REQUEST); @@ -737,9 +784,10 @@ static public function handlePaymentNotification() { * @param array $params * * @return array|bool|object + * @throws \Civi\Payment\Exception\PaymentProcessorException */ public function updateSubscriptionBillingInfo(&$message = '', $params = array()) { - if ($this->_paymentProcessor['payment_processor_type'] == 'PayPal') { + if ($this->isPayPalType($this::PAYPAL_PRO)) { $config = CRM_Core_Config::singleton(); $args = array(); $this->initialize($args, 'UpdateRecurringPaymentsProfile'); @@ -775,9 +823,10 @@ public function updateSubscriptionBillingInfo(&$message = '', $params = array()) * @param array $params * * @return array|bool|object + * @throws \Civi\Payment\Exception\PaymentProcessorException */ public function changeSubscriptionAmount(&$message = '', $params = array()) { - if ($this->_paymentProcessor['payment_processor_type'] == 'PayPal') { + if ($this->isPayPalType($this::PAYPAL_PRO)) { $config = CRM_Core_Config::singleton(); $args = array(); $this->initialize($args, 'UpdateRecurringPaymentsProfile'); @@ -807,6 +856,7 @@ public function changeSubscriptionAmount(&$message = '', $params = array()) { * @return array * - pre_approval_parameters (this will be stored on the calling form & available later) * - redirect_url (if set the browser will be redirected to this. + * @throws \Civi\Payment\Exception\PaymentProcessorException */ public function doPreApproval(&$params) { if (!$this->isPaypalExpress($params)) { @@ -1090,10 +1140,10 @@ public static function deformat($str) { * Get array of fields that should be displayed on the payment form. * * @return array - * @throws CiviCRM_API3_Exception + * @throws \Civi\Payment\Exception\PaymentProcessorException */ public function getPaymentFormFields() { - if ($this->_processorName == ts('PayPal Pro')) { + if ($this->isPayPalType($this::PAYPAL_PRO)) { return $this->getCreditCardFormFields(); } else { @@ -1125,9 +1175,10 @@ protected function mapPaypalParamsToCivicrmParams($fieldMap, $paypalParams) { * @param array $params * * @return bool + * @throws \Civi\Payment\Exception\PaymentProcessorException */ protected function isPaypalExpress($params) { - if ($this->_processorName == ts('PayPal Express')) { + if ($this->isPayPalType($this::PAYPAL_EXPRESS)) { return TRUE; } From c72dc632aebf773c4dbcdb2d6513057645a29541 Mon Sep 17 00:00:00 2001 From: Matthew Wire Date: Fri, 11 May 2018 10:23:58 +0100 Subject: [PATCH 2/2] Allow 'Cancel Subscription' for PayPal Express --- CRM/Core/Payment/PayPalImpl.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CRM/Core/Payment/PayPalImpl.php b/CRM/Core/Payment/PayPalImpl.php index 6f7ac6d8d8e4..39672f0e498d 100644 --- a/CRM/Core/Payment/PayPalImpl.php +++ b/CRM/Core/Payment/PayPalImpl.php @@ -718,7 +718,7 @@ public function isSuppressSubmitButtons() { * @throws \Civi\Payment\Exception\PaymentProcessorException */ public function cancelSubscription(&$message = '', $params = array()) { - if ($this->isPayPalType($this::PAYPAL_PRO)) { + if ($this->isPayPalType($this::PAYPAL_PRO) || $this->isPayPalType($this::PAYPAL_EXPRESS)) { $args = array(); $this->initialize($args, 'ManageRecurringPaymentsProfileStatus');