PluginProbe
GiveWP – Donation Plugin and Fundraising Platform / 4.16.6.1
GiveWP – Donation Plugin and Fundraising Platform v4.16.6.1
4.18.0 4.17.0 4.16.9 4.16.8.1 4.16.8 4.16.7.2 4.16.7.1 4.16.7 4.16.6.1 4.16.6 4.16.5.1 4.16.5 4.16.4 4.16.3 4.16.2 4.16.1 4.16.0 4.15.5 4.15.4 4.15.3 4.15.2 4.15.1 4.15.0 2.3.0 2.3.1 All 257 releases
give / src / DonationForms / Actions / ConvertDonationAmountBlockToFieldsApi.php

ConvertDonationAmountBlockToFieldsApi.php in GiveWP – Donation Plugin and Fundraising Platform 4.16.6.1, at src/DonationForms/Actions/ConvertDonationAmountBlockToFieldsApi.php

228 lines 8.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Give\DonationForms\Actions;
4
5 use Give\DonationForms\Rules\CurrencyRule;
6 use Give\DonationForms\Rules\DonationTypeRule;
7 use Give\DonationForms\Rules\Max;
8 use Give\DonationForms\Rules\Min;
9 use Give\DonationForms\Rules\Size;
10 use Give\DonationForms\Rules\SubscriptionFrequencyRule;
11 use Give\DonationForms\Rules\SubscriptionInstallmentsRule;
12 use Give\DonationForms\Rules\SubscriptionPeriodRule;
13 use Give\Donations\ValueObjects\DonationType;
14 use Give\FormBuilder\BlockModels\DonationAmountBlockModel;
15 use Give\Framework\FieldsAPI\Amount;
16 use Give\Framework\FieldsAPI\DonationAmount;
17 use Give\Framework\FieldsAPI\Exceptions\EmptyNameException;
18 use Give\Framework\FieldsAPI\Exceptions\NameCollisionException;
19 use Give\Framework\FieldsAPI\Field;
20 use Give\Framework\FieldsAPI\Group;
21 use Give\Framework\FieldsAPI\Hidden;
22 use Give\Framework\FieldsAPI\Option;
23 use Give\Framework\FieldsAPI\Radio;
24 use Give\Subscriptions\ValueObjects\SubscriptionPeriod;
25
26
27 class ConvertDonationAmountBlockToFieldsApi
28 {
29
30 /**
31 * @since 4.16.5 Set default value for the levelId hidden field.
32 * @since 4.10.0 Replaced generic 'currency' rule with custom CurrencyRule that uses GiveWP's currency list
33 * @since 3.0.0
34 *
35 * @throws EmptyNameException
36 * @throws NameCollisionException
37 */
38 public function __invoke(DonationAmountBlockModel $block, string $currency): DonationAmount
39 {
40 $amountField = DonationAmount::make('donationAmount')->tap(function (Group $group) use ($block, $currency) {
41 $amountRules = ['required', 'numeric'];
42
43 if (!$block->isCustomAmountEnabled() &&
44 $block->getPriceOption() === 'set') {
45 $size = $block->getSetPrice();
46
47 $amountRules[] = new Size($size);
48 }
49
50 if ($block->isCustomAmountEnabled()) {
51 if ($block->hasAttribute('customAmountMin')) {
52 $amountRules[] = new Min($block->getAttribute('customAmountMin'));
53 }
54
55 if ($block->hasAttribute('customAmountMax') && $block->getAttribute('customAmountMax') > 0) {
56 $amountRules[] = new Max($block->getAttribute('customAmountMax'));
57 }
58 }
59
60 /** @var Amount $amountNode */
61 $amountNode = $group->getNodeByName('amount');
62 $amountNode
63 ->label($block->getLabel())
64 ->allowCustomAmount($block->isCustomAmountEnabled())
65 ->rules(...$amountRules);
66
67 $priceOptions = $block->getPriceOption();
68 $defaultLevelId = '';
69 if ($priceOptions === 'multi') {
70 ['levels' => $levels, 'checked' => $checked] = $this->prepareLevelsArray($block);
71
72 $amountNode
73 ->allowLevels()
74 ->levels(...$levels)
75 ->defaultValue($checked);
76
77 foreach ($levels as $index => $level) {
78 if ($level['checked']) {
79 $defaultLevelId = (string)$index;
80 break;
81 }
82 }
83 } else {
84 $amountNode
85 ->fixedAmountValue($block->getSetPrice())
86 ->defaultValue($block->getSetPrice());
87 }
88
89 /** @var Hidden $levelIdNode */
90 $levelIdNode = $group->getNodeByName('levelId');
91 $levelIdNode->defaultValue($defaultLevelId);
92
93 /** @var Hidden $currencyNode */
94 $currencyNode = $group->getNodeByName('currency');
95 $currencyNode
96 ->defaultValue($currency)
97 ->rules('required', new CurrencyRule());
98 });
99
100 if (!$block->isRecurringEnabled()) {
101 $donationType = Hidden::make('donationType')
102 ->defaultValue(DonationType::SINGLE()->getValue())
103 ->rules(new DonationTypeRule());
104
105 $amountField->donationType($donationType);
106 } else {
107 $subscriptionPeriod = $this->getRecurringAmountPeriodField($block);
108
109 $donationTypeDefault = $subscriptionPeriod->getDefaultValue() === 'one-time' ? DonationType::SINGLE(
110 )->getValue() : DonationType::SUBSCRIPTION()->getValue();
111
112 $donationType = Hidden::make('donationType')
113 ->defaultValue($donationTypeDefault)
114 ->rules(new DonationTypeRule());
115
116 $subscriptionFrequency = Hidden::make('subscriptionFrequency')
117 ->defaultValue($block->getRecurringBillingInterval())
118 ->rules(new SubscriptionFrequencyRule());
119
120 $subscriptionInstallments = Hidden::make('subscriptionInstallments')
121 ->defaultValue($block->getRecurringLengthOfTime())
122 ->rules(new SubscriptionInstallmentsRule());
123
124 $amountField
125 ->enableSubscriptions()
126 ->subscriptionDetailsAreFixed($block->isRecurringFixed())
127 ->donationType($donationType)
128 ->subscriptionPeriod($subscriptionPeriod)
129 ->subscriptionFrequency($subscriptionFrequency)
130 ->subscriptionInstallments($subscriptionInstallments);
131 }
132
133 return $amountField;
134 }
135
136 /**
137 * @since 3.0.0
138 *
139 * @throws EmptyNameException
140 */
141 protected function getRecurringAmountPeriodField(DonationAmountBlockModel $block): Field
142 {
143 $recurringBillingPeriodOptions = $block->getRecurringBillingPeriodOptions();
144
145 // if recurring is fixed - fields are all hidden
146 if ($block->isRecurringFixed()) {
147 $fixedBillingPeriod = $recurringBillingPeriodOptions[0];
148
149 $subscriptionPeriodDefaultValue = SubscriptionPeriod::isValid(
150 $fixedBillingPeriod
151 ) ? (new SubscriptionPeriod($fixedBillingPeriod))->getValue() : SubscriptionPeriod::MONTH()->getValue();
152
153 return Hidden::make('subscriptionPeriod')
154 ->defaultValue($subscriptionPeriodDefaultValue)
155 ->rules(new SubscriptionPeriodRule());
156 }
157
158 if ($block->isRecurringEnableOneTimeDonations()) {
159 $recurringBillingPeriodOptions = array_merge(['one-time'], $recurringBillingPeriodOptions);
160 }
161
162 $options = array_map(static function ($option) {
163 if (SubscriptionPeriod::isValid($option)) {
164 $subscriptionPeriod = new SubscriptionPeriod($option);
165
166 return new Option($subscriptionPeriod->getValue(), $subscriptionPeriod->label(0));
167 }
168
169 return new Option($option, $option === 'one-time' ? __('One Time', 'give') : ucfirst($option));
170 }, $recurringBillingPeriodOptions);
171
172 $recurringOptInDefault = $block->getRecurringOptInDefaultBillingPeriod();
173
174 if (SubscriptionPeriod::isValid($recurringOptInDefault)) {
175 $subscriptionPeriod = new SubscriptionPeriod($recurringOptInDefault);
176
177 $defaultValue = $subscriptionPeriod->getValue();
178 } else {
179 $defaultValue = 'one-time';
180 }
181
182 return Radio::make('subscriptionPeriod')
183 ->defaultValue($defaultValue)
184 ->label(__('Choose your donation frequency', 'give'))
185 ->options(...$options)
186 ->rules(new SubscriptionPeriodRule());
187 }
188
189 /**
190 * Prepares the options array to be used in the field.
191 *
192 * @since 4.16.5 Add per-level "checked" flag.
193 * @since 3.12.0
194 *
195 * @return array ['levels' => ['label' => string, 'value' => string, 'checked' => bool][], 'checked' => string|null]
196 */
197 private function prepareLevelsArray(DonationAmountBlockModel $block): array
198 {
199 $checked = null;
200 $levels = array_values(
201 array_filter(
202 array_map(
203 function ($item) use (&$checked, $block) {
204 if (isset($item['checked']) && $item['checked']) {
205 $checked = $item['value'];
206 }
207
208 return [
209 'value' => $item['value'] ?? '',
210 'label' => $block->isDescriptionEnabled() ? $item['label'] : '',
211 'checked' => isset($item['checked']) && $item['checked'],
212 ];
213 },
214 $block->getLevels()
215 ),
216 function ($item) {
217 return $item['value'] !== '';
218 }
219 )
220 );
221
222 return [
223 'levels' => $levels,
224 'checked' => $checked,
225 ];
226 }
227 }
228