Skip to content

Commit

Permalink
Feature: add anonymous donation block (impress-org#247)
Browse files Browse the repository at this point in the history
* add anonymous donation block

* add more dissalowed field names to validator to avoid conflicts with model property names

* add existing helpText property to checkbox template with pico tooltip

* add conditional for helpText

* add default block using global settings

* add helpText/description under checkbox label

* add form migration step and factory

---------

Co-authored-by: Jon Waldstein
Co-authored-by: Jason Adams
Co-authored-by: Kyle B. Johnson
  • Loading branch information
jonwaldstein committed Aug 11, 2023
1 parent bebc527 commit 7e185d5
Show file tree
Hide file tree
Showing 21 changed files with 305 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use Give\Framework\Blocks\BlockModel;
use Give\Framework\FieldsAPI\Authentication;
use Give\Framework\FieldsAPI\BillingAddress;
use Give\Framework\FieldsAPI\Checkbox;
use Give\Framework\FieldsAPI\Contracts\Node;
use Give\Framework\FieldsAPI\DonationForm;
use Give\Framework\FieldsAPI\DonationSummary;
Expand Down Expand Up @@ -198,6 +199,14 @@ protected function createNodeFromBlockWithUniqueAttributes(BlockModel $block, in
}
});

case "givewp/anonymous":
return Checkbox::make('anonymous')
->label($block->getAttribute('label'))
->helpText($block->getAttribute('description'))
->showInAdmin()
->showInReceipt()
->rules('boolean');

default:
$customField = apply_filters(
'givewp_donation_form_block_render',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ class DonateControllerData
* @var float
*/
public $amount;
/**
* @var bool
*/
public $anonymous;
/**
* @var string
*/
Expand Down Expand Up @@ -118,6 +122,7 @@ class DonateControllerData
public $zip;

/**
* @unreleased added support for anonymous
* @since 0.5.0 Add support billing address field
* @since 0.1.0
*/
Expand All @@ -129,6 +134,7 @@ public function toDonation(int $donorId): Donation
'status' => DonationStatus::PENDING(),
'gatewayId' => $this->gatewayId,
'amount' => $this->amount(),
'anonymous' => $this->anonymous,
'donorId' => $donorId,
'firstName' => $this->firstName,
'lastName' => $this->lastName,
Expand All @@ -142,6 +148,7 @@ public function toDonation(int $donorId): Donation
}

