From 4eff0ae308ac5df6f3066aef39419469bff8a96e Mon Sep 17 00:00:00 2001 From: Paulo Iankoski Date: Fri, 18 Aug 2023 12:20:29 -0300 Subject: [PATCH 01/13] Refactor: return the block-node relationships in the donation form schema (#6875) * refactor: replace recently added hook with an additional prop on existing hook * feature: include Section node on the block node relationships array * refactor: extract duplicated code to a private method * refactor: rearrange method attributes --- .../ConvertDonationFormBlocksToFieldsApi.php | 35 +++++++++++++++---- .../Repositories/DonationFormRepository.php | 5 +-- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/DonationForms/Actions/ConvertDonationFormBlocksToFieldsApi.php b/src/DonationForms/Actions/ConvertDonationFormBlocksToFieldsApi.php index ee2042453d..1f375301fc 100644 --- a/src/DonationForms/Actions/ConvertDonationFormBlocksToFieldsApi.php +++ b/src/DonationForms/Actions/ConvertDonationFormBlocksToFieldsApi.php @@ -26,7 +26,6 @@ use Give\Framework\FieldsAPI\Section; use Give\Framework\FieldsAPI\Text; use Give\Framework\FieldsAPI\Textarea; -use Give\Helpers\Hooks; use WP_User; /** @@ -42,13 +41,18 @@ class ConvertDonationFormBlocksToFieldsApi * @var string */ protected $currency; + /** + * @var array {blockClientId: {node: Node, block: BlockModel}} + */ + protected $blockNodeRelationships = []; /** * @since 3.0.0 * + * @return array {DonationForm, array {blockClientId: {node: Node, block: BlockModel}}} * @throws TypeNotSupported|NameCollisionException */ - public function __invoke(BlockCollection $blocks, int $formId): DonationForm + public function __invoke(BlockCollection $blocks, int $formId): array { $this->formId = $formId; $this->currency = give_get_currency($formId); @@ -78,7 +82,7 @@ static function ($node) { $form->append($section); } - return $form; + return [$form, $this->blockNodeRelationships]; } /** @@ -86,9 +90,13 @@ static function ($node) { */ protected function convertTopLevelBlockToSection(BlockModel $block, int $blockIndex): Section { - return Section::make($block->getShortName() . '-' . $blockIndex) + $node = Section::make($block->getShortName() . '-' . $blockIndex) ->label($block->getAttribute('title')) ->description($block->getAttribute('description')); + + $this->mapBlockToNodeRelationships($block, $node); + + return $node; } /** @@ -104,9 +112,9 @@ protected function convertInnerBlockToNode(BlockModel $block, int $blockIndex) $node = $this->createNodeFromBlockWithUniqueAttributes($block, $blockIndex); if ($node instanceof Node) { - $node = $this->mapGenericBlockAttributesToNode($node, $block); + $node = $this->mapGenericBlockAttributesToNode($block, $node); - Hooks::doAction('givewp_donation_form_block_converted_to_node', $node, $block); + $this->mapBlockToNodeRelationships($block, $node); return $node; } @@ -356,7 +364,7 @@ protected function createNodeFromConsentBlock(BlockModel $block, int $blockIndex /** * @since 3.0.0 */ - protected function mapGenericBlockAttributesToNode(Node $node, BlockModel $block): Node + protected function mapGenericBlockAttributesToNode(BlockModel $block, Node $node): Node { if ('field' === $node->getNodeType()) { // Label @@ -385,4 +393,17 @@ protected function mapGenericBlockAttributesToNode(Node $node, BlockModel $block return $node; } + + /** + * @since 3.0.0 + * + * @return void + */ + private function mapBlockToNodeRelationships(BlockModel $block, Node $node) + { + $this->blockNodeRelationships[$block->clientId] = [ + 'block' => $block, + 'node' => $node, + ]; + } } diff --git a/src/DonationForms/Repositories/DonationFormRepository.php b/src/DonationForms/Repositories/DonationFormRepository.php index db3dbee698..751109161b 100644 --- a/src/DonationForms/Repositories/DonationFormRepository.php +++ b/src/DonationForms/Repositories/DonationFormRepository.php @@ -407,7 +407,7 @@ public function getTotalRevenue(int $formId): int public function getFormSchemaFromBlocks(int $formId, BlockCollection $blocks): DonationFormNode { try { - $form = (new ConvertDonationFormBlocksToFieldsApi())($blocks, $formId); + list($form, $blockNodeRelationships) = (new ConvertDonationFormBlocksToFieldsApi())($blocks, $formId); $formNodes = $form->all(); /** @var Section $firstSection */ @@ -433,9 +433,10 @@ function ($value, Closure $fail, string $key, array $values) use ($formId) { Log::error('Failed converting donation form blocks to fields', compact('formId', 'blocks')); $form = new DonationFormNode('donation-form'); + $blockNodeRelationships = []; } - Hooks::doAction('givewp_donation_form_schema', $form, $formId); + Hooks::doAction('givewp_donation_form_schema', $form, $formId, $blockNodeRelationships); return $form; } From e7e0132938e5aafe6e51def826e038fb61796771 Mon Sep 17 00:00:00 2001 From: Joshua Dinh <75056371+JoshuaHungDinh@users.noreply.github.com> Date: Fri, 18 Aug 2023 08:49:21 -0700 Subject: [PATCH 02/13] refactor: style custom amount with white background (#6882) --- src/DonationForms/resources/styles/components/_amount.scss | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/DonationForms/resources/styles/components/_amount.scss b/src/DonationForms/resources/styles/components/_amount.scss index cf7139f912..7a408ad2ce 100644 --- a/src/DonationForms/resources/styles/components/_amount.scss +++ b/src/DonationForms/resources/styles/components/_amount.scss @@ -1,4 +1,5 @@ @use '../variables'; + $borderColor: #9A9A9A; .givewp-groups-donationAmount { @@ -49,6 +50,7 @@ $borderColor: #9A9A9A; display: flex; align-items: center; justify-content: space-between; + background: var(--givewp-shades-white); border-width: 0.125rem; border-style: solid; border-color: $borderColor; From cd52fd86a5fd7a97b345c34dfba831ccecc8c2e4 Mon Sep 17 00:00:00 2001 From: Joshua Dinh <75056371+JoshuaHungDinh@users.noreply.github.com> Date: Fri, 18 Aug 2023 08:55:21 -0700 Subject: [PATCH 03/13] fix: update last name placeholder (#6881) --- .../js/form-builder/src/blocks/fields/donor-name/Edit.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/FormBuilder/resources/js/form-builder/src/blocks/fields/donor-name/Edit.tsx b/src/FormBuilder/resources/js/form-builder/src/blocks/fields/donor-name/Edit.tsx index 3567c01893..d4b890ec24 100644 --- a/src/FormBuilder/resources/js/form-builder/src/blocks/fields/donor-name/Edit.tsx +++ b/src/FormBuilder/resources/js/form-builder/src/blocks/fields/donor-name/Edit.tsx @@ -61,7 +61,7 @@ export default function Edit({ placeholder={lastNamePlaceholder} required={requireLastName} className={`${requireLastName ? 'give-is-required' : ''}`} - value={firstNamePlaceholder} + value={lastNamePlaceholder} onChange={null} readOnly /> @@ -141,4 +141,4 @@ export default function Edit({ ); -} \ No newline at end of file +} From 81a91a2439537bc6eea504ddf935ddc5664796e1 Mon Sep 17 00:00:00 2001 From: "Kyle B. Johnson" Date: Fri, 18 Aug 2023 14:45:09 -0400 Subject: [PATCH 04/13] Chore: Restore automated checks after codebase grafting (#6884) * Chore: Update env testing matrix With v3 we are bumping the minimum required versions of PHP (7.2) and WordPress (6.0). * chore: Prevent unsafe use of new static * chore: Prevent unsafe use of new static * chore: Update php-compat workflow versions * chore: Add WP CLI stubs for static analysis * chore: Add missing return type * refactor: Move return outside of if/else * chore: Add missing property declaration * chore: Update reference case * refactor: Update Password field to prevent storage * chore: Ignore symbol errors for recurring add-on * refactor: Remove return type for storeAsDonorMeta * fix: Skip unsupported currencies that fail tests. With the introduction of the phpmoney library in GiveWP v3 some currencies are no longer supported. * fix: Update assertion for PayPal Standard label. * fix: Add partial mock to avoid enqueueing assets * fix: Update return type * Update src/DonationForms/DataTransferObjects/AuthenticationData.php Co-authored-by: Jason Adams * Update src/DonationForms/DataTransferObjects/DonateFormRouteData.php Co-authored-by: Jason Adams * Update src/DonationForms/DataTransferObjects/DonateRouteData.php Co-authored-by: Jason Adams * chore: Update return self signatures * Apply suggestions from code review Co-authored-by: Jason Adams --- .github/workflows/php-compatibility.yml | 2 + .github/workflows/wordpress.yml | 9 +- composer.json | 3 +- composer.lock | 90 ++++++++++++++++++- phpstan.neon | 3 + .../Controllers/BlockRenderController.php | 2 +- .../AuthenticationData.php | 4 +- .../DonateFormRouteData.php | 4 +- .../DataTransferObjects/DonateRouteData.php | 4 +- ...nationConfirmationReceiptViewRouteData.php | 2 +- .../DonationFormPreviewRouteData.php | 2 +- .../DonationFormQueryData.php | 4 +- .../DonationFormViewRouteData.php | 4 +- .../LegacyPurchaseFormData.php | 2 +- .../DataTransferObjects/UserData.php | 4 +- .../ValidationRouteData.php | 6 +- src/DonationForms/Models/DonationForm.php | 4 +- .../Actions/BuildEmailPreview.php | 5 ++ .../Actions/TransferDonations.php | 21 ++++- src/FormMigration/Actions/TransferFormUrl.php | 21 ++++- .../Contracts/TransferAction.php | 25 ------ .../FormMigrationPayload.php | 4 +- .../DataTransferObjects/TransferOptions.php | 8 +- .../FieldsAPI/Concerns/HasPersistence.php | 2 +- src/Framework/FieldsAPI/Consent.php | 4 +- src/Framework/FieldsAPI/Password.php | 6 +- .../PayPalCommerceSubscriptionModule.php | 1 + .../Listeners/InvoicePaymentFailed.php | 1 + .../Controllers/BlockRenderControllerTest.php | 11 ++- ...stConvertDonationFormBlocksToFieldsApi.php | 4 +- tests/includes/legacy/tests-formatting.php | 4 + tests/includes/legacy/tests-gateways.php | 4 +- 32 files changed, 191 insertions(+), 79 deletions(-) delete mode 100644 src/FormMigration/Contracts/TransferAction.php diff --git a/.github/workflows/php-compatibility.yml b/.github/workflows/php-compatibility.yml index 4c20a57cc5..5c6a70a3b2 100644 --- a/.github/workflows/php-compatibility.yml +++ b/.github/workflows/php-compatibility.yml @@ -9,3 +9,5 @@ on: jobs: build: uses: impress-org/givewp-github-actions/.github/workflows/php-compatibility.yml@master + with: + test_versions: "[ '7.2', '8.0' ]" diff --git a/.github/workflows/wordpress.yml b/.github/workflows/wordpress.yml index 4f0eb225ef..f41b524c5d 100644 --- a/.github/workflows/wordpress.yml +++ b/.github/workflows/wordpress.yml @@ -22,14 +22,9 @@ jobs: runs-on: ubuntu-20.04 strategy: matrix: - php: [ 7.0, 7.4, 8.0 ] + php: [ 7.2, 7.4, 8.0 ] mysql: [ 'mysql:5.6', 'mysql:8.0' ] - wordpress: [ '5.0', latest ] - exclude: - - php: 7.4 - wordpress: '5.0' - - php: 8.0 - wordpress: '5.0' + wordpress: [ '6.0', latest ] services: mysql56: diff --git a/composer.json b/composer.json index 3a22f9ae71..cb4b8c65a1 100644 --- a/composer.json +++ b/composer.json @@ -30,7 +30,8 @@ "wp-cli/wp-cli-bundle": "^2.5", "yoast/phpunit-polyfills": "^1.0", "wordpress/wordpress": "dev-trunk", - "squizlabs/php_codesniffer": "^3.5" + "squizlabs/php_codesniffer": "^3.5", + "php-stubs/wp-cli-stubs": "^2.8" }, "keywords": [ "wordpress", diff --git a/composer.lock b/composer.lock index 3e86a96363..d11a780195 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "0cf04c47636def2076e1f59fbcfb678d", + "content-hash": "69c37b4b5c6ac6bc622e7449617483e9", "packages": [ { "name": "composer/installers", @@ -2444,6 +2444,94 @@ }, "time": "2013-02-24T15:01:54+00:00" }, + { + "name": "php-stubs/wordpress-stubs", + "version": "v6.3.0", + "source": { + "type": "git", + "url": "https://github.com/php-stubs/wordpress-stubs.git", + "reference": "adda7609e71d5f4dc7b87c74f8ec9e3437d2e92c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-stubs/wordpress-stubs/zipball/adda7609e71d5f4dc7b87c74f8ec9e3437d2e92c", + "reference": "adda7609e71d5f4dc7b87c74f8ec9e3437d2e92c", + "shasum": "" + }, + "require-dev": { + "nikic/php-parser": "^4.13", + "php": "^7.4 || ~8.0.0", + "php-stubs/generator": "^0.8.3", + "phpdocumentor/reflection-docblock": "^5.3", + "phpstan/phpstan": "^1.10.12", + "phpunit/phpunit": "^9.5" + }, + "suggest": { + "paragonie/sodium_compat": "Pure PHP implementation of libsodium", + "szepeviktor/phpstan-wordpress": "WordPress extensions for PHPStan" + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "WordPress function and class declaration stubs for static analysis.", + "homepage": "https://github.com/php-stubs/wordpress-stubs", + "keywords": [ + "PHPStan", + "static analysis", + "wordpress" + ], + "support": { + "issues": "https://github.com/php-stubs/wordpress-stubs/issues", + "source": "https://github.com/php-stubs/wordpress-stubs/tree/v6.3.0" + }, + "time": "2023-08-10T16:34:11+00:00" + }, + { + "name": "php-stubs/wp-cli-stubs", + "version": "v2.8.0", + "source": { + "type": "git", + "url": "https://github.com/php-stubs/wp-cli-stubs.git", + "reference": "5a4fce1430c5d59f8d8a5f0ab573930139b0279b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-stubs/wp-cli-stubs/zipball/5a4fce1430c5d59f8d8a5f0ab573930139b0279b", + "reference": "5a4fce1430c5d59f8d8a5f0ab573930139b0279b", + "shasum": "" + }, + "require": { + "php-stubs/wordpress-stubs": "^4.7 || ^5.0 || ^6.0" + }, + "require-dev": { + "php": "~7.3 || ~8.0", + "php-stubs/generator": "^0.8.0" + }, + "suggest": { + "symfony/polyfill-php73": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", + "szepeviktor/phpstan-wordpress": "WordPress extensions for PHPStan" + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "WP-CLI function and class declaration stubs for static analysis.", + "homepage": "https://github.com/php-stubs/wp-cli-stubs", + "keywords": [ + "PHPStan", + "static analysis", + "wordpress", + "wp-cli" + ], + "support": { + "issues": "https://github.com/php-stubs/wp-cli-stubs/issues", + "source": "https://github.com/php-stubs/wp-cli-stubs/tree/v2.8.0" + }, + "time": "2023-06-02T09:21:15+00:00" + }, { "name": "phpcompatibility/php-compatibility", "version": "9.3.5", diff --git a/phpstan.neon b/phpstan.neon index 10da244d30..94a2e2f34b 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -13,6 +13,9 @@ parameters: - vendor/vendor-prefixed/ scanFiles: - vendor/wordpress/wordpress/src/wp-includes/compat.php + - vendor/php-stubs/wp-cli-stubs/wp-cli-stubs.php + - vendor/php-stubs/wp-cli-stubs/wp-cli-commands-stubs.php + - vendor/php-stubs/wp-cli-stubs/wp-cli-i18n-stubs.php excludePaths: analyse: - src/LegacySubscriptions/includes/ # Scan but do not analyse diff --git a/src/DonationForms/Blocks/DonationFormBlock/Controllers/BlockRenderController.php b/src/DonationForms/Blocks/DonationFormBlock/Controllers/BlockRenderController.php index 27ae952acd..a5f9c8a9ed 100644 --- a/src/DonationForms/Blocks/DonationFormBlock/Controllers/BlockRenderController.php +++ b/src/DonationForms/Blocks/DonationFormBlock/Controllers/BlockRenderController.php @@ -91,7 +91,7 @@ private function getViewUrl(DonationForm $donationForm, string $embedId): string * * @since 3.0.0 */ - private function loadEmbedScript() + protected function loadEmbedScript() { (new EnqueueScript( 'givewp-donation-form-embed', diff --git a/src/DonationForms/DataTransferObjects/AuthenticationData.php b/src/DonationForms/DataTransferObjects/AuthenticationData.php index eaf28d871b..b7330aa5b0 100644 --- a/src/DonationForms/DataTransferObjects/AuthenticationData.php +++ b/src/DonationForms/DataTransferObjects/AuthenticationData.php @@ -21,9 +21,9 @@ class AuthenticationData * * @since 3.0.0 */ - public static function fromRequest(array $request): AuthenticationData + public static function fromRequest(array $request): self { - $self = new static(); + $self = new self(); $self->login = $request['login']; $self->password = $request['password']; diff --git a/src/DonationForms/DataTransferObjects/DonateFormRouteData.php b/src/DonationForms/DataTransferObjects/DonateFormRouteData.php index 9f5c2c02ff..f439c89a17 100644 --- a/src/DonationForms/DataTransferObjects/DonateFormRouteData.php +++ b/src/DonationForms/DataTransferObjects/DonateFormRouteData.php @@ -43,9 +43,9 @@ class DonateFormRouteData implements Arrayable * * @since 3.0.0 */ - public static function fromRequest(array $requestData): DonateFormRouteData + public static function fromRequest(array $requestData): self { - $self = new static(); + $self = new self(); $self->formId = (int)$requestData['formId']; $self->gatewayId = $requestData['gatewayId']; $self->originUrl = $requestData['originUrl']; diff --git a/src/DonationForms/DataTransferObjects/DonateRouteData.php b/src/DonationForms/DataTransferObjects/DonateRouteData.php index a8507bade1..dba9d27261 100644 --- a/src/DonationForms/DataTransferObjects/DonateRouteData.php +++ b/src/DonationForms/DataTransferObjects/DonateRouteData.php @@ -28,9 +28,9 @@ class DonateRouteData * * @since 3.0.0 */ - public static function fromRequest(array $request): DonateRouteData + public static function fromRequest(array $request): self { - $self = new static(); + $self = new self(); $self->routeSignature = $request['givewp-route-signature']; $self->routeSignatureId = $request['givewp-route-signature-id']; diff --git a/src/DonationForms/DataTransferObjects/DonationConfirmationReceiptViewRouteData.php b/src/DonationForms/DataTransferObjects/DonationConfirmationReceiptViewRouteData.php index e5853db2da..6f9497a3c0 100644 --- a/src/DonationForms/DataTransferObjects/DonationConfirmationReceiptViewRouteData.php +++ b/src/DonationForms/DataTransferObjects/DonationConfirmationReceiptViewRouteData.php @@ -18,7 +18,7 @@ class DonationConfirmationReceiptViewRouteData * * @since 3.0.0 */ - public static function fromRequest(array $request): DonationConfirmationReceiptViewRouteData + public static function fromRequest(array $request): self { $self = new self(); diff --git a/src/DonationForms/DataTransferObjects/DonationFormPreviewRouteData.php b/src/DonationForms/DataTransferObjects/DonationFormPreviewRouteData.php index b23e871975..52bf4b8566 100644 --- a/src/DonationForms/DataTransferObjects/DonationFormPreviewRouteData.php +++ b/src/DonationForms/DataTransferObjects/DonationFormPreviewRouteData.php @@ -34,7 +34,7 @@ class DonationFormPreviewRouteData */ public static function fromRequest(array $request): self { - $self = new static(); + $self = new self(); $self->formId = (int)$request['form-id']; $self->formSettings = !empty($request['form-settings']) ? FormSettings::fromJson( diff --git a/src/DonationForms/DataTransferObjects/DonationFormQueryData.php b/src/DonationForms/DataTransferObjects/DonationFormQueryData.php index 0c7f370ffb..62e26bef9c 100644 --- a/src/DonationForms/DataTransferObjects/DonationFormQueryData.php +++ b/src/DonationForms/DataTransferObjects/DonationFormQueryData.php @@ -55,9 +55,9 @@ class DonationFormQueryData * * @return DonationFormQueryData */ - public static function fromObject($queryObject): DonationFormQueryData + public static function fromObject($queryObject): self { - $self = new static(); + $self = new self(); $self->id = (int)$queryObject->id; $self->title = $queryObject->title; $self->createdAt = Temporal::toDateTime($queryObject->createdAt); diff --git a/src/DonationForms/DataTransferObjects/DonationFormViewRouteData.php b/src/DonationForms/DataTransferObjects/DonationFormViewRouteData.php index d52c4b5f01..d36f86b669 100644 --- a/src/DonationForms/DataTransferObjects/DonationFormViewRouteData.php +++ b/src/DonationForms/DataTransferObjects/DonationFormViewRouteData.php @@ -16,9 +16,9 @@ class DonationFormViewRouteData * * @since 3.0.0 */ - public static function fromRequest(array $request): DonationFormViewRouteData + public static function fromRequest(array $request): self { - $self = new static(); + $self = new self(); $self->formId = (int)$request['form-id']; diff --git a/src/DonationForms/DataTransferObjects/LegacyPurchaseFormData.php b/src/DonationForms/DataTransferObjects/LegacyPurchaseFormData.php index bffeb70e7b..0932560170 100644 --- a/src/DonationForms/DataTransferObjects/LegacyPurchaseFormData.php +++ b/src/DonationForms/DataTransferObjects/LegacyPurchaseFormData.php @@ -27,7 +27,7 @@ class LegacyPurchaseFormData * @param array{donation: Donation, donor: Donation} $array * @return LegacyPurchaseFormData */ - public static function fromArray(array $array): LegacyPurchaseFormData + public static function fromArray(array $array): self { $self = new self(); diff --git a/src/DonationForms/DataTransferObjects/UserData.php b/src/DonationForms/DataTransferObjects/UserData.php index 956455acb7..621f3ed34d 100644 --- a/src/DonationForms/DataTransferObjects/UserData.php +++ b/src/DonationForms/DataTransferObjects/UserData.php @@ -27,9 +27,9 @@ class UserData * * @since 3.0.0 */ - public static function fromUser(\WP_User $user): UserData + public static function fromUser(\WP_User $user): self { - $self = new static(); + $self = new self(); $self->firstName = $user->user_firstname; $self->lastName = $user->user_lastname; diff --git a/src/DonationForms/DataTransferObjects/ValidationRouteData.php b/src/DonationForms/DataTransferObjects/ValidationRouteData.php index eaddf78563..38bb3dc511 100644 --- a/src/DonationForms/DataTransferObjects/ValidationRouteData.php +++ b/src/DonationForms/DataTransferObjects/ValidationRouteData.php @@ -30,7 +30,7 @@ class ValidationRouteData implements Arrayable */ public static function fromRequest(array $requestData): self { - $self = new static(); + $self = new self(); $self->formId = (int)$requestData['formId']; $self->requestData = $requestData; @@ -65,9 +65,9 @@ public function validate(): JsonResponse if ($validator->fails()) { $this->throwDonationFormFieldErrorsException($validator->errors()); - } else { - return new JsonResponse(['valid' => true]); } + + return new JsonResponse(['valid' => true]); } /** diff --git a/src/DonationForms/Models/DonationForm.php b/src/DonationForms/Models/DonationForm.php index 95399ec36f..0dadb38f5c 100644 --- a/src/DonationForms/Models/DonationForm.php +++ b/src/DonationForms/Models/DonationForm.php @@ -105,9 +105,9 @@ public function save() * * @throws Exception */ - public function delete() + public function delete(): bool { - give(DonationFormRepository::class)->delete($this); + return give(DonationFormRepository::class)->delete($this); } /** diff --git a/src/FormBuilder/EmailPreview/Actions/BuildEmailPreview.php b/src/FormBuilder/EmailPreview/Actions/BuildEmailPreview.php index e52a3459f3..23f29c070f 100644 --- a/src/FormBuilder/EmailPreview/Actions/BuildEmailPreview.php +++ b/src/FormBuilder/EmailPreview/Actions/BuildEmailPreview.php @@ -9,6 +9,11 @@ */ class BuildEmailPreview { + /** + * @var ApplyPreviewTemplateTags + */ + protected $applyPreviewTemplateTagsAction; + /** * @param ApplyPreviewTemplateTags $applyPreviewTemplateTagsAction */ diff --git a/src/FormMigration/Actions/TransferDonations.php b/src/FormMigration/Actions/TransferDonations.php index 1ea01bf01c..f48b1e3777 100644 --- a/src/FormMigration/Actions/TransferDonations.php +++ b/src/FormMigration/Actions/TransferDonations.php @@ -2,12 +2,27 @@ namespace Give\FormMigration\Actions; -use Give\FormMigration\Contracts\TransferAction; use Give\Framework\Database\DB; -use Give\Framework\Exceptions\Primitives\Exception; -class TransferDonations extends TransferAction +class TransferDonations { + protected $sourceId; + + public function __construct($sourceId) + { + $this->sourceId = $sourceId; + } + + public static function from($sourceId): self + { + return new TransferDonations($sourceId); + } + + public function to($destinationId): void + { + $this->__invoke($destinationId); + } + public function __invoke($destinationId) { DB::table('give_donationmeta') diff --git a/src/FormMigration/Actions/TransferFormUrl.php b/src/FormMigration/Actions/TransferFormUrl.php index 3792606cb8..5c25fdadc5 100644 --- a/src/FormMigration/Actions/TransferFormUrl.php +++ b/src/FormMigration/Actions/TransferFormUrl.php @@ -2,10 +2,25 @@ namespace Give\FormMigration\Actions; -use Give\FormMigration\Contracts\TransferAction; - -class TransferFormUrl extends TransferAction +class TransferFormUrl { + protected $sourceId; + + public function __construct($sourceId) + { + $this->sourceId = $sourceId; + } + + public static function from($sourceId): self + { + return new TransferFormUrl($sourceId); + } + + public function to($destinationId): void + { + $this->__invoke($destinationId); + } + public function __invoke($destinationId) { $postName = get_post($this->sourceId)->post_name; diff --git a/src/FormMigration/Contracts/TransferAction.php b/src/FormMigration/Contracts/TransferAction.php deleted file mode 100644 index 8f97367fc8..0000000000 --- a/src/FormMigration/Contracts/TransferAction.php +++ /dev/null @@ -1,25 +0,0 @@ -sourceId = $sourceId; - } - - public static function from($sourceId) - { - return new static($sourceId); - } - - public function to($destinationId) - { - $this->__invoke($destinationId); - } - - public abstract function __invoke($destinationId); -} diff --git a/src/FormMigration/DataTransferObjects/FormMigrationPayload.php b/src/FormMigration/DataTransferObjects/FormMigrationPayload.php index 2a19041b45..ab4546f478 100644 --- a/src/FormMigration/DataTransferObjects/FormMigrationPayload.php +++ b/src/FormMigration/DataTransferObjects/FormMigrationPayload.php @@ -19,8 +19,8 @@ public function __construct(DonationFormV2 $formV2, DonationFormV3 $formV3) $this->formV3 = $formV3; } - public static function fromFormV2(DonationFormV2 $formV2) + public static function fromFormV2(DonationFormV2 $formV2): self { - return new static($formV2, DonationFormV3::factory()->create()); + return new self($formV2, DonationFormV3::factory()->create()); } } diff --git a/src/FormMigration/DataTransferObjects/TransferOptions.php b/src/FormMigration/DataTransferObjects/TransferOptions.php index f3c2ebdcfa..1717f3065a 100644 --- a/src/FormMigration/DataTransferObjects/TransferOptions.php +++ b/src/FormMigration/DataTransferObjects/TransferOptions.php @@ -22,18 +22,18 @@ public function __construct(bool $changeUrl, bool $delete, bool $redirect) $this->redirect = $redirect; } - public static function fromRequest(WP_REST_Request $request) + public static function fromRequest(WP_REST_Request $request): self { - return new static( + return new self( $request->get_param('changeUrl'), $request->get_param('delete'), $request->get_param('redirect') ); } - public static function fromArray($options) + public static function fromArray($options): self { - return new static( + return new self( $options['changeUrl'], $options['delete'], $options['redirect'] diff --git a/src/Framework/FieldsAPI/Concerns/HasPersistence.php b/src/Framework/FieldsAPI/Concerns/HasPersistence.php index 7da964fdd4..4703a76b10 100644 --- a/src/Framework/FieldsAPI/Concerns/HasPersistence.php +++ b/src/Framework/FieldsAPI/Concerns/HasPersistence.php @@ -103,7 +103,7 @@ public function getMetaKey() * @since 2.28.0 added types * @since 2.10.2 */ - public function storeAsDonorMeta(bool $storeAsDonorMeta = true): self + public function storeAsDonorMeta(bool $storeAsDonorMeta = true) { $this->scope = $storeAsDonorMeta ? PersistenceScope::donor() diff --git a/src/Framework/FieldsAPI/Consent.php b/src/Framework/FieldsAPI/Consent.php index 3ad6bc1045..31ece62640 100644 --- a/src/Framework/FieldsAPI/Consent.php +++ b/src/Framework/FieldsAPI/Consent.php @@ -4,10 +4,10 @@ namespace Give\Framework\FieldsAPI; -class Consent extends field +class Consent extends Field { use Concerns\HasLabel; - + protected $useGlobalSettings; protected $checkboxLabel; protected $displayType; diff --git a/src/Framework/FieldsAPI/Password.php b/src/Framework/FieldsAPI/Password.php index 20ecd41040..bc07794c3b 100644 --- a/src/Framework/FieldsAPI/Password.php +++ b/src/Framework/FieldsAPI/Password.php @@ -16,14 +16,14 @@ class Password extends Field const TYPE = 'password'; /** - * @param $storeAsDonorMeta + * @param bool $storeAsDonorMeta * * @return $this */ - public function storeAsDonorMeta($storeAsDonorMeta = true): self + public function storeAsDonorMeta(bool $storeAsDonorMeta = true) { // Do not allow password fields to be stored as donor meta. - $this->storeAsDonorMeta = false; + $this->scope = null; return $this; } diff --git a/src/PaymentGateways/Gateways/PayPalCommerce/PayPalCommerceSubscriptionModule.php b/src/PaymentGateways/Gateways/PayPalCommerce/PayPalCommerceSubscriptionModule.php index 51e285e5fd..a39be21f5e 100644 --- a/src/PaymentGateways/Gateways/PayPalCommerce/PayPalCommerceSubscriptionModule.php +++ b/src/PaymentGateways/Gateways/PayPalCommerce/PayPalCommerceSubscriptionModule.php @@ -30,6 +30,7 @@ public function createSubscription( public function cancelSubscription(Subscription $subscription) { try { + // @phpstan-ignore-next-line give(SubscriptionRepository::class) ->updateStatus($subscription->gatewaySubscriptionId, 'cancel'); diff --git a/src/PaymentGateways/Gateways/Stripe/StripePaymentElementGateway/Webhooks/Listeners/InvoicePaymentFailed.php b/src/PaymentGateways/Gateways/Stripe/StripePaymentElementGateway/Webhooks/Listeners/InvoicePaymentFailed.php index 0154b8796a..88a1feb10f 100644 --- a/src/PaymentGateways/Gateways/Stripe/StripePaymentElementGateway/Webhooks/Listeners/InvoicePaymentFailed.php +++ b/src/PaymentGateways/Gateways/Stripe/StripePaymentElementGateway/Webhooks/Listeners/InvoicePaymentFailed.php @@ -71,6 +71,7 @@ public function processEvent(Event $event) */ protected function triggerLegacyFailedEmailNotificationEvent(Invoice $invoice) { + // @phpstan-ignore-next-line $subscription = give_recurring_get_subscription_by('profile', $invoice->subscription); do_action('give_donor-subscription-payment-failed_email_notification', $subscription, $invoice); diff --git a/tests/Feature/Controllers/BlockRenderControllerTest.php b/tests/Feature/Controllers/BlockRenderControllerTest.php index cdd7b1f906..e30cdcc629 100644 --- a/tests/Feature/Controllers/BlockRenderControllerTest.php +++ b/tests/Feature/Controllers/BlockRenderControllerTest.php @@ -7,6 +7,7 @@ use Give\DonationForms\Models\DonationForm; use Give\Tests\TestCase; use Give\Tests\TestTraits\RefreshDatabase; +use PHPUnit_Framework_MockObject_MockBuilder; class BlockRenderControllerTest extends TestCase { @@ -23,11 +24,17 @@ public function testShouldReturnIframe() $donationForm = DonationForm::factory()->create(); $viewUrl = (new GenerateDonationFormViewRouteUrl())($donationForm->id); - $blockRenderController = new BlockRenderController(); + $blockRenderController = $this->createMock( + BlockRenderController::class, + function (PHPUnit_Framework_MockObject_MockBuilder $mockBuilder) { + $mockBuilder->setMethods(['loadEmbedScript']); // partial mock gateway by setting methods on the mock builder + return $mockBuilder->getMock(); + } + ); $this->assertSame( str_replace( - "", " ", '' diff --git a/tests/Unit/DonationForms/Actions/TestConvertDonationFormBlocksToFieldsApi.php b/tests/Unit/DonationForms/Actions/TestConvertDonationFormBlocksToFieldsApi.php index 1539ca5562..03f5db422f 100644 --- a/tests/Unit/DonationForms/Actions/TestConvertDonationFormBlocksToFieldsApi.php +++ b/tests/Unit/DonationForms/Actions/TestConvertDonationFormBlocksToFieldsApi.php @@ -51,7 +51,7 @@ public function testShouldReturnFormSchema() $blocks = BlockCollection::make([$block]); - $formSchema = (new ConvertDonationFormBlocksToFieldsApi())($blocks, $formId); + list($formSchema, $blockNodeRelationships) = (new ConvertDonationFormBlocksToFieldsApi())($blocks, $formId); $form = new DonationFormNode('donation-form'); $form->defaultCurrency('USD'); @@ -116,7 +116,7 @@ static function ($node, BlockModel $block, int $blockIndex) { 3 ); - $formSchema = (new ConvertDonationFormBlocksToFieldsApi())($blocks, $formId); + list($formSchema, $blockNodeRelationships) = (new ConvertDonationFormBlocksToFieldsApi())($blocks, $formId); $form = new DonationFormNode('donation-form'); $form->defaultCurrency('USD'); diff --git a/tests/includes/legacy/tests-formatting.php b/tests/includes/legacy/tests-formatting.php index ab44d644ac..01d3c506f7 100644 --- a/tests/includes/legacy/tests-formatting.php +++ b/tests/includes/legacy/tests-formatting.php @@ -76,6 +76,10 @@ public function give_get_currency_formatting_settings_provider() { // Set data. foreach ( $currencies as $code => $currency ) { + + // Skip unsupported currencies that cause failing tests. + if(in_array($code, ['VEF', 'BYR', 'IRT', 'MRO'])) continue; + $data[] = array( $code, $currency['setting'] ); } diff --git a/tests/includes/legacy/tests-gateways.php b/tests/includes/legacy/tests-gateways.php index aa161b5f62..44dc94ee67 100755 --- a/tests/includes/legacy/tests-gateways.php +++ b/tests/includes/legacy/tests-gateways.php @@ -33,7 +33,7 @@ public function test_payment_gateways() { $this->assertArrayHasKey('paypal', $out); $this->assertArrayHasKey('manual', $out); - $this->assertEquals('PayPal Standard *(v2)', $out['paypal']['admin_label']); + $this->assertEquals('PayPal Standard', $out['paypal']['admin_label']); $this->assertEquals('PayPal', $out['paypal']['checkout_label']); $this->assertEquals('Test Donation *(v2)', $out['manual']['admin_label']); @@ -85,7 +85,7 @@ public function test_default_gateway() */ public function test_get_gateway_admin_label() { - $this->assertEquals('PayPal Standard *(v2)', give_get_gateway_admin_label('paypal')); + $this->assertEquals('PayPal Standard', give_get_gateway_admin_label('paypal')); $this->assertEquals('Test Donation *(v2)', give_get_gateway_admin_label('manual')); } From 8299049e0b140934450c61f041c8bdbf64d1868b Mon Sep 17 00:00:00 2001 From: Jason Adams Date: Fri, 18 Aug 2023 12:21:06 -0700 Subject: [PATCH 05/13] Feature: Support group node visibility and polymorphism (#6887) * feature: support polymorophic group nodes and visibility * fix: correct node numeric keys after removal * fix: remove unused import * fix: amount props change to nodeProps --------- Co-authored-by: Jon Waldstein --- .../resources/app/fields/ElementNode.tsx | 7 ++- .../resources/app/fields/FieldNode.tsx | 7 ++- .../resources/app/fields/GatewayFieldNode.tsx | 7 ++- .../resources/app/fields/GroupNode.tsx | 47 +++++++++++-------- .../resources/app/fields/SectionNode.tsx | 11 ++++- .../resources/app/utilities/memoNode.ts | 18 +++++++ src/DonationForms/resources/propTypes.ts | 12 ++--- .../templates/groups/Authentication.tsx | 4 +- .../templates/groups/BillingAddress.tsx | 3 +- .../templates/groups/DonationAmount/index.tsx | 4 +- .../registrars/templates/groups/Name.tsx | 4 +- .../FieldsAPI/Concerns/RemoveNode.php | 2 + .../FieldsAPI/Concerns/RemoveNodeTest.php | 28 ++++++++++- 13 files changed, 115 insertions(+), 39 deletions(-) create mode 100644 src/DonationForms/resources/app/utilities/memoNode.ts diff --git a/src/DonationForms/resources/app/fields/ElementNode.tsx b/src/DonationForms/resources/app/fields/ElementNode.tsx index d3313ea5a3..18beacf5f8 100644 --- a/src/DonationForms/resources/app/fields/ElementNode.tsx +++ b/src/DonationForms/resources/app/fields/ElementNode.tsx @@ -1,11 +1,16 @@ import {Element} from '@givewp/forms/types'; import {useTemplateWrapper} from '../templates'; import type {ElementProps} from '@givewp/forms/propTypes'; +import memoNode from '@givewp/forms/app/utilities/memoNode'; const formTemplates = window.givewp.form.templates; -export default function ElementNode({node}: {node: Element}) { +function ElementNode({node}: {node: Element}) { const Element = useTemplateWrapper(formTemplates.elements[node.type], 'div', node.name); return ; } + +const MemoizedElementNode = memoNode(ElementNode); + +export default MemoizedElementNode; diff --git a/src/DonationForms/resources/app/fields/FieldNode.tsx b/src/DonationForms/resources/app/fields/FieldNode.tsx index 3dccb26950..abd3830d87 100644 --- a/src/DonationForms/resources/app/fields/FieldNode.tsx +++ b/src/DonationForms/resources/app/fields/FieldNode.tsx @@ -2,10 +2,11 @@ import {Field} from '@givewp/forms/types'; import {useTemplateWrapper} from '../templates'; import registerFieldAndBuildProps from '../utilities/registerFieldAndBuildProps'; import type {FieldProps} from '@givewp/forms/propTypes'; +import memoNode from '@givewp/forms/app/utilities/memoNode'; const formTemplates = window.givewp.form.templates; -export default function FieldNode({node}: {node: Field}) { +function FieldNode({node}: {node: Field}) { const {register} = window.givewp.form.hooks.useFormContext(); const {errors} = window.givewp.form.hooks.useFormState(); const Field = @@ -16,3 +17,7 @@ export default function FieldNode({node}: {node: Field}) { return ; } + +const MemoizedFieldNode = memoNode(FieldNode); + +export default MemoizedFieldNode; diff --git a/src/DonationForms/resources/app/fields/GatewayFieldNode.tsx b/src/DonationForms/resources/app/fields/GatewayFieldNode.tsx index 3b5cb6b064..f21e652a30 100644 --- a/src/DonationForms/resources/app/fields/GatewayFieldNode.tsx +++ b/src/DonationForms/resources/app/fields/GatewayFieldNode.tsx @@ -2,11 +2,12 @@ import {Field} from '@givewp/forms/types'; import registerFieldAndBuildProps from '../utilities/registerFieldAndBuildProps'; import {useDonationFormState} from '@givewp/forms/app/store'; import {withTemplateWrapper} from '@givewp/forms/app/templates'; +import memoNode from '@givewp/forms/app/utilities/memoNode'; const formTemplates = window.givewp.form.templates; const GatewayFieldTemplate = withTemplateWrapper(formTemplates.fields.gateways); -export default function GatewayFieldNode({node}: {node: Field}) { +function GatewayFieldNode({node}: {node: Field}) { const {register} = window.givewp.form.hooks.useFormContext(); const {errors} = window.givewp.form.hooks.useFormState(); const fieldProps = registerFieldAndBuildProps(node, register, errors); @@ -15,3 +16,7 @@ export default function GatewayFieldNode({node}: {node: Field}) { // @ts-ignore return ; } + +const MemoizedGatewayFieldNode = memoNode(GatewayFieldNode); + +export default MemoizedGatewayFieldNode; diff --git a/src/DonationForms/resources/app/fields/GroupNode.tsx b/src/DonationForms/resources/app/fields/GroupNode.tsx index fe3633bdf3..15b6ef43da 100644 --- a/src/DonationForms/resources/app/fields/GroupNode.tsx +++ b/src/DonationForms/resources/app/fields/GroupNode.tsx @@ -1,32 +1,39 @@ -import {Field, Group, isField} from '@givewp/forms/types'; +import {Node, Group, isField, isGroup} from '@givewp/forms/types'; import {useTemplateWrapper} from '../templates'; import type {GroupProps} from '@givewp/forms/propTypes'; -import FieldNode from '@givewp/forms/app/fields/FieldNode'; +import {memo, useEffect} from '@wordpress/element'; +import SectionNode from './SectionNode'; +import useVisibilityCondition from '@givewp/forms/app/hooks/useVisibilityCondition'; +import memoNode from '@givewp/forms/app/utilities/memoNode'; const formTemplates = window.givewp.form.templates; -export default function GroupNode({node}: {node: Group}) { +/** + * Renders a group node and its children. At this point, group nodes are not generic, and are only used for specific + * subtypes of group fields, such as the Name field. The nodes are grouped by component and props, and then passed to + * the group template component. This way the group template controls how the nodes are rendered, and can choose to + * manipulate or override props. + * + * @since 3.0.0 + */ +function GroupNode({node}: { node: Group }) { const Group = useTemplateWrapper(formTemplates.groups[node.type], 'div', node.name); - const fields = node.reduceNodes( - (fields, field: Field) => { - fields[field.name] = (props: Field) => ; + const nodeComponents = node.reduceNodes((nodes, node: Node) => { + nodes[node.name] = (props: Node) => ; - return fields; - }, - {}, - isField - ); + return nodes; + }, {}); - const fieldProps = node.reduceNodes( - (fields, field: Field) => { - fields[field.name] = field; + const nodeProps = node.reduceNodes((nodes, node: Node) => { + nodes[node.name] = node; - return fields; - }, - {}, - isField - ); + return nodes; + }, {}); - return ; + return ; } + +const MemoizedGroupNode = memoNode(GroupNode); + +export default MemoizedGroupNode; diff --git a/src/DonationForms/resources/app/fields/SectionNode.tsx b/src/DonationForms/resources/app/fields/SectionNode.tsx index 5edb346961..53a62d85b7 100644 --- a/src/DonationForms/resources/app/fields/SectionNode.tsx +++ b/src/DonationForms/resources/app/fields/SectionNode.tsx @@ -6,15 +6,18 @@ import GatewayFieldNode from '@givewp/forms/app/fields/GatewayFieldNode'; import {elementTemplateExists, fieldTemplateExists, groupTemplateExists} from '@givewp/forms/app/templates'; import useVisibilityCondition from '@givewp/forms/app/hooks/useVisibilityCondition'; import {useEffect} from '@wordpress/element'; +import memoNode from '@givewp/forms/app/utilities/memoNode'; const formTemplates = window.givewp.form.templates; /** - * Determine which node template to render + * Determine which node template to render and apply visibility conditions. It is important the visibility conditions + * occur here, instead of in the more specific components, as it prevents the subsequent hooks from firing, which can + * cause an infinite re-render loop. * * @since 3.0.0 */ -export default function SectionNode({node}: {node: Node}) { +function SectionNode({node}: {node: Node}) { const showNode = useVisibilityCondition(node.visibilityConditions); const {unregister} = window.givewp.form.hooks.useFormContext(); @@ -53,3 +56,7 @@ export default function SectionNode({node}: {node: Node}) { return null; } } + +const MemoizedSectionNode = memoNode(SectionNode); + +export default MemoizedSectionNode; diff --git a/src/DonationForms/resources/app/utilities/memoNode.ts b/src/DonationForms/resources/app/utilities/memoNode.ts new file mode 100644 index 0000000000..b277a2bc6c --- /dev/null +++ b/src/DonationForms/resources/app/utilities/memoNode.ts @@ -0,0 +1,18 @@ +import {memo} from '@wordpress/element'; +import {Node} from '@givewp/forms/types'; + +/** + * This is used for memoizing Node components. Node props come from the server and are never intended to change. The + * state of a Node may change, triggering a re-render, but the props should never change. + * + * @unreleased + */ +export default function memoNode(NodeComponent) { + return memo(NodeComponent, compareNodeProps); +} + +type NodeProp = { node: Node }; + +function compareNodeProps(oldNode: NodeProp, newNode: NodeProp) { + return oldNode.node.name === newNode.node.name; +} diff --git a/src/DonationForms/resources/propTypes.ts b/src/DonationForms/resources/propTypes.ts index f2ca249e01..0793bc3cd0 100644 --- a/src/DonationForms/resources/propTypes.ts +++ b/src/DonationForms/resources/propTypes.ts @@ -52,11 +52,11 @@ export interface PhoneProps extends Omit; }; - fieldProps: { + nodeProps: { [key: string]: FieldProps; }; } @@ -66,7 +66,7 @@ export interface HtmlProps extends ElementProps { } export interface NameProps extends GroupProps { - fields: { + nodeComponents: { honorific?: FC; firstName: FC; lastName: FC; @@ -75,7 +75,7 @@ export interface NameProps extends GroupProps { export interface BillingAddressProps extends GroupProps { groupLabel: string; - fields: { + nodeComponents: { country: FC | {}>; address1: FC; address2: FC; @@ -87,7 +87,7 @@ export interface BillingAddressProps extends GroupProps { } export interface DonationAmountProps extends GroupProps { - fields: { + nodeComponents: { amount: FC | {}>; donationType: FC; currency: FC; @@ -95,7 +95,7 @@ export interface DonationAmountProps extends GroupProps { subscriptionPeriod: FC; subscriptionInstallments: FC; }; - fieldProps: { + nodeProps: { amount: AmountProps; donationType: FieldProps; currency: FieldProps; diff --git a/src/DonationForms/resources/registrars/templates/groups/Authentication.tsx b/src/DonationForms/resources/registrars/templates/groups/Authentication.tsx index 2cd12a49d6..520cdcd0b4 100644 --- a/src/DonationForms/resources/registrars/templates/groups/Authentication.tsx +++ b/src/DonationForms/resources/registrars/templates/groups/Authentication.tsx @@ -49,7 +49,7 @@ const handleLoginPageRedirected = () => { handleLoginPageRedirected(); interface AuthProps extends GroupProps { - fields: { + nodeComponents: { login: FC; password: FC; }; @@ -63,7 +63,7 @@ interface AuthProps extends GroupProps { } export default function Authentication({ - fields: {login: Login, password: Password}, + nodeComponents: {login: Login, password: Password}, required, isAuthenticated, loginRedirect, diff --git a/src/DonationForms/resources/registrars/templates/groups/BillingAddress.tsx b/src/DonationForms/resources/registrars/templates/groups/BillingAddress.tsx index fdb35349fb..ffe6737bb8 100644 --- a/src/DonationForms/resources/registrars/templates/groups/BillingAddress.tsx +++ b/src/DonationForms/resources/registrars/templates/groups/BillingAddress.tsx @@ -3,7 +3,6 @@ import {FC, useEffect, useState} from 'react'; import {__} from '@wordpress/i18n'; import {ErrorMessage} from '@hookform/error-message'; import {useCallback} from '@wordpress/element'; -import Label from '@givewp/form-builder/blocks/fields/settings/Label'; /** * @since 3.0.0 @@ -203,7 +202,7 @@ function StateFieldContainer({ */ export default function BillingAddress({ groupLabel, - fields: {country: Country, address1: Address1, address2: Address2, city: City, state, zip: Zip}, + nodeComponents: {country: Country, address1: Address1, address2: Address2, city: City, state, zip: Zip}, apiUrl, }: BillingAddressProps) { // these are necessary to set the required indicator on the city and zip field labels diff --git a/src/DonationForms/resources/registrars/templates/groups/DonationAmount/index.tsx b/src/DonationForms/resources/registrars/templates/groups/DonationAmount/index.tsx index b18f2ed0f8..fc5cb5d0e0 100644 --- a/src/DonationForms/resources/registrars/templates/groups/DonationAmount/index.tsx +++ b/src/DonationForms/resources/registrars/templates/groups/DonationAmount/index.tsx @@ -7,7 +7,7 @@ import DonationAmountCurrencySwitcherMessage from './DonationAmountCurrencySwitc * @since 3.0.0 */ export default function DonationAmount({ - fields: { + nodeComponents: { amount: AmountField, donationType: DonationTypeField, currency: CurrencyField, @@ -15,7 +15,7 @@ export default function DonationAmount({ subscriptionInstallments: SubscriptionInstallmentsField, subscriptionFrequency: SubscriptionFrequencyField, }, - fieldProps: {amount: amountProps}, + nodeProps: {amount: amountProps}, subscriptionsEnabled, subscriptionDetailsAreFixed, }: DonationAmountProps) { diff --git a/src/DonationForms/resources/registrars/templates/groups/Name.tsx b/src/DonationForms/resources/registrars/templates/groups/Name.tsx index 2cb0ce0cb1..0417c43b6b 100644 --- a/src/DonationForms/resources/registrars/templates/groups/Name.tsx +++ b/src/DonationForms/resources/registrars/templates/groups/Name.tsx @@ -1,6 +1,8 @@ import type {NameProps} from '@givewp/forms/propTypes'; -export default function Name({fields: {honorific: Honorific, firstName: FirstName, lastName: LastName}}: NameProps) { +export default function Name({ + nodeComponents: {honorific: Honorific, firstName: FirstName, lastName: LastName}, +}: NameProps) { return ( <> {Honorific && } diff --git a/src/Framework/FieldsAPI/Concerns/RemoveNode.php b/src/Framework/FieldsAPI/Concerns/RemoveNode.php index f357259e75..30dc9390de 100644 --- a/src/Framework/FieldsAPI/Concerns/RemoveNode.php +++ b/src/Framework/FieldsAPI/Concerns/RemoveNode.php @@ -7,6 +7,7 @@ trait RemoveNode { /** + * @since 3.0.0 preserve array numeric keys * @since 2.10.2 * * @return static @@ -16,6 +17,7 @@ public function remove(string $name) foreach ($this->nodes as $index => $node) { if ($node->getName() === $name) { unset($this->nodes[$index]); + $this->nodes = array_values($this->nodes); return $this; } diff --git a/tests/Unit/Framework/FieldsAPI/Concerns/RemoveNodeTest.php b/tests/Unit/Framework/FieldsAPI/Concerns/RemoveNodeTest.php index 1ed2765731..d36eceb9fc 100644 --- a/tests/Unit/Framework/FieldsAPI/Concerns/RemoveNodeTest.php +++ b/tests/Unit/Framework/FieldsAPI/Concerns/RemoveNodeTest.php @@ -8,7 +8,9 @@ final class RemoveNodeTest extends TestCase { - + /** + * @since 2.22.0 + */ public function testRemoveNode() { $form = (new Form('form')) @@ -24,4 +26,28 @@ public function testRemoveNode() $this->assertEquals(1, $form->getNodeByName('form-section')->count()); } + + /** + * @since 3.0.0 + */ + public function testRemoveNodeKeepsArrayNumeric() + { + $form = (new Form('form')) + ->append( + Section::make('form-section') + ->append( + Text::make('firstTextField'), + Text::make('secondTextField') + ) + ); + + $form->remove('firstTextField'); + + /** @var Section $section */ + $section = $form->getNodeByName('form-section'); + $nodes = $section->all(); + + $this->assertCount(1, $nodes); + $this->assertEquals(array_values($nodes), $nodes); + } } From 9ab4fcda8e2ce088f9bb4562eaab0af1f35cd9ed Mon Sep 17 00:00:00 2001 From: Paulo Iankoski Date: Fri, 18 Aug 2023 16:29:48 -0300 Subject: [PATCH 06/13] Feature: Add new field types to the Fields API (#6866) * feature: add HasDescription concern to fields api * feature: add hasDescription concern to url field in fields api * feature: add hasDescription php trait * feature: add hasDescription to date field * feature: add hasDescription to email field * feature: add hasDescription to file field * feature: add hasDescription to phone field * feature: add hasDescription to radio field * feature: add hasDescription to select field * feature: add format property to Date and Phone fields * feature: add MultiSelect field * doc: add unreleased tags * feature: reenforce which options are accepted for fieldType * feature: add default value to dateFormat string --------- Co-authored-by: Joshua Dinh --- src/Framework/FieldsAPI/Date.php | 26 ++++++++++++++ src/Framework/FieldsAPI/MultiSelect.php | 45 +++++++++++++++++++++++++ src/Framework/FieldsAPI/Phone.php | 26 ++++++++++++++ 3 files changed, 97 insertions(+) create mode 100644 src/Framework/FieldsAPI/MultiSelect.php diff --git a/src/Framework/FieldsAPI/Date.php b/src/Framework/FieldsAPI/Date.php index c4856a1ae3..e49d7f4c1b 100644 --- a/src/Framework/FieldsAPI/Date.php +++ b/src/Framework/FieldsAPI/Date.php @@ -3,6 +3,7 @@ namespace Give\Framework\FieldsAPI; /** + * @unlreased add date format attribute * @since 2.32.0 added description * @since 2.12.0 */ @@ -15,4 +16,29 @@ class Date extends Field use Concerns\HasDescription; const TYPE = 'date'; + + /** @var string */ + protected $dateFormat = 'yyyy/mm/dd'; + + /** + * Set the date format for the element. + * + * @unreleased + */ + public function dateFormat(string $dateFormat): self + { + $this->dateFormat = $dateFormat; + + return $this; + } + + /** + * Get the date format for the element. + * + * @unreleased + */ + public function getDateFormat(): string + { + return $this->dateFormat; + } } diff --git a/src/Framework/FieldsAPI/MultiSelect.php b/src/Framework/FieldsAPI/MultiSelect.php new file mode 100644 index 0000000000..3e6b47030a --- /dev/null +++ b/src/Framework/FieldsAPI/MultiSelect.php @@ -0,0 +1,45 @@ +fieldType; + } + + /** + * @unreleased + */ + public function fieldType(string $fieldType): MultiSelect + { + if (!in_array($fieldType, ['checkbox', 'dropdown'])) { + throw new InvalidArgumentException(__('Field type must be either "checkbox" or "dropdown".', 'give')); + } + + $this->fieldType = $fieldType; + + return $this; + } +} diff --git a/src/Framework/FieldsAPI/Phone.php b/src/Framework/FieldsAPI/Phone.php index f95fe940c2..2902115d5b 100644 --- a/src/Framework/FieldsAPI/Phone.php +++ b/src/Framework/FieldsAPI/Phone.php @@ -3,6 +3,7 @@ namespace Give\Framework\FieldsAPI; /** + * @unlreased add phone format attribute * @since 2.32.0 added description * @since 2.12.0 * @since 2.14.0 add min/max length validation @@ -18,4 +19,29 @@ class Phone extends Field use Concerns\HasDescription; const TYPE = 'phone'; + + /** @var string */ + protected $phoneFormat = ''; + + /** + * Set the phone format for the element. + * + * @unreleased + */ + public function phoneFormat(string $phoneFormat): self + { + $this->phoneFormat = $phoneFormat; + + return $this; + } + + /** + * Get the phone format for the element. + * + * @unreleased + */ + public function getPhoneFormat(): string + { + return $this->phoneFormat; + } } From 086a3d22d3c4d38bb4cd370224c22221f5f0f8db Mon Sep 17 00:00:00 2001 From: Jon Waldstein Date: Fri, 18 Aug 2023 15:30:23 -0400 Subject: [PATCH 07/13] Refactor: merge PayPal Standard gateways to support v3 (#6889) --- .../PayPalStandardGateway.php | 134 ------------------ .../PayPalStandard/PayPalStandard.php | 124 +++++++++------- .../resources/js}/PayPalLogo.tsx | 0 .../resources/js}/logo.svg | 0 .../resources/js}/payPalStandardGateway.tsx | 0 .../Gateways/ServiceProvider.php | 5 - wordpress-scripts-webpack.config.js | 2 +- 7 files changed, 74 insertions(+), 191 deletions(-) delete mode 100644 src/PaymentGateways/Gateways/PayPal/PayPalStandardGateway/PayPalStandardGateway.php rename src/PaymentGateways/Gateways/{PayPal/PayPalStandardGateway => PayPalStandard/resources/js}/PayPalLogo.tsx (100%) rename src/PaymentGateways/Gateways/{PayPal/PayPalStandardGateway => PayPalStandard/resources/js}/logo.svg (100%) rename src/PaymentGateways/Gateways/{PayPal/PayPalStandardGateway => PayPalStandard/resources/js}/payPalStandardGateway.tsx (100%) diff --git a/src/PaymentGateways/Gateways/PayPal/PayPalStandardGateway/PayPalStandardGateway.php b/src/PaymentGateways/Gateways/PayPal/PayPalStandardGateway/PayPalStandardGateway.php deleted file mode 100644 index 3db5fdbdf9..0000000000 --- a/src/PaymentGateways/Gateways/PayPal/PayPalStandardGateway/PayPalStandardGateway.php +++ /dev/null @@ -1,134 +0,0 @@ -getScriptAsset(GIVE_PLUGIN_DIR . 'build/payPalStandardGateway.asset.php'); - - wp_enqueue_script( - self::id(), - GIVE_PLUGIN_URL . 'build/payPalStandardGateway.js', - $assets['dependencies'], - $assets['version'], - true - ); - } - - /** - * @inheritdoc - */ - public function formSettings(int $formId): array - { - return [ - 'fields' => [ - 'heading' => __('Make your donation quickly and securely with PayPal', 'give'), - 'subheading' => __('How it works', 'give'), - 'body' => __( - 'You will be redirected to PayPal to complete your donation with your debit card, credit card, or with your PayPal account. Once complete, you will be redirected back to this site to view your receipt.', - 'give' - ), - ] - ]; - } - - /** - * @inheritDoc - */ - public function getName(): string - { - return __('PayPal Standard', 'give'); - } - - /** - * @inheritDoc - * @param array{successUrl: string, cancelUrl: string} $gatewayData - */ - public function createPayment(Donation $donation, $gatewayData = []): RedirectOffsite - { - /** - * Add additional query args to PayPal redirect URLs. - * This does not affect the core PayPal Standard gateway functionality. - * Later in our routeMethods, there are conditionals to check for these query args - * and proceed accordingly if they exist or not making this gateway backwards compatible with legacy forms. - */ - add_filter( - 'give_gateway_paypal_redirect_args', - static function ($paypalPaymentArguments) use ($gatewayData) { - $paypalPaymentArguments['return'] = add_query_arg( - ['givewp-return-url' => $gatewayData['successUrl']], - $paypalPaymentArguments['return'] - ); - - $paypalPaymentArguments['cancel_return'] = add_query_arg( - ['givewp-return-url' => $gatewayData['cancelUrl']], - $paypalPaymentArguments['cancel_return'] - ); - - return $paypalPaymentArguments; - } - ); - - return parent::createPayment($donation, $gatewayData); - } - - /** - * @inheritDoc - */ - protected function handleSuccessPaymentReturn(array $queryParams): RedirectResponse - { - if (!empty($queryParams['givewp-return-url'])) { - return new RedirectResponse(esc_url_raw($queryParams['givewp-return-url'])); - } - - return parent::handleSuccessPaymentReturn($queryParams); - } - - /** - * This method is called when the user cancels the payment on PayPal. - * - * It should really be called handleCancelledPaymentReturn. - * - * @inheritDoc - */ - protected function handleFailedPaymentReturn(array $queryParams): RedirectResponse - { - if (!empty($queryParams['givewp-return-url'])) { - $donationId = (int)$queryParams['donation-id']; - - /** @var Donation $donation */ - $donation = Donation::find($donationId); - $donation->status = DonationStatus::CANCELLED(); - $donation->save(); - - return new RedirectResponse(esc_url_raw($queryParams['givewp-return-url'])); - } - - return parent::handleFailedPaymentReturn($queryParams); - } -} \ No newline at end of file diff --git a/src/PaymentGateways/Gateways/PayPalStandard/PayPalStandard.php b/src/PaymentGateways/Gateways/PayPalStandard/PayPalStandard.php index 306fd95775..2c2f6217fd 100644 --- a/src/PaymentGateways/Gateways/PayPalStandard/PayPalStandard.php +++ b/src/PaymentGateways/Gateways/PayPalStandard/PayPalStandard.php @@ -3,42 +3,45 @@ namespace Give\PaymentGateways\Gateways\PayPalStandard; use Give\Donations\Models\Donation; +use Give\Donations\ValueObjects\DonationStatus; use Give\Framework\Exceptions\Primitives\Exception; use Give\Framework\Http\Response\Types\RedirectResponse; use Give\Framework\PaymentGateways\Commands\RedirectOffsite; use Give\Framework\PaymentGateways\PaymentGateway; -use Give\Helpers\Call; +use Give\Framework\PaymentGateways\Traits\HandleHttpResponses; +use Give\Framework\Support\Scripts\Concerns\HasScriptAssetFile; use Give\PaymentGateways\Gateways\PayPalStandard\Actions\CreatePayPalStandardPaymentURL; -use Give\PaymentGateways\Gateways\PayPalStandard\Actions\GenerateDonationFailedPageUrl; -use Give\PaymentGateways\Gateways\PayPalStandard\Actions\GenerateDonationReceiptPageUrl; use Give\PaymentGateways\Gateways\PayPalStandard\Controllers\PayPalStandardWebhook; use Give\PaymentGateways\Gateways\PayPalStandard\Views\PayPalStandardBillingFields; -use Give_Payment; /** + * @since 3.0.0 added support for Give 3.0 forms * @since 2.19.0 */ class PayPalStandard extends PaymentGateway { + use HandleHttpResponses; + use HasScriptAssetFile; + public $routeMethods = [ 'handleIpnNotification', ]; public $secureRouteMethods = [ 'handleSuccessPaymentReturn', - 'handleFailedPaymentReturn', + 'handleCancelledPaymentReturn', ]; /** - * @inheritDoc + * @since 2.19.0 */ public function getLegacyFormFieldMarkup(int $formId, array $args): string { - return Call::invoke(PayPalStandardBillingFields::class, $formId); + return (new PayPalStandardBillingFields())($formId); } /** - * @inheritDoc + * @since 2.19.0 */ public static function id(): string { @@ -46,7 +49,7 @@ public static function id(): string } /** - * @inerhitDoc + * @since 2.19.0 */ public function getId(): string { @@ -54,15 +57,15 @@ public function getId(): string } /** - * @inheritDoc + * @since 2.19.0 */ public function getName(): string { - return esc_html__('PayPal Standard', 'give'); + return __('PayPal Standard', 'give'); } /** - * @inheritDoc + * @since 2.19.0 */ public function getPaymentMethodLabel(): string { @@ -70,23 +73,62 @@ public function getPaymentMethodLabel(): string } /** - * @inheritDoc + * @since 3.0.0 + */ + public function formSettings(int $formId): array + { + return [ + 'fields' => [ + 'heading' => __('Make your donation quickly and securely with PayPal', 'give'), + 'subheading' => __('How it works', 'give'), + 'body' => __( + 'You will be redirected to PayPal to complete your donation with your debit card, credit card, or with your PayPal account. Once complete, you will be redirected back to this site to view your receipt.', + 'give' + ), + ] + ]; + } + + /** + * @since 3.0.0 + */ + public function enqueueScript(int $formId) + { + $assets = $this->getScriptAsset(GIVE_PLUGIN_DIR . 'build/payPalStandardGateway.asset.php'); + + wp_enqueue_script( + self::id(), + GIVE_PLUGIN_URL . 'build/payPalStandardGateway.js', + $assets['dependencies'], + $assets['version'], + true + ); + } + + /** + * @since 3.0.0 update to add `givewp-return-url` to the query params + * @since 2.19.0 */ public function createPayment(Donation $donation, $gatewayData = []): RedirectOffsite { return new RedirectOffsite( - Call::invoke( - CreatePayPalStandardPaymentURL::class, + (new CreatePayPalStandardPaymentURL())( $donation, $this->generateSecureGatewayRouteUrl( 'handleSuccessPaymentReturn', $donation->id, - ['donation-id' => $donation->id] + [ + 'donation-id' => $donation->id, + 'givewp-return-url' => $gatewayData['successUrl'] + ] ), $this->generateSecureGatewayRouteUrl( - 'handleFailedPaymentReturn', + 'handleCancelledPaymentReturn', $donation->id, - ['donation-id' => $donation->id] + [ + 'donation-id' => $donation->id, + 'givewp-return-url' => $gatewayData['cancelUrl'] + ] ), $this->generateGatewayRouteUrl( 'handleIpnNotification' @@ -98,49 +140,31 @@ public function createPayment(Donation $donation, $gatewayData = []): RedirectOf /** * Handle payment redirect after successful payment on PayPal standard. * + * @since 3.0.0 update to use the $gatewayParams return url * @since 2.19.0 * @since 2.19.4 Only pending PayPal Standard donation set to processing. - * @since 2.19.6 1. Do not set donation to "processing" - * 2. Add "payment-confirmation" param to receipt page url - * - * @param array $queryParams Query params in gateway route. { - * - * @type string "donation-id" Donation id. - * - * } + * @since 2.19.6 1. Do not set donation to "processing" 2. Add "payment-confirmation" param to receipt page url */ protected function handleSuccessPaymentReturn(array $queryParams): RedirectResponse { - $donationId = (int)$queryParams['donation-id']; - - return new RedirectResponse( - esc_url_raw( - add_query_arg( - ['payment-confirmation' => self::id()], - Call::invoke(GenerateDonationReceiptPageUrl::class, $donationId) - ) - ) - ); + return new RedirectResponse(esc_url_raw($queryParams['givewp-return-url'])); } /** - * Handle payment redirect after failed payment on PayPal standard. - * - * @since 2.19.0 + * This method is called when the user cancels the payment on PayPal. * - * @param array $queryParams Query params in gateway route. { - * - * @type string "donation-id" Donation id. - * - * } + * @since 3.0.0 */ - protected function handleFailedPaymentReturn(array $queryParams): RedirectResponse + protected function handleCancelledPaymentReturn(array $queryParams): RedirectResponse { $donationId = (int)$queryParams['donation-id']; - $payment = new Give_Payment($donationId); - $payment->update_status('failed'); - return new RedirectResponse(Call::invoke(GenerateDonationFailedPageUrl::class, $donationId)); + /** @var Donation $donation */ + $donation = Donation::find($donationId); + $donation->status = DonationStatus::CANCELLED(); + $donation->save(); + + return new RedirectResponse(esc_url_raw($queryParams['givewp-return-url'])); } /** @@ -157,10 +181,8 @@ public function handleIpnNotification() * This function returns payment gateway settings. * * @since 2.19.0 - * - * @return array */ - public function getOptions() + public function getOptions(): array { $setting = [ // Section 2: PayPal Standard. diff --git a/src/PaymentGateways/Gateways/PayPal/PayPalStandardGateway/PayPalLogo.tsx b/src/PaymentGateways/Gateways/PayPalStandard/resources/js/PayPalLogo.tsx similarity index 100% rename from src/PaymentGateways/Gateways/PayPal/PayPalStandardGateway/PayPalLogo.tsx rename to src/PaymentGateways/Gateways/PayPalStandard/resources/js/PayPalLogo.tsx diff --git a/src/PaymentGateways/Gateways/PayPal/PayPalStandardGateway/logo.svg b/src/PaymentGateways/Gateways/PayPalStandard/resources/js/logo.svg similarity index 100% rename from src/PaymentGateways/Gateways/PayPal/PayPalStandardGateway/logo.svg rename to src/PaymentGateways/Gateways/PayPalStandard/resources/js/logo.svg diff --git a/src/PaymentGateways/Gateways/PayPal/PayPalStandardGateway/payPalStandardGateway.tsx b/src/PaymentGateways/Gateways/PayPalStandard/resources/js/payPalStandardGateway.tsx similarity index 100% rename from src/PaymentGateways/Gateways/PayPal/PayPalStandardGateway/payPalStandardGateway.tsx rename to src/PaymentGateways/Gateways/PayPalStandard/resources/js/payPalStandardGateway.tsx diff --git a/src/PaymentGateways/Gateways/ServiceProvider.php b/src/PaymentGateways/Gateways/ServiceProvider.php index cd3c90da68..3f7aacdd2f 100644 --- a/src/PaymentGateways/Gateways/ServiceProvider.php +++ b/src/PaymentGateways/Gateways/ServiceProvider.php @@ -8,10 +8,8 @@ use Give\Framework\Support\Scripts\Concerns\HasScriptAssetFile; use Give\Helpers\Hooks; use Give\Log\Log; -use Give\PaymentGateways\Gateways\PayPal\PayPalStandardGateway\PayPalStandardGateway; use Give\PaymentGateways\Gateways\PayPalCommerce\PayPalCommerceGateway; use Give\PaymentGateways\Gateways\PayPalCommerce\PayPalCommerceSubscriptionModule; -use Give\PaymentGateways\Gateways\PayPalStandard\PayPalStandard; use Give\PaymentGateways\Gateways\Stripe\LegacyStripeAdapter; use Give\PaymentGateways\Gateways\Stripe\StripePaymentElementGateway\StripePaymentElementGateway; use Give\PaymentGateways\Gateways\Stripe\StripePaymentElementGateway\Webhooks\Listeners\ChargeRefunded; @@ -74,9 +72,6 @@ private function registerGateways() } $registrar->registerGateway(StripePaymentElementGateway::class); - - $registrar->unregisterGateway(PayPalStandard::id()); - $registrar->registerGateway(PayPalStandardGateway::class); $registrar->unregisterGateway(PayPalCommerce::id()); $registrar->registerGateway(PayPalCommerceGateway::class); diff --git a/wordpress-scripts-webpack.config.js b/wordpress-scripts-webpack.config.js index 866c43524b..62c52fed50 100644 --- a/wordpress-scripts-webpack.config.js +++ b/wordpress-scripts-webpack.config.js @@ -35,7 +35,7 @@ module.exports = { ), testGateway: srcPath('PaymentGateways/Gateways/TestGateway/testGateway.tsx'), payPalStandardGateway: srcPath( - 'PaymentGateways/Gateways/PayPal/PayPalStandardGateway/payPalStandardGateway.tsx' + 'PaymentGateways/Gateways/PayPalStandard/resources/js/payPalStandardGateway.tsx' ), payPalCommerceGateway: srcPath('PaymentGateways/Gateways/PayPalCommerce/payPalCommerceGateway.tsx'), classicFormDesignCss: srcPath('DonationForms/FormDesigns/ClassicFormDesign/css/main.scss'), From d9b3fc9508211ec9f5e223b5bb51de27e5b1c1cd Mon Sep 17 00:00:00 2001 From: Joshua Dinh <75056371+JoshuaHungDinh@users.noreply.github.com> Date: Fri, 18 Aug 2023 13:00:56 -0700 Subject: [PATCH 08/13] fix: add transparent background to base-overrides (#6888) --- .../resources/styles/_base-overrides.scss | 51 ++++++++++--------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/src/DonationForms/resources/styles/_base-overrides.scss b/src/DonationForms/resources/styles/_base-overrides.scss index 4b0deb1e6e..f5f11e6037 100644 --- a/src/DonationForms/resources/styles/_base-overrides.scss +++ b/src/DonationForms/resources/styles/_base-overrides.scss @@ -3,43 +3,44 @@ :root, [data-theme=light], [data-theme=dark] { - // pico variables - --font-size: 16px; - --typography-spacing-vertical: 1rem; - - // map pico variables to givewp variables - --primary: var(--givewp-primary-color); - --primary-hover: var(--givewp-primary-color); - --primary-focus: var(--givewp-primary-color); - - --secondary: var(--givewp-secondary-color); - --secondary-hover: var(--givewp-secondary-color); - --secondary-focus: var(--givewp-secondary-color); - - // custom givewp variables - --givewp-breakpoint-xs: variables.$givewp-breakpoint-xs; - --givewp-breakpoint-sm: variables.$givewp-breakpoint-sm; - --givewp-breakpoint-md: variables.$givewp-breakpoint-md; - --givewp-breakpoint-lg: variables.$givewp-breakpoint-lg; - --givewp-breakpoint-xl: variables.$givewp-breakpoint-xl; + // pico variables + --font-size: 16px; + --typography-spacing-vertical: 1rem; + --background-color: transparent; + + // map pico variables to givewp variables + --primary: var(--givewp-primary-color); + --primary-hover: var(--givewp-primary-color); + --primary-focus: var(--givewp-primary-color); + + --secondary: var(--givewp-secondary-color); + --secondary-hover: var(--givewp-secondary-color); + --secondary-focus: var(--givewp-secondary-color); + + // custom givewp variables + --givewp-breakpoint-xs: variables.$givewp-breakpoint-xs; + --givewp-breakpoint-sm: variables.$givewp-breakpoint-sm; + --givewp-breakpoint-md: variables.$givewp-breakpoint-md; + --givewp-breakpoint-lg: variables.$givewp-breakpoint-lg; + --givewp-breakpoint-xl: variables.$givewp-breakpoint-xl; } // remove the green checkbox in inputs input[aria-invalid="false"], textarea[aria-invalid="false"] { - &:not([type="checkbox"]) { - background-image: none; - } + &:not([type="checkbox"]) { + background-image: none; + } } input, select, textarea { - margin-bottom: 0; + margin-bottom: 0; } h1, h2, h3, h4, h5, h6 { - --typography-spacing-vertical: 1rem; + --typography-spacing-vertical: 1rem; } pre { - white-space: break-spaces; + white-space: break-spaces; } From fba329c23236f61b905b0bc6833c4732fb907a86 Mon Sep 17 00:00:00 2001 From: Glauber Silva Date: Fri, 18 Aug 2023 17:10:14 -0300 Subject: [PATCH 09/13] Fix: load translations correctly (#6879) * fix: load translations correctly * chore: remove comment * fix: set TestGateway scripts to translations * fix: set translations to missing scripts * fix: add missing sting * format: remove space --- give.php | 14 +---- .../DonationConfirmationReceiptViewModel.php | 10 +++- .../ViewModels/DonationFormViewModel.php | 12 +++- .../registrars/templates/fields/Gateways.tsx | 4 +- src/Helpers/Language.php | 55 +++++++++++++++++++ .../Gateways/TestGateway/TestGateway.php | 5 +- 6 files changed, 81 insertions(+), 19 deletions(-) create mode 100644 src/Helpers/Language.php diff --git a/give.php b/give.php index 5faa31f229..4180202bd8 100644 --- a/give.php +++ b/give.php @@ -68,6 +68,7 @@ use Give\Framework\PaymentGateways\PaymentGatewayRegister; use Give\Framework\ValidationRules\ValidationRulesServiceProvider; use Give\Framework\WordPressShims\ServiceProvider as WordPressShimsServiceProvider; +use Give\Helpers\Language; use Give\LegacySubscriptions\ServiceProvider as LegacySubscriptionsServiceProvider; use Give\License\LicenseServiceProvider; use Give\Log\LogServiceProvider; @@ -361,6 +362,7 @@ private function setup_constants() /** * Loads the plugin language files. * + * @unreleased Use Language class * @since 1.0 * @access public * @@ -368,17 +370,7 @@ private function setup_constants() */ public function load_textdomain() { - // Set filter for Give's languages directory - $give_lang_dir = dirname(plugin_basename(GIVE_PLUGIN_FILE)) . '/languages/'; - $give_lang_dir = apply_filters('give_languages_directory', $give_lang_dir); - - // Traditional WordPress plugin locale filter. - $locale = is_admin() && function_exists('get_user_locale') ? get_user_locale() : get_locale(); - $locale = apply_filters('plugin_locale', $locale, 'give'); - - unload_textdomain('give'); - load_textdomain('give', WP_LANG_DIR . '/give/give-' . $locale . '.mo'); - load_plugin_textdomain('give', false, $give_lang_dir); + Language::load(); } /** diff --git a/src/DonationForms/ViewModels/DonationConfirmationReceiptViewModel.php b/src/DonationForms/ViewModels/DonationConfirmationReceiptViewModel.php index 2da076e3c9..47c915c996 100644 --- a/src/DonationForms/ViewModels/DonationConfirmationReceiptViewModel.php +++ b/src/DonationForms/ViewModels/DonationConfirmationReceiptViewModel.php @@ -10,6 +10,7 @@ use Give\Framework\Receipts\DonationReceipt; use Give\Framework\Receipts\DonationReceiptBuilder; use Give\Framework\Support\Scripts\Concerns\HasScriptAssetFile; +use Give\Helpers\Language; /** * @since 3.0.0 @@ -92,7 +93,7 @@ public function render(): string $donationForm = !$donationFormRepository->isLegacyForm( $this->donation->formId ) ? $this->getDonationForm() : null; - + $formDesignId = $donationForm ? $donationForm->settings->designId : DeveloperFormDesign::id(); $customCss = $donationForm && $donationForm->settings->customCss ? $donationForm->settings->customCss : null; $primaryColor = $donationForm ? $donationForm->settings->primaryColor : '#69B868'; @@ -147,7 +148,7 @@ public function enqueueGlobalStyles(string $primaryColor, string $secondaryColor 'givewp-global-form-styles', ":root { --givewp-primary-color:{$primaryColor}; - --givewp-secondary-color:{$secondaryColor}; + --givewp-secondary-color:{$secondaryColor}; }" ); @@ -168,14 +169,17 @@ public function enqueueGlobalStyles(string $primaryColor, string $secondaryColor */ private function enqueueFormScripts(int $formId, string $formDesignId) { + $handle = 'givewp-donation-form-registrars'; wp_enqueue_script( - 'givewp-donation-form-registrars', + $handle, GIVE_PLUGIN_URL . 'build/donationFormRegistrars.js', $this->getScriptAssetDependencies(GIVE_PLUGIN_DIR . 'build/donationFormRegistrars.asset.php'), GIVE_VERSION, true ); + Language::setScriptTranslations($handle); + wp_add_inline_script( 'givewp-donation-form-registrars', 'window.givewpDonationFormExports = ' . wp_json_encode($this->formExports()) . ';', diff --git a/src/DonationForms/ViewModels/DonationFormViewModel.php b/src/DonationForms/ViewModels/DonationFormViewModel.php index 00b068f7b0..6261424b9d 100644 --- a/src/DonationForms/ViewModels/DonationFormViewModel.php +++ b/src/DonationForms/ViewModels/DonationFormViewModel.php @@ -15,6 +15,7 @@ use Give\Framework\FormDesigns\Registrars\FormDesignRegistrar; use Give\Framework\Support\Scripts\Concerns\HasScriptAssetFile; use Give\Helpers\Hooks; +use Give\Helpers\Language; /** * @since 3.0.0 @@ -270,14 +271,17 @@ private function enqueueRegistrars() GIVE_VERSION ); + $handle = 'givewp-donation-form-registrars'; wp_enqueue_script( - 'givewp-donation-form-registrars', + $handle, GIVE_PLUGIN_URL . 'build/donationFormRegistrars.js', $this->getScriptAssetDependencies(GIVE_PLUGIN_DIR . 'build/donationFormRegistrars.asset.php'), GIVE_VERSION, true ); + Language::setScriptTranslations($handle); + wp_add_inline_script( 'givewp-donation-form-registrars', 'window.givewpDonationFormExports = ' . wp_json_encode($this->exports()) . ';', @@ -304,6 +308,7 @@ private function enqueueGateways(int $formId) } /** + * @unreleased Set script translations * @since 3.0.0 */ private function enqueueDesign(string $formDesignId) @@ -317,8 +322,9 @@ private function enqueueDesign(string $formDesignId) } if ($design->js()) { + $handle = 'givewp-form-design-' . $design::id(); wp_enqueue_script( - 'givewp-form-design-' . $design::id(), + $handle, $design->js(), array_merge( $design->dependencies(), @@ -326,6 +332,8 @@ private function enqueueDesign(string $formDesignId) ), true ); + + Language::setScriptTranslations($handle); } } } diff --git a/src/DonationForms/resources/registrars/templates/fields/Gateways.tsx b/src/DonationForms/resources/registrars/templates/fields/Gateways.tsx index 65beb55a90..ef827f501d 100644 --- a/src/DonationForms/resources/registrars/templates/fields/Gateways.tsx +++ b/src/DonationForms/resources/registrars/templates/fields/Gateways.tsx @@ -1,7 +1,7 @@ import {ErrorMessage} from '@hookform/error-message'; import type {GatewayFieldProps, GatewayOptionProps} from '@givewp/forms/propTypes'; import {ErrorBoundary} from 'react-error-boundary'; -import {__} from '@wordpress/i18n'; +import {__, sprintf} from '@wordpress/i18n'; import {useEffect, useMemo} from 'react'; import {createInterpolateElement} from '@wordpress/element'; @@ -146,7 +146,7 @@ function GatewayOption({gateway, defaultChecked, inputProps}: GatewayOptionProps return (
  • - +
    id"); } From dd1dba6adb9f0d2cd6c8a193368d4534a59dc934 Mon Sep 17 00:00:00 2001 From: Jon Waldstein Date: Fri, 18 Aug 2023 16:13:07 -0400 Subject: [PATCH 10/13] Refactor: update form builder window data with typed getters (#6880) * refactor: update form builder window data type declrations with simple getters * feature: use the declare const window trick --- globals.d.ts | 4 +- .../resources/js/form-builder/globals.d.ts | 3 - .../src/blocks/fields/amount/Edit.tsx | 4 +- .../blocks/fields/amount/inspector/index.tsx | 4 +- .../blocks/fields/payment-gateways/Edit.tsx | 4 +- .../fields/terms-and-conditions/Edit.tsx | 4 +- .../js/form-builder/src/common/currency.tsx | 5 +- .../form-builder/src/common/getWindowData.ts | 79 +++++--- .../form-builder/src/common/registerBlocks.ts | 4 +- .../sidebar/panels/FieldTypesList.tsx | 3 +- .../settings/donation-confirmation/index.tsx | 4 +- .../src/settings/email/logo-upload/index.tsx | 22 +-- .../components/email-preview-content.tsx | 53 +++--- .../components/send-preview-email.tsx | 54 +++--- .../settings/email/template-options/index.tsx | 96 +++++----- .../email/template-options/settings.tsx | 175 ++++++++++-------- .../resources/js/form-builder/tsconfig.json | 24 --- .../resources/js/registrars/index.ts | 16 +- tsconfig.json | 3 + wordpress-scripts-webpack.config.js | 1 + 20 files changed, 284 insertions(+), 278 deletions(-) delete mode 100644 src/FormBuilder/resources/js/form-builder/globals.d.ts delete mode 100644 src/FormBuilder/resources/js/form-builder/tsconfig.json diff --git a/globals.d.ts b/globals.d.ts index e1168d5a84..25867239f9 100644 --- a/globals.d.ts +++ b/globals.d.ts @@ -1,5 +1,5 @@ declare module '*.svg'; declare module '*.module.css'; declare module '*.module.scss'; - -declare module 'window.givewp.form.blocks'; +// this makes the wp or window.wp global variable available in the eyes of TypeScript +declare var wp; diff --git a/src/FormBuilder/resources/js/form-builder/globals.d.ts b/src/FormBuilder/resources/js/form-builder/globals.d.ts deleted file mode 100644 index a72d9124ae..0000000000 --- a/src/FormBuilder/resources/js/form-builder/globals.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -declare module '*.svg'; -declare module '*.module.css'; -declare module '*.module.scss'; \ No newline at end of file diff --git a/src/FormBuilder/resources/js/form-builder/src/blocks/fields/amount/Edit.tsx b/src/FormBuilder/resources/js/form-builder/src/blocks/fields/amount/Edit.tsx index 7c35fbaff6..9031b91cec 100644 --- a/src/FormBuilder/resources/js/form-builder/src/blocks/fields/amount/Edit.tsx +++ b/src/FormBuilder/resources/js/form-builder/src/blocks/fields/amount/Edit.tsx @@ -9,7 +9,7 @@ import {createInterpolateElement} from '@wordpress/element'; import {BaseControl, RadioControl} from '@wordpress/components'; import Notice from './notice'; -import {getFormBuilderData} from '@givewp/form-builder/common/getWindowData'; +import {getFormBuilderWindowData} from '@givewp/form-builder/common/getWindowData'; const Edit = ({attributes, setAttributes}) => { const { @@ -30,7 +30,7 @@ const Edit = ({attributes, setAttributes}) => { recurringOptInDefaultBillingPeriod, } = attributes; - const {gateways} = getFormBuilderData(); + const {gateways} = getFormBuilderWindowData(); const isRecurringSupported = gateways.some((gateway) => gateway.enabled && gateway.supportsSubscriptions); const isRecurring = isRecurringSupported && recurringEnabled; diff --git a/src/FormBuilder/resources/js/form-builder/src/blocks/fields/amount/inspector/index.tsx b/src/FormBuilder/resources/js/form-builder/src/blocks/fields/amount/inspector/index.tsx index 36f983b872..8031c748dd 100644 --- a/src/FormBuilder/resources/js/form-builder/src/blocks/fields/amount/inspector/index.tsx +++ b/src/FormBuilder/resources/js/form-builder/src/blocks/fields/amount/inspector/index.tsx @@ -12,7 +12,7 @@ import {InspectorControls} from '@wordpress/block-editor'; import {CurrencyControl, formatCurrencyAmount} from '@givewp/form-builder/common/currency'; import periodLookup from '../period-lookup'; import RecurringDonationsPromo from '@givewp/form-builder/promos/recurring-donations'; -import {getFormBuilderData} from '@givewp/form-builder/common/getWindowData'; +import {getFormBuilderWindowData} from '@givewp/form-builder/common/getWindowData'; import {useCallback, useState} from '@wordpress/element'; import Options from '@givewp/form-builder/components/OptionsPanel'; import {OptionProps} from '@givewp/form-builder/components/OptionsPanel/types'; @@ -71,7 +71,7 @@ const Inspector = ({attributes, setAttributes}) => { [recurringBillingPeriodOptions] ); - const {gateways, recurringAddonData, gatewaySettingsUrl} = getFormBuilderData(); + const {gateways, recurringAddonData, gatewaySettingsUrl} = getFormBuilderWindowData(); const enabledGateways = gateways.filter((gateway) => gateway.enabled); const recurringGateways = gateways.filter((gateway) => gateway.supportsSubscriptions); const isRecurringSupported = enabledGateways.some((gateway) => gateway.supportsSubscriptions); diff --git a/src/FormBuilder/resources/js/form-builder/src/blocks/fields/payment-gateways/Edit.tsx b/src/FormBuilder/resources/js/form-builder/src/blocks/fields/payment-gateways/Edit.tsx index 74dd314f87..383106e8a4 100644 --- a/src/FormBuilder/resources/js/form-builder/src/blocks/fields/payment-gateways/Edit.tsx +++ b/src/FormBuilder/resources/js/form-builder/src/blocks/fields/payment-gateways/Edit.tsx @@ -1,6 +1,6 @@ import {BlockEditProps} from '@wordpress/blocks'; import {ReactNode} from 'react'; -import {getFormBuilderData} from '@givewp/form-builder/common/getWindowData'; +import {getFormBuilderWindowData} from '@givewp/form-builder/common/getWindowData'; const GatewayItem = ({label, icon}: {label: string; icon: ReactNode}) => { return ( @@ -18,7 +18,7 @@ const GatewayItem = ({label, icon}: {label: string; icon: ReactNode}) => { }; export default function Edit(props: BlockEditProps) { - const {gateways} = getFormBuilderData(); + const {gateways} = getFormBuilderWindowData(); return (
    ) { const [showAgreementTextModal, setShowAgreementTextModal] = useState(false); - const globalSettings = getFormBuilderData().termsAndConditions; + const globalSettings = getFormBuilderWindowData().termsAndConditions; if (useGlobalSettings) { checkboxLabel = globalSettings.checkboxLabel; diff --git a/src/FormBuilder/resources/js/form-builder/src/common/currency.tsx b/src/FormBuilder/resources/js/form-builder/src/common/currency.tsx index 78e9fe3a78..08a6a75d06 100644 --- a/src/FormBuilder/resources/js/form-builder/src/common/currency.tsx +++ b/src/FormBuilder/resources/js/form-builder/src/common/currency.tsx @@ -1,9 +1,10 @@ import CurrencyInput, {CurrencyInputProps, formatValue} from 'react-currency-input-field'; import {BaseControl} from '@wordpress/components'; import {useInstanceId} from '@wordpress/compose'; +import {getFormBuilderWindowData} from '@givewp/form-builder/common/getWindowData'; const formatCurrencyAmount = (amount: string) => { - const {currency = 'USD'} = window?.storageData ?? {}; + const {currency = 'USD'} = getFormBuilderWindowData(); return formatValue({ value: amount, @@ -22,7 +23,7 @@ interface CurrencyControlProps extends CurrencyInputProps { } const CurrencyControl = ({label, help, hideLabelFromVision, ...rest}: CurrencyControlProps) => { - const {currency = 'USD'} = window?.storageData ?? {}; + const {currency = 'USD'} = getFormBuilderWindowData(); // simplified implementation of useBaseControlProps() const uniqueId = useInstanceId(BaseControl, 'wp-components-base-control'); diff --git a/src/FormBuilder/resources/js/form-builder/src/common/getWindowData.ts b/src/FormBuilder/resources/js/form-builder/src/common/getWindowData.ts index dba7309b55..25eb5df362 100644 --- a/src/FormBuilder/resources/js/form-builder/src/common/getWindowData.ts +++ b/src/FormBuilder/resources/js/form-builder/src/common/getWindowData.ts @@ -7,39 +7,64 @@ import type { TermsAndConditions, } from '@givewp/form-builder/types'; -declare global { - interface Window { - wp?: any; - storageData?: { - formId: number; - nonce: string; - formDesigns: FormDesign[]; - formPage: FormPageSettings; - currency: string; - gateways: Gateway[]; - recurringAddonData?: { - isInstalled: boolean; - }; - gatewaySettingsUrl: string; - emailPreviewURL: string; - emailTemplateTags: TemplateTag[]; - emailNotifications: EmailNotification[]; - emailDefaultAddress: string; - disallowedFieldNames: string[]; - donationConfirmationTemplateTags: TemplateTag[]; - termsAndConditions: TermsAndConditions; - }; - } +import BlockRegistrar from '@givewp/form-builder/registrars/blocks'; + +/** + * @since 3.0.0 + */ +interface FormBuilderWindowData { + formId: number; + nonce: string; + resourceURL: string; + previewURL: string; + blockData: string; + settings: string; + formDesigns: FormDesign[]; + formPage: FormPageSettings; + currency: string; + gateways: Gateway[]; + recurringAddonData?: { + isInstalled: boolean; + }; + gatewaySettingsUrl: string; + emailPreviewURL: string; + emailTemplateTags: TemplateTag[]; + emailNotifications: EmailNotification[]; + emailDefaultAddress: string; + disallowedFieldNames: string[]; + donationConfirmationTemplateTags: TemplateTag[]; + termsAndConditions: TermsAndConditions; } -export default function getWindowData() { +/** + * @since 3.0.0 + */ +declare const window: { + storageData: FormBuilderWindowData; + givewp: { + form: { + blocks: BlockRegistrar; + }; + }; +} & Window; + +/** + * @since 3.0.0 + */ +export default function getWindowData(): FormBuilderWindowData { return window.storageData; } -export function getStorageData() { +/** + * @since 3.0.0 + */ +export function getFormBuilderWindowData(): FormBuilderWindowData { return window.storageData; } -export function getFormBuilderData() { - return window.storageData; +/** + * @since 3.0.0 + */ +export function getBlockRegistrar(): BlockRegistrar { + return window.givewp.form.blocks; } diff --git a/src/FormBuilder/resources/js/form-builder/src/common/registerBlocks.ts b/src/FormBuilder/resources/js/form-builder/src/common/registerBlocks.ts index 6dd32c8a7e..bcfe10e41d 100644 --- a/src/FormBuilder/resources/js/form-builder/src/common/registerBlocks.ts +++ b/src/FormBuilder/resources/js/form-builder/src/common/registerBlocks.ts @@ -1,5 +1,6 @@ import {BlockSupports, registerBlockType, setUnregisteredTypeHandlerName} from '@wordpress/blocks'; import {__experimentalGetCoreBlocks} from '@wordpress/block-library'; +import {getBlockRegistrar} from '@givewp/form-builder/common/getWindowData'; /** * Registers the missing block from WordPress core. @@ -22,8 +23,7 @@ const registerMissingBlock = () => { } }; -// @ts-ignore -const blockRegistrar = window.givewp.form.blocks; +const blockRegistrar = getBlockRegistrar(); /** * @since 3.0.0 diff --git a/src/FormBuilder/resources/js/form-builder/src/components/sidebar/panels/FieldTypesList.tsx b/src/FormBuilder/resources/js/form-builder/src/components/sidebar/panels/FieldTypesList.tsx index b6ceafde1b..55df70afb2 100644 --- a/src/FormBuilder/resources/js/form-builder/src/components/sidebar/panels/FieldTypesList.tsx +++ b/src/FormBuilder/resources/js/form-builder/src/components/sidebar/panels/FieldTypesList.tsx @@ -7,9 +7,10 @@ import {Fragment, useState} from 'react'; import {BlockInstance} from '@wordpress/blocks'; import {FieldBlock} from '@givewp/form-builder/types'; import BlockTypesList from '@givewp/form-builder/components/forks/BlockTypesList'; +import {getBlockRegistrar} from '@givewp/form-builder/common/getWindowData'; // @ts-ignore -const blockRegistrar = window.givewp.form.blocks; +const blockRegistrar = getBlockRegistrar(); type SearchBlock = { id: string; diff --git a/src/FormBuilder/resources/js/form-builder/src/settings/donation-confirmation/index.tsx b/src/FormBuilder/resources/js/form-builder/src/settings/donation-confirmation/index.tsx index 1c72dd5cd2..ac6bb44ae8 100644 --- a/src/FormBuilder/resources/js/form-builder/src/settings/donation-confirmation/index.tsx +++ b/src/FormBuilder/resources/js/form-builder/src/settings/donation-confirmation/index.tsx @@ -4,9 +4,9 @@ import {setFormSettings, useFormState, useFormStateDispatch} from '@givewp/form- import PopoverContentWithTemplateTags from '@givewp/form-builder/components/settings/PopoverContentWithTemplateTags'; import usePopoverState from '@givewp/form-builder/hooks/usePopoverState'; import ControlForPopover from '@givewp/form-builder/components/settings/ControlForPopover'; -import {getFormBuilderData} from '@givewp/form-builder/common/getWindowData'; +import {getFormBuilderWindowData} from '@givewp/form-builder/common/getWindowData'; -const {donationConfirmationTemplateTags} = getFormBuilderData(); +const {donationConfirmationTemplateTags} = getFormBuilderWindowData(); const DonationConfirmation = () => { const { diff --git a/src/FormBuilder/resources/js/form-builder/src/settings/email/logo-upload/index.tsx b/src/FormBuilder/resources/js/form-builder/src/settings/email/logo-upload/index.tsx index d70a5e94ba..979efba43e 100644 --- a/src/FormBuilder/resources/js/form-builder/src/settings/email/logo-upload/index.tsx +++ b/src/FormBuilder/resources/js/form-builder/src/settings/email/logo-upload/index.tsx @@ -3,24 +3,23 @@ * @link https://wordpress.stackexchange.com/a/382291 */ -import React, { useState, useEffect } from 'react' -import _ from 'lodash' -import {Button, TextControl} from "@wordpress/components"; -import {upload} from "@wordpress/icons"; -import {__} from "@wordpress/i18n"; +import React from 'react'; +import _ from 'lodash'; +import {Button, TextControl} from '@wordpress/components'; +import {upload} from '@wordpress/icons'; +import {__} from '@wordpress/i18n'; export default ({value, onChange}) => { - // The media library uses Backbone.js, which can conflict with lodash. _.noConflict(); let frame; const openMediaLibrary = (event) => { - event.preventDefault() + event.preventDefault(); if (frame) { - frame.open() - return + frame.open(); + return; } frame = window.wp.media({ @@ -29,10 +28,9 @@ export default ({value, onChange}) => { text: __('Use this media', 'givewp'), }, multiple: false, // Set to true to allow multiple files to be selected - }) - - frame.on( 'select', function() { + }); + frame.on('select', function () { // Get media attachment details from the frame state var attachment = frame.state().get('selection').first().toJSON(); diff --git a/src/FormBuilder/resources/js/form-builder/src/settings/email/template-options/components/email-preview-content.tsx b/src/FormBuilder/resources/js/form-builder/src/settings/email/template-options/components/email-preview-content.tsx index a18bf2d727..ac3160ef03 100644 --- a/src/FormBuilder/resources/js/form-builder/src/settings/email/template-options/components/email-preview-content.tsx +++ b/src/FormBuilder/resources/js/form-builder/src/settings/email/template-options/components/email-preview-content.tsx @@ -1,18 +1,18 @@ -import {useEffect, useState} from "react"; -import {useFormState} from "@givewp/form-builder/stores/form-state"; -import {getStorageData} from "@givewp/form-builder/common/getWindowData"; -import {__} from "@wordpress/i18n"; +import {useEffect, useState} from 'react'; +import {useFormState} from '@givewp/form-builder/stores/form-state'; +import {getFormBuilderWindowData} from '@givewp/form-builder/common/getWindowData'; +import {__} from '@wordpress/i18n'; const EmailPreviewContent = ({emailType}) => { + const [previewHtml, setPreviewHtml] = useState(null); - const [ previewHtml, setPreviewHtml ] = useState(null); + const { + settings: {emailTemplateOptions, emailTemplate, emailLogo, emailFromName, emailFromEmail}, + } = useFormState(); - const {settings: {emailTemplateOptions, emailTemplate, emailLogo, emailFromName, emailFromEmail}} = useFormState(); - - const {formId, nonce, emailPreviewURL} = getStorageData() + const {formId, nonce, emailPreviewURL} = getFormBuilderWindowData(); useEffect(() => { - // @ts-ignore jQuery .post({ @@ -29,31 +29,32 @@ const EmailPreviewContent = ({emailType}) => { email_logo: emailLogo, email_from_name: emailFromName, email_from_email: emailFromEmail, - ...emailTemplateOptions[emailType] + ...emailTemplateOptions[emailType], }, }) .then((response) => { - setPreviewHtml(response) + setPreviewHtml(response); }) .fail((error) => { - setPreviewHtml('Error loading preview.') + setPreviewHtml('Error loading preview.'); }); }, []); - return previewHtml - ?