| @@ -5,10 +5,10 @@ | ||
| 5 | 5 | * Action/filter hooks used for Charitable emails. |
| 6 | 6 | * |
| 7 | 7 | * @package Charitable/Functions/Emails |
| 8 | 8 | * @version 1.5.0 |
| 9 | - * @author Eric Daams | |
| 10 | - * @copyright Copyright (c) 2019, Studio 164a | |
| 9 | + * @author David Bisset | |
| 10 | + * @copyright Copyright (c) 2023, WP Charitable LLC | |
| 11 | 11 | * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License |
| 12 | 12 | */ |
| 13 | 13 | |
| 14 | 14 | // Exit if accessed directly. |
| @@ -39,18 +39,14 @@ | ||
| 39 | 39 | * @see Charitable_Email_New_Donation::send_with_donation_id() |
| 40 | 40 | * @see Charitable_Email_Offline_Donation_Receipt::send_with_donation_id() |
| 41 | 41 | * @see Charitable_Email_Offline_Donation_Notification::send_with_donation_id() |
| 42 | 42 | */ |
| 43 | + | |
| 43 | 44 | add_action( 'charitable_after_save_donation', array( 'Charitable_Email_Donation_Receipt', 'send_with_donation_id' ) ); |
| 44 | 45 | add_action( 'charitable_after_save_donation', array( 'Charitable_Email_New_Donation', 'send_with_donation_id' ) ); |
| 45 | 46 | add_action( 'charitable_after_save_donation', array( 'Charitable_Email_Offline_Donation_Receipt', 'send_with_donation_id' ) ); |
| 46 | 47 | add_action( 'charitable_after_save_donation', array( 'Charitable_Email_Offline_Donation_Notification', 'send_with_donation_id' ) ); |
| 47 | 48 | |
| 48 | -foreach ( charitable_get_approval_statuses() as $status ) { | |
| 49 | - add_action( $status . '_' . Charitable::DONATION_POST_TYPE, array( 'Charitable_Email_Donation_Receipt', 'send_with_donation_id' ) ); | |
| 50 | - add_action( $status . '_' . Charitable::DONATION_POST_TYPE, array( 'Charitable_Email_New_Donation', 'send_with_donation_id' ) ); | |
| 51 | -} | |
| 52 | - | |
| 53 | 49 | /** |
| 54 | 50 | * Send the Campaign Ended email. |
| 55 | 51 | * |
| 56 | 52 | * This email can be sent to any recipients, within 24 hours after a campaign has reached its end date. |
| @@ -65,4 +61,51 @@ | ||
| 65 | 61 | * @see Charitable_Emails::handle_email_settings_request() |
| 66 | 62 | */ |
| 67 | 63 | add_action( 'charitable_enable_email', array( Charitable_Emails::get_instance(), 'handle_email_settings_request' ) ); |
| 68 | 64 | add_action( 'charitable_disable_email', array( Charitable_Emails::get_instance(), 'handle_email_settings_request' ) ); |
| 65 | + | |
| 66 | +/** | |
| 67 | + * Process deferred emails scheduled during AJAX to avoid Oxygen output buffer conflicts. | |
| 68 | + * | |
| 69 | + * When Oxygen + Braintree + Recurring donations are active, email sending is deferred | |
| 70 | + * via wp_cron to prevent email HTML from contaminating the AJAX JSON response. | |
| 71 | + * | |
| 72 | + * @since 1.8.9.6 | |
| 73 | + * | |
| 74 | + * @param array $email_data Contains 'class', 'args', and 'timestamp'. | |
| 75 | + */ | |
| 76 | +add_action( 'charitable_send_deferred_email', function( $email_data ) { | |
| 77 | + if ( empty( $email_data['class'] ) || ! class_exists( $email_data['class'] ) ) { | |
| 78 | + return; | |
| 79 | + } | |
| 80 | + | |
| 81 | + $args = isset( $email_data['args'] ) ? $email_data['args'] : array(); | |
| 82 | + $class = $email_data['class']; | |
| 83 | + | |
| 84 | + // Reconstruct donation object from ID. | |
| 85 | + $donation = null; | |
| 86 | + if ( ! empty( $args['donation_id'] ) ) { | |
| 87 | + $donation = charitable_get_donation( $args['donation_id'] ); | |
| 88 | + } | |
| 89 | + | |
| 90 | + if ( ! $donation ) { | |
| 91 | + return; | |
| 92 | + } | |
| 93 | + | |
| 94 | + // Reconstruct campaign donations. | |
| 95 | + $campaign_donations = $donation->get_campaign_donations(); | |
| 96 | + | |
| 97 | + // Clean output buffers to ensure no contamination. | |
| 98 | + while ( ob_get_level() > 0 ) { | |
| 99 | + ob_end_clean(); | |
| 100 | + } | |
| 101 | + | |
| 102 | + // Instantiate and send the email. | |
| 103 | + $email_object = new $class( array( | |
| 104 | + 'donation' => $donation, | |
| 105 | + 'campaign' => ! empty( $campaign_donations ) ? charitable_get_campaign( current( $campaign_donations )->campaign_id ) : null, | |
| 106 | + ) ); | |
| 107 | + | |
| 108 | + if ( method_exists( $email_object, 'send' ) ) { | |
| 109 | + $email_object->send(); | |
| 110 | + } | |
| 111 | +} ); | |