* @throws \CRM_Core_Exception
*/
private function buildPriceSet(&$form, $component = NULL) {
- $priceSetId = $this->getPriceSetID();
- $priceSet = CRM_Price_BAO_PriceSet::getSetDetail($priceSetId, TRUE, TRUE);
- $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;
+ $validPriceFieldIds = array_keys($this->getPriceFieldMetaData());
$form->assign('priceSet', $form->_priceSet);
+ // @todo - this hook wrangling can be done earlier if we set the form on $this->>order.
$feeBlock = &$form->_values['fee'];
-
// Call the buildAmount hook.
CRM_Utils_Hook::buildAmount($component ?? 'contribution', $form, $feeBlock);
// 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) {
+ foreach ($this->getPriceFieldMetaData() as $id => $field) {
if ($field['visibility'] === 'public' ||
($field['visibility'] === 'admin' && $adminFieldVisible)
) {
$options = $field['options'] ?? NULL;
- $contactId = $form->getVar('_membershipContactID');
- if ($contactId && $options) {
- $contactsLifetimeMemberships = CRM_Member_BAO_Membership::getAllContactMembership($contactId, FALSE, TRUE);
+ if ($this->_membershipContactID && $options) {
+ $contactsLifetimeMemberships = CRM_Member_BAO_Membership::getAllContactMembership($this->_membershipContactID, FALSE, TRUE);
$contactsLifetimeMembershipTypes = array_column($contactsLifetimeMemberships, 'membership_type_id');
$memTypeIdsInPriceField = array_column($options, 'membership_type_id');
$isCurrentMember = (bool) array_intersect($memTypeIdsInPriceField, $contactsLifetimeMembershipTypes);
*/
private function buildMembershipBlock() {
$cid = $this->_membershipContactID;
- $isTest = (bool) ($this->_action & CRM_Core_Action::PREVIEW);
+ $isTest = (bool) ($this->getAction() & CRM_Core_Action::PREVIEW);
$separateMembershipPayment = FALSE;
$this->addOptionalQuickFormElement('auto_renew');
if ($this->_membershipBlock) {
$separateMembershipPayment = $this->_membershipBlock['is_separate_payment'] ?? NULL;
- foreach ($this->_priceSet['fields'] as $pField) {
+ foreach ($this->getPriceFieldMetaData() as $pField) {
if (empty($pField['options'])) {
continue;
}
if ($form->_action & CRM_Core_Action::UPDATE) {
$form->_values['line_items'] = CRM_Price_BAO_LineItem::getLineItems($form->_id, 'contribution');
}
-
- $priceSet = CRM_Price_BAO_PriceSet::getSetDetail($priceSetId);
- $form->_priceSet = $priceSet[$priceSetId] ?? NULL;
- $form->_values['fee'] = $form->_priceSet['fields'] ?? NULL;
+ $form->_priceSet = [$this->getPriceSetID() => $this->order->getPriceSetMetadata()];
+ $this->setPriceFieldMetaData($this->order->getPriceFieldsMetadata());
$form->set('priceSet', $form->_priceSet);
}
}
+ /**
+ * @param array $metadata
+ */
+ public function setPriceFieldMetaData(array $metadata): void {
+ $this->_values['fee'] = $this->_priceSet['fields'] = $metadata;
+ }
+
+ public function getPriceFieldMetaData() {
+ if (!empty($this->_values['fee'])) {
+ return $this->_values['fee'];
+ }
+ if (!empty($this->_priceSet['fields'])) {
+ return $this->_priceSet['fields'];
+ }
+ return $this->order->getPriceFieldsMetadata();
+ }
+
/**
* Set the default values.
*/
*/
protected $overridableFinancialTypeID;
+ private $isExcludeExpiredFields = FALSE;
+
+ /**
+ * @param bool $isExcludeExpiredFields
+ *
+ * @return CRM_Financial_BAO_Order
+ */
+ public function setIsExcludeExpiredFields(bool $isExcludeExpiredFields): CRM_Financial_BAO_Order {
+ $this->isExcludeExpiredFields = $isExcludeExpiredFields;
+ return $this;
+ }
+
/**
* Get overridable financial type id.
*
*
* @param array $metadata
*/
- protected function setPriceFieldMetadata($metadata) {
+ protected function setPriceFieldMetadata(array $metadata): void {
+ foreach ($metadata as $index => $priceField) {
+ if ($this->isExcludeExpiredFields && !empty($priceField['active_on']) && time() < strtotime($priceField['active_on'])) {
+ unset($metadata[$index]);
+ }
+ elseif ($this->isExcludeExpiredFields && !empty($priceField['expires_on']) && strtotime($priceField['expires_on']) < time()) {
+ unset($metadata[$index]);
+ }
+ elseif (!empty($priceField['options'])) {
+ foreach ($priceField['options'] as $optionID => $option) {
+ if (!empty($option['membership_type_id'])) {
+ $membershipType = CRM_Member_BAO_MembershipType::getMembershipType((int) $option['membership_type_id']);
+ $metadata[$index]['options'][$optionID]['auto_renew'] = (int) $membershipType['auto_renew'];
+ if ($membershipType['auto_renew'] && empty($this->priceSetMetadata['auto_renew_membership_type'])) {
+ // Quick form layer supports one auto-renew membership type per price set. If we
+ // want more for any reason we can add another array property.
+ $this->priceSetMetadata['auto_renew_membership_type'] = (int) $option['membership_type_id'];
+ }
+ }
+ }
+ }
+ }
$this->priceFieldMetadata = $metadata;
+
if ($this->getForm()) {
CRM_Utils_Hook::buildAmount($this->form->getFormContext(), $this->form, $this->priceFieldMetadata);
}
/**
* Get the metadata for the fields in the price set.
*
+ * @return array
+ * @throws \CRM_Core_Exception
* @internal use in tested core code only.
*
- * @return array
*/
public function getPriceSetMetadata(): array {
if (empty($this->priceSetMetadata)) {
- $priceSetMetadata = CRM_Price_BAO_PriceSet::getCachedPriceSetDetail($this->getPriceSetID());
+ $this->priceSetMetadata = CRM_Price_BAO_PriceSet::getCachedPriceSetDetail($this->getPriceSetID());
+ $this->priceSetMetadata['id'] = $this->getPriceSetID();
// @todo - make sure this is an array - commented out for now as this PR is against the rc.
// $priceSetMetadata['extends'] = explode(CRM_Core_DAO::VALUE_SEPARATOR, $priceSetMetadata['extends']);
- $this->setPriceFieldMetadata($priceSetMetadata['fields']);
- unset($priceSetMetadata['fields']);
- $this->priceSetMetadata = $priceSetMetadata;
+ $this->setPriceFieldMetadata($this->priceSetMetadata['fields']);
+ unset($this->priceSetMetadata['fields']);
}
return $this->priceSetMetadata;
}
if (!CRM_Core_Component::isEnabled('CiviMember')) {
return FALSE;
}
- $extends = explode(CRM_Core_DAO::VALUE_SEPARATOR, $this->getPriceSetMetadata()['extends']);
+ // Access the property if set, to avoid a potential loop when the hook is called.
+ $priceSetMetadata = $this->priceSetMetadata ?: $this->getPriceSetMetadata();
+ $extends = explode(CRM_Core_DAO::VALUE_SEPARATOR, $priceSetMetadata['extends']);
return in_array(CRM_Core_Component::getComponentID('CiviMember'), $extends, FALSE);
}