From 817830b2fb231a5bd5e1a6746d253391afdaca7a Mon Sep 17 00:00:00 2001 From: Eileen McNaughton Date: Mon, 27 Nov 2023 08:56:28 +1300 Subject: [PATCH] Fix notices on premiums across all 3 pages This includes switching to apiv4 & adding escape to the templates to reflect that change --- CRM/Contribute/BAO/Premium.php | 2 +- CRM/Contribute/Form/Contribution/Confirm.php | 6 +- CRM/Contribute/Form/Contribution/ThankYou.php | 5 +- CRM/Contribute/Form/ContributionBase.php | 103 ++++++++---------- CRM/Core/Permission.php | 3 +- Civi/Test/ContributionPageTestTrait.php | 3 + .../Contribute/Form/Contribution/Confirm.tpl | 2 +- .../CRM/Contribute/Form/Contribution/Main.tpl | 2 +- .../Form/Contribution/PremiumBlock.tpl | 30 +++-- .../Contribute/Form/Contribution/ThankYou.tpl | 2 +- .../Form/Contribution/ConfirmTest.php | 38 ++++++- tests/phpunit/CiviTest/CiviUnitTestCase.php | 3 + tests/phpunit/api/v3/ContributionPageTest.php | 13 --- 13 files changed, 112 insertions(+), 100 deletions(-) diff --git a/CRM/Contribute/BAO/Premium.php b/CRM/Contribute/BAO/Premium.php index 3a84d7b945..349545ca5a 100644 --- a/CRM/Contribute/BAO/Premium.php +++ b/CRM/Contribute/BAO/Premium.php @@ -140,7 +140,7 @@ class CRM_Contribute_BAO_Premium extends CRM_Contribute_DAO_Premium { } } if (count($products)) { - $form->assign('showPremium', $formItems); + $form->assign('showPremiumSelectionFields', $formItems); $form->assign('showSelectOptions', $formItems); $form->assign('premiumBlock', $premiumBlock); } diff --git a/CRM/Contribute/Form/Contribution/Confirm.php b/CRM/Contribute/Form/Contribution/Confirm.php index 45dd561553..214efd93e7 100644 --- a/CRM/Contribute/Form/Contribution/Confirm.php +++ b/CRM/Contribute/Form/Contribution/Confirm.php @@ -500,11 +500,7 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr if (!empty($params['selectProduct']) && $params['selectProduct'] !== 'no_thanks') { $option = $params['options_' . $params['selectProduct']] ?? NULL; - $productID = $params['selectProduct']; - $this->buildPremiumsBlock(FALSE, - $productID, $option - ); - $this->set('productID', $productID); + $this->buildPremiumsBlock(FALSE, $option); $this->set('option', $option); } else { diff --git a/CRM/Contribute/Form/Contribution/ThankYou.php b/CRM/Contribute/Form/Contribution/ThankYou.php index 38854cb47f..4b2568be19 100644 --- a/CRM/Contribute/Form/Contribution/ThankYou.php +++ b/CRM/Contribute/Form/Contribution/ThankYou.php @@ -95,13 +95,12 @@ class CRM_Contribute_Form_Contribution_ThankYou extends CRM_Contribute_Form_Cont // FIXME: Some of this code is identical to Confirm.php and should be broken out into a shared function $this->assignToTemplate(); $this->_ccid = $this->get('ccid'); - $productID = $this->get('productID'); $option = $this->get('option'); $membershipTypeID = $this->get('membershipTypeID'); $this->assign('receiptFromEmail', CRM_Utils_Array::value('receipt_from_email', $this->_values)); - if ($productID) { - $this->buildPremiumsBlock(FALSE, $productID, $option); + if ($this->getProductID()) { + $this->buildPremiumsBlock(FALSE, $option); } $params = $this->_params; diff --git a/CRM/Contribute/Form/ContributionBase.php b/CRM/Contribute/Form/ContributionBase.php index 4a37189126..0260e84543 100644 --- a/CRM/Contribute/Form/ContributionBase.php +++ b/CRM/Contribute/Form/ContributionBase.php @@ -15,6 +15,7 @@ * @copyright CiviCRM LLC https://civicrm.org/licensing */ +use Civi\Api4\PremiumsProduct; use Civi\Api4\PriceSet; /** @@ -945,72 +946,55 @@ class CRM_Contribute_Form_ContributionBase extends CRM_Core_Form { * Build Premium Block im Contribution Pages. * * @param bool $formItems - * @param int $selectedProductID * @param string $selectedOption + * + * @noinspection PhpUnhandledExceptionInspection */ - protected function buildPremiumsBlock($formItems = FALSE, $selectedProductID = NULL, $selectedOption = NULL) { - $this->add('hidden', "selectProduct", $selectedProductID, ['id' => 'selectProduct']); - - $premiumDao = new CRM_Contribute_DAO_Premium(); - $premiumDao->entity_table = 'civicrm_contribution_page'; - $premiumDao->entity_id = $this->getContributionPageID(); - $premiumDao->premiums_active = 1; - - if ($premiumDao->find(TRUE)) { - $premiumID = $premiumDao->id; - $premiumBlock = []; - CRM_Core_DAO::storeValues($premiumDao, $premiumBlock); - - CRM_Financial_BAO_FinancialType::getAvailableFinancialTypes($financialTypes, CRM_Core_Action::ADD); - $addWhere = "financial_type_id IN (0)"; - if (!empty($financialTypes)) { - $addWhere = "financial_type_id IN (" . implode(',', array_keys($financialTypes)) . ")"; - } - $addWhere = "{$addWhere} OR financial_type_id IS NULL"; - - $premiumsProductDao = new CRM_Contribute_DAO_PremiumsProduct(); - $premiumsProductDao->premiums_id = $premiumID; - $premiumsProductDao->whereAdd($addWhere); - $premiumsProductDao->orderBy('weight'); - $premiumsProductDao->find(); - - $products = []; - while ($premiumsProductDao->fetch()) { - $productDAO = new CRM_Contribute_DAO_Product(); - $productDAO->id = $premiumsProductDao->product_id; - $productDAO->is_active = 1; - if ($productDAO->find(TRUE)) { - if ($selectedProductID != NULL) { - if ($selectedProductID == $productDAO->id) { - if ($selectedOption) { - $productDAO->options = ts('Selected Option') . ': ' . $selectedOption; - } - else { - $productDAO->options = NULL; - } - CRM_Core_DAO::storeValues($productDAO, $products[$productDAO->id]); - } + protected function buildPremiumsBlock(bool $formItems = FALSE, $selectedOption = NULL): void { + $selectedProductID = $this->getProductID(); + $this->add('hidden', 'selectProduct', $selectedProductID, ['id' => 'selectProduct']); + $premiumProducts = PremiumsProduct::get() + ->addSelect('product_id.*') + ->addSelect('product_id') + ->addSelect('premiums_id.*') + ->addWhere('product_id.is_active', '=', TRUE) + ->addWhere('premiums_id.entity_id', '=', $this->getContributionPageID()) + ->addWhere('premiums_id.entity_table', '=', 'civicrm_contribution_page') + ->addOrderBy('weight') + ->execute(); + $products = []; + $premium = []; + foreach ($premiumProducts as $premiumProduct) { + $product = ['options' => NULL]; + foreach ($premiumProduct as $key => $value) { + if (str_starts_with($key, 'product_id.')) { + if ($key === 'product_id.options' && $selectedProductID === $product['id'] && $selectedOption) { + // In this case we are on the thank you or confirm page so assign + // the selected option to the page for display. + $product['options'] = ts('Selected Option') . ': ' . $selectedOption; } else { - // Why? should we not skip if not found? - CRM_Core_DAO::storeValues($productDAO, $products[$productDAO->id]); + $product[str_replace('product_id.', '', $key)] = $value; } } - $options = $temp = []; - $temp = explode(',', $productDAO->options); - foreach ($temp as $value) { - $options[trim($value)] = trim($value); + if (str_starts_with($key, 'premiums_id.')) { + $premium[str_replace('premiums_id.', '', $key)] = $value; } - if ($temp[0] != '') { - $this->addElement('select', 'options_' . $productDAO->id, NULL, $options); + } + $options = array_filter(explode(',', $product['options'])); + $productOptions = []; + foreach ($options as $option) { + $optionValue = trim($option); + if ($optionValue) { + $productOptions[$optionValue] = $optionValue; } } - if (count($products)) { - $this->assign('showPremium', $formItems); - $this->assign('showSelectOptions', $formItems); - $this->assign('premiumBlock', $premiumBlock); + if (!empty($options)) { + $this->addElement('select', 'options_' . $product['id'], NULL, $productOptions); } + $products[$premiumProduct['product_id']] = $product; } + $this->assign('premiumBlock', $premium); $this->assign('products', $products ?? NULL); } @@ -1383,6 +1367,15 @@ class CRM_Contribute_Form_ContributionBase extends CRM_Core_Form { return $this->_ccid ?: CRM_Utils_Request::retrieve('ccid', 'Positive', $this); } + /** + * @return int|bool + */ + protected function getProductID() { + $productID = $this->getSubmittedValue('selectProduct') ? (int) $this->getSubmittedValue('selectProduct') : FALSE; + $this->set('productID', $productID); + return $productID; + } + /** * Get the submitted value, accessing it from whatever form in the flow it is * submitted on. diff --git a/CRM/Core/Permission.php b/CRM/Core/Permission.php index f8f2fb7ace..72a7fd80b5 100644 --- a/CRM/Core/Permission.php +++ b/CRM/Core/Permission.php @@ -1152,7 +1152,8 @@ class CRM_Core_Permission { ], ]; $permissions['line_item'] = $permissions['contribution']; - $permissions['product'] = $permissions['contribution']; + $permissions['product'] = $permissions['premiums'] = $permissions['premiums_product'] = $permissions['contribution']; + $permissions['product']['get'] = $permissions['premiums']['get'] = $permissions['premiums_product']['get'] = [['access CiviCRM', 'access CiviContribute', 'make online contributions']]; $permissions['financial_item'] = $permissions['contribution']; $permissions['financial_type']['get'] = $permissions['contribution']['get']; diff --git a/Civi/Test/ContributionPageTestTrait.php b/Civi/Test/ContributionPageTestTrait.php index 5f6e833827..1c386681af 100644 --- a/Civi/Test/ContributionPageTestTrait.php +++ b/Civi/Test/ContributionPageTestTrait.php @@ -122,6 +122,7 @@ trait ContributionPageTestTrait { 'description' => '5 dollars worth of monopoly money', 'options' => 'White, Black, Green', 'price' => 1, + 'is_active' => TRUE, 'min_contribution' => 5, 'cost' => .05, ], '5_dollars'); @@ -130,6 +131,7 @@ trait ContributionPageTestTrait { 'description' => '10 dollars worth of monopoly money', 'options' => 'White, Black, Green', 'price' => 2, + 'is_active' => TRUE, 'min_contribution' => 10, 'cost' => .05, ], '10_dollars'); @@ -137,6 +139,7 @@ trait ContributionPageTestTrait { 'entity_id' => $this->getContributionPageID($identifier), 'entity_table' => 'civicrm_contribution_page', 'premiums_intro_title' => 'Get free monopoly money with your donation', + 'premiums_active' => TRUE, ], $identifier); $this->createTestEntity('PremiumsProduct', [ 'premiums_id' => $this->ids['Premium'][$identifier], diff --git a/templates/CRM/Contribute/Form/Contribution/Confirm.tpl b/templates/CRM/Contribute/Form/Contribution/Confirm.tpl index e39176129d..73fbf903be 100644 --- a/templates/CRM/Contribute/Form/Contribution/Confirm.tpl +++ b/templates/CRM/Contribute/Form/Contribution/Confirm.tpl @@ -268,7 +268,7 @@ {/if} {/crmRegion} - {include file="CRM/Contribute/Form/Contribution/PremiumBlock.tpl" context="confirmContribution"} + {include file="CRM/Contribute/Form/Contribution/PremiumBlock.tpl" context="confirmContribution" showPremiumSelectionFields=false preview=false} {if $customPost}
diff --git a/templates/CRM/Contribute/Form/Contribution/Main.tpl b/templates/CRM/Contribute/Form/Contribution/Main.tpl index 7d25368f5a..96ab9b0d5f 100644 --- a/templates/CRM/Contribute/Form/Contribution/Main.tpl +++ b/templates/CRM/Contribute/Form/Contribution/Main.tpl @@ -185,7 +185,7 @@ {include file="CRM/common/CMSUser.tpl"}
- {include file="CRM/Contribute/Form/Contribution/PremiumBlock.tpl" context="makeContribution" preview=false} + {include file="CRM/Contribute/Form/Contribution/PremiumBlock.tpl" context="makeContribution" preview=false showPremiumSelectionFields=true}
{if $honoreeProfileFields && $honoreeProfileFields|@count} diff --git a/templates/CRM/Contribute/Form/Contribution/PremiumBlock.tpl b/templates/CRM/Contribute/Form/Contribution/PremiumBlock.tpl index 9ad512c6e2..6f69bf58b2 100644 --- a/templates/CRM/Contribute/Form/Contribution/PremiumBlock.tpl +++ b/templates/CRM/Contribute/Form/Contribution/PremiumBlock.tpl @@ -12,11 +12,11 @@ {if $context EQ "makeContribution"}
{if $premiumBlock.premiums_intro_title} - {$premiumBlock.premiums_intro_title} + {$premiumBlock.premiums_intro_title|escape} {/if} {if $premiumBlock.premiums_intro_text}
- {$premiumBlock.premiums_intro_text} + {$premiumBlock.premiums_intro_text|escape}
{/if} {/if} @@ -25,7 +25,7 @@
{if $premiumBlock.premiums_intro_title} - {$premiumBlock.premiums_intro_title} + {$premiumBlock.premiums_intro_title|escape} {else} {ts}Your Premium Selection{/ts} {/if} @@ -33,23 +33,23 @@ {/if} {if $preview} - {assign var="showSelectOptions" value="1"} + {assign var="showPremiumSelectionFields" value="1"} {/if} {strip}
- {if $showPremium AND !$preview AND $premiumBlock.premiums_nothankyou_position EQ 1} + {if $showPremiumSelectionFields AND !$preview AND $premiumBlock.premiums_nothankyou_position EQ 1}
- {$premiumBlock.premiums_nothankyou_label} + {$premiumBlock.premiums_nothankyou_label|escape}
- {$premiumBlock.premiums_nothankyou_label} + {$premiumBlock.premiums_nothankyou_label|escape}
{/if} {foreach from=$products item=row} -
+
{if $row.thumbnail}
{$row.name|escape}
{/if}
{$row.name|escape}
@@ -69,13 +69,11 @@
{$row.description|escape}
- {if $showSelectOptions} - {assign var="pid" value="options_"|cat:$row.id} - {if $pid} + {if $showPremiumSelectionFields} + {assign var="premium_option" value="options_"|cat:$row.id}
-

{$form.$pid.html}

+

{$form.$premium_option.html}

- {/if} {else}

{$row.options|purify}

@@ -90,13 +88,13 @@
{/foreach} - {if $showPremium AND !$preview AND $premiumBlock.premiums_nothankyou_position EQ 2} + {if $showPremiumSelectionFields AND !$preview AND $premiumBlock.premiums_nothankyou_position EQ 2}
- {$premiumBlock.premiums_nothankyou_label} + {$premiumBlock.premiums_nothankyou_label|escape}
- {$premiumBlock.premiums_nothankyou_label} + {$premiumBlock.premiums_nothankyou_label|escape}
{/if} diff --git a/templates/CRM/Contribute/Form/Contribution/ThankYou.tpl b/templates/CRM/Contribute/Form/Contribution/ThankYou.tpl index 5d6e7943b5..ccae978698 100644 --- a/templates/CRM/Contribute/Form/Contribution/ThankYou.tpl +++ b/templates/CRM/Contribute/Form/Contribution/ThankYou.tpl @@ -300,7 +300,7 @@ {/crmRegion} {/if} - {include file="CRM/Contribute/Form/Contribution/PremiumBlock.tpl" context="thankContribution"} + {include file="CRM/Contribute/Form/Contribution/PremiumBlock.tpl" context="thankContribution" showPremiumSelectionFields=false preview=false} {if $customPost}
diff --git a/tests/phpunit/CRM/Contribute/Form/Contribution/ConfirmTest.php b/tests/phpunit/CRM/Contribute/Form/Contribution/ConfirmTest.php index 521252c5f2..26c98f0f9f 100644 --- a/tests/phpunit/CRM/Contribute/Form/Contribution/ConfirmTest.php +++ b/tests/phpunit/CRM/Contribute/Form/Contribution/ConfirmTest.php @@ -315,12 +315,13 @@ class CRM_Contribute_Form_Contribution_ConfirmTest extends CiviUnitTestCase { /** * @param array $submittedValues - * @param int $contributionPageID + * @param int|null $contributionPageID + * Will default to calling $this->>getContributionPageID() * * @return \Civi\Test\FormWrapper|\Civi\Test\FormWrappers\EventFormOnline|\Civi\Test\FormWrappers\EventFormParticipant|null */ - protected function submitOnlineContributionForm(array $submittedValues, int $contributionPageID) { - $form = $this->getTestForm('CRM_Contribute_Form_Contribution_Main', $submittedValues, ['id' => $contributionPageID]) + protected function submitOnlineContributionForm(array $submittedValues, ?int $contributionPageID = NULL) { + $form = $this->getTestForm('CRM_Contribute_Form_Contribution_Main', $submittedValues, ['id' => $contributionPageID ?: $this->getContributionPageID()]) ->addSubsequentForm('CRM_Contribute_Form_Contribution_Confirm'); $form->processForm(); return $form; @@ -444,6 +445,25 @@ class CRM_Contribute_Form_Contribution_ConfirmTest extends CiviUnitTestCase { $mailUtil->checkMailLog([\Civi::format()->money(337.55), 'Tax Rate', 'Subtotal']); } + /** + * Test form submission with basic price set. + */ + public function testSubmit(): void { + $this->contributionPageWithPriceSetCreate(); + $this->submitOnlineContributionForm([ + 'id' => $this->getContributionPageID(), + 'first_name' => 'J', + 'last_name' => 'T', + 'email-5' => 'JT@ohcanada.ca', + 'receive_date' => date('Y-m-d H:i:s'), + 'payment_processor_id' => 0, + 'priceSetId' => $this->getPriceSetID('ContributionPage'), + 'price_' . $this->ids['PriceField']['radio_field'] => $this->ids['PriceFieldValue']['10_dollars'], + ]); + $contribution = $this->getCreatedContribution(); + $this->assertEquals(5.00, $contribution['non_deductible_amount']); + } + /** * Test form submission with multiple option price set. * @@ -615,4 +635,16 @@ class CRM_Contribute_Form_Contribution_ConfirmTest extends CiviUnitTestCase { $this->assertMailSentNotContainingString('Amount'); } + /** + * Get the just-created contribution. + * + * @return array + */ + protected function getCreatedContribution(): array { + return $this->callAPISuccessGetSingle('Contribution', [ + 'contribution_page_id' => $this->getContributionPageID(), + 'version' => 4, + ]); + } + } diff --git a/tests/phpunit/CiviTest/CiviUnitTestCase.php b/tests/phpunit/CiviTest/CiviUnitTestCase.php index 0774edd7c4..7c14de40f0 100644 --- a/tests/phpunit/CiviTest/CiviUnitTestCase.php +++ b/tests/phpunit/CiviTest/CiviUnitTestCase.php @@ -1662,6 +1662,9 @@ class CiviUnitTestCase extends PHPUnit\Framework\TestCase { 'civicrm_price_set_entity', 'civicrm_price_field_value', 'civicrm_price_field', + 'civicrm_product', + 'civicrm_premiums', + 'civicrm_premiums_product', ]; $this->quickCleanup($tablesToTruncate); CRM_Core_DAO::executeQuery("DELETE FROM civicrm_membership_status WHERE name NOT IN('New', 'Current', 'Grace', 'Expired', 'Pending', 'Cancelled', 'Deceased')"); diff --git a/tests/phpunit/api/v3/ContributionPageTest.php b/tests/phpunit/api/v3/ContributionPageTest.php index c992a3a3b0..28055fc315 100644 --- a/tests/phpunit/api/v3/ContributionPageTest.php +++ b/tests/phpunit/api/v3/ContributionPageTest.php @@ -133,19 +133,6 @@ class api_v3_ContributionPageTest extends CiviUnitTestCase { $this->assertEquals(12, $result['values']['start_date']['type']); } - /** - * Test form submission with basic price set. - */ - public function testSubmit(): void { - $this->setUpContributionPage(); - $submitParams = $this->getBasicSubmitParams(); - - $this->callAPISuccess('ContributionPage', 'submit', $submitParams); - $contribution = $this->callAPISuccess('Contribution', 'getsingle', ['contribution_page_id' => $this->getContributionPageID(), 'return' => ['non_deductible_amount']]); - //assert non-deductible amount - $this->assertEquals(5.00, $contribution['non_deductible_amount']); - } - /** * Test form submission with basic price set. */ -- 2.25.1