/**
* @unreleased added support for anonymous
* @since 0.5.0 Add support billing address field
* @since 0.3.0
*/
Expand All @@ -153,6 +160,7 @@ public function toInitialSubscriptionDonation(int $donorId, int $subscriptionId)
'status' => DonationStatus::PENDING(),
'gatewayId' => $this->gatewayId,
'amount' => $this->amount(),
'anonymous' => $this->anonymous,
'donorId' => $donorId,
'firstName' => $this->firstName,
'lastName' => $this->lastName,
Expand Down
1 change: 1 addition & 0 deletions src/DonationForms/resources/propTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export interface RadioFieldProps extends FieldProps {

export interface CheckboxProps extends FieldProps {
value: string | number;
helpText?: string;
}

export interface ElementProps extends Element {}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
import type {CheckboxProps} from '@givewp/forms/propTypes';

/**
* @unreleased added helpText
* @since 0.4.0
*/
export default function Checkbox({Label, ErrorMessage, value, fieldError, inputProps}: CheckboxProps) {
export default function Checkbox({Label, ErrorMessage, value, helpText, fieldError, inputProps}: CheckboxProps) {
return (
<label>
<input type="checkbox" value={value} aria-invalid={fieldError ? 'true' : 'false'} {...inputProps} />
<Label />

{helpText && (
<div className="givewp-fields-checkbox__description">
<small>{helpText}</small>
</div>
)}

<ErrorMessage />
</label>
);
Expand Down
3 changes: 2 additions & 1 deletion src/DonationForms/resources/styles/base.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@
@import "components/donation-summary";
@import "components/receipt";
@import "components/pagination";
@import "components/billingAddress";
@import "components/billingAddress";
}

@layer base-elements {
@import "elements/header";
@import "elements/form";
@import "elements/sections";
@import "elements/groups";
@import "elements/fields";
@import "elements/multi-step-form";
}

Expand Down
5 changes: 5 additions & 0 deletions src/DonationForms/resources/styles/elements/_fields.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.givewp-fields-checkbox {
&__description {
margin-left: calc(1.25em + 0.375em);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

namespace Give\FormBuilder\Actions;

use Give\DonationForms\Models\DonationForm;
use Give\Framework\Blocks\BlockModel;

/**
* In v2 forms, there was a concept of "Default Options" in global GiveWP settings.
* In v3 forms, we have "Default Blocks" instead. This action converts the global default options into default blocks.
*
* @unreleased
*/
class ConvertGlobalDefaultOptionsToDefaultBlocks
{
/**
* @unreleased
*/
public function __invoke(DonationForm $form)
{
$this->handleAnonymousDonations($form);
}

/**
* @unreleased
*/
protected function handleAnonymousDonations(DonationForm $form)
{
if (give_is_anonymous_donation_field_enabled($form->id)) {
$anonymousDonationsBlock = BlockModel::make([
'name' => 'givewp/anonymous',
'attributes' => [
'label' => __('Make this an anonymous donation.', 'give'),
'description' => __(
'Would you like to prevent your name, image, and comment from being displayed publicly?',
'give'
),
],
]);

$form->blocks->insertAfter('givewp/email', $anonymousDonationsBlock);
}
}
}
3 changes: 3 additions & 0 deletions src/FormBuilder/ServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Give\FormBuilder;

use Give\DonationForms\Models\DonationForm;
use Give\FormBuilder\Actions\ConvertGlobalDefaultOptionsToDefaultBlocks;
use Give\FormBuilder\Actions\DequeueAdminScriptsInFormBuilder;
use Give\FormBuilder\Actions\DequeueAdminStylesInFormBuilder;
use Give\FormBuilder\Actions\UpdateEmailSettingsMeta;
Expand Down Expand Up @@ -59,6 +60,8 @@ public function boot()
give(UpdateEmailSettingsMeta::class)->__invoke($form);
give(UpdateEmailTemplateMeta::class)->__invoke($form);
});

Hooks::addAction('givewp_form_builder_new_form', ConvertGlobalDefaultOptionsToDefaultBlocks::class);

$this->setupOnboardingTour();
}
Expand Down
32 changes: 32 additions & 0 deletions src/FormBuilder/ViewModels/FormBuilderViewModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,17 @@

use Give\DonationForms\Actions\GenerateDonationFormPreviewRouteUrl;
use Give\DonationForms\Models\DonationForm;
use Give\Donations\Models\Donation;
use Give\Donations\ValueObjects\DonationMetaKeys;
use Give\Donors\Models\Donor;
use Give\Donors\ValueObjects\DonorMetaKeys;
use Give\FormBuilder\DataTransferObjects\EmailNotificationData;
use Give\FormBuilder\ValueObjects\FormBuilderRestRouteConfig;
use Give\Framework\FormDesigns\FormDesign;
use Give\Framework\FormDesigns\Registrars\FormDesignRegistrar;
use Give\Framework\PaymentGateways\PaymentGateway;
use Give\Framework\PaymentGateways\PaymentGatewayRegister;
use Give\Subscriptions\Models\Subscription;

class FormBuilderViewModel
{
Expand Down Expand Up @@ -56,6 +61,7 @@ public function storageData(int $donationFormId): array
}, apply_filters('give_email_notification_options_metabox_fields', array(), $donationFormId)),
'emailPreviewURL' => rest_url('givewp/form-builder/email-preview'),
'emailDefaultAddress' => get_option('admin_email'),
'disallowedFieldNames' => $this->getDisallowedFieldNames(),
'donationConfirmationTemplateTags' => $this->getDonationConfirmationPageTemplateTags(),
'termsAndConditions' => [
'checkboxLabel' => give_get_option('agree_to_terms_label'),
Expand Down Expand Up @@ -171,4 +177,30 @@ public function getGateways(): array

return array_values($builderPaymentGatewayData);
}

