From 908b774880219169ea56f9f2b6a6143861d26394 Mon Sep 17 00:00:00 2001 From: Eileen McNaughton Date: Fri, 13 Oct 2023 10:11:14 +1300 Subject: [PATCH] Split shared function with mostly unshared code Almost all the code in this function is specific to the online form - we don't gain much by sharing but it is harder to make changes because of having to check the impact of each change on both forms. Note both forms have test cover over this --- CRM/Contribute/Form/Contribution.php | 51 ++++++++++++++++++++- CRM/Contribute/Form/Contribution/Main.php | 51 ++++++++++++++++++++- CRM/Price/BAO/PriceSet.php | 55 +++++++++++++++++++++-- 3 files changed, 151 insertions(+), 6 deletions(-) diff --git a/CRM/Contribute/Form/Contribution.php b/CRM/Contribute/Form/Contribution.php index 50f54285ca..7e6f3da3c5 100644 --- a/CRM/Contribute/Form/Contribution.php +++ b/CRM/Contribute/Form/Contribution.php @@ -605,8 +605,7 @@ class CRM_Contribute_Form_Contribution extends CRM_Contribute_Form_AbstractEditP $getOnlyPriceSetElements = FALSE; } - $this->set('priceSetId', $this->_priceSetId); - CRM_Price_BAO_PriceSet::buildPriceSet($this, 'contribution', FALSE); + $this->buildPriceSet($this, 'contribution', FALSE); // get only price set form elements. if ($getOnlyPriceSetElements) { @@ -925,6 +924,54 @@ class CRM_Contribute_Form_Contribution extends CRM_Contribute_Form_AbstractEditP } } + /** + * Build the price set form. + * + * @param CRM_Core_Form $form + * @param string|null $component + * @param bool $validFieldsOnly + */ + private function buildPriceSet($form, $component = NULL, $validFieldsOnly = TRUE): void { + $priceSetId = $this->getPriceSetID(); + + $priceSet = CRM_Price_BAO_PriceSet::getSetDetail($priceSetId, TRUE, $validFieldsOnly); + $form->_priceSet = $priceSet[$priceSetId] ?? NULL; + $validPriceFieldIds = array_keys($form->_priceSet['fields']); + + // @todo - this code is from previously shared function - can probaly go. + // Mark which field should have the auto-renew checkbox, if any. CRM-18305 + if (!empty($form->_membershipTypeValues) && is_array($form->_membershipTypeValues)) { + $autoRenewMembershipTypes = []; + foreach ($form->_membershipTypeValues as $membershipTypeValue) { + if ($membershipTypeValue['auto_renew']) { + $autoRenewMembershipTypes[] = $membershipTypeValue['id']; + } + } + foreach ($form->_priceSet['fields'] as $field) { + if (array_key_exists('options', $field) && is_array($field['options'])) { + foreach ($field['options'] as $option) { + if (!empty($option['membership_type_id'])) { + if (in_array($option['membership_type_id'], $autoRenewMembershipTypes)) { + $form->_priceSet['auto_renew_membership_field'] = $field['id']; + // Only one field can offer auto_renew memberships, so break here. + break; + } + } + } + } + } + } + $form->_priceSet['id'] = $form->_priceSet['id'] ?? $priceSetId; + $form->assign('priceSet', $form->_priceSet); + + $feeBlock = &$form->_priceSet['fields']; + + // Call the buildAmount hook. + CRM_Utils_Hook::buildAmount($component ?? 'contribution', $form, $feeBlock); + + CRM_Price_BAO_PriceSet::addPriceFieldsToForm($form, $feeBlock, $validFieldsOnly, __CLASS__, $validPriceFieldIds); + } + /** * Global form rule. * diff --git a/CRM/Contribute/Form/Contribution/Main.php b/CRM/Contribute/Form/Contribution/Main.php index e05211d3f5..b03a742bda 100644 --- a/CRM/Contribute/Form/Contribution/Main.php +++ b/CRM/Contribute/Form/Contribution/Main.php @@ -349,7 +349,7 @@ class CRM_Contribute_Form_Contribution_Main extends CRM_Contribute_Form_Contribu // build price set form. $this->set('priceSetId', $this->_priceSetId); if (empty($this->_ccid)) { - CRM_Price_BAO_PriceSet::buildPriceSet($this, $this->getFormContext()); + $this->buildPriceSet($this, $this->getFormContext()); } if ($this->_values['is_monetary'] && $this->_values['is_recur'] && empty($this->_values['pledge_id']) @@ -468,6 +468,55 @@ class CRM_Contribute_Form_Contribution_Main extends CRM_Contribute_Form_Contribu $this->addFormRule(['CRM_Contribute_Form_Contribution_Main', 'formRule'], $this); } + /** + * Build the price set form. + * + * @param CRM_Core_Form $form + * @param string|null $component + * @param bool $validFieldsOnly + * + * @return void + * @throws \CRM_Core_Exception + */ + private function buildPriceSet(&$form, $component = NULL, $validFieldsOnly = TRUE) { + $priceSetId = $this->getPriceSetID(); + $priceSet = CRM_Price_BAO_PriceSet::getSetDetail($priceSetId, TRUE, $validFieldsOnly); + $form->_priceSet = $priceSet[$priceSetId] ?? NULL; + $validPriceFieldIds = array_keys($form->_priceSet['fields']); + + // Mark which field should have the auto-renew checkbox, if any. CRM-18305 + if (!empty($form->_membershipTypeValues) && is_array($form->_membershipTypeValues)) { + $autoRenewMembershipTypes = []; + foreach ($form->_membershipTypeValues as $membershipTypeValue) { + if ($membershipTypeValue['auto_renew']) { + $autoRenewMembershipTypes[] = $membershipTypeValue['id']; + } + } + foreach ($form->_priceSet['fields'] as $field) { + if (array_key_exists('options', $field) && is_array($field['options'])) { + foreach ($field['options'] as $option) { + if (!empty($option['membership_type_id'])) { + if (in_array($option['membership_type_id'], $autoRenewMembershipTypes)) { + $form->_priceSet['auto_renew_membership_field'] = $field['id']; + // Only one field can offer auto_renew memberships, so break here. + break; + } + } + } + } + } + } + $form->_priceSet['id'] = $form->_priceSet['id'] ?? $priceSetId; + $form->assign('priceSet', $form->_priceSet); + + $feeBlock = &$form->_values['fee']; + + // Call the buildAmount hook. + CRM_Utils_Hook::buildAmount($component ?? 'contribution', $form, $feeBlock); + + CRM_Price_BAO_PriceSet::addPriceFieldsToForm($form, $feeBlock, $validFieldsOnly, __CLASS__, $validPriceFieldIds); + } + /** * Build Membership Block in Contribution Pages. * @todo this was shared on CRM_Contribute_Form_ContributionBase but we are refactoring and simplifying for each diff --git a/CRM/Price/BAO/PriceSet.php b/CRM/Price/BAO/PriceSet.php index 874fcd2085..2d66eac6c8 100644 --- a/CRM/Price/BAO/PriceSet.php +++ b/CRM/Price/BAO/PriceSet.php @@ -791,9 +791,11 @@ WHERE id = %1"; * @param bool $validFieldsOnly * * @return void - * @throws \CRM_Core_Exception + * + * @deprecated since 5.68. Will be removed around 5.80. */ public static function buildPriceSet(&$form, $component = NULL, $validFieldsOnly = TRUE) { + CRM_Core_Error::deprecatedFunctionWarning('copy & paste ....'); $priceSetId = $form->get('priceSetId'); if (!$priceSetId) { return; @@ -840,7 +842,49 @@ WHERE id = %1"; // Call the buildAmount hook. CRM_Utils_Hook::buildAmount($component ?? 'contribution', $form, $feeBlock); - self::addPriceFieldsToForm($form, $feeBlock, $validFieldsOnly, $className, $validPriceFieldIds); + $hideAdminValues = !CRM_Core_Permission::check('edit contributions'); + // CRM-14492 Admin price fields should show up on event registration if user has 'administer CiviCRM' permissions + $adminFieldVisible = CRM_Core_Permission::check('administer CiviCRM'); + $checklifetime = FALSE; + foreach ($feeBlock as $id => $field) { + if (($field['visibility'] ?? NULL) == 'public' || + (($field['visibility'] ?? NULL) == 'admin' && $adminFieldVisible == TRUE) || + !$validFieldsOnly + ) { + $options = $field['options'] ?? NULL; + if ($className == 'CRM_Contribute_Form_Contribution_Main' && $component = 'membership') { + $contactId = $form->getVar('_membershipContactID'); + if ($contactId && $options) { + $checklifetime = $checklifetime ?: self::checkCurrentMembership($options, $contactId); + } + } + + $formClasses = ['CRM_Contribute_Form_Contribution', 'CRM_Member_Form_Membership']; + + if (!is_array($options) || !in_array($id, $validPriceFieldIds)) { + continue; + } + elseif ($hideAdminValues && !in_array($className, $formClasses)) { + foreach ($options as $key => $currentOption) { + if ($currentOption['visibility_id'] == CRM_Price_BAO_PriceField::getVisibilityOptionID('admin')) { + unset($options[$key]); + } + } + } + if (!empty($options)) { + CRM_Price_BAO_PriceField::addQuickFormElement($form, + 'price_' . $field['id'], + $field['id'], + FALSE, + CRM_Utils_Array::value('is_required', $field, FALSE), + NULL, + $options + ); + } + } + } + $form->assign('ispricelifetime', $checklifetime); + } /** @@ -1616,13 +1660,18 @@ WHERE ct.id = cp.financial_type_id AND /** * Add the relevant price fields to the form. * + * DO NOT use form outside core tested code - function is public for + * refactoring purposes only. + * + * @internal + * * @param \CRM_Core_Form $form * @param array $feeBlock * @param bool $validFieldsOnly * @param string $className * @param array $validPriceFieldIds */ - protected static function addPriceFieldsToForm(CRM_Core_Form $form, $feeBlock, bool $validFieldsOnly, string $className, array $validPriceFieldIds) { + public static function addPriceFieldsToForm(CRM_Core_Form $form, $feeBlock, bool $validFieldsOnly, string $className, array $validPriceFieldIds) { $hideAdminValues = !CRM_Core_Permission::check('edit contributions'); // CRM-14492 Admin price fields should show up on event registration if user has 'administer CiviCRM' permissions $adminFieldVisible = CRM_Core_Permission::check('administer CiviCRM'); -- 2.25.1