Merge pull request #4545 from monishdeb/CRM-15361
[civicrm-core.git] / CRM / Contribute / Form / AbstractEditPayment.php
index f9b9b054df8ef1e2fe878d4f1d58b47817aa674d..768730769faa7e9f6fc25dbc693995607c96ba41 100644 (file)
@@ -49,10 +49,22 @@ class CRM_Contribute_Form_AbstractEditPayment extends CRM_Core_Form {
   public $_paymentProcessor;
   public $_recurPaymentProcessors;
 
+  /**
+   * array of processor options in the format id => array($id => $label)
+   * WARNING it appears that the format used to differ to this and there are places in the code that
+   * expect the old format. $this->_paymentProcessors provides the additional data which this
+   * array seems to have provided in the past
+   * @var array
+   */
   public $_processors;
 
   /**
-   * the id of the contribution that we are proceessing
+   * available payment processors with full details including the key 'object' indexed by their id
+   * @var array
+   */
+  protected $_paymentProcessors = array();
+  /**
+   * the id of the contribution that we are processing
    *
    * @var int
    * @public
@@ -157,6 +169,13 @@ class CRM_Contribute_Form_AbstractEditPayment extends CRM_Core_Form {
    */
   public $_lineItems;
 
+  /**
+   * Is this a backoffice form
+   * (this will affect whether paypal express code is displayed)
+   * @var bool
+   */
+  public $isBackOffice = TRUE;
+
   protected $_formType;
   protected $_cdType;
 
@@ -246,6 +265,12 @@ WHERE  contribution_id = {$id}
 
   /**
    * This function process contribution related objects.
+   *
+   * @param integer $contributionId
+   * @param integer $statusId
+   * @param integer|null $previousStatusId
+   *
+   * @return null|string
    */
   protected function updateRelatedComponent($contributionId, $statusId, $previousStatusId = NULL) {
     $statusMsg = NULL;
@@ -335,54 +360,31 @@ LEFT JOIN  civicrm_contribution on (civicrm_contribution.contact_id = civicrm_co
   }
 
   /**
-   * @return array (0 => array(int $ppId => string $label), 1 => array(...payproc details...))
+   * @return array of valid processors. The array resembles the DB table but also has 'object' as a key
+   * @throws Exception
    */
-  public function getValidProcessorsAndAssignFutureStartDate() {
-    $validProcessors = array();
-    // restrict to payment_type = 1 (credit card only) and billing mode 1 and 3
-    $processors = CRM_Core_PseudoConstant::paymentProcessor(FALSE, FALSE, "billing_mode IN ( 1, 3 ) AND payment_type = 1");
-
-    foreach ($processors as $ppID => $label) {
-      $paymentProcessor = CRM_Financial_BAO_PaymentProcessor::getPayment($ppID, $this->_mode);
-      // at this stage only Authorize.net has been tested to support future start dates so if it's enabled let the template know
-      // to show receive date
-      $processorsSupportingFutureStartDate = array('AuthNet');
-      if (in_array($paymentProcessor['payment_processor_type'], $processorsSupportingFutureStartDate)) {
-        $this->assign('processorSupportsFutureStartDate', TRUE);
-      }
-      if ($paymentProcessor['payment_processor_type'] == 'PayPal' && !$paymentProcessor['user_name']) {
-        continue;
-      }
-      elseif ($paymentProcessor['payment_processor_type'] == 'Dummy' && $this->_mode == 'live') {
-        continue;
-      }
-      else {
-        $paymentObject = CRM_Core_Payment::singleton($this->_mode, $paymentProcessor, $this);
-        $error = $paymentObject->checkConfig();
-        if (empty($error)) {
-          $validProcessors[$ppID] = $label;
-        }
-        $paymentObject = NULL;
-      }
-    }
-    if (empty($validProcessors)) {
-      CRM_Core_Error::fatal(ts('You will need to configure the %1 settings for your Payment Processor before you can submit credit card transactions.', array(1 => $this->_mode)));
-    }
-    else {
-      return array($validProcessors, $paymentProcessor);
+  public function getValidProcessors() {
+    $defaultID = NULL;
+    $capabilities = array('BackOffice');
+    if ($this->_mode == 'live') {
+      $capabilities[] = 'LiveMode';
     }
+    $processors = CRM_Financial_BAO_PaymentProcessor::getPaymentProcessors($capabilities);
+    return $processors;
+
   }
 
   /**
    * Assign billing type id to bltID
    *
+   * @throws CRM_Core_Exception
    * @return void
    */
   public function assignBillingType() {
     $locationTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Address', 'location_type_id', array(), 'validate');
     $this->_bltID = array_search('Billing', $locationTypes);
     if (!$this->_bltID) {
-      CRM_Core_Error::fatal(ts('Please set a location type of %1', array(1 => 'Billing')));
+      throw new CRM_Core_Exception(ts('Please set a location type of %1', array(1 => 'Billing')));
     }
     $this->set('bltID', $this->_bltID);
     $this->assign('bltID', $this->_bltID);
@@ -394,9 +396,21 @@ LEFT JOIN  civicrm_contribution on (civicrm_contribution.contact_id = civicrm_co
   public function assignProcessors() {
     //ensure that processor has a valid config
     //only valid processors get display to user
-    if ($this->_mode) {
-      list($this->_processors, $paymentProcessor) = $this->getValidProcessorsAndAssignFutureStartDate();
 
+    if ($this->_mode) {
+      $this->assign(CRM_Financial_BAO_PaymentProcessor::hasPaymentProcessorSupporting(array('supportsFutureRecurStartDate')), TRUE);
+      $this->_paymentProcessors = $this->getValidProcessors();
+      if (!isset($this->_paymentProcessor['id'])) {
+        // if the payment processor isn't set yet (as indicated by the presence of an id,) we'll grab the first one which should be the default
+        $this->_paymentProcessor = reset($this->_paymentProcessors);
+      }
+      if (empty($this->_paymentProcessors)) {
+        throw new CRM_Core_Exception(ts('You will need to configure the %1 settings for your Payment Processor before you can submit a credit card transactions.', array(1 => $this->_mode)));
+      }
+      $this->_processors  = array();
+      foreach ($this->_paymentProcessors as $id => $processor) {
+        $this->_processors[$id] = ts($processor['name']);
+      }
       //get the valid recurring processors.
       $recurring = CRM_Core_PseudoConstant::paymentProcessor(FALSE, FALSE, 'is_recur = 1');
       $this->_recurPaymentProcessors = array_intersect_assoc($this->_processors, $recurring);
@@ -406,8 +420,8 @@ LEFT JOIN  civicrm_contribution on (civicrm_contribution.contact_id = civicrm_co
     );
 
     // this required to show billing block
-    $this->assign_by_ref('paymentProcessor', $paymentProcessor);
-    $this->assign('hidePayPalExpress', TRUE);
+    // @todo remove this assignment the billing block is now designed to be always included but will not show fieldsets unless those sets of fields are assigned
+    $this->assign_by_ref('paymentProcessor', $processor);
   }
 
   /**
@@ -567,4 +581,27 @@ LEFT JOIN  civicrm_contribution on (civicrm_contribution.contact_id = civicrm_co
     return $submittedValues;
   }
 
+  /**
+   * common block for setting up the parts of a form that relate to credit / debit card
+   * @throws Exception
+   */
+  protected function assignPaymentRelatedVariables() {
+    try {
+      if ($this->_contactID) {
+        list($this->userDisplayName, $this->userEmail) = CRM_Contact_BAO_Contact_Location::getEmailDetails($this->_contactID);
+        $this->assign('displayName', $this->userDisplayName);
+      }
+      if ($this->_mode) {
+        $this->assignProcessors();
+
+        $this->assignBillingType();
+
+        $this->_fields = array();
+        CRM_Core_Payment_Form::setPaymentFieldsByProcessor($this, $this->_paymentProcessor);
+      }
+    }
+    catch (CRM_Core_Exception $e) {
+      CRM_Core_Error::fatal($e->getMessage());
+    }
+  }
 }