From c4cbe830140b265873d4546f783506a9bb157575 Mon Sep 17 00:00:00 2001 From: "Kyle B. Johnson" Date: Mon, 9 Jan 2023 15:06:13 -0500 Subject: [PATCH] Fix: Store backwards compatible form meta (#109) * fix: Store backwards compatible form meta Co-authored-by: Jon Waldstein --- .../StoreBackwardsCompatibleFormMeta.php | 83 ++++++++++++ src/NextGen/DonationForm/ServiceProvider.php | 4 + .../StoreBackwardsCompatibleFormMetaTest.php | 124 ++++++++++++++++++ 3 files changed, 211 insertions(+) create mode 100644 src/NextGen/DonationForm/Actions/StoreBackwardsCompatibleFormMeta.php create mode 100644 tests/Unit/DonationForm/Actions/StoreBackwardsCompatibleFormMetaTest.php diff --git a/src/NextGen/DonationForm/Actions/StoreBackwardsCompatibleFormMeta.php b/src/NextGen/DonationForm/Actions/StoreBackwardsCompatibleFormMeta.php new file mode 100644 index 000000000..6ddc4e657 --- /dev/null +++ b/src/NextGen/DonationForm/Actions/StoreBackwardsCompatibleFormMeta.php @@ -0,0 +1,83 @@ +storeDonationLevels($donationForm); + $this->storeDonationGoal($donationForm); + } + + /** + * @unreleased + */ + public function storeDonationLevels(DonationForm $donationForm) + { + $amountField = $donationForm->schema()->getNodeByName('amount'); + + if (!$amountField) { + return; + } + + $donationLevels = $amountField->getLevels(); + $donationLevels = array_map(function ($donationLevel, $index) { + return [ + '_give_id' => [ + 'level_id' => $index, + ], + '_give_amount' => $donationLevel + ]; + }, $donationLevels, array_keys($donationLevels)); + + // @todo: Replace with DonationFormMetaKeys::PRICE_OPTION when available. + $this->saveSingleFormMeta($donationForm->id, '_give_price_option', 'multi'); + $this->saveSingleFormMeta($donationForm->id, DonationFormMetaKeys::DONATION_LEVELS, $donationLevels); + } + + /** + * @unreleased + */ + public function storeDonationGoal(DonationForm $donationForm) + { + $this->saveSingleFormMeta( + $donationForm->id, + DonationFormMetaKeys::GOAL_OPTION, + $donationForm->settings->enableDonationGoal ? 'enabled' : 'disabled' + ); + + $goalType = $donationForm->settings->goalType->getValue(); + $goalType = ($goalType === 'donations') ? 'donation' : $goalType; // @todo Mismatch. Legacy uses "donation" instead of "donations". + $this->saveSingleFormMeta($donationForm->id, '_give_goal_format', $goalType); + + $metaLookup = [ + 'donation' => '_give_number_of_donation_goal', + 'donors' => '_give_number_of_donor_goal', + 'amount' => '_give_set_goal', + ]; + + $goalAmount = ('amount' === $goalType) ? give_sanitize_amount_for_db( + $donationForm->settings->goalAmount + ) : $donationForm->settings->goalAmount; + $this->saveSingleFormMeta($donationForm->id, $metaLookup[$goalType], $goalAmount); + } + + /** + * @unreleased + */ + protected function saveSingleFormMeta($formId, $metaKey, $metaValue) + { + if (give()->form_meta->get_meta($formId, $metaKey, true)) { + give()->form_meta->update_meta($formId, $metaKey, $metaValue); + } else { + give()->form_meta->add_meta($formId, $metaKey, $metaValue); + } + } +} diff --git a/src/NextGen/DonationForm/ServiceProvider.php b/src/NextGen/DonationForm/ServiceProvider.php index 0905d9267..f205b8b23 100644 --- a/src/NextGen/DonationForm/ServiceProvider.php +++ b/src/NextGen/DonationForm/ServiceProvider.php @@ -3,6 +3,7 @@ namespace Give\NextGen\DonationForm; use Give\Helpers\Hooks; +use Give\NextGen\DonationForm\Actions\StoreBackwardsCompatibleFormMeta; use Give\NextGen\DonationForm\Blocks\DonationFormBlock\Block as DonationFormBlock; use Give\NextGen\DonationForm\Routes\DonateRoute; use Give\NextGen\DonationForm\Routes\DonationFormPreviewRoute; @@ -31,5 +32,8 @@ public function boot() Hooks::addAction('template_redirect', DonateRoute::class); Hooks::addAction('template_redirect', DonationFormViewRoute::class); Hooks::addAction('template_redirect', DonationFormPreviewRoute::class); + + Hooks::addAction('givewp_donation_form_created', StoreBackwardsCompatibleFormMeta::class); + Hooks::addAction('givewp_donation_form_updated', StoreBackwardsCompatibleFormMeta::class); } } diff --git a/tests/Unit/DonationForm/Actions/StoreBackwardsCompatibleFormMetaTest.php b/tests/Unit/DonationForm/Actions/StoreBackwardsCompatibleFormMetaTest.php new file mode 100644 index 000000000..486699818 --- /dev/null +++ b/tests/Unit/DonationForm/Actions/StoreBackwardsCompatibleFormMetaTest.php @@ -0,0 +1,124 @@ +create(); + + $this->assertEquals('multi', $this->getSingleFormMeta($donationForm->id, '_give_price_option' )); + $this->assertIsArray($this->getSingleFormMeta($donationForm->id, DonationFormMetaKeys::DONATION_LEVELS)); + } + + /** + * @unreleased + */ + public function testDonationLevelMetaIsStoredOnUpdate() + { + /** @var DonationForm $donationForm */ + $donationForm = DonationForm::factory()->create(); + give()->form_meta->delete_meta($donationForm->id, '_give_price_option'); + give()->form_meta->delete_meta($donationForm->id, DonationFormMetaKeys::DONATION_LEVELS); + + $donationForm->save(); // Trigger update. + + $this->assertEquals('multi', $this->getSingleFormMeta($donationForm->id, '_give_price_option' )); + $this->assertIsArray($this->getSingleFormMeta($donationForm->id, DonationFormMetaKeys::DONATION_LEVELS)); + } + + /** + * @unreleased + */ + public function testDonationGoalMetaIsStoredOnInsert() + { + /** @var DonationForm $donationForm */ + $donationForm = DonationForm::factory()->make(); + $donationForm->settings->enableDonationGoal = true; + $donationForm->settings->goalType = GoalType::AMOUNT(); + $donationForm->settings->goalAmount = 500; + $donationForm->save(); // Trigger created hook. + + $this->assertEquals('enabled', $this->getSingleFormMeta($donationForm->id, DonationFormMetaKeys::GOAL_OPTION )); + $this->assertEquals('amount', $this->getSingleFormMeta($donationForm->id, '_give_goal_format' )); + $this->assertSame('500.000000', $this->getSingleFormMeta($donationForm->id, '_give_set_goal' )); + } + + /** + * @unreleased + */ + public function testDonationGoalMetaIsStoredOnUpdate() + { + /** @var DonationForm $donationForm */ + $donationForm = DonationForm::factory()->create(); + give()->form_meta->delete_meta($donationForm->id, DonationFormMetaKeys::GOAL_OPTION); + give()->form_meta->delete_meta($donationForm->id, '_give_goal_format'); + give()->form_meta->delete_meta($donationForm->id, '_give_set_goal'); + + $donationForm->settings->enableDonationGoal = true; + $donationForm->settings->goalType = GoalType::AMOUNT(); + $donationForm->settings->goalAmount = 500; + $donationForm->save(); // Trigger update hook. + + $this->assertEquals('enabled', $this->getSingleFormMeta($donationForm->id, DonationFormMetaKeys::GOAL_OPTION )); + $this->assertEquals('amount', $this->getSingleFormMeta($donationForm->id, '_give_goal_format' )); + $this->assertSame('500.000000', $this->getSingleFormMeta($donationForm->id, '_give_set_goal' )); + } + + /** + * @unreleased + */ + public function testDonationGoalMetaUsesGoalTypeMetaKeyAmount() + { + /** @var DonationForm $donationForm */ + $donationForm = DonationForm::factory()->make(); + $donationForm->settings->goalType = GoalType::AMOUNT(); + $donationForm->save(); + + $this->assertNotNull($this->getSingleFormMeta($donationForm->id, '_give_set_goal' )); + } + + /** + * @unreleased + */ + public function testDonationGoalMetaUsesGoalTypeMetaKeyDonations() + { + /** @var DonationForm $donationForm */ + $donationForm = DonationForm::factory()->make(); + $donationForm->settings->goalType = GoalType::DONATIONS(); + $donationForm->save(); + + $this->assertNotNull($this->getSingleFormMeta($donationForm->id, '_give_number_of_donation_goal' )); + } + + /** + * @unreleased + */ + public function testDonationGoalMetaUsesGoalTypeMetaKeyDonors() + { + /** @var DonationForm $donationForm */ + $donationForm = DonationForm::factory()->make(); + $donationForm->settings->goalType = GoalType::DONORS(); + $donationForm->save(); + + $this->assertNotNull($this->getSingleFormMeta($donationForm->id, '_give_number_of_donor_goal' )); + } + + protected function getSingleFormMeta($formId, $metaKey) + { + return give()->form_meta->get_meta($formId, $metaKey, $single = true); + } +}