/**
* In the Form Builder custom fields have meta keys. These meta keys are used for both the field name and the meta,
* as not to be too confusing. This array is used to prevent the user from creating meta keys that conflict with the
* existing meta or field names.
*
* @unreleased
*/
protected function getDisallowedFieldNames(): array
{
$disallowedFieldNames = array_merge(
Donation::propertyKeys(),
array_values(DonationMetaKeys::toArray()),
Donor::propertyKeys(),
array_values(DonorMetaKeys::toArray()),
Subscription::propertyKeys(),
[
'fund_id',
'login',
'consent',
'donation-summary',
]
);

return array_values(array_unique($disallowedFieldNames));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import {CheckboxControl} from '@wordpress/components';
import {BlockEditProps} from '@wordpress/blocks';

export default function Edit({attributes}: BlockEditProps<any>) {
const {label, description} = attributes;

return (
<>
<div>
<CheckboxControl label={label} readOnly onChange={null} help={description} />
</div>
</>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import settings from './settings';

import {FieldBlock} from '@givewp/form-builder/types';

const field: FieldBlock = {
name: 'givewp/anonymous',
settings,
};

export default field;
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import {__} from '@wordpress/i18n';
import type {FieldBlock} from '@givewp/form-builder/types';
import Edit from './Edit';
import {Icon} from '@wordpress/icons';
import {Path, SVG} from '@wordpress/components';
import {GiveWPSupports} from '@givewp/form-builder/supports/types';

const givewp: GiveWPSupports = {
fieldSettings: {
label: {
default: __('Make this an anonymous donation.', 'give'),
},
description: {
default: __(
'Would you like to prevent your name, image, and comment from being displayed publicly?',
'give'
),
},
metaKey: false,
placeholder: false,
required: false,
storeAsDonorMeta: false,
displayInAdmin: false,
displayInReceipt: false,
defaultValue: false,
emailTag: false,
},
};

const settings: FieldBlock['settings'] = {
title: __('Anonymous Donation', 'give'),
description: __(
'Do you want to provide donors the ability mark themselves anonymous while giving? This will prevent their information from appearing publicly on your website but you will still receive their information for your records in the admin panel.',
'give'
),
category: 'input',
supports: {
html: false,
multiple: false,
// @ts-ignore
givewp
},
icon: () => (
<Icon
icon={
<SVG width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<Path
d="M10.8449 6.89062L7.05176 16.5H9.1684L9.89932 14.6484H14.1006L14.8316 16.5H16.9482L13.155 6.89062H10.8449ZM10.6765 12.6797L12 9.32658L13.3235 12.6797H10.6765Z"
fill="#000C00"
/>
<Path
d="M18 2.625H6V0.75H0.75V6H2.625V18H0.75V23.25H6V21.375H18V23.25H23.25V18H21.375V6H23.25V0.75H18V2.625ZM2.25 4.5V2.25H4.5V4.5H2.25ZM4.5 21.75H2.25V19.5H4.5V21.75ZM18 19.875H6V18H4.125V6H6V4.125H18V6H19.875V18H18V19.875ZM21.75 19.5V21.75H19.5V19.5H21.75ZM19.5 2.25H21.75V4.5H19.5V2.25Z"
fill="#000C00"
/>
</SVG>
}
/>
),
edit: Edit,
save: () => null,
};

export default settings;
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import amount from './amount';
import login from './login';
import billingAddress from './billing-address';
import termsAndConditions from './terms-and-conditions';
import anonymous from './anonymous';

/**
* @note Blocks in the appender are listed in the order that the blocks are registered.
Expand All @@ -25,6 +26,7 @@ const FieldBlocks: FieldBlock[] = [
login,
billingAddress,
termsAndConditions,
anonymous,
];

export default FieldBlocks;
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {
import type {
EmailNotification,
FormDesign,
FormPageSettings,
Expand All @@ -25,6 +25,7 @@ declare global {
emailTemplateTags: TemplateTag[];
emailNotifications: EmailNotification[];
emailDefaultAddress: string;
disallowedFieldNames: string[];
donationConfirmationTemplateTags: TemplateTag[];
termsAndConditions: TermsAndConditions;
};
Expand Down
Loading

0 comments on commit 7e185d5

Please sign in to comment.