Wordpress Cron doesn't fire wp_mail() but php mail() function
Asked Answered
M

1

6

I´m trying to use wp_mail in cronjob task, but no email was sent. Instead pure php function mail() works.

Question 1): Why does mail() work but wp_mail doesn't?

Question 2): Calling www.domain.de/wp-cron.php manually fires the email. But the html email body of the received email is still a string and not translated to html. Do you know why?

Searched for solutions, found some. According to this post (Cron job in WordPress not working), I setup my cronjob like this:

Setup a custom interval:

function example_add_cron_interval( $schedules ) {
$schedules['five_seconds'] = array(
    'interval' => 5,
    'display'  => esc_html__( 'Every Five Seconds' ),
);
$schedules['daily'] = array(
    'display' => esc_html__( 'Once Daily' ) 
);
return $schedules;
}
add_filter( 'cron_schedules', 'example_add_cron_interval', 999 );

activate cronjob:

function cron_activation() {
    if( !wp_next_scheduled( 'dbs_cron_hook' ) ) {  
        wp_schedule_event(time(), 'daily', 'dbs_cron_hook' );  
    }
}
add_action('init', 'cron_activation');

Do logic: function my_task_function() {

$max_hours = 336; // entspricht 2 Wochen
global $post;
$args = array( 'post_type' => 'bookings', );
$booking_listing = new WP_Query( $args );
$mail_body = '<table>';

if( $booking_listing->have_posts() ) :
    while( $booking_listing->have_posts() ) : $booking_listing->the_post();

        $post_id = get_the_ID();
        $email_sent_timestamp = intval( get_post_meta( $post_id, 'approvement_email_sent', true ) );
        $event_id = intval( get_post_meta( $post_id, 'event_id', true ) );

        if( $email_sent_timestamp != 0 ){

            $date = date_create();
            $now_timestamp = date_timestamp_get($date);
            $hoursPassed = diff_timestamp( $now_timestamp, $email_sent_timestamp );

            var_dump($hoursPassed["full_hours"] >= $max_hours);

            if( $hoursPassed >=  $max_hours ){

                update_post_meta( $event_id, 'event_reserved', intval(0) );
                $mail_body .= '<tr><td>BuchungsNr ' . $post_id . ': 2 Wochen sind abgelaufen.</td></tr><tr><td>Der Termin ' . $event_id . ' wurde wieder aktiviert.</td></tr>';

            }
        }

    endwhile;
else:
    wp_send_json_error( "No events found" );
endif;

$mail_body .= '</table>';

var_dump($max_hours);

// wp_mail( '[email protected]', 'Rervierung ' . $post_id . ' abgelaufen', $mail_body );

mail( '[email protected]', 'Rervierung ' . $post_id . ' abgelaufen', $mail_body );

}
add_action( 'dbs_cron_hook', 'my_task_function' );

I disabled wp cron in config.php like this define('DISABLE_WP_CRON', true);

And setup a system cronjob on the server like this * */1 * * * /vrmd/webserver/php70/bin/php-cli /homepages/xxxxxx/wp-cron.php > /dev/null Hope you can help me.

EDIT to Question 2: just use $headers in mail() function

$headers = "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: text/html; charset=UTF-8\r\n";
mail( $to, $subject, $mail_body, $headers );

Question 1 still wondering...

Mythical answered 27/4, 2018 at 7:38 Comment(0)
R
0

For your first question: If I understand your question and edit right, you are asking, why wp_mail() does not work in an "plain" cron-job, whereas it does, if you use it the wordpress-way, with a filter hook.

So, if you fire the cronjob via the wordpress filter, wordpress gets bootstraped and all the internal things, which wordpress do, run. If you just have an custom cronjob, the wordpress core never gets loaded, so wp_mail() can not work.

One possible way around this problem would be to call manually an require(wp-load.php);

Rorqual answered 19/8, 2024 at 14:40 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.