← All changes
|
includes/admin/forms/class-charitable-admin-donation-form.php
+178
-86
1.6.9
→
1.8.13
View file →
| @@ -2,13 +2,13 @@ | ||
| 2 | 2 | /** |
| 3 | 3 | * Admin donation form model class. |
| 4 | 4 | * |
| 5 | 5 | * @package Charitable/Classes/Charitable_Admin_Donation_Form |
| 6 | - * @author Eric Daams | |
| 7 | - * @copyright Copyright (c) 2019, Studio 164a | |
| 6 | + * @author David Bisset | |
| 7 | + * @copyright Copyright (c) 2023, WP Charitable LLC | |
| 8 | 8 | * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License |
| 9 | 9 | * @since 1.5.0 |
| 10 | - * @version 1.5.11 | |
| 10 | + * @version 1.6.55 | |
| 11 | 11 | */ |
| 12 | 12 | |
| 13 | 13 | // Exit if accessed directly. |
| 14 | 14 | if ( ! defined( 'ABSPATH' ) ) { |
| @@ -109,15 +109,15 @@ | ||
| 109 | 109 | 'priority' => 40, |
| 110 | 110 | ), |
| 111 | 111 | 'user_fields' => array( |
| 112 | 112 | 'type' => 'fieldset', |
| 113 | - 'fields' => $this->get_section_fields( 'user' ), | |
| 113 | + 'fields' => $this->get_user_fields(), | |
| 114 | 114 | 'priority' => 50, |
| 115 | 115 | 'tabindex' => 100, |
| 116 | 116 | ), |
| 117 | 117 | 'meta_fields' => array( |
| 118 | 118 | 'type' => 'fieldset', |
| 119 | - 'fields' => $this->get_section_fields( 'meta' ), | |
| 119 | + 'fields' => $this->get_meta_fields(), | |
| 120 | 120 | 'priority' => 60, |
| 121 | 121 | 'tabindex' => 200, |
| 122 | 122 | ), |
| 123 | 123 | ); |
| @@ -122,30 +122,50 @@ | ||
| 122 | 122 | ), |
| 123 | 123 | ); |
| 124 | 124 | |
| 125 | 125 | if ( $this->has_donation() ) { |
| 126 | - if ( 'manual' != $this->get_donation()->get_gateway() ) { | |
| 127 | - $fields['meta_fields']['fields']['date']['type'] = 'hidden'; | |
| 126 | + if ( 'manual' !== $this->get_donation()->get_gateway() ) { | |
| 127 | + $fields['meta_fields']['fields']['date']['type'] = 'hidden'; | |
| 128 | + $fields['meta_fields']['fields']['date']['value'] = Charitable_Data_Processor::sanitize_datepicker( $fields['meta_fields']['fields']['date']['value'] ); | |
| 128 | 129 | } |
| 129 | 130 | |
| 130 | 131 | $fields['meta_fields']['fields']['time'] = array( |
| 131 | 132 | 'type' => 'hidden', |
| 132 | 133 | 'priority' => 2, |
| 133 | - 'value' => date( 'H:i:s', strtotime( $this->get_donation()->post_date_gmt ) ), | |
| 134 | + 'value' => date( 'H:i:s', strtotime( $this->get_donation()->post_date_gmt ) ), // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date | |
| 134 | 135 | ); |
| 135 | 136 | } else { |
| 136 | 137 | $fields['donor_id'] = array( |
| 137 | - 'type' => 'select', | |
| 138 | - 'options' => $this->get_all_donors(), | |
| 139 | - 'priority' => 41, | |
| 140 | - 'value' => '', | |
| 141 | - 'description' => __( 'Select an existing donor or choose "Add a New Donor" to create a new donor.', 'charitable' ), | |
| 138 | + 'type' => 'select', | |
| 139 | + 'options' => $this->get_all_donors(), | |
| 140 | + 'priority' => 41, | |
| 141 | + 'value' => '', | |
| 142 | + 'description' => __( 'Select an existing donor or choose "Add a New Donor" to create a new donor.', 'charitable' ), | |
| 143 | + 'wrapper_class' => array( 'select2' ), | |
| 144 | + 'attrs' => array( | |
| 145 | + 'data-nonce' => wp_create_nonce( 'donor-select' ), | |
| 146 | + ), | |
| 142 | 147 | ); |
| 148 | + } | |
| 143 | 149 | |
| 144 | - $fields['user_fields']['attrs'] = array( | |
| 145 | - 'data-trigger-key' => '#donor-id', | |
| 146 | - 'data-trigger-value' => 'new', | |
| 147 | - ); | |
| 150 | + /* User can only create a donation for themselves. */ | |
| 151 | + if ( ! current_user_can( 'edit_others_donations' ) ) { | |
| 152 | + $user = charitable_get_user( get_current_user_id() ); | |
| 153 | + | |
| 154 | + if ( array_key_exists( 'donor_id', $fields ) ) { | |
| 155 | + $fields['donor_id']['type'] = 'hidden'; | |
| 156 | + $fields['donor_id']['value'] = $user->get_donor_id(); | |
| 157 | + } | |
| 158 | + | |
| 159 | + foreach ( $fields['user_fields']['fields'] as $key => $details ) { | |
| 160 | + $fields['user_fields']['fields'][ $key ]['value'] = $user->$key; | |
| 161 | + | |
| 162 | + if ( $key === 'email' ) { | |
| 163 | + $fields['user_fields']['fields'][ $key ]['field_attrs'] = array( | |
| 164 | + 'attrs' => array( 'disabled' => 'disabled' ), | |
| 165 | + ); | |
| 166 | + } | |
| 167 | + } | |
| 148 | 168 | } |
| 149 | 169 | |
| 150 | 170 | /** |
| 151 | 171 | * Filter the admin donation form fields. |
| @@ -205,27 +225,29 @@ | ||
| 205 | 225 | $keys, |
| 206 | 226 | array_map( array( $this, 'maybe_set_field_value' ), wp_list_pluck( $fields, 'admin_form' ), $keys ) |
| 207 | 227 | ); |
| 208 | 228 | |
| 209 | - if ( 'meta' == $section ) { | |
| 210 | - $fields['log_note'] = array( | |
| 211 | - 'label' => __( 'Donation Note', 'charitable' ), | |
| 212 | - 'type' => 'textarea', | |
| 213 | - 'priority' => 12, | |
| 214 | - 'required' => false, | |
| 215 | - ); | |
| 229 | + uasort( $fields, 'charitable_priority_sort' ); | |
| 216 | 230 | |
| 217 | - if ( $this->should_add_donation_receipt_checkbox() ) { | |
| 218 | - $fields['send_donation_receipt'] = array( | |
| 219 | - 'type' => 'checkbox', | |
| 220 | - 'label' => __( 'Send an email receipt to the donor.', 'charitable' ), | |
| 221 | - 'value' => 1, | |
| 222 | - 'default' => 1, | |
| 223 | - 'priority' => 16, | |
| 224 | - ); | |
| 225 | - } | |
| 226 | - } | |
| 231 | + return $fields; | |
| 232 | + } | |
| 227 | 233 | |
| 234 | + /** | |
| 235 | + * Return the fields for the user section. | |
| 236 | + * | |
| 237 | + * @since 1.6.28 | |
| 238 | + * | |
| 239 | + * @return array | |
| 240 | + */ | |
| 241 | + public function get_user_fields() { | |
| 242 | + $fields = $this->get_section_fields( 'user' ); | |
| 243 | + $loading_icon = charitable()->get_path( 'assets', false ) . 'images/charitable-loading.gif'; | |
| 244 | + $fields['overlay'] = array( | |
| 245 | + 'type' => 'content', | |
| 246 | + 'priority' => 1, | |
| 247 | + 'content' => '<div class="charitable-overlay" style="display: none;"><img src="' . $loading_icon . '" width=60 height=60 alt="' . __( 'Loading icon', 'charitable' ) . '" /></div>', | |
| 248 | + ); | |
| 249 | + | |
| 228 | 250 | uasort( $fields, 'charitable_priority_sort' ); |
| 229 | 251 | |
| 230 | 252 | return $fields; |
| 231 | 253 | } |
| @@ -230,28 +252,37 @@ | ||
| 230 | 252 | return $fields; |
| 231 | 253 | } |
| 232 | 254 | |
| 233 | 255 | /** |
| 234 | - * Return the merged fields. | |
| 256 | + * Return the fields for the meta section. | |
| 235 | 257 | * |
| 236 | - * @since 1.5.0 | |
| 258 | + * @since 1.6.28 | |
| 259 | + * @since 1.8.1.8 Added the `charitable_admin_donation_form_meta_fields` filter. | |
| 237 | 260 | * |
| 238 | 261 | * @return array |
| 239 | 262 | */ |
| 240 | - public function get_merged_fields() { | |
| 241 | - if ( ! isset( $this->merged_fields ) ) { | |
| 242 | - $this->merged_fields = array(); | |
| 263 | + public function get_meta_fields() { | |
| 264 | + $fields = $this->get_section_fields( 'meta' ); | |
| 265 | + $fields['log_note'] = array( | |
| 266 | + 'label' => __( 'Donation Note', 'charitable' ), | |
| 267 | + 'type' => 'textarea', | |
| 268 | + 'priority' => 12, | |
| 269 | + 'required' => false, | |
| 270 | + ); | |
| 243 | 271 | |
| 244 | - foreach ( $this->get_fields() as $section_id => $section ) { | |
| 245 | - if ( array_key_exists( 'fields', $section ) ) { | |
| 246 | - $this->merged_fields = array_merge( $this->merged_fields, $section['fields'] ); | |
| 247 | - } else { | |
| 248 | - $this->merged_fields[ $section_id ] = $section; | |
| 249 | - } | |
| 250 | - } | |
| 272 | + if ( $this->should_add_donation_receipt_checkbox() ) { | |
| 273 | + $fields['send_donation_receipt'] = array( | |
| 274 | + 'type' => 'checkbox', | |
| 275 | + 'label' => __( 'Send an email receipt to the donor.', 'charitable' ), | |
| 276 | + 'value' => 1, | |
| 277 | + 'default' => 1, | |
| 278 | + 'priority' => 16, | |
| 279 | + ); | |
| 251 | 280 | } |
| 252 | 281 | |
| 253 | - return $this->merged_fields; | |
| 282 | + uasort( $fields, 'charitable_priority_sort' ); | |
| 283 | + | |
| 284 | + return apply_filters( 'charitable_admin_donation_form_meta_fields', $fields, $this ); | |
| 254 | 285 | } |
| 255 | 286 | |
| 256 | 287 | /** |
| 257 | 288 | * Get the value submitted for a particular field. |
| @@ -262,9 +293,10 @@ | ||
| 262 | 293 | * @param mixed $default The default value to return if the value was not submitted. |
| 263 | 294 | * @return mixed |
| 264 | 295 | */ |
| 265 | 296 | public function get_submitted_value( $field, $default = false ) { |
| 266 | - return array_key_exists( $field, $_POST ) ? $_POST[ $field ] : $default; | |
| 297 | + $data = $this->get_submitted_values(); | |
| 298 | + return isset( $data[ $field ] ) ? $data[ $field ] : $default; | |
| 267 | 299 | } |
| 268 | 300 | |
| 269 | 301 | /** |
| 270 | 302 | * Filter a campaign donation array, making sure both a campaign |
| @@ -275,8 +307,10 @@ | ||
| 275 | 307 | * @param object $campaign_donation A particular campaign donation. |
| 276 | 308 | * @return boolean |
| 277 | 309 | */ |
| 278 | 310 | public function filter_campaign_donation( $campaign_donation ) { |
| 311 | + $campaign_donation = (array) $campaign_donation; | |
| 312 | + | |
| 279 | 313 | return array_key_exists( 'campaign_id', $campaign_donation ) |
| 280 | 314 | && array_key_exists( 'amount', $campaign_donation ) |
| 281 | 315 | && ! empty( $campaign_donation['campaign_id'] ) |
| 282 | 316 | && ! empty( $campaign_donation['amount'] ); |
| @@ -296,12 +330,24 @@ | ||
| 296 | 330 | } |
| 297 | 331 | |
| 298 | 332 | $this->valid = $this->check_required_fields( $this->get_merged_fields() ); |
| 299 | 333 | |
| 300 | - $campaign_donations = array_key_exists( 'campaign_donations', $_POST ) ? $_POST['campaign_donations'] : array(); | |
| 301 | - $_POST['campaign_donations'] = array_filter( $campaign_donations, array( $this, 'filter_campaign_donation' ) ); | |
| 334 | + /** | |
| 335 | + * If required fields are missing, get the error message from the | |
| 336 | + * notices and add them to the admin notices. | |
| 337 | + */ | |
| 338 | + if ( ! $this->valid ) { | |
| 339 | + charitable_get_admin_notices()->fill_notices_from_frontend(); | |
| 340 | + } | |
| 302 | 341 | |
| 303 | - if ( empty( $_POST['campaign_donations'] ) ) { | |
| 342 | + // phpcs:disable WordPress.Security.NonceVerification.Missing | |
| 343 | + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Array data, sanitized in filter_campaign_donation | |
| 344 | + $campaign_donations = array_key_exists( 'campaign_donations', $_POST ) ? wp_unslash( $_POST['campaign_donations'] ) : array(); | |
| 345 | + $campaign_donations = array_filter( $campaign_donations, array( $this, 'filter_campaign_donation' ) ); | |
| 346 | + $_POST['campaign_donations'] = $campaign_donations; | |
| 347 | + | |
| 348 | + if ( empty( $campaign_donations ) ) { | |
| 349 | + // phpcs:enable WordPress.Security.NonceVerification.Missing | |
| 304 | 350 | charitable_get_admin_notices()->add_error( __( 'You must provide both a campaign and amount.', 'charitable' ) ); |
| 305 | 351 | |
| 306 | 352 | $this->valid = false; |
| 307 | 353 | } |
| @@ -335,9 +381,9 @@ | ||
| 335 | 381 | */ |
| 336 | 382 | public function get_donation_values() { |
| 337 | 383 | $values = array( |
| 338 | 384 | 'ID' => $this->get_submitted_value( 'ID' ), |
| 339 | - 'donor_id' => abs( $this->get_submitted_value( 'donor_id' ) ), | |
| 385 | + 'donor_id' => abs( (int) $this->get_submitted_value( 'donor_id' ) ), | |
| 340 | 386 | 'status' => $this->get_submitted_value( 'status' ), |
| 341 | 387 | 'log_note' => $this->get_submitted_value( 'log_note' ), |
| 342 | 388 | 'user_id' => 0, |
| 343 | 389 | ); |
| @@ -350,8 +396,23 @@ | ||
| 350 | 396 | $values = $this->sanitize_submitted_date( $values ); |
| 351 | 397 | $values = $this->sanitize_submitted_log_note( $values ); |
| 352 | 398 | $values = $this->sanitize_submitted_donor( $values ); |
| 353 | 399 | |
| 400 | + /* Ensure that the user has not created a donation for someone else. */ | |
| 401 | + if ( ! current_user_can( 'edit_others_donations' ) ) { | |
| 402 | + $user = charitable_get_user( get_current_user_id() ); | |
| 403 | + | |
| 404 | + $values['donor_id'] = $user->get_donor_id(); | |
| 405 | + | |
| 406 | + if ( array_key_exists( 'user_id', $values ) ) { | |
| 407 | + $values['user_id'] = $user->ID; | |
| 408 | + } | |
| 409 | + | |
| 410 | + if ( array_key_exists( 'user', $values ) && array_key_exists( 'email', $values['user'] ) ) { | |
| 411 | + $values['user']['email'] = $user->email; | |
| 412 | + } | |
| 413 | + } | |
| 414 | + | |
| 354 | 415 | foreach ( $this->get_merged_fields() as $key => $field ) { |
| 355 | 416 | if ( $this->should_field_be_added( $field, $key, $values ) ) { |
| 356 | 417 | $values[ $field['data_type'] ][ $key ] = $this->get_field_value_from_submission( $field, $key ); |
| 357 | 418 | } |
| @@ -451,20 +512,20 @@ | ||
| 451 | 512 | } |
| 452 | 513 | |
| 453 | 514 | $donor = new Charitable_Donor( $values['donor_id'] ); |
| 454 | 515 | |
| 455 | - /* Populate the 'user' and 'user_id' args with this donor's stored details. */ | |
| 516 | + /* Populate the user_id' arg, then prepare the 'user' array. */ | |
| 456 | 517 | $values['user_id'] = $donor->get_user()->ID; |
| 457 | 518 | $values['user'] = array( |
| 458 | - 'email' => $donor->get_donor_meta( 'email' ), | |
| 459 | - 'first_name' => $donor->get_donor_meta( 'first_name' ), | |
| 460 | - 'last_name' => $donor->get_donor_meta( 'last_name' ), | |
| 461 | - 'address' => $donor->get_donor_meta( 'address' ), | |
| 462 | - 'address_2' => $donor->get_donor_meta( 'address_2' ), | |
| 463 | - 'postcode' => $donor->get_donor_meta( 'postcode' ), | |
| 464 | - 'state' => $donor->get_donor_meta( 'state' ), | |
| 465 | - 'country' => $donor->get_donor_meta( 'country' ), | |
| 466 | - 'phone' => $donor->get_donor_meta( 'phone' ), | |
| 519 | + 'email' => $this->get_submitted_value( 'email' ), | |
| 520 | + 'first_name' => $this->get_submitted_value( 'first_name' ), | |
| 521 | + 'last_name' => $this->get_submitted_value( 'last_name' ), | |
| 522 | + 'address' => $this->get_submitted_value( 'address' ), | |
| 523 | + 'address_2' => $this->get_submitted_value( 'address_2' ), | |
| 524 | + 'postcode' => $this->get_submitted_value( 'postcode' ), | |
| 525 | + 'state' => $this->get_submitted_value( 'state' ), | |
| 526 | + 'country' => $this->get_submitted_value( 'country' ), | |
| 527 | + 'phone' => $this->get_submitted_value( 'phone' ), | |
| 467 | 528 | ); |
| 468 | 529 | |
| 469 | 530 | return $values; |
| 470 | 531 | } |
| @@ -510,14 +571,17 @@ | ||
| 510 | 571 | * @return array |
| 511 | 572 | */ |
| 512 | 573 | protected function sanitize_submitted_log_note( $values ) { |
| 513 | 574 | if ( ! $values['log_note'] ) { |
| 514 | - $values['log_note'] = sprintf( __( 'Donation updated manually by <a href="%s">%s</a>.', 'charitable' ), | |
| 575 | + $values['log_note'] = sprintf( | |
| 576 | + /* translators: %1$s: User profile URL, %2$s: User display name */ | |
| 577 | + __( 'Donation updated manually by <a href="%1$s">%2$s</a>.', 'charitable' ), | |
| 515 | 578 | admin_url( 'user-edit.php?user_id=' . wp_get_current_user()->ID ), |
| 516 | 579 | wp_get_current_user()->display_name |
| 517 | 580 | ); |
| 518 | 581 | } else { |
| 519 | - $values['log_note'] .= sprintf( ' - <a href="%s">%s</a>', | |
| 582 | + $values['log_note'] .= sprintf( | |
| 583 | + ' - <a href="%s">%s</a>', | |
| 520 | 584 | admin_url( 'user-edit.php?user_id=' . wp_get_current_user()->ID ), |
| 521 | 585 | wp_get_current_user()->display_name |
| 522 | 586 | ); |
| 523 | 587 | } |
| @@ -558,28 +622,44 @@ | ||
| 558 | 622 | |
| 559 | 623 | /** |
| 560 | 624 | * Sanitize the date. |
| 561 | 625 | * |
| 562 | - * @since 1.5.0 | |
| 626 | + * @since 1.5.0 | |
| 627 | + * @version 1.8.8.5 | |
| 563 | 628 | * |
| 564 | 629 | * @param array $values The submitted values. |
| 565 | 630 | * @return array |
| 566 | 631 | */ |
| 567 | 632 | protected function sanitize_submitted_date( $values ) { |
| 568 | - $donation = charitable_get_donation( $this->get_submitted_value( 'ID' ) ); | |
| 569 | - $is_new = false === $donation || 'Auto Draft' === $donation->post_title; | |
| 570 | - $date = $this->get_submitted_value( 'date' ); | |
| 571 | - $time = $this->get_submitted_value( 'time', '00:00:00' ); | |
| 572 | - $values['date_gmt'] = charitable_sanitize_date( $date, 'Y-m-d ' . $time ); | |
| 633 | + $donation = charitable_get_donation( $this->get_submitted_value( 'ID' ) ); | |
| 634 | + $is_new = false === $donation || 'Auto Draft' === $donation->post_title; | |
| 635 | + $date = $this->get_submitted_value( 'date' ); | |
| 636 | + $time = $this->get_submitted_value( 'time', '00:00:00' ); | |
| 573 | 637 | |
| 638 | + /* The date has already been sanitized in Charitable_Date_Processor::sanitize_datepicker */ | |
| 639 | + $values['date_gmt'] = $date . ' ' . $time; | |
| 640 | + | |
| 574 | 641 | /* If the date matches today's date and it's a new donation, save the time too. */ |
| 575 | - if ( date( 'Y-m-d 00:00:00' ) == $values['date_gmt'] && $is_new ) { | |
| 576 | - $values['date_gmt'] = date( 'Y-m-d H:i:s' ); | |
| 642 | + if ( date( 'Y-m-d 00:00:00' ) == $values['date_gmt'] && $is_new ) { // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date | |
| 643 | + $values['date_gmt'] = date( 'Y-m-d H:i:s' ); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date | |
| 577 | 644 | } |
| 578 | 645 | |
| 579 | - /* If the donation date has been changed, the time is always set to 00:00:00 */ | |
| 646 | + /* If the donation date has been changed, preserve the original time from the donation log */ | |
| 580 | 647 | if ( $values['date_gmt'] !== $donation->post_date_gmt && ! $is_new ) { |
| 581 | - $values['date_gmt'] = charitable_sanitize_date( $date, 'Y-m-d 00:00:00' ); | |
| 648 | + // Get the original donation time from the donation log | |
| 649 | + $donation_log = get_post_meta( $donation->ID, '_donation_log', true ); | |
| 650 | + $original_time = '00:00:00'; // Default fallback | |
| 651 | + | |
| 652 | + if ( is_array( $donation_log ) && ! empty( $donation_log ) ) { | |
| 653 | + // Get the first log entry which contains the original creation time | |
| 654 | + $first_log_entry = $donation_log[0]; | |
| 655 | + if ( isset( $first_log_entry['time'] ) ) { | |
| 656 | + // Convert the original timestamp to GMT time format | |
| 657 | + $original_time = gmdate( 'H:i:s', $first_log_entry['time'] ); | |
| 658 | + } | |
| 659 | + } | |
| 660 | + | |
| 661 | + $values['date_gmt'] = $date . ' ' . $original_time; | |
| 582 | 662 | } |
| 583 | 663 | |
| 584 | 664 | return $values; |
| 585 | 665 | } |
| @@ -586,21 +666,24 @@ | ||
| 586 | 666 | |
| 587 | 667 | /** |
| 588 | 668 | * Get a key=>value array of all existing donors. |
| 589 | 669 | * |
| 590 | - * @since 1.5.0 | |
| 670 | + * @since 1.5.0 | |
| 671 | + * @version 1.8.8 | |
| 591 | 672 | * |
| 592 | 673 | * @return array |
| 593 | 674 | */ |
| 594 | 675 | protected function get_all_donors() { |
| 595 | - $donors = new Charitable_Donor_Query( array( | |
| 596 | - 'number' => -1, | |
| 597 | - 'orderby' => 'name', | |
| 598 | - 'order' => 'ASC', | |
| 599 | - 'output' => 'raw', | |
| 600 | - 'status' => false, // Return any. | |
| 601 | - 'include_erased' => false, | |
| 602 | - ) ); | |
| 676 | + $donors = new Charitable_Donor_Query( | |
| 677 | + array( | |
| 678 | + 'number' => -1, | |
| 679 | + 'orderby' => 'name', | |
| 680 | + 'order' => 'ASC', | |
| 681 | + 'output' => 'raw', | |
| 682 | + 'status' => false, // Return any. | |
| 683 | + 'include_erased' => false, | |
| 684 | + ) | |
| 685 | + ); | |
| 603 | 686 | |
| 604 | 687 | $donor_list = array(); |
| 605 | 688 | |
| 606 | 689 | foreach ( $donors as $donor ) { |
| @@ -612,10 +695,12 @@ | ||
| 612 | 695 | |
| 613 | 696 | $donor_list[ $donor->donor_id ] = $name; |
| 614 | 697 | } |
| 615 | 698 | |
| 699 | + // Apply a filter here to allow for the donor list to be modified. | |
| 700 | + $donor_list = apply_filters( 'charitable_admin_donation_form_donor_list', $donor_list ); | |
| 701 | + | |
| 616 | 702 | $list = array( |
| 617 | - '' => __( 'Select a Donor', 'charitable' ), | |
| 618 | 703 | 'new' => __( 'Add a New Donor', 'charitable' ), |
| 619 | 704 | 'existing' => array( |
| 620 | 705 | 'label' => __( 'Existing Donors', 'charitable' ), |
| 621 | 706 | 'options' => $donor_list, |
| @@ -628,8 +713,9 @@ | ||
| 628 | 713 | /** |
| 629 | 714 | * Set a field's initial value. |
| 630 | 715 | * |
| 631 | 716 | * @since 1.5.0 |
| 717 | + * @version 1.8.9.1 | |
| 632 | 718 | * |
| 633 | 719 | * @param array $field Field definition. |
| 634 | 720 | * @param string $key The key of the field. |
| 635 | 721 | * @return array |
| @@ -634,10 +720,12 @@ | ||
| 634 | 720 | * @param string $key The key of the field. |
| 635 | 721 | * @return array |
| 636 | 722 | */ |
| 637 | 723 | protected function maybe_set_field_value( $field, $key ) { |
| 724 | + // phpcs:disable WordPress.Security.NonceVerification.Missing | |
| 638 | 725 | if ( array_key_exists( $key, $_POST ) ) { |
| 639 | - $field['value'] = $_POST[ $key ]; | |
| 726 | + $field['value'] = sanitize_text_field( wp_unslash( $_POST[ $key ] ) ); | |
| 727 | + // phpcs:enable WordPress.Security.NonceVerification.Missing | |
| 640 | 728 | return $field; |
| 641 | 729 | } |
| 642 | 730 | |
| 643 | 731 | /* Checkboxes don't need a value set. */ |
| @@ -648,12 +736,16 @@ | ||
| 648 | 736 | if ( ! $this->has_donation() ) { |
| 649 | 737 | return $field; |
| 650 | 738 | } |
| 651 | 739 | |
| 652 | - if ( array_key_exists( 'value_callback', $field ) ) { | |
| 740 | + if ( isset( $field['value_callback'] ) ) { | |
| 653 | 741 | $value = call_user_func( $field['value_callback'], $this->get_donation(), $key ); |
| 654 | 742 | } else { |
| 655 | 743 | $value = $this->donation->get( $key ); |
| 744 | + } | |
| 745 | + | |
| 746 | + if ( isset( $field['timestamp_callback'] ) ) { | |
| 747 | + $field['timestamp'] = call_user_func( $field['timestamp_callback'], $this->get_donation(), $key ); | |
| 656 | 748 | } |
| 657 | 749 | |
| 658 | 750 | if ( ! $value ) { |
| 659 | 751 | return $field; |