Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: donation confirmation page redirect #7439

Merged
merged 15 commits into from
Aug 23, 2024
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions includes/shortcodes.php
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ function give_register_form_shortcode( $atts ) {
*
* Shows a donation receipt.
*
* @unreleased add give_donation_confirmation_page_enqueue_scripts
* @since 3.7.0 Sanitize and escape attributes
* @since 1.0
*
Expand Down Expand Up @@ -390,13 +391,15 @@ function give_receipt_shortcode( $atts ) {
if ( ! wp_doing_ajax() ) {
give_get_template_part( 'receipt/placeholder' );

return sprintf(
do_action('give_donation_confirmation_page_enqueue_scripts');

return apply_filters('give_receipt_shortcode_output', sprintf(
'<div id="give-receipt" data-shortcode="%1$s" data-receipt-type="%2$s" data-donation-key="%3$s" >%4$s</div>',
htmlspecialchars( wp_json_encode( $give_receipt_args ) ),
esc_attr($receipt_type),
esc_attr($donation_id),
ob_get_clean()
);
));
}

return give_display_donation_receipt( $atts );
Expand Down
10 changes: 7 additions & 3 deletions src/Controller/Form.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ public function loadTemplateOnFrontend()
/**
* Load receipt view.
*
* @unreleased add action give_donation_confirmation_page_enqueue_scripts
* @since 2.7.0
*/
public function loadReceiptView()
Expand All @@ -71,6 +72,8 @@ public function loadReceiptView()
return;
}

do_action('give_donation_confirmation_page_enqueue_scripts');

// Handle success page.
if (FormUtils::isViewingFormReceipt() && ! FormUtils::isLegacyForm()) {
/* @var Template $formTemplate */
Expand Down Expand Up @@ -113,7 +116,6 @@ public function loadReceiptView()
include $formTemplate->getReceiptView();
exit();
}

// Render receipt on success page in iframe.
add_filter('the_content', [$this, 'showReceiptInIframeOnSuccessPage'], 1);
}
Expand Down Expand Up @@ -164,6 +166,7 @@ public function setFailedTransactionError()
/**
* Handle receipt shortcode on success page
*
* @unreleased add filter give_donation_confirmation_success_page_shortcode_view
* @since 2.7.0
*
* @param string $content
Expand All @@ -173,9 +176,10 @@ public function setFailedTransactionError()
public function showReceiptInIframeOnSuccessPage($content)
{
$receiptShortcode = ShortcodeUtils::getReceiptShortcodeFromConfirmationPage();
$content = str_replace($receiptShortcode, give_form_shortcode([]), $content);

return $content;
$view = apply_filters('give_donation_confirmation_success_page_shortcode_view', give_form_shortcode([]));

return str_replace($receiptShortcode, $view, $content);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ public function __invoke(DonateControllerData $formData, Donation $donation, ?Su
(new AddRedirectUrlsToGatewayData())($formData, $donation);
(new UpdateDonationLevelId())($formData->getDonationForm(), $donation);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace Give\DonationForms\Actions;

use Give\DonationForms\DataTransferObjects\DonationConfirmationReceiptViewRouteData;

class ReplaceGiveReceiptShortcodeViewWithDonationConfirmationIframe
{
/**
* Replace the give_receipt shortcode with the v3 confirmation page iframe.
*
* @unreleased
*/
public function __invoke(string $view): string
{
$data = DonationConfirmationReceiptViewRouteData::fromRequest(give_clean($_GET));

if ($data->receiptId) {
$viewUrl = (new GenerateDonationConfirmationReceiptViewRouteUrl())($data->receiptId);
return "<iframe style='width: 1px;min-width: 100%;border: 0;' data-givewp-embed src='$viewUrl'></iframe>";
}

return $view;
}
}
23 changes: 23 additions & 0 deletions src/DonationForms/DataTransferObjects/DonateControllerData.php
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,17 @@ public function toInitialSubscriptionDonation(int $donorId, int $subscriptionId)
}

/**
* @unreleased Added "givewp_donation_confirmation_page_redirect_enabled" filter
* @since 3.0.0
*/
public function getSuccessUrl(Donation $donation): string
{
$form = $this->getDonationForm();

if (apply_filters('givewp_donation_confirmation_page_redirect_enabled', $form->settings->enableReceiptConfirmationPage, $donation->formId)) {
return $this->getDonationConfirmationPageFromSettings($donation);
}

return $this->isEmbed ?
$this->getDonationConfirmationReceiptUrl($donation) :
$this->getDonationConfirmationReceiptViewRouteUrl($donation);
Expand Down Expand Up @@ -222,6 +229,22 @@ public function getDonationConfirmationReceiptUrl(Donation $donation): string
return (new GenerateDonationConfirmationReceiptUrl())($donation, $this->originUrl, $this->embedId);
}

