PluginProbe
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) / 1.8.13
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) v1.8.13
1.8.13 1.8.12.3 1.8.12.2 1.8.12.1 1.8.12 1.8.11.3 1.8.11.2 1.8.11.1 1.8.11 1.6.6 1.6.60 1.6.7 1.6.8 1.6.9 1.7.0 1.7.0.1 1.7.0.11 1.7.0.12 1.7.0.14 1.7.0.2 1.7.0.3 1.7.0.5 1.7.0.6 1.7.0.7 1.7.0.9 All 211 releases
charitable / includes / admin / campaign-builder / fields / class-donate-amount.php

class-donate-amount.php in Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) 1.8.13, at includes/admin/campaign-builder/fields/class-donate-amount.php

539 lines 20.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Class to add donation amount (oringially from the widget) to a campaign form in the builder.
4 *
5 * @package Charitable
6 * @author David Bisset
7 * @copyright Copyright (c) 2023, WP Charitable LLC
8 * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
9 * @since 1.8.0
10 * @version 1.8.0
11 */
12
13 if ( ! defined( 'ABSPATH' ) ) {
14 exit;
15 }
16
17 if ( ! class_exists( 'Charitable_Field_Donate_Amount' ) ) :
18
19 /**
20 * Class to add campaign field donate amount field to a campaign form in the builder.
21 */
22 class Charitable_Field_Donate_Amount extends Charitable_Builder_Field {
23
24 /**
25 * Primary class constructor.
26 *
27 * @since 1.8.0
28 */
29 public function init() {
30
31 // Basic information.
32 $this->name = esc_html__( 'Donate Amount', 'charitable' );
33 $this->type = 'donate-amount';
34 $this->icon = 'fa fa-dollar';
35 $this->order = 100;
36 $this->group = 'standard';
37
38 $this->align_default = 'center';
39
40 // Edit/Duplication information.
41 $this->can_be_edited = true;
42 $this->can_be_deleted = true;
43 $this->can_be_duplicated = false;
44 $this->edit_label = esc_html__( 'Edit Donate Amount', 'charitable' );
45 $this->edit_type = 'donate-amount';
46 $this->edit_section = 'standard';
47 $this->max_allowed = 1;
48
49 // Misc.
50 $this->tooltip = '';
51
52 // Define additional field properties.
53 // add_action( 'charitable_frontend_js', [ $this, 'frontend_js' ] );
54 // add_action( 'charitable_builder_backend_scripts', [ $this, 'builder_js' ]); // admin_enqueue_scripts.
55 add_filter( 'charitable_builder_field_button_attributes', [ $this, 'make_unique_button' ], 10, 4 );
56 }
57
58 /**
59 * Field options panel inside the builder.
60 *
61 * @since 1.8.0
62 *
63 * @param array $field Field settings.
64 */
65 public function field_options( $field ) {
66 /*
67 * Basic field options.
68 */
69
70 // Options open markup.
71 }
72
73 /**
74 * Render the field.
75 *
76 * @since 1.8.0
77 *
78 * @param array $field_data Any field data.
79 * @param array $campaign_data Amount data and settings.
80 * @param integer $field_id The field ID.
81 * @param string $mode Where the field is being displayed ("preview" or "template").
82 * @param array $template_data Tempalate data.
83 */
84 public function render( $field_data = false, $campaign_data = false, $field_id = false, $mode = 'template', $template_data = false ) {
85
86 $headline = ! empty( $field_data['headline'] ) ? esc_html( $field_data['headline'] ) : false;
87 $campaign_id = isset( $campaign_data['id'] ) && 0 !== intval( $campaign_data['id'] ) ? intval( $campaign_data['id'] ) : false;
88
89 $preview_or_template_css = ( 'preview' === $mode ) ? 'preview' : 'template';
90 $input_disabled_attr = ( 'preview' === $mode ) ? 'disabled="true"' : false;
91 $donation_amount_found = false;
92
93 $currency_helper = charitable_get_currency_helper();
94
95 ob_start();
96
97 if ( 'preview' === $mode ) :
98 echo '<div class="placeholder">';
99 endif;
100
101 if ( 'preview' === $mode || ( 'template' === $mode && false !== $headline ) ) :
102 echo '<h5 class="charitable-field-' . esc_attr( $preview_or_template_css ) . '-headline">' . esc_html( $headline ) . '</h5>';
103 endif;
104
105 // if there is no campaign id, then we assume this is a new campaign and assign the default donation amounts.
106 if ( false === $campaign_id ) {
107
108 echo '
109 <div class="charitable-' . esc_attr( $preview_or_template_css ) . '-donation-options">
110 <ul class="charitable-' . esc_attr( $preview_or_template_css ) . '-donation-amounts">
111 <li class="charitable-' . esc_attr( $preview_or_template_css ) . '-donation-amount suggested-donation-amount">
112 <label><span class="amount">' . esc_html( $currency_helper->get_monetary_amount( '5.00' ) ) . '</span></label>
113 </li>
114 <li class="charitable-' . esc_attr( $preview_or_template_css ) . '-donation-amount suggested-donation-amount">
115 <label><span class="amount">' . esc_html( $currency_helper->get_monetary_amount( '10.00' ) ) . '</span></label>
116 </li>
117 <li class="charitable-' . esc_attr( $preview_or_template_css ) . '-donation-amount suggested-donation-amount selected">
118 <label><span class="amount">' . esc_html( $currency_helper->get_monetary_amount( '15.00' ) ) . '</span></label>
119 </li>
120 <li class="charitable-' . esc_attr( $preview_or_template_css ) . '-donation-amount suggested-donation-amount">
121 <label><span class="amount">' . esc_html( $currency_helper->get_monetary_amount( '20.00' ) ) . '</span></label>
122 </li>
123 <li class="charitable-' . esc_attr( $preview_or_template_css ) . '-donation-amount custom-donation-amount">
124 <span class="custom-donation-amount-wrapper">
125 <label>
126 <input type="radio" name="donation_amount" value="custom"><span class="description">' . esc_html__( 'Custom Amount', 'charitable' ) . '</span>
127 </label>
128 <input type="text" ' . esc_attr( $input_disabled_attr ) . ' class="custom-donation-input" name="custom_donation_amount" placeholder="' . esc_html__( 'Custom Donation Amount', 'charitable' ) . '" value="">
129 </span>
130 </li>
131 </ul>
132 </div>';
133
134 } else {
135
136 $campaign = charitable_get_campaign( $campaign_id );
137
138 // We want the button to contain a donation amount, but we go with what is in the SESSION first, then the DEFAULT amount.
139 $donation_amount_in_session = $campaign->get_donation_amount_in_session();
140
141 if ( ! $campaign ) :
142 echo '<p>Cannot recieve donations.</p>';
143 echo '</div> <!-- placeholder -->';
144 $html = ob_get_clean();
145 echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
146 return;
147 endif;
148
149 $suggested_donations = $campaign->get_suggested_donations();
150
151 if ( empty( $suggested_donations ) && ! $campaign->get( 'allow_custom_donations' ) ) :
152 echo '<p>No donation options available.</p>';
153 echo '</div> <!-- placeholder -->';
154 $html = ob_get_clean();
155 echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
156 return;
157 endif;
158
159 echo '
160 <div class="charitable-' . esc_attr( $preview_or_template_css ) . '-donation-options">
161 <ul class="charitable-' . esc_attr( $preview_or_template_css ) . '-donation-amounts">';
162
163 if ( ! empty( $suggested_donations ) ) :
164
165 $suggested_donations_default = ! empty( $campaign_data['settings']['donation-options']['suggested_donations_default'] ) ? intval( $campaign_data['settings']['donation-options']['suggested_donations_default'] ) : 0;
166
167 foreach ( $suggested_donations as $suggested_donation_id => $suggested_donation ) :
168
169 $selected_css = false;
170 $checked_attribute = false;
171
172 if ( ( $donation_amount_in_session && $donation_amount_in_session === $suggested_donation['amount'] )
173 || ( ! $donation_amount_in_session && $suggested_donation_id === $suggested_donations_default ) ) {
174 $selected_css = 'selected';
175 $checked_attribute = 'checked="true"';
176 $donation_amount_found = true;
177 }
178
179 ?>
180 <li class="charitable-<?php echo esc_attr( $preview_or_template_css ); ?>-donation-amount suggested-donation-amount <?php echo esc_attr( $selected_css ); ?>">
181 <label>
182 <input type="radio" name="donation_amount" value="<?php echo esc_attr( $suggested_donation['amount'] ); ?>" <?php echo esc_attr( $checked_attribute ); ?>>
183 <span class="amount"><?php echo esc_html( $currency_helper->get_monetary_amount( $suggested_donation['amount'] ) ); ?></span>
184 <?php
185 /*
186 * The builder's "Optional Description" beside each amount. Rows saved before
187 * that input existed, written by the legacy metabox, or added programmatically
188 * have no 'description' key at all, so this is guarded rather than read
189 * directly. The span is omitted entirely when the description is blank, which
190 * keeps the markup (and so the layout) identical for the campaigns that never
191 * filled it in.
192 *
193 * wp_kses_post() rather than esc_html() to match
194 * templates/donation-form/donation-amount-list.php, so the same description
195 * renders the same way in this block and on the donation form.
196 */
197 if ( ! empty( $suggested_donation['description'] ) ) :
198 ?>
199 <span class="description"><?php echo wp_kses_post( $suggested_donation['description'] ); ?></span>
200 <?php
201 endif;
202 ?>
203 </label>
204 </li>
205 <?php
206 endforeach;
207 endif;
208 ?>
209
210 <?php
211
212 $custom_donation_amount_class = ! empty( $campaign_data['settings']['donation-options']['allow_custom_donations'] ) ? false : 'charitable-hidden';
213
214 $value = false === $donation_amount_found && $donation_amount_in_session !== 0 ? $currency_helper->get_monetary_amount( $donation_amount_in_session ) : false;
215
216 ?>
217
218 <li class="charitable-<?php echo esc_attr( $preview_or_template_css ); ?>-donation-amount custom-donation-amount <?php echo $custom_donation_amount_class; ?>"> <?php // phpcs:ignore ?>
219 <span class="custom-donation-amount-wrapper">
220 <label>
221 <input type="radio" name="donation_amount" value="custom"><span class="description"><?php echo esc_html__( 'Custom amount', 'charitable' ); ?></span>
222 </label>
223 <input type="text" <?php echo esc_attr( $input_disabled_attr ); ?> class="custom-donation-input" name="custom_donation_amount" placeholder="<?php echo esc_html__( 'Custom Donation Amount', 'charitable' ); ?>" value="<?php echo esc_attr( $value ); ?>">
224 </span>
225 </li>
226
227 <?php
228
229 echo '
230 </ul>
231 </div>';
232
233 }
234
235 if ( 'preview' === $mode ) :
236 echo '</div> <!-- placeholder -->';
237 endif;
238
239 $html = ob_get_clean();
240
241 return $html;
242 }
243
244 /**
245 * Donate Amount preview inside the builder.
246 *
247 * @since 1.8.0
248 *
249 * @param array $field_data Field data and settings.
250 * @param array $campaign_data Campaign data and settings.
251 * @param array $field_id Field ID.
252 * @param string $theme Template data.
253 */
254 public function field_preview( $field_data = false, $campaign_data = false, $field_id = false, $theme = '' ) {
255
256 $html = $this->field_title( $this->name );
257 $html .= $this->field_wrapper( $this->render( $field_data, $campaign_data, $field_id, 'preview' ), $field_data );
258
259 echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
260 }
261
262 /**
263 * The display on the campaign front-end.
264 *
265 * @since 1.8.0
266 *
267 * @param string $field_type The passed field type.
268 * @param array $field_data Any field data.
269 * @param array $campaign_data Amount data and settings.
270 */
271 public function field_display( $field_type = '', $field_data = false, $campaign_data = false ) {
272
273 $html = $this->field_display_wrapper( $this->render( $field_data, $campaign_data ), $field_data );
274
275 echo apply_filters( 'charitable_campaign_builder_' . $this->type . '_field_display', $html, $campaign_data ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
276 }
277
278 /**
279 * Donate Amount display on the form front-end.
280 *
281 * @since 1.8.0
282 *
283 * @param integer $field_id Number ID.
284 * @param array $campaign_data Amount data and settings.
285 */
286 public function settings_display( $field_id = false, $campaign_data = false ) {
287
288 if ( ! class_exists( 'Charitable_Builder_Form_Fields' ) ) {
289 return;
290 }
291
292 $charitable_builder_form_fields = new Charitable_Builder_Form_Fields();
293
294 $settings = isset( $campaign_data['fields'][ $field_id ] ) ? $campaign_data['fields'][ $field_id ] : false;
295
296 ob_start();
297
298 ?>
299
300 <h4 class="charitable-panel-field" data-field-id="<?php echo intval( $field_id ); ?>"><?php echo esc_html( $this->name ); ?> (ID: <?php echo intval( $field_id ); ?>)</h4>
301
302 <?php
303
304 echo $charitable_builder_form_fields->generate_text( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
305 isset( $settings['headline'] ) ? $settings['headline'] : '',
306 esc_html__( 'Headline', 'charitable' ),
307 array(
308 'id' => 'field_' . esc_attr( $this->type ) . '_headline' . '_' . intval( $field_id ), // phpcs:ignore
309 'name' => array( '_fields', intval( $field_id ), 'headline' ),
310 'field_id' => intval( $field_id ),
311 'tooltip' => esc_html__( 'Add a headline to this field.', 'charitable' ),
312 'class' => 'charitable-campaign-builder-headline',
313 )
314 );
315
316 echo $charitable_builder_form_fields->generate_divider( false, false, array( 'field_id' => $field_id ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
317
318 echo $charitable_builder_form_fields->generate_donation_amounts_mini( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
319 $campaign_data,
320 esc_html__( 'Suggested Donation Amounts', 'charitable' ),
321 array(
322 'from' => 'field',
323 'id' => 'field_' . esc_attr( $this->type ) . '_donation_amounts' . '_' . intval( $field_id ), // phpcs:ignore
324 'name' => array( '_fields', intval( $field_id ), 'donation_amounts' ),
325 'field_id' => intval( $field_id ),
326 'default' => false,
327 )
328 );
329
330 echo $charitable_builder_form_fields->generate_divider( false, false, array( 'field_id' => $field_id ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
331
332 $campaign_settings = false;
333
334 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Display/routing parameter
335 if ( ! empty( $_GET['campaign_id'] ) ) {
336 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Display/routing parameter
337 $campaign_id = intval( wp_unslash( $_GET['campaign_id'] ) );
338 if ( $campaign_id > 0 ) {
339 $campaign_settings = get_post_meta( $campaign_id, 'campaign_settings_v2', true );
340 }
341 }
342
343 $default_allow_custom = false !== $campaign_settings && ! isset( $campaign_settings['settings']['donation-options']['allow_custom_donations'] ) ? false : '1';
344
345 echo $charitable_builder_form_fields->generate_toggle( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
346 $default_allow_custom,
347 esc_html__( 'Allow Custom Donations', 'charitable' ),
348 array(
349 'id' => 'field_' . esc_attr( $this->type ) . '_allow_custom_donations' . '_' . intval( $field_id ), // phpcs:ignore
350 'name' => array( '_fields', intval( $field_id ), 'allow_custom_donations' ),
351 'container_class' => 'charitable-campaign-builder-allow-custom-donations',
352 'field_id' => esc_attr( $field_id ),
353 'checked_value' => '1',
354 )
355 );
356
357 echo $charitable_builder_form_fields->generate_divider( false, false, array( 'field_id' => $field_id ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
358
359 echo $charitable_builder_form_fields->generate_text( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
360 isset( $settings['css_class'] ) ? $settings['css_class'] : false,
361 esc_html__( 'CSS Class', 'charitable' ),
362 array(
363 'id' => 'field_' . esc_attr( $this->type ) . '_css_class' . '_' . intval( $field_id ),
364 'name' => array( '_fields', intval( $field_id ), 'css_class' ),
365 'field_id' => intval( $field_id ),
366 'tooltip' => esc_html__( 'Add CSS classes (seperated by a space) for this field to customize it\'s appearance in your theme.', 'charitable' ),
367 )
368 );
369
370 ?>
371
372 <?php
373
374 $html = ob_get_clean();
375
376 return $html;
377 }
378
379 /**
380 * Display settings for AJAX requests.
381 *
382 * @since 1.8.0
383 * @version 1.8.9.1
384 *
385 * @return void
386 */
387 public function settings_display_ajax() {
388 // phpcs:disable WordPress.Security.NonceVerification.Missing
389 $field_id = isset( $_POST['field_id'] ) ? intval( wp_unslash( $_POST['field_id'] ) ) : 0;
390 $campaign_id = isset( $_POST['campaign_id'] ) ? intval( wp_unslash( $_POST['campaign_id'] ) ) : 0; // todo: should this be added? see a few lines down.
391 // phpcs:enable WordPress.Security.NonceVerification.Missing
392
393 if ( ! class_exists( 'Charitable_Builder_Form_Fields' ) ) {
394 wp_send_json_error( esc_html__( 'Something went wrong while performing this action.', 'charitable' ) );
395 }
396
397 $charitable_builder_form_fields = new Charitable_Builder_Form_Fields();
398
399 $campaign_data = get_post_meta( $campaign_id, 'campaign_settings_v2', true );
400 $settings = isset( $campaign_data['fields'][ $field_id ] ) ? $campaign_data['fields'][ $field_id ] : false;
401
402 ob_start();
403
404 ?>
405
406 <?php
407
408 echo $charitable_builder_form_fields->generate_text( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
409 isset( $settings['headline'] ) ? $settings['headline'] : '',
410 esc_html__( 'Headline', 'charitable' ),
411 array(
412 'id' => 'field_' . esc_attr( $this->type ) . '_headline' . '_' . intval( $field_id ), // phpcs:ignore
413 'name' => array( '_fields', intval( $field_id ), 'headline' ),
414 'field_id' => intval( $field_id ),
415 'tooltip' => esc_html__( 'Add a headline to this field.', 'charitable' ),
416 'class' => 'charitable-campaign-builder-headline',
417 )
418 );
419
420 echo $charitable_builder_form_fields->generate_text( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
421 $settings['css_class'],
422 esc_html__( 'CSS Class', 'charitable' ),
423 array(
424 'id' => 'field_' . esc_attr( $this->type ) . '_css_class',
425 'name' => array( 'fields', esc_attr( $this->type ), 'css_class' ),
426 'tooltip' => esc_html( $this->tooltip ),
427 )
428 );
429
430 ?>
431
432 <?php
433
434 $html = ob_get_clean();
435
436 wp_send_json_success( [ 'html' => $html ] );
437
438 exit;
439 }
440
441 /**
442 * Enqueue frontend js.
443 *
444 * @since 1.8.0
445 */
446 public function frontend_js() {
447 }
448
449 /**
450 * Enqueue frontend limit option js.
451 *
452 * @since 1.8.0
453 *
454 * @param array $min Min or not.
455 */
456 public function builder_js( $min ) {
457 }
458
459 /**
460 * Amountat and sanitize field.
461 *
462 * @since 1.8.0
463 *
464 * @param int $field_id Field type.
465 * @param mixed $field_submit Field value that was submitted.
466 * @param array $campaign_data Campaign data and settings.
467 */
468 public function format( $field_id, $field_submit, $campaign_data ) {
469 }
470
471 /**
472 * Validate field on form submit.
473 *
474 * @since 1.8.0
475 *
476 * @param int $field_id Field ID.
477 * @param mixed $field_submit Field value that was submitted.
478 * @param array $campaign_data Campaign data and settings.
479 */
480 public function validate( $field_id, $field_submit, $campaign_data ) {
481 }
482
483
484 /**
485 * Return attributes that disable the field button if campaign_data shows one already exists in the template.
486 *
487 * @since 1.8.0
488 *
489 * @param array $field_attr All the settings for this field button.
490 * @param array $field Field data.
491 * @param array $campaign_data Campaign data and settings.
492 * @param array $current_fields Current fields according to saved campaign data.
493 */
494 public function make_unique_button( $field_attr = false, $field = false, $campaign_data = false, $current_fields = false ) {
495
496 if ( false === $field || false === $campaign_data || false === $current_fields || ! is_array( $campaign_data ) || ! is_array( $current_fields ) || empty( $field['type'] ) ) {
497 return $field_attr;
498 }
499
500 if ( ! empty( $field['type'] ) && $field['type'] !== $this->type ) {
501 return $field_attr;
502 }
503
504 // is this already in the template?
505 if ( in_array( $this->type, $current_fields, true ) ) {
506 $field_attr['class'][] = 'charitable-disabled';
507 }
508
509 return $field_attr;
510 }
511
512 /**
513 * Possible depreciated function.
514 *
515 * @since 1.8.0
516 *
517 * @param string $field Field type.
518 * @param array $field_atts Field value that was submitted.
519 * @param array $campaign_data Campaign data and settings.
520 */
521 public function section_top( $field, $field_atts, $campaign_data ) {
522 }
523
524 /**
525 * Possible depreciated function.
526 *
527 * @since 1.8.0
528 *
529 * @param string $field Field type.
530 * @param array $field_atts Field value that was submitted.
531 * @param array $campaign_data Campaign data and settings.
532 */
533 public function section_bottom( $field, $field_atts, $campaign_data ) {
534 }
535 }
536
537 new Charitable_Field_Donate_Amount();
538
539 endif;