CRM-15555 towards allowing processor fields to be set by processors
authorEileen McNaughton <eileen@fuzion.co.nz>
Mon, 3 Nov 2014 04:26:56 +0000 (17:26 +1300)
committerEileen McNaughton <eileen@fuzion.co.nz>
Mon, 3 Nov 2014 04:26:56 +0000 (17:26 +1300)
CRM/Contribute/Form/AbstractEditPayment.php
CRM/Contribute/Form/Contribution.php
CRM/Core/Payment.php
CRM/Core/Payment/Form.php
CRM/Financial/BAO/PaymentProcessor.php
CRM/Utils/String.php
api/api.php
templates/CRM/Core/BillingBlock.tpl

index 34f031ce6ecc55a9ba60d7f2fdc01c24f30337b7..5612dae1ae29cf723a467e75c3d3ec7238eb6e47 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
@@ -341,10 +353,7 @@ 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
+   * @return array of valid processors. The array resembles the DB table but also has 'object' as a key
    * @throws Exception
    */
   public function getValidProcessors() {
@@ -383,12 +392,16 @@ LEFT JOIN  civicrm_contribution on (civicrm_contribution.contact_id = civicrm_co
 
     if ($this->_mode) {
       $this->assign(CRM_Financial_BAO_PaymentProcessor::hasPaymentProcessorSupporting(array('supportsFutureRecurStartDate')), TRUE);
-      $processors = $this->getValidProcessors();
-      if (empty($processors)) {
+      $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 ($processors as $id => $processor) {
+      foreach ($this->_paymentProcessors as $id => $processor) {
         $this->_processors[$id] = ts($processor['name']);
       }
       //get the valid recurring processors.
index cca070f75773a0d37e1da183230990bad9721939..d34144b289bf0d5b807ea2b266f3d83ac8838c5e 100644 (file)
@@ -287,7 +287,7 @@ class CRM_Contribute_Form_Contribution extends CRM_Contribute_Form_AbstractEditP
       $this->assignBillingType();
 
       $this->_fields = array();
-      CRM_Core_Payment_Form::setPaymentFieldsByType(CRM_Utils_Array::value('payment_type', $this->_processors), $this);
+      CRM_Core_Payment_Form::setPaymentFieldsByProcessor($this, $this->_paymentProcessor);
     }
     catch (CRM_Core_Exception $e) {
       CRM_Core_Error::fatal($e->getMessage());
@@ -496,6 +496,7 @@ class CRM_Contribute_Form_Contribution extends CRM_Contribute_Form_AbstractEditP
    * @access public
    */
   public function buildQuickForm() {
+    //@todo document the purpose of cdType (if still in use)
     if ($this->_cdType) {
       CRM_Custom_Form_CustomData::buildQuickForm($this);
       return;
@@ -579,21 +580,16 @@ class CRM_Contribute_Form_Contribution extends CRM_Contribute_Form_AbstractEditP
       $paneNames[ts('Premium Information')] = 'Premium';
     }
 
-    $ccPane = NULL;
     if ($this->_mode) {
-      if (CRM_Utils_Array::value('payment_type', $this->_processors) & CRM_Core_Payment::PAYMENT_TYPE_DIRECT_DEBIT
-      ) {
-        $ccPane = array(ts('Direct Debit Information') => 'DirectDebit');
-      }
-      else {
-        $ccPane = array(ts('Credit Card Information') => 'CreditCard');
+      if (CRM_Core_Payment_Form::buildPaymentForm($this, $this->_paymentProcessor, FALSE) == TRUE) {
+        $buildRecurBlock = TRUE;
+        foreach ($this->billingPane as $name => $label) {
+          //@todo reduce variation so we don't have to convert 'credit_card' to 'CreditCard'
+          $paneNames[$label] = CRM_Utils_String::convertStringToCamel($name);
+        }
       }
     }
-    if (is_array($ccPane)) {
-      $paneNames = array_merge($ccPane, $paneNames);
-    }
 
-    $buildRecurBlock = FALSE;
     foreach ($paneNames as $name => $type) {
       $urlParams = "snippet=4&formType={$type}";
       if ($this->_mode) {
@@ -621,15 +617,9 @@ class CRM_Contribute_Form_Contribution extends CRM_Contribute_Form_AbstractEditP
         $allPanes[$name]['open'] = 'true';
       }
 
-      if ($type == 'CreditCard') {
-        $buildRecurBlock = TRUE;
-        $this->add('hidden', 'hidden_CreditCard', 1);
-        CRM_Core_Payment_Form::buildCreditCard($this, TRUE);
-      }
-      elseif ($type == 'DirectDebit') {
-        $buildRecurBlock = TRUE;
-        $this->add('hidden', 'hidden_DirectDebit', 1);
-        CRM_Core_Payment_Form::buildDirectDebit($this, TRUE);
+      if ($type == 'CreditCard' || $type == 'DirectDebit') {
+        //@todo would be good to align tpl name with form name...
+        $this->add('hidden', 'hidden_' . $type, 1);
       }
       else {
         $additionalInfoFormFunction = 'build' . $type;
index 432b1c21f1b8f691ac063abbfc2988fb320e4687..bfc013bc9bc6dbe642732b7315d32b559828dd4b 100644 (file)
@@ -206,11 +206,32 @@ abstract class CRM_Core_Payment {
   /**
    * Getter for accessing member vars
    *
+   * @param $name
+   *
+   * @return null
    */
   function getVar($name) {
     return isset($this->$name) ? $this->$name : NULL;
   }
 
+  /**
+   * get name for the payment information type
+   *
+   * @return string
+   */
+  public function getPaymentTypeName() {
+    return $this->_paymentProcessor['payment_type'] == 1 ? 'credit_card' : 'debit_card';
+  }
+
+  /**
+   * get label for the payment information type
+   *
+   * @return string
+   */
+  public function getPaymentTypeLabel() {
+    return $this->_paymentProcessor['payment_type'] == 1 ? 'Credit Card' : 'Debit Card';
+  }
+
   /**
    * get array of fields that should be displayed on the payment form
    * @todo make payment type an option value & use it in the function name - currently on debit & credit card work
@@ -218,7 +239,7 @@ abstract class CRM_Core_Payment {
    * @throws CiviCRM_API3_Exception
    */
   public function getPaymentFormFields() {
-    if ($this->_paymentProcessor['payment_type'] == 4) {
+    if ($this->_paymentProcessor['billing_mode'] == 4) {
       return array();
     }
     return $this->_paymentProcessor['payment_type'] == 1 ? $this->getCreditCardFormFields() : $this->getDirectDebitFormFields();
@@ -226,6 +247,7 @@ abstract class CRM_Core_Payment {
 
   /**
    * get array of fields that should be displayed on the payment form for credit cards
+   *
    * @return array
    */
   protected function getCreditCardFormFields() {
@@ -239,6 +261,7 @@ abstract class CRM_Core_Payment {
 
   /**
    * get array of fields that should be displayed on the payment form for direct debits
+   *
    * @return array
    */
   protected function getDirectDebitFormFields() {
@@ -250,6 +273,137 @@ abstract class CRM_Core_Payment {
     );
   }
 
+  /**
+   * return an array of all the details about the fields potentially required for payment fields
+   * Only those determined by getPaymentFormFields will actually be assigned to the form
+   *
+   * @return array field metadata
+   */
+  public function getPaymentFormFieldsMetadata() {
+    //@todo convert credit card type into an option value
+    $creditCardType = array('' => ts('- select -')) + CRM_Contribute_PseudoConstant::creditCard();
+    return array(
+      'credit_card_number' => array(
+        'htmlType' => 'text',
+        'name' => 'credit_card_number',
+        'title' => ts('Card Number'),
+        'cc_field' => TRUE,
+        'attributes' => array(
+          'size' => 20,
+          'maxlength' => 20,
+          'autocomplete' => 'off'
+        ),
+        'is_required' => TRUE,
+      ),
+      'cvv2' => array(
+        'htmlType' => 'text',
+        'name' => 'cvv2',
+        'title' => ts('Security Code'),
+        'cc_field' => TRUE,
+        'attributes' => array(
+          'size' => 5,
+          'maxlength' => 10,
+          'autocomplete' => 'off'
+        ),
+        'is_required' => CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::CONTRIBUTE_PREFERENCES_NAME,
+          'cvv_backoffice_required',
+          NULL,
+          1
+        ),
+        'rules' => array(
+          array(
+            'rule_message' => ts('Please enter a valid value for your card security code. This is usually the last 3-4 digits on the card\'s signature panel.'),
+            'rule_name' => 'integer',
+            'rule_parameters' => NULL,
+        )),
+      ),
+      'credit_card_exp_date' => array(
+        'htmlType' => 'date',
+        'name' => 'credit_card_exp_date',
+        'title' => ts('Expiration Date'),
+        'cc_field' => TRUE,
+        'attributes' => CRM_Core_SelectValues::date('creditCard'),
+        'is_required' => TRUE,
+        'rules' => array(
+          array(
+            'rule_message' => ts('Card expiration date cannot be a past date.'),
+            'rule_name' => 'currentDate',
+            'rule_parameters' => TRUE,
+          )),
+      ),
+      'credit_card_type' => array(
+        'htmlType' => 'select',
+        'name' => 'credit_card_type',
+        'title' => ts('Card Type'),
+        'cc_field' => TRUE,
+        'attributes' => $creditCardType,
+        'is_required' => FALSE,
+      ),
+      'account_holder' => array(
+        'htmlType' => 'text',
+        'name' => 'account_holder',
+        'title' => ts('Account Holder'),
+        'cc_field' => TRUE,
+        'attributes' => array(
+          'size' => 20,
+          'maxlength' => 34,
+          'autocomplete' => 'on'
+        ),
+        'is_required' => TRUE,
+      ),
+      //e.g. IBAN can have maxlength of 34 digits
+      'bank_account_number' => array(
+        'htmlType' => 'text',
+        'name' => 'bank_account_number',
+        'title' => ts('Bank Account Number'),
+        'cc_field' => TRUE,
+        'attributes' => array(
+          'size' => 20,
+          'maxlength' => 34,
+          'autocomplete' => 'off'
+        ),
+        'rules' => array(
+          array(
+            'rule_message' => ts('Please enter a valid Bank Identification Number (value must not contain punctuation characters).'),
+            'rule_name' => 'nopunctuation',
+            'rule_parameters' => NULL,
+        )),
+        'is_required' => TRUE,
+      ),
+      //e.g. SWIFT-BIC can have maxlength of 11 digits
+      'bank_identification_number' => array(
+        'htmlType' => 'text',
+        'name' => 'bank_identification_number',
+        'title' => ts('Bank Identification Number'),
+        'cc_field' => TRUE,
+        'attributes' => array(
+          'size' => 20,
+          'maxlength' => 11,
+          'autocomplete' => 'off'
+        ),
+        'is_required' => TRUE,
+        'rules' => array(
+          array(
+            'rule_message' => ts('Please enter a valid Bank Identification Number (value must not contain punctuation characters).'),
+            'rule_name' => 'nopunctuation',
+            'rule_parameters' => NULL,
+        )),
+      ),
+      'bank_name' => array(
+        'htmlType' => 'text',
+        'name' => 'bank_name',
+        'title' => ts('Bank Name'),
+        'cc_field' => TRUE,
+        'attributes' => array(
+          'size' => 20,
+          'maxlength' => 64,
+          'autocomplete' => 'off'
+        ),
+        'is_required' => TRUE,
+
+      )
+    );
+  }
 
   /**
    * This function collects all the information from a web/api form and invokes
index b7074407e8fc7a636d3969fad2d8c8459946f6e2..ee191dbc2e72edb96412fc337406768a05386fee 100644 (file)
@@ -36,7 +36,7 @@ class CRM_Core_Payment_Form {
 
   /**
    * Add payment fields are depending on payment type
-   *
+   * @deprecated  - use the setPaymentFieldsByPaymentType which leverages the processor to determine the fields
    * @param int $type eg CRM_Core_Payment::PAYMENT_TYPE_DIRECT_DEBIT
    * @param CRM_Core_Form $form
    */
@@ -49,6 +49,34 @@ class CRM_Core_Payment_Form {
     }
   }
 
+
+  /**
+   * Add payment fields are depending on payment type
+   *
+   * @param CRM_Core_Form $form
+   * @param array $processor array of properties including 'object' as loaded from CRM_Financial_BAO_PaymentProcessor::getPaymentProcessors
+   */
+  static public function setPaymentFieldsByProcessor(&$form, $processor) {
+    $form->billingFieldSets = array();
+    $paymentFields = self::getPaymentFields($processor);
+    dpm($paymentFields);
+    $paymentTypeName = self::getPaymentTypeName($processor);
+    $paymentTypeLabel = self::getPaymentTypeLabel($processor);
+    //@todo if we switch to iterating through the fieldsets we won't need to assign these directly
+    $form->assign('paymentTypeName', $paymentTypeName);
+    $form->assign('paymentTypeLabel', $paymentTypeLabel);
+
+    $form->billingFieldSets[$paymentTypeName]['fields'] = $form->_paymentFields = array_intersect_key(self::getPaymentFieldMetadata($processor), array_flip($paymentFields));
+    $form->billingPane = array($paymentTypeName => $paymentTypeLabel);
+    $form->assign('paymentFields', $paymentFields);
+    if ($processor['billing_mode'] != 4) {
+      //@todo setPaymentFields defines the billing fields - this should be moved to the processor class & renamed getBillingFields
+      //also set the billingFieldSet to hold all the details required to render the fieldset so we can iterate through the fieldset - making
+      // it easier to re-order. For not the billingFieldSets param is used to determine whether to show the billing pane
+      CRM_Core_Payment_Form::_setPaymentFields($form);
+      $form->billingFieldSets['billing_name_address-group']['fields'] = array();
+    }
+  }
   /**
    * create all common fields needed for a credit card or direct debit transaction
    *
@@ -148,7 +176,7 @@ class CRM_Core_Payment_Form {
 
   /**
    * create all fields needed for a credit card transaction
-   *
+   * @deprecated  - use the setPaymentFieldsByPaymentType which leverages the processor to determine the fields
    * @param CRM_Core_Form $form
    *
    * @return void
@@ -208,9 +236,10 @@ class CRM_Core_Payment_Form {
   /**
    * @param CRM_Core_Form $form
    * @param bool $useRequired
+   * @param array $paymentFields
    */
-  static function addCommonFields(&$form, $useRequired) {
-    foreach ($form->_paymentFields as $name => $field) {
+  static function addCommonFields(&$form, $useRequired, $paymentFields) {
+    foreach ($paymentFields as $name => $field) {
       if (!empty($field['cc_field'])) {
         if ($field['htmlType'] == 'chainSelect') {
           $form->addChainSelect($field['name'], array('required' => $useRequired && $field['is_required']));
@@ -229,7 +258,7 @@ class CRM_Core_Payment_Form {
 
   /**
    * create all fields needed for direct debit transaction
-   *
+   * @deprecated  - use the setPaymentFieldsByPaymentType which leverages the processor to determine the fields
    * @param $form
    *
    * @return void
@@ -286,37 +315,102 @@ class CRM_Core_Payment_Form {
 
   /**
    * @param array $paymentProcessor
-   * @todo it may be necessary to set details that affect it - mostly likely take Country as a param
+   * @todo it will be necessary to set details that affect it - mostly likely take Country as a param. Should we add generic
+   * setParams on processor class or just setCountry which we know we need?
    *
-   * @return mixed
+   * @return array
    */
   static function getPaymentFields($paymentProcessor) {
-    return array();
     $paymentProcessorObject = CRM_Core_Payment::singleton(($paymentProcessor['is_test'] ? 'test' : 'live'), $paymentProcessor);
-    return $paymentProcessorObject->getPaymentFields();
+    return $paymentProcessorObject->getPaymentFormFields();
   }
 
   /**
-   * @param $form
+   * @param array $paymentProcessor
    *
+   * @return array
+   */
+  static function getPaymentFieldMetadata($paymentProcessor) {
+    $paymentProcessorObject = CRM_Core_Payment::singleton(($paymentProcessor['is_test'] ? 'test' : 'live'), $paymentProcessor);
+    return $paymentProcessorObject->getPaymentFormFieldsMetadata();
+  }
+
+  /**
    * @param array $paymentProcessor
-   * @todo it may be necessary to set details that affect it - mostly likely take Country as a param
    *
-   * @return mixed
+   * @return string
    */
-  protected static function setPaymentFields(&$form, $paymentProcessor) {
-    $fields = self::getPaymentFields($paymentProcessor);
+  static function getPaymentTypeName($paymentProcessor) {
+    $paymentProcessorObject = CRM_Core_Payment::singleton(($paymentProcessor['is_test'] ? 'test' : 'live'), $paymentProcessor);
+    return $paymentProcessorObject->getPaymentTypeName();
+  }
 
+  /**
+   * @param array $paymentProcessor
+   *
+   * @return string
+   */
+  static function getPaymentTypeLabel($paymentProcessor) {
+    $paymentProcessorObject = CRM_Core_Payment::singleton(($paymentProcessor['is_test'] ? 'test' : 'live'), $paymentProcessor);
+    return ts(($paymentProcessorObject->getPaymentTypeLabel()) . ' Information');
   }
 
-  static function buildPaymentForm(&$form, $useRequired = FALSE) {
+  /**
+   * @param CRM_Core_Form $form
+   * @param array $processor array of properties including 'object' as loaded from CRM_Financial_BAO_PaymentProcessor::getPaymentProcessors
+   * @param bool $isBillingDataOptional
+   *
+   * @return bool
+   */
+  static function buildPaymentForm($form, $processor, $isBillingDataOptional){
+    self::setPaymentFieldsByProcessor($form, $processor);
+    self::addCommonFields($form, !$isBillingDataOptional, $form->_paymentFields);
+    self::addRules($form, $form->_paymentFields);
+    self::addPaypalExpressCode($form);
+    return (!empty($form->_paymentFields));
+  }
 
+  /**
+   * @param CRM_Core_Form $form
+   * @param array $paymentFields array of properties including 'object' as loaded from CRM_Financial_BAO_PaymentProcessor::getPaymentProcessors
+
+   * @param $paymentFields
+   */
+  static function addRules(&$form, $paymentFields) {
+    foreach ($paymentFields as $paymentField => $fieldSpecs) {
+      if (!empty($fieldSpecs['rules'])) {
+        foreach ($fieldSpecs['rules'] as $rule) {
+          $form->addRule($paymentField,
+            $rule['rule_message'],
+            $rule['rule_name'],
+            $rule['rule_parameters']
+          );
+        }
+      }
+    }
   }
 
   /**
-   * Function to add all the credit card fields
+   * billing mode button is basically synonymous with paypal express  - this is probably a good example of 'odds & sods' code we
+   * need to find a way for the payment processor to assign. A tricky aspect is that the payment processor may need to set the order
    *
    * @param $form
+   */
+  static function addPaypalExpressCode(&$form) {
+    if ($form->_paymentProcessor['billing_mode'] & CRM_Core_Payment::BILLING_MODE_BUTTON) {
+      $form->_expressButtonName = $form->getButtonName('upload', 'express');
+      $form->assign('expressButtonName', $form->_expressButtonName);
+      $form->add('image',
+        $form->_expressButtonName,
+        $form->_paymentProcessor['url_button'],
+        array('class' => 'crm-form-submit')
+      );
+    }
+  }
+  /**
+   * Function to add all the credit card fields
+   * @deprecated Use BuildPaymentForm
+   * @param $form
    * @param bool $useRequired
    *
    * @return void
@@ -325,7 +419,7 @@ class CRM_Core_Payment_Form {
   static function buildCreditCard(&$form, $useRequired = FALSE) {
     if ($form->_paymentProcessor['billing_mode'] & CRM_Core_Payment::BILLING_MODE_FORM) {
       self::setCreditCardFields($form);
-      self::addCommonFields($form, $useRequired);
+      self::addCommonFields($form, $useRequired, $form->_paymentFields);
 
       $form->addRule('cvv2',
         ts('Please enter a valid value for your card security code. This is usually the last 3-4 digits on the card\'s signature panel.'),
@@ -339,6 +433,7 @@ class CRM_Core_Payment_Form {
 
     }
 
+
     if ($form->_paymentProcessor['billing_mode'] & CRM_Core_Payment::BILLING_MODE_BUTTON) {
       $form->_expressButtonName = $form->getButtonName('upload', 'express');
       $form->assign('expressButtonName', $form->_expressButtonName);
@@ -379,7 +474,7 @@ class CRM_Core_Payment_Form {
   static function buildDirectDebit(&$form, $useRequired = FALSE) {
     if ($form->_paymentProcessor['billing_mode'] & CRM_Core_Payment::BILLING_MODE_FORM) {
       self::setDirectDebitFields($form);
-      self::addCommonFields($form, $useRequired);
+      self::addCommonFields($form, $useRequired, $form->_paymentFields);
 
       $form->addRule('bank_identification_number',
         ts('Please enter a valid Bank Identification Number (value must not contain punctuation characters).'),
@@ -391,15 +486,6 @@ class CRM_Core_Payment_Form {
         'nopunctuation'
       );
     }
-
-    if ($form->_paymentProcessor['billing_mode'] & CRM_Core_Payment::BILLING_MODE_BUTTON) {
-      $form->_expressButtonName = $form->getButtonName($form->buttonType(), 'express');
-      $form->add('image',
-        $form->_expressButtonName,
-        $form->_paymentProcessor['url_button'],
-        array('class' => 'crm-form-submit')
-      );
-    }
   }
 
   /**
index 1a72cbf6ab152349e4a3965877fff1d0af758370..c26e03780cc55aebb754f6c198127597e7601578 100644 (file)
@@ -302,7 +302,7 @@ class CRM_Financial_BAO_PaymentProcessor extends CRM_Financial_DAO_PaymentProces
       }
     }
      * */
-    $retrievalParameters = array('is_active' => TRUE, 'options' => array('sort' => 'is_default, name'));
+    $retrievalParameters = array('is_active' => TRUE, 'options' => array('sort' => 'is_default DESC, name'));
     if ($isExcludeTest) {
       $retrievalParameters['is_test'] = 0;
     }
@@ -324,12 +324,18 @@ class CRM_Financial_BAO_PaymentProcessor extends CRM_Financial_DAO_PaymentProces
    * @param array $capabilities
    * @param bool $isIncludeTest
    *
+   * @param array $ids
+   *
    * @return array available processors
    */
-  static function getPaymentProcessors($capabilities = array(), $isIncludeTest = FALSE, $reset = FALSE) {
+  static function getPaymentProcessors($capabilities = array(), $isIncludeTest = FALSE, $ids = array()) {
     $processors = self::getAllPaymentProcessors(!$isIncludeTest);
     if ($capabilities) {
       foreach ($processors as $index => $processor) {
+        if (!empty($ids) && !in_array($processor['id'], $ids)) {
+          unset ($processors[$index]);
+          continue;
+        }
         if (($error = $processor['object']->checkConfig()) != NULL) {
           unset ($processors[$index]);
           continue;
index 1643491496d49a1c352e489abb4245c00591ad29..79f4f7af05b24113d01c1a4aa35617e44eb0243a 100644 (file)
@@ -102,6 +102,26 @@ class CRM_Utils_String {
     }
   }
 
+  /**
+   * convert possibly underscore separated words to camel case with special handling for 'UF'
+   * e.g
+   * membership_payment returns MembershipPayment
+   * @param string $string
+   *
+   * @return string string
+   */
+  static function convertStringToCamel($string) {
+    $fragments = explode('_', $string);
+    foreach ($fragments as & $fragment) {
+      $fragment = ucfirst($fragment);
+    }
+    // Special case: UFGroup, UFJoin, UFMatch, UFField
+    if ($fragments[0] === 'Uf') {
+      $fragments[0] = 'UF';
+    }
+    return implode('', $fragments);
+  }
+
   /**
    *
    * Takes a variable name and munges it randomly into another variable name
index c09d220249775dfe0cc439890f1aa65e28676fb1..8882e8df90f85a3611cf668d8a581ca1978431c3 100644 (file)
@@ -100,20 +100,11 @@ function civicrm_error($result) {
 
 /**
  * @param $entity
- * @param null $version
  *
  * @return string
  */
-function _civicrm_api_get_camel_name($entity, $version = NULL) {
-  $fragments = explode('_', $entity);
-  foreach ($fragments as & $fragment) {
-    $fragment = ucfirst($fragment);
-  }
-  // Special case: UFGroup, UFJoin, UFMatch, UFField
-  if ($fragments[0] === 'Uf') {
-    $fragments[0] = 'UF';
-  }
-  return implode('', $fragments);
+function _civicrm_api_get_camel_name($entity) {
+  return CRM_Utils_String::convertStringToCamel($entity);
 }
 
 /**
index 56cad1d54086e6c89ef8900b9e9073abba048d9a..f172e866ba550e9b9583b2c6e8014758b75f9220 100644 (file)
@@ -25,7 +25,7 @@
 *}
 {crmRegion name="billing-block"}
 <div id="payment_information">
-  {if $paymentFields}
+  {if $paymentFields|@count}
     <fieldset class="billing_mode-group {$paymentTypeName}_info-group">
       <legend>
         {$paymentTypeLabel}
@@ -51,7 +51,7 @@
       </div>
     </fieldset>
   {/if}
-  {if $billingDetailsFields}
+  {if $billingDetailsFields|@count}
     {if $profileAddressFields}
       <input type="checkbox" id="billingcheckbox" value="0">
       <label for="billingcheckbox">{ts}My billing address is the same as above{/ts}</label>