← All changes
|
includes/donations/class-charitable-donation-processor.php
+248
-96
1.6.9
→
1.8.13
View file →
| @@ -1,17 +1,20 @@ | ||
| 1 | 1 | <?php |
| 2 | 2 | /** |
| 3 | 3 | * The class that is responsible for responding to donation events. |
| 4 | 4 | * |
| 5 | - * @version 1.0.0 | |
| 6 | - * @package Charitable/Classes/Charitable_Donation_Processor | |
| 7 | - * @author Eric Daams | |
| 8 | - * @copyright Copyright (c) 2019, Studio 164a | |
| 9 | - * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License | |
| 5 | + * @package Charitable/Classes/Charitable_Donation_Processor | |
| 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.0.0 | |
| 10 | + * @version 1.6.55 | |
| 10 | 11 | */ |
| 11 | 12 | |
| 12 | 13 | // Exit if accessed directly. |
| 13 | -if ( ! defined( 'ABSPATH' ) ) { exit; } | |
| 14 | +if ( ! defined( 'ABSPATH' ) ) { | |
| 15 | + exit; | |
| 16 | +} | |
| 14 | 17 | |
| 15 | 18 | if ( ! class_exists( 'Charitable_Donation_Processor' ) ) : |
| 16 | 19 | |
| 17 | 20 | /** |
| @@ -126,8 +129,9 @@ | ||
| 126 | 129 | /** |
| 127 | 130 | * Executed when a user first clicks the Donate button on a campaign. |
| 128 | 131 | * |
| 129 | 132 | * @since 1.0.0 |
| 133 | + * @version 1.8.3.2 | |
| 130 | 134 | * |
| 131 | 135 | * @return void |
| 132 | 136 | */ |
| 133 | 137 | public static function add_donation_to_session() { |
| @@ -136,10 +140,14 @@ | ||
| 136 | 140 | if ( ! $processor->get_campaign() ) { |
| 137 | 141 | return; |
| 138 | 142 | } |
| 139 | 143 | |
| 140 | - $nonce = $_POST['charitable-donate-now']; | |
| 144 | + if ( ! isset( $_POST['charitable-donate-now'] ) ) { | |
| 145 | + return; | |
| 146 | + } | |
| 141 | 147 | |
| 148 | + $nonce = sanitize_text_field( wp_unslash( $_POST['charitable-donate-now'] ) ); | |
| 149 | + | |
| 142 | 150 | if ( ! wp_verify_nonce( $nonce, 'charitable-donate' ) ) { |
| 143 | 151 | |
| 144 | 152 | /* For backwards compatibility, we also check this nonce. */ |
| 145 | 153 | if ( ! wp_verify_nonce( $nonce, 'charitable-donate-' ) ) { |
| @@ -146,16 +154,21 @@ | ||
| 146 | 154 | return; |
| 147 | 155 | } |
| 148 | 156 | } |
| 149 | 157 | |
| 158 | + /* Possibly add a donation amount if user clicked on a campaign builder donate button */ | |
| 159 | + $donation_amount = ! empty( $_POST['charitable_donation_amount'] ) && ! empty( $_POST['charitable_builder'] ) ? esc_html( $_POST['charitable_donation_amount'] ) : 0; // phpcs:ignore | |
| 160 | + | |
| 161 | + /* Strip any currency symbols and make sure $donation_amount is a float. */ | |
| 162 | + $donation_amount = charitable_sanitize_amount( (string) $donation_amount ); | |
| 163 | + | |
| 150 | 164 | /* Save the donation in the session */ |
| 151 | - charitable_get_session()->add_donation( $processor->get_campaign()->ID, 0 ); | |
| 165 | + charitable_get_session()->add_donation( $processor->get_campaign()->ID, $donation_amount ); | |
| 152 | 166 | |
| 153 | 167 | $donations_url = charitable_get_permalink( 'campaign_donation_page', array( 'campaign_id' => $processor->get_campaign()->ID ) ); |
| 154 | 168 | |
| 155 | - wp_redirect( $donations_url ); | |
| 156 | - | |
| 157 | - die(); | |
| 169 | + wp_safe_redirect( $donations_url ); | |
| 170 | + exit(); | |
| 158 | 171 | } |
| 159 | 172 | |
| 160 | 173 | /** |
| 161 | 174 | * Process the donation. |
| @@ -169,15 +182,41 @@ | ||
| 169 | 182 | public function process_donation() { |
| 170 | 183 | $processor = self::get_instance(); |
| 171 | 184 | $campaign = $processor->get_campaign(); |
| 172 | 185 | |
| 186 | + if ( charitable_is_debug() ) { | |
| 187 | + error_log( 'process_donation start' ); // phpcs:ignore | |
| 188 | + } | |
| 189 | + | |
| 173 | 190 | if ( ! $campaign ) { |
| 174 | 191 | return; |
| 175 | 192 | } |
| 176 | 193 | |
| 194 | + /* Check to ensure the donation is not going to an inactive campaign post. */ | |
| 195 | + if ( ! $campaign->can_receive_donations() ) { | |
| 196 | + if ( charitable_is_debug() ) { | |
| 197 | + error_log( 'Campaign cannot receive donations' ); // phpcs:ignore | |
| 198 | + } | |
| 199 | + return; | |
| 200 | + } | |
| 201 | + | |
| 177 | 202 | /* Validate the form submission and retrieve the values. */ |
| 178 | 203 | $form = $campaign->get_donation_form(); |
| 204 | + if ( charitable_is_debug() ) { | |
| 205 | + // phpcs:disable | |
| 206 | + error_log( 'process_donation - form' ); | |
| 207 | + error_log( print_r( $form, true ) ); | |
| 208 | + // phpcs:enable | |
| 209 | + } | |
| 179 | 210 | |
| 211 | + if ( charitable_is_debug() ) { | |
| 212 | + // phpcs:disable | |
| 213 | + error_log( '=== FORM DATA DEBUG ===' ); | |
| 214 | + error_log( 'POST data available to form: ' . print_r( $_POST, true ) ); | |
| 215 | + error_log( 'REQUEST data available to form: ' . print_r( $_REQUEST, true ) ); | |
| 216 | + // phpcs:enable | |
| 217 | + } | |
| 218 | + | |
| 180 | 219 | /** |
| 181 | 220 | * Do something before any donation form processing takes place. |
| 182 | 221 | * |
| 183 | 222 | * @since 1.0.0 |
| @@ -187,8 +226,13 @@ | ||
| 187 | 226 | */ |
| 188 | 227 | do_action( 'charitable_before_process_donation_form', $processor, $form ); |
| 189 | 228 | |
| 190 | 229 | if ( ! $form->validate_submission() ) { |
| 230 | + if ( charitable_is_debug() ) { | |
| 231 | + // phpcs:disable | |
| 232 | + error_log( 'Validation form not valid' ); | |
| 233 | + // phpcs:enable | |
| 234 | + } | |
| 191 | 235 | return false; |
| 192 | 236 | } |
| 193 | 237 | |
| 194 | 238 | $values = $form->get_donation_values(); |
| @@ -193,8 +237,17 @@ | ||
| 193 | 237 | |
| 194 | 238 | $values = $form->get_donation_values(); |
| 195 | 239 | $gateway = $values['gateway']; |
| 196 | 240 | |
| 241 | + if ( charitable_is_debug() ) { | |
| 242 | + // phpcs:disable | |
| 243 | + error_log( '=== DONATION PROCESSOR DEBUG ===' ); | |
| 244 | + error_log( 'Gateway from form values: ' . $gateway ); | |
| 245 | + error_log( 'All form values: ' . print_r( $values, true ) ); | |
| 246 | + error_log( 'POST data: ' . print_r( $_POST, true ) ); | |
| 247 | + // phpcs:enable | |
| 248 | + } | |
| 249 | + | |
| 197 | 250 | /** |
| 198 | 251 | * Validate the gateway values. |
| 199 | 252 | * |
| 200 | 253 | * @since 1.0.0 |
| @@ -203,8 +256,15 @@ | ||
| 203 | 256 | * @param string $gateway The gateway ID. |
| 204 | 257 | * @param array $values The values submitted by the user. |
| 205 | 258 | */ |
| 206 | 259 | if ( ! apply_filters( 'charitable_validate_donation_form_submission_gateway', true, $gateway, $values ) ) { |
| 260 | + if ( charitable_is_debug() ) { | |
| 261 | + // phpcs:disable | |
| 262 | + error_log( 'process_donation not valid' ); | |
| 263 | + error_log( print_r( $gateway, true ) ); | |
| 264 | + error_log( print_r( $values, true ) ); | |
| 265 | + // phpcs:enable | |
| 266 | + } | |
| 207 | 267 | return false; |
| 208 | 268 | } |
| 209 | 269 | |
| 210 | 270 | $this->donation_id = $processor->save_donation( $values ); |
| @@ -240,10 +300,20 @@ | ||
| 240 | 300 | * @param int $donation_id The donation ID. |
| 241 | 301 | * @param Charitable_Donation_Processor $processor The Donation Processor object. |
| 242 | 302 | * @return mixed |
| 243 | 303 | */ |
| 244 | - return apply_filters( 'charitable_process_donation_' . $gateway, true, $this->donation_id, $processor ); | |
| 304 | + if ( charitable_is_debug() ) { | |
| 305 | + // phpcs:disable | |
| 306 | + error_log( 'This Gateway is Charitable version 1.3.0 compatible... The gateway is ' . $gateway ); | |
| 307 | + error_log( 'The donation id is ' . $this->donation_id ); | |
| 308 | + error_log( 'Charitable_Donation_Processor Object is: [commented out] ' ); | |
| 309 | + // phpcs:enable | |
| 310 | + } | |
| 245 | 311 | |
| 312 | + $hook_name = 'charitable_process_donation_' . $gateway; | |
| 313 | + | |
| 314 | + return apply_filters( $hook_name, true, $this->donation_id, $processor ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound -- Hook name is dynamically constructed with the plugin prefix 'charitable_process_donation_'. | |
| 315 | + | |
| 246 | 316 | } else { |
| 247 | 317 | /** |
| 248 | 318 | * Send donation processing to the payment gateway. |
| 249 | 319 | * |
| @@ -273,51 +343,105 @@ | ||
| 273 | 343 | * |
| 274 | 344 | * @return void |
| 275 | 345 | */ |
| 276 | 346 | public static function process_donation_form_submission() { |
| 277 | - | |
| 278 | 347 | $processor = self::get_instance(); |
| 279 | 348 | $result = $processor->process_donation(); |
| 280 | 349 | |
| 281 | 350 | $processor->redirect_after_gateway_processing( $result ); |
| 282 | - | |
| 283 | 351 | } |
| 284 | 352 | |
| 285 | 353 | /** |
| 286 | 354 | * Add a donation with AJAX. |
| 287 | 355 | * |
| 288 | - * @since 1.3.0 | |
| 356 | + * @since 1.3.0 | |
| 357 | + * @version 1.8.7 | |
| 289 | 358 | * |
| 290 | 359 | * @return void |
| 291 | 360 | */ |
| 292 | 361 | public static function ajax_process_donation_form_submission() { |
| 293 | - if ( ! isset( $_POST['campaign_id'] ) ) { | |
| 362 | + /* Prevent any displayed errors from messing with the AJAX response. */ | |
| 363 | + if ( charitable_is_debug() ) { // phpcs:ignore | |
| 364 | + // do nothing, allow php/server settings to determine php logging. | |
| 365 | + } else { | |
| 366 | + ini_set( 'display_errors', 0 ); // phpcs:ignore | |
| 367 | + } | |
| 368 | + | |
| 369 | + if ( ! isset( $_POST['campaign_id'] ) ) { // @codingStandardsIgnoreLine | |
| 294 | 370 | wp_send_json_error( new WP_Error( 'missing_campaign_id', __( 'Campaign ID was not found. Unable to create donation.', 'charitable' ) ) ); |
| 295 | 371 | } |
| 296 | 372 | |
| 297 | 373 | $processor = self::get_instance(); |
| 374 | + $result = $processor->process_donation(); | |
| 298 | 375 | |
| 299 | - $result = $processor->process_donation(); | |
| 376 | + $response = is_array( $result ) ? $result : array(); | |
| 300 | 377 | |
| 301 | - if ( $result ) { | |
| 302 | - $response = array( | |
| 303 | - 'success' => true, | |
| 304 | - 'redirect_to' => $processor->get_redirection_after_gateway_processing( $result ), | |
| 305 | - ); | |
| 378 | + if ( $processor->donation_processed_successfully( $result ) ) { | |
| 379 | + $response['success'] = true; | |
| 380 | + $response['redirect_to'] = $processor->get_redirection_after_gateway_processing( $result ); | |
| 306 | 381 | } else { |
| 382 | + | |
| 383 | + // Start with getting errors from the notices class. | |
| 307 | 384 | $errors = charitable_get_notices()->get_errors(); |
| 385 | + // If there is no errors, set the errors to an empty array. | |
| 386 | + if ( empty( $errors ) || ! is_array( $errors ) ) { | |
| 387 | + $errors = array(); | |
| 388 | + } | |
| 308 | 389 | |
| 390 | + // Check and see if there are errors in the response too. | |
| 391 | + if ( ! empty( $response['errors'] ) ) { | |
| 392 | + $errors = array_merge( $errors, $response['errors'] ); | |
| 393 | + } | |
| 394 | + | |
| 309 | 395 | if ( empty( $errors ) ) { |
| 310 | 396 | $errors = array( __( 'Unable to process donation.', 'charitable' ) ); |
| 311 | 397 | } |
| 312 | 398 | |
| 313 | - $response = array( | |
| 314 | - 'success' => false, | |
| 315 | - 'errors' => $errors, | |
| 399 | + // Log the AJAX processing failure | |
| 400 | + $context = array( | |
| 401 | + 'campaign_id' => $processor->get_donation_data_value( 'campaign_id' ), | |
| 402 | + 'amount' => $processor->get_donation_data_value( 'donation_amount' ), | |
| 403 | + 'gateway' => $processor->get_donation_data_value( 'gateway' ), | |
| 316 | 404 | 'donation_id' => (int) $processor->get_donation_id(), |
| 317 | 405 | ); |
| 406 | + charitable_log_form_error( 'ajax_failure', 'donation_processing_failed', $context ); | |
| 407 | + | |
| 408 | + $response['success'] = false; | |
| 409 | + $response['errors'] = $errors; | |
| 410 | + $response['donation_id'] = (int) $processor->get_donation_id(); | |
| 411 | + | |
| 412 | + // get the gateway from the processor. | |
| 413 | + $gateway = $processor->get_donation_data_value( 'gateway' ); | |
| 414 | + | |
| 415 | + // If the gateway is square, we need to add to add errors to the donation log. | |
| 416 | + if ( 'square' === $gateway ) { | |
| 417 | + // If we are in test mode, remove the first error because that reads "Test mode is enabled". | |
| 418 | + if ( charitable_get_option( 'test_mode' ) ) { | |
| 419 | + // If there is at least one element, check the first one for a value that contains "Test mode is enabled". | |
| 420 | + if ( count( $errors ) > 0 ) { | |
| 421 | + if ( strpos( $errors[0], 'Test mode is enabled' ) !== false ) { | |
| 422 | + $errors = array_slice( $errors, 1 ); | |
| 423 | + } | |
| 424 | + } | |
| 425 | + } | |
| 426 | + $errors = implode( ', ', $errors ); | |
| 427 | + $processor->update_donation_log( $processor->get_donation_id(), 'Payment attempt failed.' ); | |
| 428 | + } | |
| 318 | 429 | } |
| 319 | 430 | |
| 431 | + if ( charitable_is_debug() ) { | |
| 432 | + // phpcs:disable | |
| 433 | + error_log( 'ajax_process_donation_form_submission - response' ); | |
| 434 | + error_log( print_r( $response, true ) ); | |
| 435 | + // phpcs:enable | |
| 436 | + } | |
| 437 | + | |
| 438 | + // Experimenting with a different response structure. | |
| 439 | + // These are errors displayed to the user (and hopefully not loggeD). | |
| 440 | + if ( ! empty( $response['errors'] ) ) { | |
| 441 | + // Insert an element into the first position of the array. | |
| 442 | + $response['errors'] = array_merge( array( 'An error occurred while processing your donation.' ), $response['errors'] ); | |
| 443 | + } | |
| 320 | 444 | wp_send_json( $response ); |
| 321 | 445 | |
| 322 | 446 | exit(); |
| 323 | 447 | } |
| @@ -340,8 +464,10 @@ | ||
| 340 | 464 | /* Validate the form submission and retrieve the values. */ |
| 341 | 465 | $form = new Charitable_Donation_Amount_Form( $campaign ); |
| 342 | 466 | |
| 343 | 467 | /** |
| 468 | + * Do something before the donation amount form is processed. | |
| 469 | + * | |
| 344 | 470 | * @hook charitable_before_process_donation_amount_form |
| 345 | 471 | */ |
| 346 | 472 | do_action( 'charitable_before_process_donation_amount_form', $processor, $form ); |
| 347 | 473 | |
| @@ -348,14 +474,16 @@ | ||
| 348 | 474 | /** |
| 349 | 475 | * Form validated, so add the donation to session. |
| 350 | 476 | */ |
| 351 | 477 | if ( $form->validate_submission() ) { |
| 352 | - | |
| 353 | 478 | $submitted = $form->get_donation_values(); |
| 479 | + $period = array_key_exists( 'donation_period', $submitted ) ? $submitted['donation_period'] : 'once'; | |
| 354 | 480 | |
| 355 | - charitable_get_session()->add_donation( $submitted['campaign_id'], $submitted['amount'] ); | |
| 481 | + charitable_get_session()->add_donation( $submitted['campaign_id'], $submitted['amount'], $period ); | |
| 356 | 482 | |
| 357 | 483 | /** |
| 484 | + * Do something after the donation amount form is processed. | |
| 485 | + * | |
| 358 | 486 | * @hook charitable_after_process_donation_amount_form |
| 359 | 487 | */ |
| 360 | 488 | do_action( 'charitable_after_process_donation_amount_form', $processor, $submitted ); |
| 361 | 489 | } |
| @@ -361,9 +489,9 @@ | ||
| 361 | 489 | } |
| 362 | 490 | |
| 363 | 491 | $redirect_url = charitable_get_permalink( 'campaign_donation_page', array( 'campaign_id' => $campaign->ID ) ); |
| 364 | 492 | |
| 365 | - if ( 'same_page' == charitable_get_option( 'donation_form_display', 'separate_page' ) ) { | |
| 493 | + if ( 'same_page' == charitable_get_option( 'donation_form_display', 'separate_page' ) ) { // phpcs:ignore | |
| 366 | 494 | $redirect_url .= '#charitable-donation-form'; |
| 367 | 495 | } |
| 368 | 496 | |
| 369 | 497 | wp_safe_redirect( $redirect_url ); |
| @@ -370,8 +498,24 @@ | ||
| 370 | 498 | die(); |
| 371 | 499 | } |
| 372 | 500 | |
| 373 | 501 | /** |
| 502 | + * Checks whether a donation has been processed successfully. | |
| 503 | + * | |
| 504 | + * @since 1.6.44 | |
| 505 | + * | |
| 506 | + * @param boolean|array $result The result returned from process_donation. | |
| 507 | + * @return boolean | |
| 508 | + */ | |
| 509 | + public function donation_processed_successfully( $result ) { | |
| 510 | + if ( is_array( $result ) ) { | |
| 511 | + return array_key_exists( 'success', $result ) ? $result['success'] : true; | |
| 512 | + } | |
| 513 | + | |
| 514 | + return $result; | |
| 515 | + } | |
| 516 | + | |
| 517 | + /** | |
| 374 | 518 | * Inserts a new donation. |
| 375 | 519 | * |
| 376 | 520 | * This method is designed to be completely form agnostic. |
| 377 | 521 | * |
| @@ -428,9 +572,9 @@ | ||
| 428 | 572 | charitable_get_notices()->add_errors_from_wp_error( $donation_id ); |
| 429 | 573 | return 0; |
| 430 | 574 | } |
| 431 | 575 | |
| 432 | - if ( 0 == $donation_id ) { | |
| 576 | + if ( 0 == $donation_id ) { // phpcs:ignore | |
| 433 | 577 | charitable_get_notices()->add_error( __( 'We were unable to save the donation. Please try again.', 'charitable' ) ); |
| 434 | 578 | return 0; |
| 435 | 579 | } |
| 436 | 580 | |
| @@ -463,9 +607,9 @@ | ||
| 463 | 607 | $session->add_donation_key( $this->get_donation_data_value( 'donation_key' ) ); |
| 464 | 608 | |
| 465 | 609 | /* Required in case the donor is redirected back to the donation form. */ |
| 466 | 610 | foreach ( $this->get_campaign_donations_data() as $campaign ) { |
| 467 | - $session->add_donation( $campaign['campaign_id'], $campaign['amount'] ); | |
| 611 | + $session->add_donation( $campaign['campaign_id'], $campaign['amount'], $this->get_donation_data_value( 'donation_key', 'once' ) ); | |
| 468 | 612 | } |
| 469 | 613 | } |
| 470 | 614 | |
| 471 | 615 | /** |
| @@ -504,9 +648,9 @@ | ||
| 504 | 648 | |
| 505 | 649 | if ( array_key_exists( 'campaign_donation_id', $campaign ) ) { |
| 506 | 650 | $campaign_donation_id = $campaign['campaign_donation_id']; |
| 507 | 651 | } else { |
| 508 | - $campaign_donation_id = array_search( $campaign['campaign_id'], $campaign_donations ); | |
| 652 | + $campaign_donation_id = array_search( $campaign['campaign_id'], $campaign_donations ); // phpcs:ignore | |
| 509 | 653 | } |
| 510 | 654 | |
| 511 | 655 | /* Avoid adding duplicate campaign donations when re-submitting a campaign. */ |
| 512 | 656 | if ( false !== $campaign_donation_id ) { |
| @@ -529,9 +673,9 @@ | ||
| 529 | 673 | $campaign['donor_id'] = $donor_id; |
| 530 | 674 | $campaign['donation_id'] = $donation_id; |
| 531 | 675 | $campaign_donation_id = charitable_get_table( 'campaign_donations' )->insert( $campaign ); |
| 532 | 676 | |
| 533 | - if ( 0 == $campaign_donation_id ) { | |
| 677 | + if ( 0 == $campaign_donation_id ) { // phpcs:ignore | |
| 534 | 678 | return 0; |
| 535 | 679 | } |
| 536 | 680 | } |
| 537 | 681 | }//end foreach |
| @@ -552,8 +696,9 @@ | ||
| 552 | 696 | 'donation_gateway' => $this->get_donation_data_value( 'gateway' ), |
| 553 | 697 | 'donor' => $this->get_donation_data_value( 'user' ), |
| 554 | 698 | 'test_mode' => charitable_get_option( 'test_mode', 0 ), |
| 555 | 699 | 'donation_key' => $this->get_donation_data_value( 'donation_key' ), |
| 700 | + 'currency' => charitable_get_currency(), | |
| 556 | 701 | ); |
| 557 | 702 | |
| 558 | 703 | if ( $this->get_donation_data_value( 'meta' ) ) { |
| 559 | 704 | $meta = array_merge( $meta, $this->get_donation_data_value( 'meta' ) ); |
| @@ -597,14 +742,17 @@ | ||
| 597 | 742 | return; |
| 598 | 743 | } |
| 599 | 744 | |
| 600 | 745 | $donor_id = $this->get_donor_id(); |
| 601 | - $meta = $this->get_donation_data_value( 'meta' ); | |
| 746 | + $meta = $this->get_donation_data_value( 'meta', array() ); | |
| 602 | 747 | $contact_consent = array_key_exists( 'contact_consent', $meta ) ? (bool) $meta['contact_consent'] : false; |
| 603 | 748 | |
| 604 | - charitable_get_table( 'donors' )->update( $donor_id, array( | |
| 605 | - 'contact_consent' => $contact_consent, | |
| 606 | - ) ); | |
| 749 | + charitable_get_table( 'donors' )->update( | |
| 750 | + $donor_id, | |
| 751 | + array( | |
| 752 | + 'contact_consent' => $contact_consent, | |
| 753 | + ) | |
| 754 | + ); | |
| 607 | 755 | } |
| 608 | 756 | |
| 609 | 757 | /** |
| 610 | 758 | * Add a message to the donation log. |
| @@ -641,9 +789,9 @@ | ||
| 641 | 789 | * @param string $key The key to search for. |
| 642 | 790 | * @param mixed $default Fallback value to return if the data is not set. |
| 643 | 791 | * @return mixed |
| 644 | 792 | */ |
| 645 | - public function get_donation_data_value( $key, $default = false ) { | |
| 793 | + public function get_donation_data_value( $key, $default = false ) { // phpcs:ignore | |
| 646 | 794 | $data = $this->get_donation_data(); |
| 647 | 795 | return isset( $data[ $key ] ) ? $data[ $key ] : $default; |
| 648 | 796 | } |
| 649 | 797 | |
| @@ -664,9 +812,9 @@ | ||
| 664 | 812 | * Returns the campaign donations array, or false if the data is invalid. |
| 665 | 813 | * |
| 666 | 814 | * @since 1.0.0 |
| 667 | 815 | * |
| 668 | - * @return string[]|false | |
| 816 | + * @return array[]|false | |
| 669 | 817 | */ |
| 670 | 818 | public function get_campaign_donations_data() { |
| 671 | 819 | if ( ! isset( $this->campaign_donations_data ) ) { |
| 672 | 820 | |
| @@ -683,9 +831,9 @@ | ||
| 683 | 831 | return false; |
| 684 | 832 | } |
| 685 | 833 | |
| 686 | 834 | if ( ! isset( $campaign['campaign_name'] ) ) { |
| 687 | - $campaign['campaign_name'] = get_the_title( $campaign['campaign_id'] ); | |
| 835 | + $campaign['campaign_name'] = get_post_field( 'post_title', $campaign['campaign_id'], 'raw' ); | |
| 688 | 836 | } |
| 689 | 837 | |
| 690 | 838 | $this->campaign_donations_data[] = $campaign; |
| 691 | 839 | } |
| @@ -715,9 +863,9 @@ | ||
| 715 | 863 | $this->donor_id = charitable_get_table( 'donors' )->get_donor_id_by_email( $user_data['email'] ); |
| 716 | 864 | } |
| 717 | 865 | |
| 718 | 866 | /* If we still do not have a donor ID, it means that this is a first-time donor */ |
| 719 | - if ( 0 == $this->donor_id ) { | |
| 867 | + if ( 0 == $this->donor_id ) { // phpcs:ignore | |
| 720 | 868 | $user = new Charitable_User( $this->get_donation_data_value( 'user_id', get_current_user_id() ) ); |
| 721 | 869 | $this->donor_id = $user->add_donor( $user_data ); |
| 722 | 870 | } |
| 723 | 871 | }//end if |
| @@ -725,8 +873,54 @@ | ||
| 725 | 873 | return $this->donor_id; |
| 726 | 874 | } |
| 727 | 875 | |
| 728 | 876 | /** |
| 877 | + * Returns the name of the donor. | |
| 878 | + * | |
| 879 | + * @since 1.0.0 | |
| 880 | + * @since 1.6.14 Changed access to public. Previously protected. | |
| 881 | + * | |
| 882 | + * @return string | |
| 883 | + */ | |
| 884 | + public function get_donor_name() { | |
| 885 | + $user = new WP_User( $this->get_donation_data_value( 'user_id', 0 ) ); | |
| 886 | + $user_data = $this->get_donation_data_value( 'user' ); | |
| 887 | + $first_name = isset( $user_data['first_name'] ) ? $user_data['first_name'] : $user->get( 'first_name' ); | |
| 888 | + $last_name = isset( $user_data['last_name'] ) ? $user_data['last_name'] : $user->get( 'last_name' ); | |
| 889 | + return trim( sprintf( '%s %s', $first_name, $last_name ) ); | |
| 890 | + } | |
| 891 | + | |
| 892 | + /** | |
| 893 | + * Returns a comma separated list of the campaigns that are being donated to. | |
| 894 | + * | |
| 895 | + * @since 1.0.0 | |
| 896 | + * @since 1.6.14 Changed access to public. Previously protected. | |
| 897 | + * | |
| 898 | + * @return string | |
| 899 | + */ | |
| 900 | + public function get_campaign_names() { | |
| 901 | + $campaigns = wp_list_pluck( $this->get_campaign_donations_data(), 'campaign_name' ); | |
| 902 | + return implode( ', ', $campaigns ); | |
| 903 | + } | |
| 904 | + | |
| 905 | + /** | |
| 906 | + * Returns the donation status. Defaults to charitable-pending. | |
| 907 | + * | |
| 908 | + * @since 1.0.0 | |
| 909 | + * | |
| 910 | + * @return string | |
| 911 | + */ | |
| 912 | + protected function get_donation_status() { | |
| 913 | + $status = $this->get_donation_data_value( 'status', 'charitable-pending' ); | |
| 914 | + | |
| 915 | + if ( ! charitable_is_valid_donation_status( $status ) ) { | |
| 916 | + $status = 'charitable-pending'; | |
| 917 | + } | |
| 918 | + | |
| 919 | + return $status; | |
| 920 | + } | |
| 921 | + | |
| 922 | + /** | |
| 729 | 923 | * Redirect the user after the gateway has processed the donation. |
| 730 | 924 | * |
| 731 | 925 | * @uses Charitable_Donation_Processor::get_redirection_after_gateway_processing() |
| 732 | 926 | * |
| @@ -738,9 +932,9 @@ | ||
| 738 | 932 | private function redirect_after_gateway_processing( $gateway_processing ) { |
| 739 | 933 | $redirect_url = $this->get_redirection_after_gateway_processing( $gateway_processing ); |
| 740 | 934 | |
| 741 | 935 | /* If the gateway processing failed, add the error notices to the session. */ |
| 742 | - if ( false == $gateway_processing ) { | |
| 936 | + if ( false == $gateway_processing ) { // phpcs:ignore | |
| 743 | 937 | |
| 744 | 938 | /* Log the failed payment. */ |
| 745 | 939 | $this->update_donation_log( |
| 746 | 940 | $this->donation_id, |
| @@ -760,10 +954,10 @@ | ||
| 760 | 954 | /** |
| 761 | 955 | * If the gateway processing returned an array with a directive to NOT |
| 762 | 956 | * use wp_safe_redirect, use wp_redirect instead. |
| 763 | 957 | */ |
| 764 | - if ( isset( $gateway_processing['safe'] ) && false == $gateway_processing['safe'] ) { | |
| 765 | - wp_redirect( $redirect_url, $status ); | |
| 958 | + if ( isset( $gateway_processing['safe'] ) && false == $gateway_processing['safe'] ) { // phpcs:ignore | |
| 959 | + wp_safe_redirect( $redirect_url, $status ); | |
| 766 | 960 | die(); |
| 767 | 961 | } |
| 768 | 962 | |
| 769 | 963 | wp_safe_redirect( $redirect_url, $status ); |
| @@ -779,24 +973,18 @@ | ||
| 779 | 973 | * @param mixed $gateway_processing The result of the gateway processing. |
| 780 | 974 | * @return string |
| 781 | 975 | */ |
| 782 | 976 | private function get_redirection_after_gateway_processing( $gateway_processing ) { |
| 783 | - if ( false == $gateway_processing ) { | |
| 784 | - | |
| 977 | + if ( false == $gateway_processing ) { // phpcs:ignore | |
| 785 | 978 | $redirect_url = esc_url( add_query_arg( array( 'donation_id' => $this->donation_id ), wp_get_referer() ) ); |
| 786 | - | |
| 787 | 979 | } elseif ( is_array( $gateway_processing ) && isset( $gateway_processing['redirect'] ) ) { |
| 788 | - | |
| 789 | 980 | $redirect_url = $gateway_processing['redirect']; |
| 790 | - | |
| 791 | 981 | } else { |
| 792 | - | |
| 793 | 982 | /* Fall back to returning the donation receipt URL. */ |
| 794 | 983 | $redirect_url = charitable_get_permalink( 'donation_receipt_page', array( 'donation_id' => $this->donation_id ) ); |
| 795 | - | |
| 796 | 984 | } |
| 797 | 985 | |
| 798 | - return $redirect_url; | |
| 986 | + return apply_filters( 'charitable_redirection_after_gateway_processing', $redirect_url, $gateway_processing, $this ); | |
| 799 | 987 | } |
| 800 | 988 | |
| 801 | 989 | /** |
| 802 | 990 | * Validate user data passed to insert. |
| @@ -813,9 +1001,9 @@ | ||
| 813 | 1001 | $ret = $this->get_donation_data_value( 'user_id' ) || $this->get_donation_data_value( 'donor_id' ); |
| 814 | 1002 | |
| 815 | 1003 | if ( ! $ret ) { |
| 816 | 1004 | $user = $this->get_donation_data_value( 'user', array() ); |
| 817 | - $ret = array_key_exists( 'email', $user ) && strlen( $user['email'] ); | |
| 1005 | + $ret = array_key_exists( 'email', $user ) && is_email( $user['email'] ); | |
| 818 | 1006 | } |
| 819 | 1007 | |
| 820 | 1008 | return $ret; |
| 821 | 1009 | } |
| @@ -840,53 +1028,17 @@ | ||
| 840 | 1028 | ); |
| 841 | 1029 | |
| 842 | 1030 | $core_values['post_date'] = get_date_from_gmt( $core_values['post_date_gmt'] ); |
| 843 | 1031 | |
| 1032 | + /** | |
| 1033 | + * Filter the core Donation post values to store. | |
| 1034 | + * | |
| 1035 | + * @since 1.0.0 | |
| 1036 | + * | |
| 1037 | + * @param array $core_values The values to save to the posts table. | |
| 1038 | + * @param Charitable_Donation_Processor $processor The donation processer object. | |
| 1039 | + */ | |
| 844 | 1040 | return apply_filters( 'charitable_donation_values_core', $core_values, $this ); |
| 845 | - } | |
| 846 | - | |
| 847 | - /** | |
| 848 | - * Returns the donation status. Defaults to charitable-pending. | |
| 849 | - * | |
| 850 | - * @since 1.0.0 | |
| 851 | - * | |
| 852 | - * @return string | |
| 853 | - */ | |
| 854 | - protected function get_donation_status() { | |
| 855 | - $status = $this->get_donation_data_value( 'status', 'charitable-pending' ); | |
| 856 | - | |
| 857 | - if ( ! charitable_is_valid_donation_status( $status ) ) { | |
| 858 | - $status = 'charitable-pending'; | |
| 859 | - } | |
| 860 | - | |
| 861 | - return $status; | |
| 862 | - } | |
| 863 | - | |
| 864 | - /** | |
| 865 | - * Returns the name of the donor. | |
| 866 | - * | |
| 867 | - * @since 1.0.0 | |
| 868 | - * | |
| 869 | - * @return string | |
| 870 | - */ | |
| 871 | - protected function get_donor_name() { | |
| 872 | - $user = new WP_User( $this->get_donation_data_value( 'user_id', 0 ) ); | |
| 873 | - $user_data = $this->get_donation_data_value( 'user' ); | |
| 874 | - $first_name = isset( $user_data['first_name'] ) ? $user_data['first_name'] : $user->get( 'first_name' ); | |
| 875 | - $last_name = isset( $user_data['last_name'] ) ? $user_data['last_name'] : $user->get( 'last_name' ); | |
| 876 | - return trim( sprintf( '%s %s', $first_name, $last_name ) ); | |
| 877 | - } | |
| 878 | - | |
| 879 | - /** | |
| 880 | - * Returns a comma separated list of the campaigns that are being donated to. | |
| 881 | - * | |
| 882 | - * @since 1.0.0 | |
| 883 | - * | |
| 884 | - * @return string | |
| 885 | - */ | |
| 886 | - protected function get_campaign_names() { | |
| 887 | - $campaigns = wp_list_pluck( $this->get_campaign_donations_data(), 'campaign_name' ); | |
| 888 | - return implode( ', ', $campaigns ); | |
| 889 | 1041 | } |
| 890 | 1042 | |
| 891 | 1043 | /** |
| 892 | 1044 | * Set a unique key for the donation. |