/**
* @unreleased
*/
public function getDonationConfirmationPageFromSettings(Donation $donation): string
{
$settings = give_get_settings();

$page = isset($settings['success_page'])
? get_permalink(absint($settings['success_page']))
: get_bloginfo('url');

$page = apply_filters('givewp_donation_confirmation_page_redirect_permalink', $page, $donation->formId);

return esc_url_raw(add_query_arg(['receipt-id' => $donation->purchaseKey], $page));
}

/**
* @since 3.0.0
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?php

namespace Give\DonationForms\Listeners;

use Give\DonationForms\DataTransferObjects\DonateControllerData;
Expand All @@ -15,13 +16,20 @@ class TemporarilyReplaceLegacySuccessPageUri
*
* This is a temporary solution until we can update the gateway api to support the new receipt urls.
*
* @unreleased Added "givewp_enable_donation_confirmation_page_redirect" filter
* @since 3.0.0
*
* @return void
*/
public function __invoke(DonateControllerData $formData, Donation $donation)
{
$filteredUrl = $formData->getDonationConfirmationReceiptViewRouteUrl($donation);
$redirectUrl = $formData->getDonationConfirmationPageFromSettings($donation);
$form = $formData->getDonationForm();

if (apply_filters('givewp_donation_confirmation_page_redirect_enabled', $form->settings->enableReceiptConfirmationPage, $donation->formId)) {
$filteredUrl = $redirectUrl;
}

add_filter('give_get_success_page_uri', static function ($url) use ($filteredUrl) {
return $filteredUrl;
Expand Down
16 changes: 12 additions & 4 deletions src/DonationForms/Properties/FormSettings.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@
use Give\Framework\Support\Contracts\Jsonable;

/**
* @unreleased Added $enableReceiptConfirmationPage property
* @since 3.12.0 Add goalProgressType
* @since 3.2.0 Remove addSlashesRecursive method
* @since 3.0.0
* @since 3.2.0 Remove addSlashesRecursive method
* @since 3.0.0
*/
class FormSettings implements Arrayable, Jsonable
{
Expand Down Expand Up @@ -261,11 +262,15 @@ class FormSettings implements Arrayable, Jsonable
* @var array
*/
public $currencySwitcherSettings;

/**
* @since 3.7.0 Added formExcerpt
* @unreleased
* @var bool
*/
public $enableReceiptConfirmationPage;

/**
* @unreleased Added $enableReceiptConfirmationPage
* @since 3.7.0 Added formExcerpt
* @since 3.11.0 Sanitize customCSS property
* @since 3.2.0 Added registrationNotification
* @since 3.0.0
Expand Down Expand Up @@ -313,6 +318,9 @@ public static function fromArray(array $array): self
'{first_name}, your contribution means a lot and will be put to good use in making a difference. We’ve sent your donation receipt to {email}.',
'give'
);

$self->enableReceiptConfirmationPage = $array['enableReceiptConfirmationPage'] ?? false;

$self->formStatus = ! empty($array['formStatus']) ? new DonationFormStatus(
$array['formStatus']
) : DonationFormStatus::DRAFT();
Expand Down
12 changes: 12 additions & 0 deletions src/DonationForms/ServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Exception;
use Give\DonationForms\Actions\DispatchDonateControllerDonationCreatedListeners;
use Give\DonationForms\Actions\DispatchDonateControllerSubscriptionCreatedListeners;
use Give\DonationForms\Actions\ReplaceGiveReceiptShortcodeViewWithDonationConfirmationIframe;
use Give\DonationForms\Actions\SanitizeDonationFormPreviewRequest;
use Give\DonationForms\Actions\StoreBackwardsCompatibleFormMeta;
use Give\DonationForms\Blocks\DonationFormBlock\Block as DonationFormBlock;
Expand Down Expand Up @@ -197,6 +198,17 @@ protected function registerSingleFormPage()
protected function registerShortcodes()
{
Hooks::addFilter('givewp_form_shortcode_output', GiveFormShortcode::class, '__invoke', 10, 2);
Hooks::addFilter('give_donation_confirmation_success_page_shortcode_view', ReplaceGiveReceiptShortcodeViewWithDonationConfirmationIframe::class);
Hooks::addFilter('give_receipt_shortcode_output', ReplaceGiveReceiptShortcodeViewWithDonationConfirmationIframe::class);
add_action('give_donation_confirmation_page_enqueue_scripts', function() {
wp_enqueue_script(
'givewp-donation-form-embed',
GIVE_PLUGIN_URL . 'build/donationFormEmbed.js',
[],
GIVE_VERSION,
true
);
});
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import {__} from '@wordpress/i18n';
import {PanelRow} from '@wordpress/components';
import {PanelRow, ToggleControl} from '@wordpress/components';
import {SettingsSection} from '@givewp/form-builder-library';
import DonationConfirmation from './donation-confirmation';
import {getFormBuilderWindowData} from '@givewp/form-builder/common/getWindowData';
import TemplateTags from '@givewp/form-builder/components/settings/TemplateTags';
import {createInterpolateElement} from '@wordpress/element';

const {donationConfirmationTemplateTags} = getFormBuilderWindowData();

/**
* @unreleased Added setting for enableReceiptConfirmationPage
* @since 3.3.0
*/
export default function FormDonationConfirmationSettingsGroup({settings, setSettings}) {
const {receiptHeading, receiptDescription} = settings;
const {receiptHeading, receiptDescription, enableReceiptConfirmationPage} = settings;

return (
<>
Expand Down Expand Up @@ -46,6 +48,21 @@ export default function FormDonationConfirmationSettingsGroup({settings, setSett
<TemplateTags templateTags={donationConfirmationTemplateTags} />
</PanelRow>
</SettingsSection>
<SettingsSection title={__('Confirmation Page Redirect', 'give')}>
<PanelRow>
<ToggleControl
label={__('Enable redirect', 'give')}
checked={enableReceiptConfirmationPage}
onChange={() => setSettings({enableReceiptConfirmationPage: !enableReceiptConfirmationPage})}
help={createInterpolateElement(
__( 'When enabled, donors are redirected to a separate page to view their donation confirmation rather than viewing it on the donation form page. This can be useful for event and conversion tracking tools like Google Analytics. <a>Learn how to customize the confirmation page.</a>', 'give' ),
{
a: <a href="https://docs.givewp.com/success-page" target="_blank" title="GiveWP success page docs"/>,
}
)}
/>
</PanelRow>
</SettingsSection>
</>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {FormStatus} from '@givewp/form-builder/types/formStatus';
import {EmailTemplateOption} from '@givewp/form-builder/types/emailTemplateOption';

/**
* @unreleased Added enableReceiptConfirmationPage
* @since 3.7.0 Added formExcerpt
* @since 3.0.0
*/
Expand Down Expand Up @@ -56,4 +57,5 @@ export type FormSettings = {
designSettingsImageOpacity: string;
designSettingsImageColor: string;
formExcerpt: string;
enableReceiptConfirmationPage: boolean;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

namespace Give\Tests\Unit\DonationForms\Actions;

use Give\DonationForms\Actions\GenerateDonationConfirmationReceiptViewRouteUrl;
use Give\DonationForms\Actions\ReplaceGiveReceiptShortcodeViewWithDonationConfirmationIframe;
use Give\Donations\Models\Donation;
use Give\Tests\TestCase;
use Give\Tests\TestTraits\RefreshDatabase;

/**
* @unreleased
*/
class TestReplaceGiveReceiptShortcodeViewWithDonationConfirmationIframe extends TestCase
{
use RefreshDatabase;

/**
* @unreleased
*/
public function testShouldNotReplaceGiveReceiptShortcodeViewWithDonationConfirmationIframe()
{
$view = 'originalView';

$result = (new ReplaceGiveReceiptShortcodeViewWithDonationConfirmationIframe())($view);

$this->assertEquals($view, $result);
}

/**
* @unreleased
*/
public function testShouldNotReplaceGiveReceiptShortcodeViewWithDonationConfirmationIframeIfInvalidReceiptId(): void
{
$view = 'originalView';
$_GET['receipt_id'] = 1234;

$result = (new ReplaceGiveReceiptShortcodeViewWithDonationConfirmationIframe())($view);

$this->assertEquals($view, $result);
}

/**
* @unreleased
*/
public function testShouldReplaceGiveReceiptShortcodeViewWithDonationConfirmationIframe(): void
{
/** @var Donation $donation */
$donation = Donation::factory()->create();
$view = 'originalView';
$receiptId = $donation->purchaseKey;
$_GET['receipt-id'] = $receiptId;

$result = (new ReplaceGiveReceiptShortcodeViewWithDonationConfirmationIframe())($view);
$replacedViewUrl = (new GenerateDonationConfirmationReceiptViewRouteUrl())($receiptId);

$this->assertEquals("<iframe style='width: 1px;min-width: 100%;border: 0;' data-givewp-embed src='$replacedViewUrl'></iframe>", $result);
}
}
Loading