Skip to:
Content

BuddyPress.org


Ignore:
Timestamp:
01/27/2016 09:12:25 PM (7 years ago)
Author:
djpaul
Message:

Emails: introducing bp_send_email, which is our replacement for wp_mail.

As wp_mail is a pluggable function, if we detect it has been re-declared, or if something has filtered to enable HTML emails, BuddyPress will fallback and let wp_mail send the email for us. This maintains compatibility for customised sites until mail delivery plugins are updated to work with BuddyPress (or new plugins are written).

See #6592. Props timersys, mercime, boonebgorges, hnla, DJPaul.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/bp-core/bp-core-functions.php

    r10474 r10478  
    27472747    ) );
    27482748}
     2749
     2750
     2751/** Email *****************************************************************/
     2752
     2753/**
     2754 * Get an BP_Email object for the specified email type.
     2755 *
     2756 * This function pre-populates the object with the subject, content, and template from the appropriate
     2757 * email post type item. It does not replace placeholder tokens in the content with real values.
     2758 *
     2759 * @since 2.5.0
     2760 *
     2761 * @param string $email_type Unique identifier for a particular type of email.
     2762 * @return BP_Email|WP_Error BP_Email object, or WP_Error if there was a problem.
     2763 */
     2764function bp_get_email( $email_type ) {
     2765    $args = array(
     2766        'no_found_rows'    => true,
     2767        'numberposts'      => 1,
     2768        'post_status'      => 'publish',
     2769        'post_type'        => bp_get_email_post_type(),
     2770        'suppress_filters' => false,
     2771
     2772        'tax_query'        => array(
     2773            array(
     2774                'field'    => 'slug',
     2775                'taxonomy' => bp_get_email_tax_type(),
     2776                'terms'    => $email_type,
     2777            )
     2778        ),
     2779    );
     2780
     2781    /**
     2782     * Filters arguments used to find an email post type object.
     2783     *
     2784     * @since 2.5.0
     2785     *
     2786     * @param array  $args       Arguments for get_posts() used to fetch a post object.
     2787     * @param string $email_type Unique identifier for a particular type of email.
     2788     */
     2789    $args = apply_filters( 'bp_get_email_args', $args, $email_type );
     2790    $post = get_posts( $args );
     2791    if ( ! $post ) {
     2792        return new WP_Error( 'missing_email', __FUNCTION__, array( $email_type, $args ) );
     2793    }
     2794
     2795    /**
     2796     * Filters arguments used to create the BP_Email object.
     2797     *
     2798     * @since 2.5.0
     2799     *
     2800     * @param WP_Post $post       Post object containing the contents of the email.
     2801     * @param string  $email_type Unique identifier for a particular type of email.
     2802     * @param array   $args       Arguments used with get_posts() to fetch a post object.
     2803     * @param WP_Post[] All posts retrieved by get_posts( $args ). May only contain $post.
     2804     */
     2805    $post  = apply_filters( 'bp_get_email_post', $post[0], $email_type, $args, $post );
     2806    $email = new BP_Email( $email_type );
     2807
     2808
     2809    /*
     2810     * Set some email properties for convenience.
     2811     */
     2812
     2813    // Post object (sets subject, content, template).
     2814    $email->set_post_object( $post );
     2815
     2816    /**
     2817     * Filters the BP_Email object returned by bp_get_email().
     2818     *
     2819     * @since 2.5.0
     2820     *
     2821     * @param BP_Email $email      An object representing a single email, ready for mailing.
     2822     * @param WP_Post  $post       Post object containing the contents of the email.
     2823     * @param string   $email_type Unique identifier for a particular type of email.
     2824     * @param array    $args       Arguments used with get_posts() to fetch a post object.
     2825     * @param WP_Post[] All posts retrieved by get_posts( $args ). May only contain $post.
     2826     */
     2827    return apply_filters( 'bp_get_email', $email, $email_type, $args, $post );
     2828}
     2829
     2830/**
     2831 * Send email, similar to WordPress' wp_mail().
     2832 *
     2833 * A true return value does not automatically mean that the user received the
     2834 * email successfully. It just only means that the method used was able to
     2835 * process the request without any errors.
     2836 *
     2837 * @since 2.5.0
     2838 *
     2839 * @param string $email_type Type of email being sent.
     2840 * @param string|array|int|WP_User $to Either a email address, user ID, WP_User object,
     2841 *                                     or an array containg the address and name.
     2842 * @param array $args {
     2843 *     Optional. Array of extra. parameters.
     2844 *
     2845 *     @type array $tokens Optional. Assocative arrays of string replacements for the email.
     2846 * }
     2847 * @return bool|WP_Error True if the email was sent successfully. Otherwise, a WP_Error object
     2848 *                       describing why the email failed to send. The contents will vary based
     2849 *                       on the email delivery class you are using.
     2850 */
     2851function bp_send_email( $email_type, $to, $args = array() ) {
     2852    static $is_default_wpmail = null;
     2853    static $wp_html_emails    = null;
     2854
     2855    // Has wp_mail() been filtered to send HTML emails?
     2856    if ( is_null( $wp_html_emails ) ) {
     2857        /** This filter is documented in wp-includes/pluggable.php */
     2858        $wp_html_emails = apply_filters( 'wp_mail_content_type', 'text/plain' ) === 'text/html';
     2859    }
     2860
     2861    // wp_mail() is a pluggable function. Has it been re-defined by another plugin?
     2862    if ( is_null( $is_default_wpmail ) ) {
     2863        try {
     2864            $mirror            = new ReflectionFunction( 'wp_mail' );
     2865            $is_default_wpmail = substr( $mirror->getFileName(), -strlen( 'pluggable.php' ) ) === 'pluggable.php';
     2866        } catch ( Exception $e ) {
     2867            $is_default_wpmail = true;
     2868        }
     2869    }
     2870
     2871    $args = bp_parse_args( $args, array(
     2872        'tokens' => array(),
     2873    ), 'send_email' );
     2874
     2875
     2876    /*
     2877     * Build the email.
     2878     */
     2879
     2880    $email = bp_get_email( $email_type );
     2881    if ( is_wp_error( $email ) ) {
     2882        return $email;
     2883    }
     2884
     2885    // From, subject, content are set automatically.
     2886    $email->set_to( $to );
     2887    $email->set_tokens( $args['tokens'] );
     2888
     2889    $status = $email->validate();
     2890    if ( is_wp_error( $status ) ) {
     2891        return $status;
     2892    }
     2893
     2894    /**
     2895     * Filter this to skip BP's email handling and instead send everything to wp_mail().
     2896     *
     2897     * This is done if wp_mail_content_type() has been configured for HTML,
     2898     * or if wp_mail() has been redeclared (it's a pluggable function).
     2899     *
     2900     * @since 2.5.0
     2901     *
     2902     * @param bool $use_wp_mail Whether to fallback to the regular wp_mail() function or not.
     2903     */
     2904    $must_use_wpmail = apply_filters( 'bp_mail_use_wp_mail', $wp_html_emails || ! $is_default_wpmail );
     2905
     2906    if ( $must_use_wpmail ) {
     2907        $to = $email->get( 'to' );
     2908
     2909        return wp_mail(
     2910            array_shift( $to )->get_address(),
     2911            $email->get( 'subject', 'replace-tokens' ),
     2912            $email->get( 'content_plaintext', 'replace-tokens' )
     2913        );
     2914    }
     2915
     2916
     2917    /*
     2918     * Send the email.
     2919     */
     2920
     2921    /**
     2922     * Filter the email delivery class.
     2923     *
     2924     * Defaults to BP_PHPMailer, which as you can guess, implements PHPMailer.
     2925     *
     2926     * @since 2.5.0
     2927     *
     2928     * @param string $deliver_class The email delivery class name.
     2929     * @param string $email_type Type of email being sent.
     2930     * @param string[]|string $to Array or comma-separated list of email addresses to the email to.
     2931     * @param array $args {
     2932     *     Optional. Array of extra parameters.
     2933     *
     2934     *     @type array $tokens Optional. Assocative arrays of string replacements for the email.
     2935     * }
     2936     */
     2937    $delivery_class = apply_filters( 'bp_send_email_delivery_class', 'BP_PHPMailer', $email_type, $to, $args );
     2938    if ( ! class_exists( $delivery_class ) ) {
     2939        return new WP_Error( 'missing_class', __CLASS__, $this );
     2940    }
     2941
     2942    $delivery = new $delivery_class();
     2943    $status   = $delivery->bp_email( $email );
     2944
     2945    if ( is_wp_error( $status ) ) {
     2946        /**
     2947         * Fires after BuddyPress has tried - and failed - to send an email.
     2948         *
     2949         * @since 2.5.0
     2950         *
     2951         * @param WP_Error $status A WP_Error object describing why the email failed to send. The contents
     2952         *                         will vary based on the email delivery class you are using.
     2953         * @param BP_Email $email The email we tried to send.
     2954         */
     2955        do_action( 'bp_send_email_failure', $status, $email );
     2956
     2957    } else {
     2958        /**
     2959         * Fires after BuddyPress has succesfully sent an email.
     2960         *
     2961         * @since 2.5.0
     2962         *
     2963         * @param bool $status True if the email was sent successfully.
     2964         * @param BP_Email $email The email sent.
     2965         */
     2966        do_action( 'bp_send_email_success', $status, $email );
     2967    }
     2968
     2969    return $status;
     2970}
     2971
    27492972/**
    27502973 * Return email appearance settings.
Note: See TracChangeset for help on using the changeset viewer.