0

I have a frontend submission form, where users can add events to a custom post type. I want to send an email to each user 1 week before this event takes place.

The emails are sent via wp_cron. The function is called with a hook. It's working correctly, but I want to add custom values to the email body.

With my code its not possible to add dynamic value to the body template of my email.

With this function below, I loop through the events post type and get the required data

function leweb_get_events_detail() {

    // Query
    global $wp_query;

    // Arguments  
    $args = array(
        'post_type' => 'events',
    );

    // Start the Query
    $query = new WP_Query( $args );

    // The Loop
    if( $query->have_posts() ) {

        $results = array();

        while( $query->have_posts() ) {

            $query->the_post();             

            $event_date_timestamp = get_post_meta( get_the_ID(), 'event_date_timestamp', true );
            $future_timestamp = strtotime("+1 week");

            // Damit wird geprüft ob schon einmal diese Email gesendet wurde
            $notification = get_post_meta( get_the_ID(), 'event_creator_notification' );

            if( !in_array( '1week', $notification )  && $event_date_timestamp < $future_timestamp ) {

                $event_id = get_the_ID();
                $event_email = get_post_meta( get_the_ID(), 'event_email', true );

                $results[] = array( 
                                'event_id'      => $event_id, 
                                'event_date_timestamp' => $event_date_timestamp,
                                'event_email'     => $event_email,
                );

            }
        }

        return $results;

    }

    wp_reset_query();

}

The function below lets me fetch data from the post_meta array:

function leweb_get_values_from_post_meta( $meta = '') {

    $results = leweb_get_events_detail();

    $values = array();
    foreach( $results as $key => $value ){

        $values[] = $value[ $meta ];

    }

    return $values;
}

The function below is called from wp_cron. The email is sent to all recipients who match the above conditions and a value is added to the post meta, to prevent multiple sends of this email.

function leweb_send_mail_to_author() {


    // Alle Emails aus dem Array auslesen und für das BCC Feld im Email Header vorbereiten
    $emails = leweb_get_values_from_post_meta( 'event_email');

    if ( !empty( $emails ) ) {

        $emails = 'BCC: ' . implode( ',', $emails );

        // Email senden
        $to = '';
        $subject = 'Dein Event findet bald statt!';
        $body = file_get_contents( get_stylesheet_directory() . '/templates/email/event-creator-notification.php');
        $headers = array( 'Content-Type: text/html; charset=UTF-8','From: Example <[email protected]>', $emails );

        wp_mail( $to, $subject, $body, $headers );

        // Wert in post_meta eintragen um die Mehrfachsendung zu verhindern
        $post_id = leweb_get_values_from_post_meta( 'event_id');

        foreach( $post_id as $id ) {

            add_post_meta( $id, 'event_creator_notification', '1week' );

        }

    }

}

After I coded this I figured out. it's not possible to send dynamic content in the body of my email. The only way to achieve this, is to call the wp_mail() in foreach. But this would be heavy I think? It's possible that this job sends up to hundred emails per run in the future...

So I was wondering if there is another way to do this cleanly?

1
  • It appears this question is actually 2 questions, which wasn't made clear. Try to keep to 1 question per question, you can always link to this question for context. By bundling questions like this you severely reduce your chances of an answer as nobody will answer unless they can answer every single question you asked. Remember this is a Q&A site not a Discussion Forum, an answer needs to be able to concretely, canonically, and absolutely answer the question
    – Tom J Nowell
    Oct 25, 2019 at 15:35

1 Answer 1

2

Here's your problem:

        $body = file_get_contents( get_stylesheet_directory() . '/templates/email/event-creator-notification.php');

file_get_contents literally just gets the contents of that file. There's no PHP execution. Instead, if you want to get the output of something as a variable, use output buffers, e.g.

ob_start(); // everything echo'd after this gets put in the buffer
get_template_part( 'templates/email/event-creator-notification' );
$body = ob_get_clean(); // get the buffers contents and stop output buffering
2
  • Thank you Tom, this solution i already implemented. My bigger concern is, should i call wp_mail() everytime to send an email or should i call i once, like i did it in OP? Should i add the code, where wp_mail() is called in the query loop to my OP? Oct 25, 2019 at 15:15
  • hmm we keep questions to 1 question per question, you can always open a brand new question if you have an additional question. Remember this isn't a discussion forum or a bulletin board. Otherwise to be honest I don't see why it would or wouldn't be heavier, and if it's a concern I would just try it out and measure the time difference. I expect the difference to be statistically insignificant. Sending an email is still sending an email wether you do it in a post loop or elsewhere, there's no magical savings to be had
    – Tom J Nowell
    Oct 25, 2019 at 15:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.