Skip to content

Commit

Permalink
Merge branch 'epic/donation-amount-level-descriptions' into feature/l…
Browse files Browse the repository at this point in the history
…evel-descriptions-frontend-ui
  • Loading branch information
JoshuaHungDinh authored Apr 23, 2024
2 parents befa008 + 5162654 commit 73edb86
Show file tree
Hide file tree
Showing 18 changed files with 305 additions and 92 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,19 +56,25 @@ public function __invoke(DonationAmountBlockModel $block, string $currency): Don

/** @var Amount $amountNode */
$amountNode = $group->getNodeByName('amount');
$defaultLevel = $block->getDefaultLevel() > 0 ? $block->getDefaultLevel() : 10;
$amountNode
->label($block->getLabel())
->levels(...$block->getLevels())
->allowLevels($block->getPriceOption() === 'multi')
->allowCustomAmount($block->isCustomAmountEnabled())
->fixedAmountValue($block->getSetPrice())
->defaultValue(
$block->getPriceOption() === 'set' ?
$block->getSetPrice() : $defaultLevel
)
->rules(...$amountRules);

$priceOptions = $block->getPriceOption();
if ($priceOptions === 'multi') {
['levels' => $levels, 'checked' => $checked] = $this->prepareLevelsArray($block);

$amountNode
->allowLevels()
->levels(...$levels)
->defaultValue($checked);
} else {
$amountNode
->fixedAmountValue($block->getSetPrice())
->defaultValue($block->getSetPrice());
}

/** @var Hidden $currencyNode */
$currencyNode = $group->getNodeByName('currency');
$currencyNode
Expand Down Expand Up @@ -164,4 +170,41 @@ protected function getRecurringAmountPeriodField(DonationAmountBlockModel $block
->options(...$options)
->rules(new SubscriptionPeriodRule());
}

/**
* Prepares the options array to be used in the field.
*
* @unreleased
*
* @return array ['options' => ['label' => string, 'value' => string][], 'checked' => string]
*/
private function prepareLevelsArray(DonationAmountBlockModel $block): array
{
$checked = null;
$levels = array_values(
array_filter(
array_map(
function ($item) use (&$checked, $block) {
if (isset($item['checked']) && $item['checked']) {
$checked = $item['value'];
}

return [
'value' => $item['value'] ?? '',
'label' => $block->isDescriptionEnabled() ? $item['label'] : '',
];
},
$block->getLevels()
),
function ($item) {
return $item['value'] !== '';
}
)
);

return [
'levels' => $levels,
'checked' => $checked,
];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public function __invoke(DonationForm $donationForm)
}

/**
* @unreleased Update to store donation levels with descriptions
* @since 3.0.0 update with dynamic values from amount field
* @since 3.0.0
*/
Expand All @@ -43,7 +44,8 @@ public function storeDonationLevels(DonationForm $donationForm)
'_give_id' => [
'level_id' => $index,
],
'_give_amount' => $donationLevel
'_give_amount' => $donationLevel['value'],
'_give_text' => $donationLevel['label'] ?? '',
];
}, $donationLevels, array_keys($donationLevels));

Expand Down
80 changes: 80 additions & 0 deletions src/DonationForms/Migrations/UpdateDonationLevelsSchema.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php

namespace Give\DonationForms\Migrations;

use Give\DonationForms\Repositories\DonationFormRepository;
use Give\Framework\Migrations\Contracts\Migration;

/**
* Update the donation levels schema to support descriptions
*
* @unreleased
*/
class UpdateDonationLevelsSchema extends Migration
{
/**
* @inheritdoc
*/
public static function id()
{
return 'donation-forms-donation-levels-schema';
}

/**
* @inheritdoc
*/
public static function title()
{
return 'Update Donation Levels schema to support descriptions';
}

/**
* @inheritdoc
*/
public static function timestamp()
{
return strtotime('2024-04-22');
}

/**
* @unreleased
*/
public function run()
{
$forms = give(DonationFormRepository::class)
->prepareQuery()
->whereIsNotNull("give_formmeta_attach_meta_fields.meta_value")
->getAll();

if ( ! $forms) {
return;
}

foreach ($forms as $form) {
$amountBlock = $form->blocks->findByName('givewp/donation-amount');

if ( ! $amountBlock) {
continue;
}

$blockAttributes = $amountBlock->getAttributes();
$levels = $blockAttributes["levels"];
$defaultLevel = $blockAttributes["defaultLevel"] ?? 0;

if ( ! is_array($levels) || empty($levels) || isset($levels[0]['value'])) {
continue;
}

$levels = array_map(function($level) use ($defaultLevel) {
return [
'value' => $level,
'label' => '',
'checked' => $level === $defaultLevel,
];
}, $levels);

$amountBlock->setAttribute('levels', $levels);
$form->save();
}
}
}
4 changes: 3 additions & 1 deletion src/DonationForms/ServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@
use Give\DonationForms\DataTransferObjects\DonationFormPreviewRouteData;
use Give\DonationForms\DataTransferObjects\DonationFormViewRouteData;
use Give\DonationForms\FormDesigns\ClassicFormDesign\ClassicFormDesign;
use Give\DonationForms\FormDesigns\TwoPanelStepsFormLayout\TwoPanelStepsFormLayout;
use Give\DonationForms\FormDesigns\MultiStepFormDesign\MultiStepFormDesign;
use Give\DonationForms\FormDesigns\TwoPanelStepsFormLayout\TwoPanelStepsFormLayout;
use Give\DonationForms\FormPage\TemplateHandler;
use Give\DonationForms\Migrations\CleanMultipleSlashesOnDB;
use Give\DonationForms\Migrations\RemoveDuplicateMeta;
use Give\DonationForms\Migrations\UpdateDonationLevelsSchema;
use Give\DonationForms\Repositories\DonationFormRepository;
use Give\DonationForms\Routes\AuthenticationRoute;
use Give\DonationForms\Routes\DonateRoute;
Expand Down Expand Up @@ -76,6 +77,7 @@ public function boot()
give(MigrationsRegister::class)->addMigrations([
CleanMultipleSlashesOnDB::class,
RemoveDuplicateMeta::class,
UpdateDonationLevelsSchema::class,
]);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,13 @@ protected function createAmountBlock(): BlockModel
'attributes' => [
"label" => __("Donation Amount", 'give'),
"levels" => [
10,
25,
50,
100,
250,
500
['value' => 10, 'checked' => true],
['value' => 25],
['value' => 50],
['value' => 100],
['value' => 250],
['value' => 500],
],
"defaultLevel" => 10,
"priceOption" => "multi",
"setPrice" => 25,
"customAmount" => true,
Expand Down
13 changes: 6 additions & 7 deletions src/FormBuilder/BlockModels/DonationAmountBlockModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,23 +60,22 @@ public function getLabel(): string
}

