Php8.x fixes on Main online contribution page
authorEileen McNaughton <emcnaughton@wikimedia.org>
Sun, 15 Oct 2023 21:58:32 +0000 (10:58 +1300)
committerEileen McNaughton <emcnaughton@wikimedia.org>
Mon, 16 Oct 2023 05:45:13 +0000 (18:45 +1300)
CRM/Contribute/Form/Contribution/Main.php
CRM/Contribute/Form/ContributionBase.php
CRM/Price/BAO/PriceField.php
CRM/Profile/Form.php
templates/CRM/Contribute/Form/Contribution/Main.tpl

index e291f8c16cb738e98403bbad93a3b666b3fd5bb6..897d29d78683cdf4408fabeb922427bc56134a78 100644 (file)
@@ -126,14 +126,14 @@ class CRM_Contribute_Form_Contribution_Main extends CRM_Contribute_Form_Contribu
       // remove component related fields
       foreach ($this->_fields as $name => $fieldInfo) {
         //don't set custom data Used for Contribution (CRM-1344)
-        if (substr($name, 0, 7) == 'custom_') {
+        if (substr($name, 0, 7) === 'custom_') {
           $id = substr($name, 7);
           if (!CRM_Core_BAO_CustomGroup::checkCustomField($id, ['Contribution', 'Membership'])) {
             continue;
           }
           // ignore component fields
         }
-        elseif (array_key_exists($name, $contribFields) || (substr($name, 0, 11) == 'membership_') || (substr($name, 0, 13) == 'contribution_')) {
+        elseif (array_key_exists($name, $contribFields) || (substr($name, 0, 11) === 'membership_') || (substr($name, 0, 13) == 'contribution_')) {
           continue;
         }
         $fields[$name] = $fieldInfo;
@@ -146,8 +146,9 @@ class CRM_Contribute_Form_Contribution_Main extends CRM_Contribute_Form_Contribu
       $billingDefaults = $this->getProfileDefaults('Billing', $contactID);
       $this->_defaults = array_merge($this->_defaults, $billingDefaults);
     }
-    if (!empty($this->_ccid) && !empty($this->_pendingAmount)) {
-      $this->_defaults['total_amount'] = CRM_Utils_Money::formatLocaleNumericRoundedForDefaultCurrency($this->_pendingAmount);
+    $balance = $this->getContributionBalance();
+    if ($balance) {
+      $this->_defaults['total_amount'] = CRM_Utils_Money::formatLocaleNumericRoundedForDefaultCurrency($balance);
     }
 
     /*
@@ -401,10 +402,9 @@ class CRM_Contribute_Form_Contribution_Main extends CRM_Contribute_Form_Contribu
         CRM_Core_BAO_CMSUser::buildForm($this, $profileID, TRUE);
       }
     }
-    if ($this->_pcpId && empty($this->_ccid)) {
+    if ($this->getPcpID() && empty($this->_ccid)) {
       if (CRM_PCP_BAO_PCP::displayName($this->_pcpId)) {
         $pcp_supporter_text = CRM_PCP_BAO_PCP::getPcpSupporterText($this->_pcpId, $this->_id, 'contribute');
-        $this->assign('pcpSupporterText', $pcp_supporter_text);
       }
       $prms = ['id' => $this->_pcpId];
       CRM_Core_DAO::commonRetrieve('CRM_PCP_DAO_PCP', $prms, $pcpInfo);
@@ -420,6 +420,7 @@ class CRM_Contribute_Form_Contribution_Main extends CRM_Contribute_Form_Contribu
         $this->addField('pcp_personal_note', ['entity' => 'ContributionSoft', 'context' => 'create', 'style' => 'height: 3em; width: 40em;']);
       }
     }
+    $this->assign('pcpSupporterText', $pcp_supporter_text ?? NULL);
     if (empty($this->_values['fee']) && empty($this->_ccid)) {
       throw new CRM_Core_Exception(ts('This page does not have any price fields configured or you may not have permission for them. Please contact the site administrator for more details.'));
     }
@@ -542,13 +543,29 @@ class CRM_Contribute_Form_Contribution_Main extends CRM_Contribute_Form_Contribu
         }
         if (!empty($options)) {
           $label = (!empty($this->_membershipBlock) && $field['name'] === 'contribution_amount') ? ts('Additional Contribution') : $field['label'];
+          $extra = [];
+          $fieldID = (int) $field['id'];
+          if ($fieldID === $this->getPriceFieldOtherID()) {
+            $extra = [
+              'onclick' => 'useAmountOther("price_' . $this->getPriceFieldMainID() . '");',
+              'autocomplete' => 'off',
+            ];
+          }
+          if ($fieldID === $this->getPriceFieldMainID()) {
+            $extra = [
+              'onclick' => 'clearAmountOther("price_' . $this->getPriceFieldOtherID() . '");',
+            ];
+          }
+
           CRM_Price_BAO_PriceField::addQuickFormElement($form,
-            'price_' . $field['id'],
+            'price_' . $fieldID,
             $field['id'],
             FALSE,
             $field['is_required'] ?? FALSE,
             $label,
-            $options
+            $options,
+            [],
+            $extra
           );
         }
       }
@@ -556,6 +573,46 @@ class CRM_Contribute_Form_Contribution_Main extends CRM_Contribute_Form_Contribu
     $form->assign('ispricelifetime', $checklifetime);
   }
 
+  /**
+   * Get the idea of the other amount field if the form is configured to offer it.
+   *
+   * The other amount field is an alternative to the configured radio options,
+   * specific to this form.
+   *
+   * @return int|null
+   */
+  private function getPriceFieldOtherID(): ?int {
+    if (!$this->isQuickConfig()) {
+      return NULL;
+    }
+    foreach ($this->order->getPriceFieldsMetadata() as $field) {
+      if ($field['name'] === 'other_amount') {
+        return (int) $field['id'];
+      }
+    }
+    return NULL;
+  }
+
+  /**
+   * Get the idea of the other amount field if the form is configured to offer an other amount.
+   *
+   * The other amount field is an alternative to the configured radio options,
+   * specific to this form.
+   *
+   * @return int|null
+   */
+  private function getPriceFieldMainID(): ?int {
+    if (!$this->isQuickConfig() || !$this->getPriceFieldOtherID()) {
+      return NULL;
+    }
+    foreach ($this->order->getPriceFieldsMetadata() as $field) {
+      if ($field['name'] !== 'other_amount') {
+        return (int) $field['id'];
+      }
+    }
+    return NULL;
+  }
+
   /**
    * Build Membership  Block in Contribution Pages.
    * @todo this was shared on CRM_Contribute_Form_ContributionBase but we are refactoring and simplifying for each
@@ -1000,7 +1057,7 @@ class CRM_Contribute_Form_Contribution_Main extends CRM_Contribute_Form_Contribu
     }
 
     if (isset($fields['selectProduct']) &&
-      $fields['selectProduct'] != 'no_thanks'
+      $fields['selectProduct'] !== 'no_thanks'
     ) {
       $productDAO = new CRM_Contribute_DAO_Product();
       $productDAO->id = $fields['selectProduct'];
@@ -1223,9 +1280,9 @@ class CRM_Contribute_Form_Contribution_Main extends CRM_Contribute_Form_Contribu
         }
       }
     }
-
-    if (!empty($this->_ccid) && !empty($this->_pendingAmount)) {
-      $params['amount'] = $this->_pendingAmount;
+    $balance = $this->getContributionBalance();
+    if ($balance) {
+      $params['amount'] = $balance;
     }
     else {
       // from here on down, $params['amount'] holds a monetary value (or null) rather than an option ID
@@ -1425,24 +1482,11 @@ class CRM_Contribute_Form_Contribution_Main extends CRM_Contribute_Form_Contribu
       }
     }
     $this->assign('dummyTitle', $dummyTitle);
-
+    $this->assign('pendingAmount', $this->getContributionBalance());
     if (empty($this->getExistingContributionID())) {
       return;
     }
-    if (!$this->getContactID()) {
-      CRM_Core_Error::statusBounce(ts("Returning since there is no contact attached to this contribution id."));
-    }
-
-    $paymentBalance = CRM_Contribute_BAO_Contribution::getContributionBalance($this->_ccid);
-    //bounce if the contribution is not pending.
-    if ((float) $paymentBalance <= 0) {
-      CRM_Core_Error::statusBounce(ts("Returning since contribution has already been handled."));
-    }
-    if (!empty($paymentBalance)) {
-      $this->_pendingAmount = $paymentBalance;
-      $this->assign('pendingAmount', $this->_pendingAmount);
-    }
-
+    // @todo - all this stuff is likely obsolete.
     if ($taxAmount = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_Contribution', $this->_ccid, 'tax_amount')) {
       $this->assign('taxAmount', $taxAmount);
     }
@@ -1453,6 +1497,29 @@ class CRM_Contribute_Form_Contribution_Main extends CRM_Contribute_Form_Contribu
     $this->assign('priceSetID', $this->getPriceSetID());
   }
 
+  /**
+   * Get the balance amount if an existing contribution is being paid.
+   *
+   * @return float|null
+   *
+   * @throws \CRM_Core_Exception
+   */
+  private function getContributionBalance(): ?float {
+    if (empty($this->getExistingContributionID())) {
+      return NULL;
+    }
+    if (!$this->getContactID()) {
+      CRM_Core_Error::statusBounce(ts('Returning since there is no contact attached to this contribution id.'));
+    }
+
+    $paymentBalance = CRM_Contribute_BAO_Contribution::getContributionBalance($this->_ccid);
+    //bounce if the contribution is not pending.
+    if ((float) $paymentBalance <= 0) {
+      CRM_Core_Error::statusBounce(ts('Returning since contribution has already been handled.'));
+    }
+    return $paymentBalance;
+  }
+
   /**
    * Function for unit tests on the postProcess function.
    *
@@ -1474,7 +1541,7 @@ class CRM_Contribute_Form_Contribution_Main extends CRM_Contribute_Form_Contribu
    *
    * @param array $params
    *
-   * @return mixed
+   * @return bool
    * @throws \CRM_Core_Exception
    */
   protected function hasSeparateMembershipPaymentAmount($params) {
index 30e2bedca103dc0602d00f2127912b75a3c50a96..db7d69715be041922b9ae655c0261f73c567ad98 100644 (file)
@@ -115,6 +115,8 @@ class CRM_Contribute_Form_ContributionBase extends CRM_Core_Form {
    * Pcp id
    *
    * @var int
+   *
+   * @internal use getPcpID().
    */
   public $_pcpId;
 
@@ -468,10 +470,9 @@ class CRM_Contribute_Form_ContributionBase extends CRM_Core_Form {
     $this->set('membershipBlock', $this->getMembershipBlock());
 
     // Handle PCP
-    $pcpId = CRM_Utils_Request::retrieve('pcpId', 'Positive', $this);
-    if ($pcpId) {
+    $pcpId = $this->getPcpID();
+    if ($this->getPcpID()) {
       $pcp = CRM_PCP_BAO_PCP::handlePcp($pcpId, 'contribute', $this->_values);
-      $this->_pcpId = $pcp['pcpId'];
       $this->_pcpBlock = $pcp['pcpBlock'];
       $this->_pcpInfo = $pcp['pcpInfo'];
     }
@@ -800,8 +801,6 @@ class CRM_Contribute_Form_ContributionBase extends CRM_Core_Form {
           }
         }
 
-        $this->assign($name, $fields);
-
         if ($profileContactType && count($viewOnlyFileValues[$profileContactType])) {
           $this->assign('viewOnlyPrefixFileValues', $viewOnlyFileValues);
         }
@@ -810,6 +809,7 @@ class CRM_Contribute_Form_ContributionBase extends CRM_Core_Form {
         }
       }
     }
+    $this->assign($name, $fields ?? NULL);
   }
 
   /**
@@ -987,7 +987,6 @@ class CRM_Contribute_Form_ContributionBase extends CRM_Core_Form {
               ];
             }
             $locDataURL = CRM_Utils_System::url('civicrm/ajax/permlocation', $args, FALSE, NULL, FALSE);
-            $form->assign('locDataURL', $locDataURL);
           }
           if (count($organizations) > 0) {
             $form->add('select', 'onbehalfof_id', '', CRM_Utils_Array::collect('name', $organizations));
@@ -1022,7 +1021,6 @@ class CRM_Contribute_Form_ContributionBase extends CRM_Core_Form {
           CRM_Core_Permission::CREATE, NULL
         );
 
-        $form->assign('onBehalfOfFields', $profileFields);
         if (!empty($form->_submitValues['onbehalf'])) {
           if (!empty($form->_submitValues['onbehalfof_id'])) {
             $form->assign('submittedOnBehalf', $form->_submitValues['onbehalfof_id']);
@@ -1055,6 +1053,8 @@ class CRM_Contribute_Form_ContributionBase extends CRM_Core_Form {
         }
       }
     }
+    $form->assign('locDataURL', $locDataURL ?? NULL);
+    $form->assign('onBehalfOfFields', $profileFields ?? NULL);
 
   }
 
@@ -1406,4 +1406,16 @@ class CRM_Contribute_Form_ContributionBase extends CRM_Core_Form {
     return $lineItems;
   }
 
+  /**
+   * Get the PCP ID being contributed to.
+   *
+   * @return int|null
+   */
+  protected function getPcpID(): ?int {
+    if ($this->_pcpId === NULL) {
+      $this->_pcpId = CRM_Utils_Request::retrieve('pcpId', 'Positive', $this);
+    }
+    return $this->_pcpId ? (int) $this->_pcpId : NULL;
+  }
+
 }
index 7ed8a664fb53ad6f689d04598db4befc90feb6ae..98b2422c85d72c49b97ee34e17d3819ac1cfa46b 100644 (file)
@@ -236,6 +236,8 @@ class CRM_Price_BAO_PriceField extends CRM_Price_DAO_PriceField {
    *
    * @param null $fieldOptions
    * @param array $freezeOptions
+   * @param array $extra
+   *   Passed through to the add element function, use to add js.
    *
    * @return null
    */
@@ -247,7 +249,8 @@ class CRM_Price_BAO_PriceField extends CRM_Price_DAO_PriceField {
     $useRequired = TRUE,
     $label = NULL,
     $fieldOptions = NULL,
-    $freezeOptions = []
+    $freezeOptions = [],
+    array $extra = []
   ) {
 
     $field = new CRM_Price_DAO_PriceField();
@@ -256,9 +259,10 @@ class CRM_Price_BAO_PriceField extends CRM_Price_DAO_PriceField {
       /* FIXME: failure! */
       return NULL;
     }
-    $label = $label ?: $field['label'];
+    $label = $label ?: $field->label;
     $is_pay_later = 0;
     $isQuickConfig = CRM_Price_BAO_PriceSet::isQuickConfig($field->price_set_id);
+    // @todo - pass is_pay_later in rather than checking form properties
     if (isset($qf->_mode) && empty($qf->_mode)) {
       $is_pay_later = 1;
     }
@@ -274,6 +278,7 @@ class CRM_Price_BAO_PriceField extends CRM_Price_DAO_PriceField {
     // get currency name for price field and option attributes
     $currencyName = $config->defaultCurrency;
 
+    // @todo - pass useRequired in rather than checking form properties
     if (isset($qf->_online) && $qf->_online) {
       $useRequired = FALSE;
     }
@@ -306,21 +311,16 @@ class CRM_Price_BAO_PriceField extends CRM_Price_DAO_PriceField {
           $max_value,
         ]);
 
-        $extra = [];
         if (!empty($fieldOptions[$optionKey]['label'])) {
           //check for label.
           $label = $fieldOptions[$optionKey]['label'];
         }
+        // @todo - move this back to the only calling function on Contribution_Form_Main.php
         if ($isQuickConfig && $field->name === 'other_amount') {
           if (!empty($qf->_membershipBlock)) {
             $useRequired = 0;
           }
           $label .= '  ' . $currencySymbol;
-          $qf->assign('priceset', $elementName);
-          $extra = [
-            'onclick' => 'useAmountOther();',
-            'autocomplete' => 'off',
-          ];
         }
 
         $element = &$qf->add('text', $elementName, $label,
@@ -359,10 +359,6 @@ class CRM_Price_BAO_PriceField extends CRM_Price_DAO_PriceField {
       case 'Radio':
         $choice = [];
 
-        if ($isQuickConfig && $field->name === 'contribution_amount') {
-          $qf->assign('contriPriceset', $elementName);
-        }
-
         foreach ($customOption as $opId => $opt) {
           $priceOptionText = self::buildPriceOptionText($opt, $field->is_display_amounts, $valueFieldName);
           if (isset($opt['visibility_id'])) {
@@ -371,16 +367,14 @@ class CRM_Price_BAO_PriceField extends CRM_Price_DAO_PriceField {
           else {
             $visibility_id = self::getVisibilityOptionID('public');
           }
-          $extra = [
+          $extra += [
             'price' => json_encode([$elementName, $priceOptionText['priceVal']]),
             'data-amount' => $opt[$valueFieldName],
             'data-currency' => $currencyName,
             'data-price-field-values' => json_encode($customOption),
             'visibility' => $visibility_id,
           ];
-          if ($isQuickConfig && $field->name == 'contribution_amount') {
-            $extra += ['onclick' => 'clearAmountOther();'];
-          }
+          // @todo - move this back to the only calling function on Contribution_Form_Main.php
           if ($field->name == 'membership_amount') {
             $extra += [
               'onclick' => "return showHideAutoRenew({$opt['membership_type_id']});",
@@ -395,6 +389,7 @@ class CRM_Price_BAO_PriceField extends CRM_Price_DAO_PriceField {
             $qf->add('text', 'txt-' . $elementName, $label, ['size' => '4']);
           }
         }
+        // @todo - move this back to the only calling function on Contribution_Form_Main.php
         if (!empty($qf->_membershipBlock) && $field->name == 'contribution_amount') {
           $choice['-1'] = ts('No thank you');
           $choiceAttrs['-1'] = [
@@ -431,6 +426,7 @@ class CRM_Price_BAO_PriceField extends CRM_Price_DAO_PriceField {
         }
 
         // make contribution field required for quick config when membership block is enabled
+        // @todo - move this back to the only calling function on Contribution_Form_Main.php
         if (($field->name == 'membership_amount' || $field->name == 'contribution_amount')
           && !empty($qf->_membershipBlock) && !$field->is_required
         ) {
@@ -524,6 +520,7 @@ class CRM_Price_BAO_PriceField extends CRM_Price_DAO_PriceField {
         }
         break;
     }
+    // @todo - move this action back to the calling function
     if (isset($qf->_online) && $qf->_online) {
       $element->freeze();
     }
@@ -733,7 +730,7 @@ WHERE  id IN (" . implode(',', array_keys($priceFields)) . ')';
         }
       }
 
-      list($componentName) = explode(':', $fields['_qf_default']);
+      [$componentName] = explode(':', $fields['_qf_default']);
       // now we have all selected amount in hand.
       $totalAmount = array_sum($selectedAmounts);
       // The form offers a field to enter the amount paid. This may differ from the amount that is due to complete the purchase
index 80605866ecbc072de78080edf25f1a66c51df704..13b351e53ebebeeb204d6d01a06f6c9e2974e318 100644 (file)
@@ -889,13 +889,11 @@ class CRM_Profile_Form extends CRM_Core_Form {
     $this->setDefaultsValues();
 
     $action = CRM_Utils_Request::retrieve('action', 'String', $this, FALSE, NULL);
-
-    if ($this->_mode == self::MODE_CREATE || $this->_mode == self::MODE_EDIT) {
+    $isCreateOrEditMode = $this->_mode == self::MODE_CREATE || $this->_mode == self::MODE_EDIT;
+    if ($isCreateOrEditMode) {
       CRM_Core_BAO_CMSUser::buildForm($this, $this->_gid, $emailPresent, $action);
     }
-    else {
-      $this->assign('showCMS', FALSE);
-    }
+    $this->assign('showCMS', $isCreateOrEditMode);
 
     $this->assign('groupId', $this->_gid);
 
index 08c54321bcc73b98308cc3de1b1e17f3353e951d..c6a322673b7446ca96f7b770dce31ef49b6cb383 100644 (file)
   <script type="text/javascript">
 
     // Putting these functions directly in template so they are available for standalone forms
-    function useAmountOther() {
-      var priceset = {/literal}{if $contriPriceset}'{$contriPriceset}'{else}0{/if}{literal};
-
-      for( i=0; i < document.Main.elements.length; i++ ) {
+    function useAmountOther(mainPriceFieldName) {
+     for( i=0; i < document.Main.elements.length; i++ ) {
         element = document.Main.elements[i];
-        if ( element.type == 'radio' && element.name == priceset ) {
+        if ( element.type == 'radio' && element.name === mainPriceFieldName ) {
           if (element.value == '0' ) {
             element.click();
           }
       }
     }
 
-    function clearAmountOther() {
-      var priceset = {/literal}{if $priceset}'#{$priceset}'{else}0{/if}{literal}
-      if( priceset ){
-        cj(priceset).val('');
-        cj(priceset).blur();
-      }
+    function clearAmountOther(otherPriceFieldName) {
+      cj('#' + otherPriceFieldName).val('');
+      cj('#' + otherPriceFieldName).blur();
       if (document.Main.amount_other == null) return; // other_amt field not present; do nothing
       document.Main.amount_other.value = "";
     }
@@ -71,7 +66,7 @@
     </div>
     {include file="CRM/common/cidzero.tpl"}
 
-    {if $islifetime or $ispricelifetime}
+    {if $isShowMembershipBlock && ($islifetime or $ispricelifetime)}
       <div class="help">{ts}You have a current Lifetime Membership which does not need to be renewed.{/ts}</div>
     {/if}
 
               {$form.pledge_frequency_unit.html}<span id="pledge_installments_num">&nbsp;{ts}for{/ts}&nbsp;{$form.pledge_installments.html}&nbsp;{ts}installments.{/ts}</span>
             </div>
             <div class="clear"></div>
-            {if $start_date_editable}
+            {if array_key_exists('start_date', $form) && $start_date_editable}
               {if $is_date}
                 <div class="label">{$form.start_date.label}</div><div class="content">{$form.start_date.html}</div>
               {else}
                 <div class="label">{$form.start_date.label}</div><div class="content">{$form.start_date.html}</div>
               {/if}
-            {else}
+            {elseif array_key_exists('start_date', $form)}
               <div class="label">{$form.start_date.label}</div>
               <div class="content">{$start_date_display|crmDate:'%b %e, %Y'}</div>
             {/if}