CRM-16808 paypal express follow up fixes
authoreileenmcnaugton <eileen@fuzion.co.nz>
Wed, 26 Aug 2015 12:22:22 +0000 (00:22 +1200)
committereileenmcnaugton <eileen@fuzion.co.nz>
Wed, 26 Aug 2015 23:59:55 +0000 (11:59 +1200)
CRM/Contribute/Form/Contribution/Main.php
CRM/Core/Form.php
CRM/Core/Payment.php
CRM/Core/Payment/PayPalImpl.php
CRM/Event/Form/Registration/Confirm.php
CRM/Event/Form/Registration/Register.php

index eeb94c6fcf723106bb68811977e4a321f0dc849f..0832bd9aa47fd006f5fe563461b8d33121ba78f9 100644 (file)
@@ -1294,7 +1294,7 @@ class CRM_Contribute_Form_Contribution_Main extends CRM_Contribute_Form_Contribu
     $this->set('invoiceID', $invoiceID);
     $params['invoiceID'] = $invoiceID;
     $params['description'] = ts('Online Contribution') . ': ' . (($this->_pcpInfo['title']) ? $this->_pcpInfo['title'] : $this->_values['title']);
-
+    $params['button'] = $this->controller->getButtonName();
     // required only if is_monetary and valid positive amount
     if ($this->_values['is_monetary'] &&
       is_array($this->_paymentProcessor) &&
@@ -1346,31 +1346,6 @@ class CRM_Contribute_Form_Contribution_Main extends CRM_Contribute_Form_Contribu
 
   }
 
-  /**
-   * Handle pre approval for processors.
-   *
-   * This fits with the flow where a pre-approval is done and then confirmed in the next stage when confirm is hit.
-   *
-   * This applies to processors that
-   * @param array $params
-   */
-  protected function handlePreApproval(&$params) {
-    try {
-      $payment = Civi\Payment\System::singleton()->getByProcessor($this->_paymentProcessor);
-      $params['component'] = 'contribute';
-      $result = $payment->doPreApproval($params);
-    }
-    catch (\Civi\Payment\Exception\PaymentProcessorException $e) {
-      CRM_Core_Error::displaySessionError($e->getMessage());
-      CRM_Utils_System::redirect($params['cancelURL']);
-    }
-
-    $this->set('pre_approval_parameters', $result['pre_approval_parameters']);
-    if (!empty($result['redirect_url'])) {
-      CRM_Utils_System::redirect($result['redirect_url']);
-    }
-  }
-
   /**
    * Process confirm function and pass browser to the thank you page.
    */
index 932c1d81844525f18d6834de7e778193a5a95fe3..f39bdf09c6d3d536abd78ed11764fd60fe4c69cc 100644 (file)
@@ -740,6 +740,39 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
     $this->assign('paymentProcessorID', $this->_paymentProcessorID);
   }
 
