From cb1412040f1e539020ec39338fe3c0c7b0ab6d78 Mon Sep 17 00:00:00 2001 From: Jon Waldstein Date: Thu, 26 Oct 2023 09:17:09 -0400 Subject: [PATCH] Refactor: create new forms using block models for translatable strings (#7053) Co-authored-by: Jon Waldstein --- ...rateDefaultDonationFormBlockCollection.php | 157 ++++++++++++++++++ src/FormBuilder/Routes/CreateFormRoute.php | 9 +- src/Framework/Blocks/BlockModel.php | 33 +++- ...DefaultDonationFormBlockCollectionTest.php | 140 ++++++++++++++++ 4 files changed, 326 insertions(+), 13 deletions(-) create mode 100644 src/FormBuilder/Actions/GenerateDefaultDonationFormBlockCollection.php create mode 100644 tests/Unit/Actions/GenerateDefaultDonationFormBlockCollectionTest.php diff --git a/src/FormBuilder/Actions/GenerateDefaultDonationFormBlockCollection.php b/src/FormBuilder/Actions/GenerateDefaultDonationFormBlockCollection.php new file mode 100644 index 0000000000..3841ea8150 --- /dev/null +++ b/src/FormBuilder/Actions/GenerateDefaultDonationFormBlockCollection.php @@ -0,0 +1,157 @@ +createSection( + __('How much would you like to donate today?', 'give'), + __('All donations directly impact our organization and help us further our mission.?', 'give'), + $this->createAmountBlock() + ); + + $section2 = $this->createSection( + __('Who\'s Giving Today?', 'give'), + __('We\'ll never share this information with anyone', 'give'), + $this->createDonorNameBlock(), + $this->createEmailBlock() + ); + + $section3 = $this->createSection( + __('Payment Details', 'give'), + __('How would you like to pay for your donation?', 'give'), + $this->createDonationSummaryBlock(), + $this->createPaymentGatewaysBlock() + ); + + return BlockCollection::make([ + $section1, + $section2, + $section3 + ]); + } + + /** + * @unreleased + */ + protected function createSection(string $title, string $description, BlockModel ...$innerBlocks): BlockModel + { + return BlockModel::make([ + 'name' => 'givewp/section', + 'attributes' => [ + 'title' => $title, + 'description' => $description, + ], + 'innerBlocks' => new BlockCollection($innerBlocks), + ]); + } + + /** + * @unreleased + */ + protected function createAmountBlock(): BlockModel + { + return BlockModel::make([ + 'name' => 'givewp/donation-amount', + 'attributes' => [ + "label" => __("Donation Amount", 'give'), + "levels" => [ + 10, + 25, + 50, + 100, + 250, + 500 + ], + "defaultLevel" => 10, + "priceOption" => "multi", + "setPrice" => 25, + "customAmount" => true, + "customAmountMin" => 1, + "recurringBillingPeriodOptions" => [ + "month" + ], + "recurringBillingInterval" => 1, + "recurringEnabled" => false, + "recurringLengthOfTime" => "0", + "recurringOptInDefaultBillingPeriod" => "month", + "recurringEnableOneTimeDonations" => true + ], + 'innerBlocks' => [], + ]); + } + + /** + * @unreleased + */ + protected function createDonorNameBlock(): BlockModel + { + return BlockModel::make([ + 'name' => 'givewp/donor-name', + 'attributes' => [ + "showHonorific" => false, + "honorifics" => [ + __("Mr", 'give'), + __("Ms", 'give'), + __("Mrs", 'give') + ], + "firstNameLabel" => __("First name", 'give'), + "firstNamePlaceholder" => __("First name", 'give'), + "lastNameLabel" => __("Last name", 'give'), + "lastNamePlaceholder" => __("Last name", 'give'), + "requireLastName" => false + ], + "innerBlocks" => [] + ]); + } + + /** + * @unreleased + */ + protected function createEmailBlock(): BlockModel + { + return BlockModel::make([ + 'name' => 'givewp/email', + 'attributes' => [ + "label" => __("Email Address", 'give'), + "isRequired" => true, + ], + "innerBlocks" => [] + ]); + } + + /** + * @unreleased + */ + protected function createDonationSummaryBlock(): BlockModel + { + return BlockModel::make([ + 'name' => 'givewp/donation-summary', + 'attributes' => [], + 'innerBlocks' => [] + ]); + } + + /** + * @unreleased + */ + protected function createPaymentGatewaysBlock(): BlockModel + { + return BlockModel::make([ + 'name' => 'givewp/payment-gateways', + 'attributes' => [], + 'innerBlocks' => [] + ]); + } +} \ No newline at end of file diff --git a/src/FormBuilder/Routes/CreateFormRoute.php b/src/FormBuilder/Routes/CreateFormRoute.php index 40b0e0c3a6..ad22968c8b 100644 --- a/src/FormBuilder/Routes/CreateFormRoute.php +++ b/src/FormBuilder/Routes/CreateFormRoute.php @@ -6,8 +6,8 @@ use Give\DonationForms\Models\DonationForm; use Give\DonationForms\Properties\FormSettings; use Give\DonationForms\ValueObjects\DonationFormStatus; +use Give\FormBuilder\Actions\GenerateDefaultDonationFormBlockCollection; use Give\FormBuilder\FormBuilderRouteBuilder; -use Give\Framework\Blocks\BlockCollection; use Give\Helpers\Hooks; /** @@ -16,6 +16,7 @@ class CreateFormRoute { /** + * @unreleased updated default form blocks to be generated from block models instead of json * @since 3.0.0 * * @return void @@ -30,10 +31,6 @@ public function __invoke() exit(); } if ('new' === $_GET['donationFormID']) { - $blocksJson = file_get_contents( - GIVE_PLUGIN_DIR . 'src/FormBuilder/resources/js/form-builder/src/blocks.json' - ); - $form = new DonationForm([ 'title' => __('GiveWP Donation Form', 'give'), 'status' => DonationFormStatus::DRAFT(), @@ -41,7 +38,7 @@ public function __invoke() 'enableDonationGoal' => true, 'goalAmount' => 1000, ]), - 'blocks' => BlockCollection::fromJson($blocksJson) + 'blocks' => (new GenerateDefaultDonationFormBlockCollection())(), ]); Hooks::doAction('givewp_form_builder_new_form', $form); diff --git a/src/Framework/Blocks/BlockModel.php b/src/Framework/Blocks/BlockModel.php index e18159fe87..bc8de55513 100644 --- a/src/Framework/Blocks/BlockModel.php +++ b/src/Framework/Blocks/BlockModel.php @@ -29,6 +29,8 @@ class BlockModel implements Arrayable public $innerBlocks; /** + * @unreleased added innerBlocks sanitization + * @since 3.0.0 * @param string $name * @param string $clientId * @param bool $isValid @@ -46,7 +48,28 @@ public function __construct( $this->clientId = $clientId ?? wp_generate_uuid4(); $this->isValid = $isValid; $this->attributes = $attributes; - $this->innerBlocks = $innerBlocks ?: new BlockCollection([]); + $this->innerBlocks = $this->sanitizeInnerBlocks($innerBlocks); + } + + /** + * @unreleased + * + * @param array|BlockCollection|null $innerBlocks + */ + public function sanitizeInnerBlocks($innerBlocks): BlockCollection + { + if (empty($innerBlocks)) { + return new BlockCollection([]); + } + + if (is_a($innerBlocks, BlockCollection::class)) { + return $innerBlocks; + } + + return new BlockCollection( + array_map([__CLASS__, 'make'], + $innerBlocks) + ); } /** @@ -94,6 +117,7 @@ public function getShortName(): string } /** + * @unreleased simplified innerBlocks param * @since 3.0.0 * * @param array $blockData @@ -101,17 +125,12 @@ public function getShortName(): string */ public static function make( array $blockData ): BlockModel { - $innerBlocks = !empty($blockData['innerBlocks']) ? new BlockCollection( - array_map([__CLASS__, 'make'], - $blockData['innerBlocks']) - ) : new BlockCollection([]); - return new BlockModel( $blockData['name'], !empty($blockData['clientId']) ? $blockData['clientId'] : wp_generate_uuid4(), !empty($blockData['isValid']) ? $blockData['isValid'] : true, !empty($blockData['attributes']) ? $blockData['attributes'] : [], - $innerBlocks + $blockData['innerBlocks'] ?? [] ); } diff --git a/tests/Unit/Actions/GenerateDefaultDonationFormBlockCollectionTest.php b/tests/Unit/Actions/GenerateDefaultDonationFormBlockCollectionTest.php new file mode 100644 index 0000000000..cda7a7435f --- /dev/null +++ b/tests/Unit/Actions/GenerateDefaultDonationFormBlockCollectionTest.php @@ -0,0 +1,140 @@ +assertCount(3, $blockCollection->getBlocks()); + } + + /** + * @unreleased + */ + public function testShouldIncludeDefaultDonationAmountBlock(): void + { + $blockCollection = (new GenerateDefaultDonationFormBlockCollection())(); + + $block = $blockCollection->findByName('givewp/donation-amount'); + + $this->assertInstanceOf(BlockModel::class, $block); + + $this->assertEquals( + $block->getAttributes(), + [ + "label" => __("Donation Amount", 'give'), + "levels" => [ + 10, + 25, + 50, + 100, + 250, + 500 + ], + "defaultLevel" => 10, + "priceOption" => "multi", + "setPrice" => 25, + "customAmount" => true, + "customAmountMin" => 1, + "recurringBillingPeriodOptions" => [ + "month" + ], + "recurringBillingInterval" => 1, + "recurringEnabled" => false, + "recurringLengthOfTime" => "0", + "recurringOptInDefaultBillingPeriod" => "month", + "recurringEnableOneTimeDonations" => true + ] + ); + } + + /** + * @unreleased + */ + public function testShouldIncludeDefaultDonorNameBlock(): void + { + $blockCollection = (new GenerateDefaultDonationFormBlockCollection())(); + + $block = $blockCollection->findByName('givewp/donor-name'); + + $this->assertInstanceOf(BlockModel::class, $block); + + $this->assertEquals( + $block->getAttributes(), + [ + "showHonorific" => false, + "honorifics" => [ + __("Mr", 'give'), + __("Ms", 'give'), + __("Mrs", 'give') + ], + "firstNameLabel" => __("First name", 'give'), + "firstNamePlaceholder" => __("First name", 'give'), + "lastNameLabel" => __("Last name", 'give'), + "lastNamePlaceholder" => __("Last name", 'give'), + "requireLastName" => false + ] + ); + } + + /** + * @unreleased + */ + public function testShouldIncludeDefaultEmailBlock(): void + { + $blockCollection = (new GenerateDefaultDonationFormBlockCollection())(); + + $block = $blockCollection->findByName('givewp/email'); + + $this->assertInstanceOf(BlockModel::class, $block); + + $this->assertEquals( + $block->getAttributes(), + [ + "label" => __("Email Address", 'give'), + "isRequired" => true, + ] + ); + } + + /** + * @unreleased + */ + public function testShouldIncludeDefaultDonationSummaryBlock(): void + { + $blockCollection = (new GenerateDefaultDonationFormBlockCollection())(); + + $block = $blockCollection->findByName('givewp/donation-summary'); + + $this->assertInstanceOf(BlockModel::class, $block); + + $this->assertEquals([], $block->getAttributes()); + } + + /** + * @unreleased + */ + public function testShouldIncludeDefaultPaymentGatewaysBlock(): void + { + $blockCollection = (new GenerateDefaultDonationFormBlockCollection())(); + + $block = $blockCollection->findByName('givewp/payment-gateways'); + + $this->assertInstanceOf(BlockModel::class, $block); + + $this->assertEquals([], $block->getAttributes()); + } +} \ No newline at end of file