PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 4.3.2
GiveWP – Donation Plugin and Fundraising Platform v4.3.2
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 2.3.2 2.30.0 2.31.0 2.31.1 2.32.0 2.33.0 2.33.1 2.33.2 2.33.3 2.33.4 2.33.5 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.5.0 2.5.1 2.5.10 2.5.11 2.5.12 2.5.13 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.7 2.5.8 2.5.9 2.6.0 2.6.1 2.6.2 2.6.3 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.9.0 2.9.1 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.10.0 3.11.0 3.12.0 3.12.1 3.12.2 3.12.3 3.13.0 3.14.0 3.14.1 3.14.2 3.15.0 3.15.1 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.17.0 3.17.1 3.17.2 3.18.0 3.19.0 3.19.1 3.19.2 3.19.3 3.19.4 3.2.0 3.2.1 3.2.2 3.20.0 3.21.0 3.21.1 3.22.0 3.22.1 3.22.2 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.6.0 3.6.1 3.6.2 3.7.0 3.8.0 3.9.0 4.0.0 4.1.0 4.1.1 4.10.0 4.10.1 4.11.0 4.12.0 4.13.0 4.13.1 4.13.2 4.14.0 4.14.1 4.14.2 4.14.3 4.14.4 4.14.5 4.14.6 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.1 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 trunk 1.9.0 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.2 2.11.3 2.12.0 2.12.1 2.12.2 2.12.3 2.13.0 2.13.1 2.13.2 2.13.3 2.13.4 2.14.0 2.15.0 2.16.0 2.16.1 2.17.0 2.17.1 2.17.3 2.18.0 2.18.1 2.19.1 2.19.2 2.19.3 2.19.4 2.19.5 2.19.6 2.19.7 2.19.8 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.20.0 2.20.1 2.20.2 2.21.0 2.21.1 2.21.2 2.21.3 2.21.4 2.22.0 2.22.1 2.22.2 2.22.3 2.23.0 2.23.1 2.23.2 2.24.0 2.24.1 2.24.2 2.25.0 2.25.1 2.25.2 2.25.3 2.26.0 2.27.0 2.27.1 2.27.2 2.27.3 2.28.0 2.29.0 2.29.1 2.29.2
give / src / FormBuilder / ViewModels / FormBuilderViewModel.php
give / src / FormBuilder / ViewModels Last commit date
FormBuilderViewModel.php 1 year ago
FormBuilderViewModel.php
413 lines
1 <?php
2
3 namespace Give\FormBuilder\ViewModels;
4
5 use Give\Campaigns\Models\Campaign;
6 use Give\DonationForms\Actions\GenerateDonationFormPreviewRouteUrl;
7 use Give\DonationForms\Models\DonationForm;
8 use Give\DonationForms\ValueObjects\GoalProgressType;
9 use Give\DonationForms\ValueObjects\GoalSource;
10 use Give\DonationForms\ValueObjects\GoalType;
11 use Give\Donations\Models\Donation;
12 use Give\Donations\ValueObjects\DonationMetaKeys;
13 use Give\Donors\Models\Donor;
14 use Give\Donors\ValueObjects\DonorMetaKeys;
15 use Give\FormBuilder\DataTransferObjects\EmailNotificationData;
16 use Give\FormBuilder\ValueObjects\FormBuilderRestRouteConfig;
17 use Give\Framework\FormDesigns\FormDesign;
18 use Give\Framework\FormDesigns\Registrars\FormDesignRegistrar;
19 use Give\Framework\PaymentGateways\PaymentGateway;
20 use Give\Framework\Support\Facades\Scripts\ScriptAsset;
21 use Give\Helpers\IntlTelInput;
22 use Give\Subscriptions\Models\Subscription;
23 use Give_License;
24
25 class FormBuilderViewModel
26 {
27 /**
28 * @since 3.12.0 Add goalProgressOptions key to the returned array
29 * @since 3.9.0 Add support to intlTelInputSettings key in the returned array
30 * @since 3.7.0 Add support to isExcerptEnabled key in the returned array
31 * @since 3.2.0 Add nameTitlePrefixes key to the returned array
32 * @since 3.0.0
33 */
34 public function storageData(int $donationFormId): array
35 {
36 /** @var DonationForm $donationForm */
37 $donationForm = DonationForm::find($donationFormId);
38
39 return [
40 'formId' => $donationFormId,
41 'resourceURL' => rest_url(FormBuilderRestRouteConfig::NAMESPACE . '/form/' . $donationFormId),
42 'previewURL' => (new GenerateDonationFormPreviewRouteUrl())($donationFormId),
43 'nonce' => wp_create_nonce('wp_rest'),
44 'blockData' => $donationForm->blocks->toJson(),
45 'settings' => $donationForm->settings->toJson(),
46 'currency' => give_get_currency(),
47 'formDesigns' => array_map(static function ($designClass) {
48 /** @var FormDesign $design */
49 $design = give($designClass);
50
51 return [
52 'id' => $design::id(),
53 'name' => $design::name(),
54 'isMultiStep' => $design->isMultiStep(),
55 ];
56 }, give(FormDesignRegistrar::class)->getDesigns()),
57 'formPage' => [
58 'isEnabled' => give_is_setting_enabled(give_get_option('forms_singular')),
59 // Note: Boolean values must be nested in an array to maintain boolean type, see \WP_Scripts::localize().
60 'permalink' => add_query_arg(['p' => $donationFormId], site_url('?post_type=give_forms')),
61 'rewriteSlug' => get_post_type_object('give_forms')->rewrite['slug'],
62 'baseUrl' => preg_replace('/^https?:\/\//', '', site_url()),
63 ],
64 'gateways' => $this->getGateways(),
65 'gatewaySettingsUrl' => admin_url('edit.php?post_type=give_forms&page=give-settings&tab=gateways'),
66 'isRecurringEnabled' => defined('GIVE_RECURRING_VERSION') ? GIVE_RECURRING_VERSION : null,
67 'recurringAddonData' => [
68 'isInstalled' => defined('GIVE_RECURRING_VERSION'),
69 ],
70 'formFieldManagerData' => [
71 'isInstalled' => defined('GIVE_FFM_VERSION'),
72 'isLicensed' => (Give_License::get_license_by_plugin_dirname('give-form-field-manager')['license'] ?? '') === 'valid',
73 ],
74 'emailTemplateTags' => $this->getEmailTemplateTags(),
75 'emailNotifications' => array_map(static function ($notification) {
76 return EmailNotificationData::fromLegacyNotification($notification);
77 }, apply_filters('give_email_notification_options_metabox_fields', [], $donationFormId)),
78 'emailPreviewURL' => rest_url('givewp/form-builder/email-preview'),
79 'emailDefaultAddress' => get_option('admin_email'),
80 'disallowedFieldNames' => $this->getDisallowedFieldNames(),
81 'donationConfirmationTemplateTags' => $this->getDonationConfirmationPageTemplateTags(),
82 'termsAndConditions' => [
83 'checkboxLabel' => give_get_option('agree_to_terms_label'),
84 'agreementText' => give_get_option('agreement_text'),
85 ],
86 'goalTypeOptions' => $this->getGoalTypeOptions(),
87 'goalSourceOptions' => $this->getGoalSourceOptions(),
88 'goalProgressOptions' => $this->getGoalProgressOptions(),
89 'nameTitlePrefixes' => give_get_option('title_prefixes', array_values(give_get_default_title_prefixes())),
90 'isExcerptEnabled' => give_is_setting_enabled(give_get_option('forms_excerpt')),
91 'intlTelInputSettings' => IntlTelInput::getSettings(),
92 'campaignColors' => $this->getCampaignColors($donationFormId),
93 ];
94 }
95
96 /**
97 * @since 3.0.0
98 */
99 public function isRecurringEnabled(): bool
100 {
101 return defined('GIVE_RECURRING_VERSION') && GIVE_RECURRING_VERSION;
102 }
103
104 /**
105 * @since 3.0.0
106 */
107 public function getGoalTypeOption(
108 string $value,
109 string $label,
110 string $description,
111 bool $isCurrency = false
112 ): array
113 {
114 return [
115 'value' => $value,
116 'label' => $label,
117 'description' => $description,
118 'isCurrency' => $isCurrency,
119 ];
120 }
121
122
123 /**
124 * @since 4.1.0
125 */
126 public function getGoalSourceOption(
127 string $value,
128 string $label,
129 string $description
130 ): array
131 {
132 return [
133 'value' => $value,
134 'label' => $label,
135 'description' => $description,
136 ];
137 }
138
139
140 /**
141 * @since 3.12.0
142 */
143 public function getGoalProgressOption(
144 string $value,
145 string $label,
146 string $description
147 ): array
148 {
149 return [
150 'value' => $value,
151 'label' => $label,
152 'description' => $description
153 ];
154 }
155
156
157 /**
158 * @since 3.0.0
159 */
160 public function getGoalTypeOptions(): array
161 {
162 $options = [
163 $this->getGoalTypeOption(
164 GoalType::AMOUNT,
165 __('Amount Raised', 'give'),
166 __('The total amount raised for the form', 'give'),
167 true
168 ),
169 $this->getGoalTypeOption(
170 GoalType::DONATIONS,
171 __('Number of Donations', 'give'),
172 __('The total number of donations made for the form', 'give')
173 ),
174 $this->getGoalTypeOption(
175 GoalType::DONORS,
176 __('Number of Donors', 'give'),
177 __('The total number of unique donors who have donated to the form', 'give')
178 ),
179 ];
180
181 if ($this->isRecurringEnabled()) {
182 return array_merge($options, [
183 $this->getGoalTypeOption(
184 GoalType::AMOUNT_FROM_SUBSCRIPTIONS,
185 __('Subscription Amount Raised', 'give'),
186 __('The total amount raised for the form through subscriptions', 'give'),
187 true
188 ),
189 $this->getGoalTypeOption(
190 GoalType::SUBSCRIPTIONS,
191 __('Number of Subscriptions', 'give'),
192 __('The total number of subscriptions made for the form', 'give')
193 ),
194 $this->getGoalTypeOption(
195 GoalType::DONORS_FROM_SUBSCRIPTIONS,
196 __('Number of Subscribers', 'give'),
197 __('The total number of unique donors who have donated to the form through subscriptions', 'give')
198 ),
199 ]);
200 }
201
202 return $options;
203 }
204
205 /**
206 * @since 4.1.0
207 */
208 public function getGoalSourceOptions(): array
209 {
210 return [
211 $this->getGoalTypeOption(
212 GoalSource::CAMPAIGN,
213 __('Campaign', 'give'),
214 __('The goal for this form will automatically adjust according to the campaign goal. Change campaign goal.', 'give')
215 ),
216 $this->getGoalTypeOption(
217 GoalSource::FORM,
218 __('Custom', 'give'),
219 __('Set the custom goal for this form', 'give')
220 ),
221 ];
222 }
223
224 /**
225 * @since 3.12.0
226 */
227 public function getGoalProgressOptions(): array
228 {
229 return [
230 $this->getGoalProgressOption(
231 GoalProgressType::ALL_TIME,
232 __('All time', 'give'),
233 __('Displays the goal progress for a lifetime, starting from when this form was published.', 'give')
234 ),
235 $this->getGoalProgressOption(
236 GoalProgressType::CUSTOM,
237 __('Custom', 'give'),
238 __('Displays the goal progress from the start date to the end date.', 'give')
239 )
240 ];
241 }
242
243 /**
244 * @since 3.0.0
245 */
246 public function getEmailTemplateTags(array $tags = []): array
247 {
248 return array_map(static function ($tag) {
249 $tag['id'] = $tag['tag'];
250 $tag['desc'] = html_entity_decode($tag['desc'], ENT_QUOTES);
251 $tag['description'] = html_entity_decode($tag['description'], ENT_QUOTES);
252
253 return $tag;
254 }, array_merge($tags, array_values(give()->email_tags->get_tags())));
255 }
256
257 /**
258 * @since 3.0.0
259 */
260 public function getDonationConfirmationPageTemplateTags(): array
261 {
262 $templateTags = $this->getEmailTemplateTags([
263 [
264 'tag' => 'first_name',
265 'desc' => __('The first name supplied by the donor during their donation.', 'give'),
266 'description' => __('The first name supplied by the donor during their donation.', 'give'),
267 'func' => null,
268 "context" => 'donation',
269 ],
270 [
271 'tag' => 'last_name',
272 'desc' => __('The last name supplied by the donor during their donation.', 'give'),
273 'description' => __('The last name supplied by the donor during their donation.', 'give'),
274 'func' => null,
275 "context" => 'donation',
276 ],
277 [
278 'tag' => 'email',
279 'desc' => __('The email supplied by the donor during their donation.', 'give'),
280 'description' => __('The email supplied by the donor during their donation.', 'give'),
281 'func' => null,
282 "context" => 'donation',
283 ],
284 ]);
285
286 $supportedContexts = [
287 "general",
288 "form",
289 "donation",
290 "donor",
291 "subscription",
292 ];
293
294 array_multisort($templateTags, SORT_ASC);
295
296 return array_values(
297 array_filter($templateTags, static function ($tag) use ($supportedContexts) {
298 return !empty($tag['description']) && in_array((string)$tag['context'], $supportedContexts, true);
299 })
300 );
301 }
302
303 /**
304 * @since 3.0.0
305 */
306 public function jsPathFromPluginRoot(): string
307 {
308 return GIVE_PLUGIN_URL . 'build/formBuilderApp.js';
309 }
310
311 /**
312 * @since 3.0.0
313 */
314 public function jsPathToRegistrars(): string
315 {
316 return GIVE_PLUGIN_URL . 'build/formBuilderRegistrars.js';
317 }
318
319 /**
320 * @since 3.0.0
321 */
322 public function jsRegistrarsDependencies(): array
323 {
324 return ScriptAsset::getDependencies(GIVE_PLUGIN_DIR . 'build/formBuilderRegistrars.asset.php');
325 }
326
327 /**
328 * @since 3.0.0
329 */
330 public function jsDependencies(): array
331 {
332 $dependencies = ScriptAsset::getDependencies(GIVE_PLUGIN_DIR . 'build/formBuilderApp.asset.php');
333
334 return array_merge($dependencies, ['@givewp/form-builder/registrars']);
335 }
336
337 /**
338 * @since 3.0.0
339 */
340 public function getGateways(): array
341 {
342 $enabledGateways = array_keys(give_get_option('gateways_v3', []));
343
344 $builderPaymentGatewayData = array_map(static function ($gatewayClass) use ($enabledGateways) {
345 /** @var PaymentGateway $gateway */
346 $gateway = give($gatewayClass);
347
348 return [
349 'id' => $gateway::id(),
350 'enabled' => in_array($gateway::id(), $enabledGateways, true),
351 'label' => give_get_gateway_checkout_label($gateway::id(), 3) ?? $gateway->getPaymentMethodLabel(),
352 'supportsSubscriptions' => $gateway->supportsSubscriptions(),
353 ];
354 }, give()->gateways->getPaymentGateways(3));
355
356 return array_values($builderPaymentGatewayData);
357 }
358
359 /**
360 * In the Form Builder custom fields have meta keys. These meta keys are used for both the field name and the meta,
361 * as not to be too confusing. This array is used to prevent the user from creating meta keys that conflict with the
362 * existing meta or field names.
363 *
364 * @since 4.3.2 Add country, state, city, zip, address1, and address2 to the disallowed field names.
365 * @since 3.0.0
366 */
367 protected function getDisallowedFieldNames(): array
368 {
369 $disallowedFieldNames = array_merge(
370 Donation::propertyKeys(),
371 array_values(DonationMetaKeys::toArray()),
372 Donor::propertyKeys(),
373 array_values(DonorMetaKeys::toArray()),
374 Subscription::propertyKeys(),
375 [
376 'fund_id',
377 'login',
378 'consent',
379 'donation-summary',
380 'country',
381 'state',
382 'city',
383 'zip',
384 'address1',
385 'address2',
386 ]
387 );
388
389 return array_values(array_unique($disallowedFieldNames));
390 }
391
392 /**
393 * @since 4.1.0
394 */
395 private function getCampaignColors(int $formId): array
396 {
397 /** @var Campaign $campaign */
398 $campaign = give()->campaigns->getByFormId($formId);
399
400 if ($campaign) {
401 return [
402 'primaryColor' => $campaign->primaryColor,
403 'secondaryColor' => $campaign->secondaryColor,
404 ];
405 }
406
407 return [
408 'primaryColor' => '',
409 'secondaryColor' => '',
410 ];
411 }
412 }
413