CRM-13179 use api function so get billing defaults in order to use 'sensible fallback...
[civicrm-core.git] / CRM / Event / Form / Registration / Register.php
index 5a4f0336b92d9da53d240128ce80868582c4b084..7947fdb1ea20b5cee09134cee0431ead438cb9ec 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 /*
  +--------------------------------------------------------------------+
- | CiviCRM version 4.3                                                |
+ | CiviCRM version 4.4                                                |
  +--------------------------------------------------------------------+
  | Copyright CiviCRM LLC (c) 2004-2013                                |
  +--------------------------------------------------------------------+
@@ -80,18 +80,21 @@ class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration {
   function preProcess() {
     parent::preProcess();
 
-    CRM_Contribute_Form_Contribution_Main::preProcessPaymentOptions($this);
-    if ($this->_snippet) {
-      return;
-    }
-
     //CRM-4320.
     //here we can't use parent $this->_allowWaitlist as user might
     //walk back and we maight set this value in this postProcess.
     //(we set when spaces < group count and want to allow become part of waiting )
-
     $eventFull = CRM_Event_BAO_Participant::eventFull($this->_eventId, FALSE, CRM_Utils_Array::value('has_waitlist', $this->_values['event']));
 
+    // Get payment processors if appropriate for this event
+    // We hide the payment fields if the event is full or requires approval,
+    // and the current user has not yet been approved CRM-12279
+    $noFees = (($eventFull || $this->_requireApproval) && !$this->_allowConfirmation);
+    CRM_Contribute_Form_Contribution_Main::preProcessPaymentOptions($this, $noFees);
+    if ($this->_snippet) {
+      return;
+    }
+
     $this->_allowWaitlist = FALSE;
     if ($eventFull && !$this->_allowConfirmation &&
       CRM_Utils_Array::value('has_waitlist', $this->_values['event'])
@@ -137,38 +140,12 @@ class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration {
       // see function comment block for explanation of this
       return;
     }
-
-    $contactID = parent::getContactID();
+    $this->_defaults = array();
+    $contactID = $this->getContactID();
     if ($contactID) {
       //@todo CRM-11915 I observed that even when the billing block is not present the routine to retrieve the billing defaults is still called - which seems a bit redundant.
-      $names = array(
-        'first_name', 'middle_name', 'last_name',
-        "street_address-{$this->_bltID}", "city-{$this->_bltID}", "postal_code-{$this->_bltID}",
-        "country_id-{$this->_bltID}", "state_province_id-{$this->_bltID}",
-      );
-
-      foreach ($names as $name) {
-        $fields[$name] = 1;
-      }
-      $fields["state_province-{$this->_bltID}"] = 1;
-      $fields["country-{$this->_bltID}"] = 1;
-      $fields["email-{$this->_bltID}"] = 1;
-      $fields['email-Primary'] = 1;
-
-      CRM_Core_BAO_UFGroup::setProfileDefaults($contactID, $fields, $this->_defaults);
-
-      // use primary email address if billing email address is empty
-      if (empty($this->_defaults["email-{$this->_bltID}"]) &&
-        !empty($this->_defaults['email-Primary'])
-      ) {
-        $this->_defaults["email-{$this->_bltID}"] = $this->_defaults['email-Primary'];
-      }
-
-      foreach ($names as $name) {
-        if (isset($this->_defaults[$name])) {
-          $this->_defaults['billing_' . $name] = $this->_defaults[$name];
-        }
-      }
+      $billingDefaults = $this->getProfileDefaults('Billing', $contactID);
+      $this->_defaults = array_merge($this->_defaults, $billingDefaults);
     }
     $config = CRM_Core_Config::singleton();
     // set default country from config if no country set
@@ -176,10 +153,9 @@ class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration {
       $this->_defaults["billing_country_id-{$this->_bltID}"] = $config->defaultContactCountry;
     }
 
-    // now fix all state country selectors
-    CRM_Core_BAO_Address::fixAllStateSelects($this, $this->_defaults);
-
     if ($this->_snippet) {
+      // now fix all state country selectors
+      CRM_Core_BAO_Address::fixAllStateSelects($this, $this->_defaults);
       return $this->_defaults;
     }
 
@@ -211,6 +187,9 @@ class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration {
       CRM_Core_BAO_UFGroup::setProfileDefaults($contactID, $fields, $this->_defaults);
     }
 
+    // now fix all state country selectors
+    CRM_Core_BAO_Address::fixAllStateSelects($this, $this->_defaults);
+
     // Set default payment processor as default payment_processor radio button value
     if (!empty($this->_paymentProcessors)) {
       foreach ($this->_paymentProcessors as $pid => $value) {
@@ -330,6 +309,19 @@ class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration {
    * @access public
    */
   public function buildQuickForm() {
+    // build profiles first so that we can determine address fields etc
+    // and then show copy address checkbox
+    $this->buildCustom($this->_values['custom_pre_id'], 'customPre');
+    $this->buildCustom($this->_values['custom_post_id'], 'customPost');
+
+    if (!empty($this->_fields)) {
+      $profileAddressFields = array();
+      foreach ($this->_fields as $key => $value) {
+        CRM_Core_BAO_UFField::assignAddressField($key, $profileAddressFields);
+      }
+      $this->set('profileAddressFields', $profileAddressFields);
+    }
+
     // Build payment processor form
     if ($this->_ppType) {
       CRM_Core_Payment_ProcessorForm::buildQuickForm($this);
@@ -339,11 +331,10 @@ class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration {
       }
     }
 
-    $contactID = parent::getContactID();
+    $contactID = $this->getContactID();
     $this->assign('contact_id', $contactID);
     $this->assign('display_name', CRM_Contact_BAO_Contact::displayName($contactID));
 
-    $config = CRM_Core_Config::singleton();
     $this->add('hidden', 'scriptFee', NULL);
     $this->add('hidden', 'scriptArray', NULL);
 
@@ -402,9 +393,6 @@ class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration {
     $this->assign('allowGroupOnWaitlist', $allowGroupOnWaitlist);
     $this->assign('isAdditionalParticipants', $isAdditionalParticipants);
 
-    $this->buildCustom($this->_values['custom_pre_id'], 'customPre');
-    $this->buildCustom($this->_values['custom_post_id'], 'customPost');
-
     //lets get js on two different qf elements.
     $showHidePayfieldName = NULL;
     $showHidePaymentInformation = FALSE;
@@ -412,15 +400,21 @@ class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration {
       self::buildAmount($this);
     }
 
-    $pps = NULL;
-    $this->_paymentProcessors = $this->get('paymentProcessors');
+    $pps = array();
+    //@todo this processor adding fn is another one duplicated on contribute - a shared
+    // common class would make this sort of thing extractable
     if (!empty($this->_paymentProcessors)) {
-      $pps = $this->_paymentProcessors;
-      foreach ($pps as $key => & $name) {
+      foreach ($this->_paymentProcessors as $key => $name) {
+        if($name['billing_mode'] == 1) {
+          $onlinePaymentProcessorEnabled = TRUE;
+        }
         $pps[$key] = $name['name'];
       }
     }
-
+    if($this->getContactID() === '0' && !$this->_values['event']['is_multiple_registrations']) {
+      //@todo we are blocking for multiple registrations because we haven't tested
+      $this->addCidZeroOptions($onlinePaymentProcessorEnabled);
+    }
     if (CRM_Utils_Array::value('is_pay_later', $this->_values['event']) &&
       ($this->_allowConfirmation || (!$this->_requireApproval && !$this->_allowWaitlist))
     ) {
@@ -447,7 +441,7 @@ class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration {
     $this->assign('bypassPayment', $bypassPayment);
     $this->assign('showHidePaymentInformation', $showHidePaymentInformation);
 
-    $userID = parent::getContactID();
+    $userID = $this->getContactID();
 
     if (!$userID) {
       $createCMSUser = FALSE;
@@ -615,7 +609,7 @@ class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration {
           }
 
           //build the element.
-          CRM_Price_BAO_Field::addQuickFormElement($form,
+          CRM_Price_BAO_PriceField::addQuickFormElement($form,
             $elementName,
             $fieldId,
             FALSE,
@@ -831,13 +825,16 @@ class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration {
       }
 
       $lineItem = array();
-      CRM_Price_BAO_Set::processAmount($self->_values['fee'], $fields, $lineItem);
+      CRM_Price_BAO_PriceSet::processAmount($self->_values['fee'], $fields, $lineItem);
       if ($fields['amount'] < 0) {
         $errors['_qf_default'] = ts('Event Fee(s) can not be less than zero. Please select the options accordingly');
       }
     }
 
     if ($self->_values['event']['is_monetary']) {
+      if (($fields['amount'] > 0) && !isset($fields['payment_processor'])) {
+        $errors['payment_processor'] = ts('Please select a Payment Method');
+      }
       if (is_array($self->_paymentProcessor)) {
         $payment = CRM_Core_Payment::singleton($self->_mode, $self->_paymentProcessor, $this);
         $error = $payment->checkConfig($self->_mode);
@@ -846,8 +843,9 @@ class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration {
         }
       }
       // return if this is express mode
-      $config = CRM_Core_Config::singleton();
-      if ($self->_paymentProcessor['billing_mode'] & CRM_Core_Payment::BILLING_MODE_BUTTON) {
+      if ($self->_paymentProcessor &&
+        $self->_paymentProcessor['billing_mode'] & CRM_Core_Payment::BILLING_MODE_BUTTON
+      ) {
         if (CRM_Utils_Array::value($self->_expressButtonName . '_x', $fields) ||
           CRM_Utils_Array::value($self->_expressButtonName . '_y', $fields) ||
           CRM_Utils_Array::value($self->_expressButtonName, $fields)
@@ -856,7 +854,7 @@ class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration {
         }
       }
 
-      $isZeroAmount = $skipPayementValidation = FALSE;
+      $isZeroAmount = $skipPaymentValidation = FALSE;
       if (CRM_Utils_Array::value('priceSetId', $fields)) {
         if (CRM_Utils_Array::value('amount', $fields) == 0) {
           $isZeroAmount = TRUE;
@@ -878,41 +876,23 @@ class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration {
       }
 
       if ($isZeroAmount && !($self->_forcePayement && CRM_Utils_Array::value('additional_participants', $fields))) {
-        $skipPayementValidation = TRUE;
+        $skipPaymentValidation = TRUE;
       }
 
       // also return if paylater mode or zero fees for valid members
       if (CRM_Utils_Array::value('is_pay_later', $fields) ||
         CRM_Utils_Array::value('bypass_payment', $fields) ||
-        $skipPayementValidation ||
+        $skipPaymentValidation ||
         (!$self->_allowConfirmation && ($self->_requireApproval || $self->_allowWaitlist))
       ) {
         return empty($errors) ? TRUE : $errors;
       }
-      if (property_exists($self, '_paymentFields') && !empty($self->_paymentFields )) {
-        foreach ($self->_paymentFields as $name => $fld) {
-          if ($fld['is_required'] &&
-            CRM_Utils_System::isNull(CRM_Utils_Array::value($name, $fields))
-          ) {
-            $errors[$name] = ts('%1 is a required field.', array(1 => $fld['title']));
-          }
-        }
+      if (!empty($self->_paymentFields)) {
+        CRM_Core_Form::validateMandatoryFields($self->_paymentFields, $fields, $errors);
       }
+      CRM_Core_Payment_Form::validateCreditCard($fields, $errors);
     }
-    // make sure that credit card number and cvv are valid
-    if (CRM_Utils_Array::value('credit_card_type', $fields)) {
-      if (CRM_Utils_Array::value('credit_card_number', $fields) &&
-        !CRM_Utils_Rule::creditCardNumber($fields['credit_card_number'], $fields['credit_card_type'])
-      ) {
-        $errors['credit_card_number'] = ts('Please enter a valid Credit Card Number');
-      }
 
-      if (CRM_Utils_Array::value('cvv2', $fields) &&
-        !CRM_Utils_Rule::cvv($fields['cvv2'], $fields['credit_card_type'])
-      ) {
-        $errors['cvv2'] = ts('Please enter a valid Credit Card Verification Number');
-      }
-    }
     foreach (CRM_Contact_BAO_Contact::$_greetingTypes as $greeting) {
       if ($greetingType = CRM_Utils_Array::value($greeting, $fields)) {
         $customizedValue = CRM_Core_OptionGroup::getValue($greeting, 'Customized', 'name');
@@ -1055,7 +1035,7 @@ class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration {
       }
       else {
         $lineItem = array();
-        CRM_Price_BAO_Set::processAmount($this->_values['fee'], $params, $lineItem);
+        CRM_Price_BAO_PriceSet::processAmount($this->_values['fee'], $params, $lineItem);
         $this->set('lineItem', array($lineItem));
         $this->set('lineItemParticipantsCount', array($primaryParticipantCount));
       }
@@ -1099,7 +1079,9 @@ class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration {
       $this->_params[] = $params;
       $this->set('params', $this->_params);
 
-      if ($this->_paymentProcessor['billing_mode'] & CRM_Core_Payment::BILLING_MODE_BUTTON) {
+      if ($this->_paymentProcessor &&
+        $this->_paymentProcessor['billing_mode'] & CRM_Core_Payment::BILLING_MODE_BUTTON
+      ) {
         //get the button name
         $buttonName = $this->controller->getButtonName();
         if (in_array($buttonName,
@@ -1151,7 +1133,9 @@ class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration {
           CRM_Utils_System::redirect($paymentURL);
         }
       }
-      elseif ($this->_paymentProcessor['billing_mode'] & CRM_Core_Payment::BILLING_MODE_NOTIFY) {
+      elseif ($this->_paymentProcessor &&
+        $this->_paymentProcessor['billing_mode'] & CRM_Core_Payment::BILLING_MODE_NOTIFY
+      ) {
         $this->set('contributeMode', 'notify');
       }
     }
@@ -1235,7 +1219,7 @@ class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration {
           $contactID = $value['contact_id'];
         }
         else {
-          $contactID = parent::getContactID();
+          $contactID = $this->getContactID();
         }
 
         CRM_Event_Form_Registration_Confirm::fixLocationFields($value, $fields);
@@ -1250,7 +1234,7 @@ class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration {
         // we dont store in userID in case the user is doing multiple
         // transactions etc
         // for things like tell a friend
-        if (!parent::getContactID() && CRM_Utils_Array::value('is_primary', $value)) {
+        if (!$this->getContactID() && CRM_Utils_Array::value('is_primary', $value)) {
           $session->set('transaction.userID', $contactID);
         }
 
@@ -1382,7 +1366,7 @@ class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration {
     $contactID = NULL;
     $session = CRM_Core_Session::singleton();
     if (!$isAdditional) {
-      $contactID = parent::getContactID();
+      $contactID = $self->getContactID();
     }
 
     if (!$contactID && is_array($fields) && $fields) {