+  /**
+   * Handle pre approval for processors.
+   *
+   * This fits with the flow where a pre-approval is done and then confirmed in the next stage when confirm is hit.
+   *
+   * This function is shared between contribution & event forms & this is their common class.
+   *
+   * However, this should be seen as an in-progress refactor, the end goal being to also align the
+   * backoffice forms that action payments.
+   *
+   * @param array $params
+   */
+  protected function handlePreApproval(&$params) {
+    try {
+      $payment = Civi\Payment\System::singleton()->getByProcessor($this->_paymentProcessor);
+      $params['component'] = 'contribute';
+      $result = $payment->doPreApproval($params);
+      if (empty($result)) {
+        // This could happen, for example, when paypal looks at the button value & decides it is not paypal express.
+        return;
+      }
+    }
+    catch (\Civi\Payment\Exception\PaymentProcessorException $e) {
+      CRM_Core_Error::displaySessionError($e->getMessage());
+      CRM_Utils_System::redirect($params['cancelURL']);
+    }
+
+    $this->set('pre_approval_parameters', $result['pre_approval_parameters']);
+    if (!empty($result['redirect_url'])) {
+      CRM_Utils_System::redirect($result['redirect_url']);
+    }
+  }
+
   /**
    * Setter function for options.
    *
index 39f5aa34a251b82564fd3e388497c08491c37592..8dde6f3fe3c596b0c4ab5030365766e39b71edaa 100644 (file)
@@ -82,6 +82,25 @@ abstract class CRM_Core_Payment {
 
   protected $_paymentProcessor;
 
+  /**
+   * Base url of the calling form.
+   *
+   * This is used for processors that need to return the browser back to the CiviCRM site.
+   *
+   * @var string
+   */
+  protected $baseReturnUrl;
+
+  /**
+   * Set Base return URL.
+   *
+   * @param string $url
+   *   Url of site to return browser to.
+   */
+  public function setBaseReturnUrl($url) {
+    $this->baseReturnUrl = $url;
+  }
+
   /**
    * Opportunity for the payment processor to override the entire form build.
    *
@@ -539,9 +558,14 @@ abstract class CRM_Core_Payment {
   /**
    * Get base url dependent on component.
    *
-   * @return string|void
+   * (or preferably set it using the setter function).
+   *
+   * @return string
    */
   protected function getBaseReturnUrl() {
+    if ($this->baseReturnUrl) {
+      return $this->baseReturnUrl;
+    }
     if ($this->_component == 'event') {
       $baseURL = 'civicrm/event/register';
     }
index a811b096758ec8723ad2d4ed4bf298c76d2bfe7c..e513bace19376ec2ec0350cca74a26455d4de2a2 100644 (file)
@@ -25,6 +25,8 @@
  +--------------------------------------------------------------------+
  */
 
+use Civi\Payment\Exception\PaymentProcessorException;
+
 /**
  *
  * @package CRM
@@ -88,7 +90,7 @@ class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment {
    * @return bool
    */
   protected function supportsPreApproval() {
-    if ($this->_processorName == ts('PayPal Express')) {
+    if ($this->_processorName == ts('PayPal Express') || $this->_processorName == ts('PayPal Pro')) {
       return TRUE;
     }
     return FALSE;
@@ -226,7 +228,7 @@ class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment {
    * @return array
    */
   public function getPreApprovalDetails($storedDetails) {
-    return $this->getExpressCheckoutDetails($storedDetails['token']);
+    return empty($storedDetails['token']) ? array() : $this->getExpressCheckoutDetails($storedDetails['token']);
   }
 
   /**
@@ -427,7 +429,9 @@ class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment {
    * @throws \Civi\Payment\Exception\PaymentProcessorException
    */
   public function doPayment(&$params, $component = 'contribute') {
-    if ($this->_paymentProcessor['payment_processor_type'] != 'PayPal_Express') {
+    if ($this->_paymentProcessor['payment_processor_type'] != 'PayPal_Express'
+    && (!empty($params['credit_card_number']) && empty($params['token']))
+    ) {
       return parent::doPayment($params, $component);
     }
     $this->_component = $component;
@@ -741,6 +745,9 @@ class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment {
    *   - redirect_url (if set the browser will be redirected to this.
    */
   public function doPreApproval(&$params) {
+    if (!isset($params['button']) || !stristr($params['button'], 'express')) {
+      return array();
+    }
     $this->_component = $params['component'];
     $token = $this->setExpressCheckOut($params);
     return array(
index eaf024563d9d60e1eceeb8545df4a03f776328d8..bcafb74ea1c2bb590630bd154bdfec239e3afa38 100644 (file)
@@ -582,6 +582,10 @@ class CRM_Event_Form_Registration_Confirm extends CRM_Event_Form_Registration {
         if (is_array($this->_paymentProcessor)) {
           $payment = $this->_paymentProcessor['object'];
         }
+        if (!empty($this->_paymentProcessor) &&  $this->_paymentProcessor['object']->supports('preApproval')) {
+          $preApprovalParams = $this->_paymentProcessor['object']->getPreApprovalDetails($this->get('pre_approval_parameters'));
+          $value = array_merge($value, $preApprovalParams);
+        }
         $result = NULL;
 
         if (!empty($value['is_pay_later']) ||
index 7362870b6fb2e596968ca489928f7830cbfff3f5..00367dada86328d6e8abc3724415ebdee9c63d15 100644 (file)
@@ -912,7 +912,11 @@ class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration {
   }
 
   /**
-   * Check if profiles are complete when event registration occurs(CRM-9587)
+   * Check if profiles are complete when event registration occurs(CRM-9587).
+   *
+   * @param array $fields
+   * @param array $errors
+   * @param int $eventId
    */
   public static function checkProfileComplete($fields, &$errors, $eventId) {
     $email = '';
@@ -1066,6 +1070,7 @@ class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration {
 
       if (is_array($this->_paymentProcessor)) {
         $payment = $this->_paymentProcessor['object'];
+        $payment->setBaseReturnUrl('civicrm/event/register');
       }
       // default mode is direct
       $this->set('contributeMode', 'direct');
@@ -1091,6 +1096,8 @@ class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration {
         $params['invoiceID'] = $invoiceID;
       }
       $this->_params = $this->get('params');
+      // Set the button so we know what
+      $params['button'] = $this->controller->getButtonName();
       if (!empty($this->_params) && is_array($this->_params)) {
         $this->_params[0] = $params;
       }
@@ -1099,77 +1106,66 @@ class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration {
         $this->_params[] = $params;
       }
       $this->set('params', $this->_params);
-
       if ($this->_paymentProcessor &&
-        $this->_paymentProcessor['billing_mode'] & CRM_Core_Payment::BILLING_MODE_BUTTON
+        $this->_paymentProcessor['object']->supports('preApproval')
+        && !$this->_allowWaitlist &&
+        !$this->_requireApproval
       ) {
-        //get the button name
-        $buttonName = $this->controller->getButtonName();
-        if (in_array($buttonName,
-            array(
-              $this->_expressButtonName,
-              $this->_expressButtonName . '_x',
-              $this->_expressButtonName . '_y',
-            )
-          ) && empty($params['is_pay_later']) &&
-          !$this->_allowWaitlist &&
-          !$this->_requireApproval
-        ) {
-          $this->set('contributeMode', 'express');
 
-          // Send Event Name & Id in Params
-          $params['eventName'] = $this->_values['event']['title'];
-          $params['eventId'] = $this->_values['event']['id'];
-
-          $params['cancelURL'] = CRM_Utils_System::url('civicrm/event/register',
-            "_qf_Register_display=1&qfKey={$this->controller->_key}",
-            TRUE, NULL, FALSE
-          );
-          if (CRM_Utils_Array::value('additional_participants', $params, FALSE)) {
-            $urlArgs = "_qf_Participant_1_display=1&rfp=1&qfKey={$this->controller->_key}";
-          }
-          else {
-            $urlArgs = "_qf_Confirm_display=1&rfp=1&qfKey={$this->controller->_key}";
-          }
-          $params['returnURL'] = CRM_Utils_System::url('civicrm/event/register',
-            $urlArgs,
-            TRUE, NULL, FALSE
-          );
-          $params['invoiceID'] = $invoiceID;
+        $this->handlePreApproval($params);
 
-          $params['component'] = 'event';
-          $token = $payment->doPreApproval($params);
-          if (is_a($token, 'CRM_Core_Error')) {
-            CRM_Core_Error::displaySessionError($token);
-            CRM_Utils_System::redirect($params['cancelURL']);
-          }
+        $this->set('contributeMode', 'express');
 
-          $this->set('token', $token);
+        // Send Event Name & Id in Params
+        $params['eventName'] = $this->_values['event']['title'];
+        $params['eventId'] = $this->_values['event']['id'];
 
-          $paymentURL = $this->_paymentProcessor['url_site'] . "/cgi-bin/webscr?cmd=_express-checkout&token=$token";
+        $params['cancelURL'] = CRM_Utils_System::url('civicrm/event/register',
+          "_qf_Register_display=1&qfKey={$this->controller->_key}",
+          TRUE, NULL, FALSE
+        );
+        if (CRM_Utils_Array::value('additional_participants', $params, FALSE)) {
+          $urlArgs = "_qf_Participant_1_display=1&rfp=1&qfKey={$this->controller->_key}";
+        }
+        else {
+          $urlArgs = "_qf_Confirm_display=1&rfp=1&qfKey={$this->controller->_key}";
+        }
+        $params['returnURL'] = CRM_Utils_System::url('civicrm/event/register',
+          $urlArgs,
+          TRUE, NULL, FALSE
+        );
+        $params['invoiceID'] = $invoiceID;
 
-          CRM_Utils_System::redirect($paymentURL);
+        $params['component'] = 'event';
+        $token = $payment->doPreApproval($params);
+        if (is_a($token, 'CRM_Core_Error')) {
+          CRM_Core_Error::displaySessionError($token);
+          CRM_Utils_System::redirect($params['cancelURL']);
         }
+
+        $this->set('token', $token);
+
+        $paymentURL = $this->_paymentProcessor['url_site'] . "/cgi-bin/webscr?cmd=_express-checkout&token=$token";
+        CRM_Utils_System::redirect($paymentURL);
       }
       elseif ($this->_paymentProcessor &&
         $this->_paymentProcessor['billing_mode'] & CRM_Core_Payment::BILLING_MODE_NOTIFY
       ) {
         $this->set('contributeMode', 'notify');
       }
-    }
-    else {
-      $session = CRM_Core_Session::singleton();
-      $params['description'] = ts('Online Event Registration') . ' ' . $this->_values['event']['title'];
+      else {
+        $params['description'] = ts('Online Event Registration') . ' ' . $this->_values['event']['title'];
 
-      $this->_params = array();
-      $this->_params[] = $params;
-      $this->set('params', $this->_params);
+        $this->_params = array();
+        $this->_params[] = $params;
+        $this->set('params', $this->_params);
 
-      if (
-        empty($params['additional_participants'])
-        && !$this->_values['event']['is_confirm_enabled'] // CRM-11182 - Optional confirmation screen
-      ) {
-        self::processRegistration($this->_params);
+        if (
+          empty($params['additional_participants'])
+          && !$this->_values['event']['is_confirm_enabled'] // CRM-11182 - Optional confirmation screen
+        ) {
+          self::processRegistration($this->_params);
+        }
       }
     }
 
@@ -1186,8 +1182,6 @@ class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration {
    * @param array $params
    *   Form values.
    * @param int $contactID
-   *
-   * @return void
    */
   public function processRegistration($params, $contactID = NULL) {
     $session = CRM_Core_Session::singleton();
@@ -1313,7 +1307,7 @@ class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration {
         $primaryContactId, $isTest, TRUE
       );
 
-      //lets carry all paticipant params w/ values.
+      //lets carry all participant params w/ values.
       foreach ($additionalIDs as $participantID => $contactId) {
         $participantNum = NULL;
         if ($participantID == $registerByID) {
@@ -1366,7 +1360,7 @@ class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration {
    *
    * @param array $fields
    *   The input form values(anonymous user).
-   * @param array $self
+   * @param CRM_Event_Form_Registration_Register $self
    *   Event data.
    * @param bool $isAdditional
    *   Treat isAdditional participants a bit differently.