/**
* @unreleased Changed the return type to an array of OptionsProps
* @since 3.0.0
*
* @return float[]
* @return array ['label' => string, 'value' => string, 'checked' => bool][]
*/
public function getLevels(): array
{
return array_map(static function($level) {
return (float)filter_var($level, FILTER_SANITIZE_NUMBER_FLOAT,FILTER_FLAG_ALLOW_FRACTION);
}, $this->block->getAttribute('levels'));
return $this->block->getAttribute('levels');
}

/**
* @since 3.0.0
* @unreleased
*/
public function getDefaultLevel(): ?float
public function isDescriptionEnabled(): bool
{
return (float)filter_var($this->block->getAttribute('defaultLevel'), FILTER_SANITIZE_NUMBER_FLOAT,FILTER_FLAG_ALLOW_FRACTION);
return $this->block->getAttribute('descriptionsEnabled') === true;
}

/**
Expand Down
26 changes: 19 additions & 7 deletions src/FormBuilder/resources/js/form-builder/src/blocks.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,26 @@
"attributes": {
"label": "Donation Amount",
"levels": [
10,
25,
50,
100,
250,
500
{
"value": 10,
"checked": true
},
{
"value": 25
},
{
"value": 50
},
{
"value": 100
},
{
"value": 250
},
{
"value": 500
}
],
"defaultLevel": 10,
"priceOption": "multi",
"setPrice": 25,
"customAmount": true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,39 @@ import {OneTimeAmountMessage, RecurringAmountMessage} from '@givewp/forms/shared
import Notice from './notice';
import {getFormBuilderWindowData} from '@givewp/form-builder/common/getWindowData';
import {DonationAmountAttributes} from '@givewp/form-builder/blocks/fields/amount/types';

const DonationLevels = ({levels, defaultLevel}: {levels: DonationAmountAttributes['levels']; defaultLevel: DonationAmountAttributes['defaultLevel']}) => (
<LevelGrid>
import cx from 'classnames';

const DonationLevels = ({
levels,
descriptionsEnabled,
}: {
levels: DonationAmountAttributes['levels'];
descriptionsEnabled: DonationAmountAttributes['descriptionsEnabled'];
}) => (
<LevelGrid descriptionsEnabled={descriptionsEnabled}>
{levels.map((level, index) => {
const levelAmount = formatCurrencyAmount(level.toString());
const levelAmount = formatCurrencyAmount(level?.value?.toString());

return (
<LevelButton selected={level === defaultLevel} key={index}>
{levelAmount}
<LevelButton selected={level.checked} key={index} descriptionsEnabled={descriptionsEnabled}>
<span
className={cx({
'give-donation-block__level__amount': descriptionsEnabled,
})}
>
{levelAmount}
</span>

{descriptionsEnabled && (
<span className={'give-donation-block__level__label'}>
{level.label ? level.label : __('Description goes here', 'give')}
</span>
)}
</LevelButton>
);
})}
</LevelGrid>
);

const CustomAmount = ({amount}: {amount: DonationAmountAttributes['setPrice']}) => (
<CurrencyControl value={amount} label={__('Custom amount', 'give')} hideLabelFromVision />
);
Expand Down Expand Up @@ -57,7 +75,6 @@ const Edit = ({attributes, setAttributes}) => {
const {
label = __('Donation Amount', 'give'),
levels,
defaultLevel,
priceOption,
setPrice,
customAmount,
Expand All @@ -67,6 +84,7 @@ const Edit = ({attributes, setAttributes}) => {
recurringLengthOfTime,
recurringOptInDefaultBillingPeriod,
recurringEnableOneTimeDonations,
descriptionsEnabled,
} = attributes as DonationAmountAttributes;

const {gateways} = getFormBuilderWindowData();
Expand Down Expand Up @@ -102,7 +120,12 @@ const Edit = ({attributes, setAttributes}) => {
/>
)}

{isMultiLevel && <DonationLevels levels={levels} defaultLevel={defaultLevel} />}
{isMultiLevel && (
<DonationLevels
levels={levels}
descriptionsEnabled={descriptionsEnabled}
/>
)}

{customAmount && <CustomAmount amount={setPrice} />}

Expand Down
Loading

0 comments on commit 73edb86

Please sign in to comment.