0

I've created a function to send an email each week, but it doesn't seem to work and I don't know why. In addition I have several doubts because of my lack of experience with wp_cron and wp_mail, so here's what I need and my doubts, and below my code:

  1. Set a weekly recurring event. (link)
  2. Schedule the event to start 2016/10/10 at 5pm UTF, and only fire once a week. (I already scheduled it for this morning for testing purposes, that's how I know it isn't working). I am not sure if it will fire every week or each time the site gets a visit.
  3. Get the users and check every field if is complete.
  4. Send an email if one of the fields is not complete.
  5. Set the email parameters as shown below.

First:

/**
 * Weekly schedule for WordPress
 */
function intervalo_semanal_para_emails( $schedules ) {
  // add a 'weekly' schedule to the existing set
  $schedules['weekly'] = array(
    'interval' => 604800,
    'display' => __('Once Weekly')
  );
  return $schedules;
}
add_filter( 'cron_schedules', 'intervalo_semanal_para_emails' ); 

Second:

/**
 * Get the Users and send an email each monday
 */

// schedule the enviar_email_a_preparadores event only once
if( !wp_next_scheduled( 'enviar_email_a_preparadores' ) ) {
   wp_schedule_event( 1476118800, 'weekly', 'enviar_email_a_preparadores' );
}

Third, and the rest:

add_action( 'enviar_email_a_preparadores', 'send_email_to_uncompleted_profiles' );
function send_email_to_uncompleted_profiles() {

  $preparadores = get_users( array( 'role__in' => 'preparador' ) );

  foreach ( $preparadores as $preparador ) {

    /* Get the ACF ID to retrieve the custom fields */
    $user_id_acf = 'user_'.$preparador->ID; /* I use ACF for some fields */

    /* Get the User Alias */
    $alias_author = get_the_author_meta( 'nickname', $preparador->ID );

    /* 
     * Check if the fields are complete, if not, store as variables to use in the Mail Function
     */

    // Descripción Breve
    if (!get_field('descripcion_breve', $user_id_acf)) {
      $descripcion_breve = "<strong>Descripción breve</strong>: Por favor, añade una descripción breve a tu perfil.";
    }

    // Titulación del preparador
    if (!get_field('titulacion_preparador', $user_id_acf)) {
      $titulacion_preparador = "<strong>Titulación</strong>: Por favor, añade cual es tu titulación.";
    }

    // Alias del Preparador
    if (empty($alias_author)) {
      $alias_preparador = "<strong>Alias</strong>: Por favor, añade un Alias a tu perfil para que te identifiquen.";
    }

    // Experiencia del Preparador
    if (!get_field('experiencia_desde', $user_id_acf)) {
      $experiencia_desde = "<strong>Experiencia desde</strong>: Indica desde cuando tienes experiencia como preparador.";
    }

    // Precio/Hora
    if (!get_field('precio_hora_preparador', $user_id_acf)) {
      $precio_hora_preparador = "<strong>Precio/hora</strong>: Por favor, añade un precio/hora aproximado.";
    }

    // Conocimiento Interno del Organismo Convocante
    if (!get_field('conocimiento_interno', $user_id_acf)) {
      $conocimiento_interno = "<strong>Conocimiento Interno</strong>: Por favor, indica si tienes conocimiento de la plaza para la que preparas.";
    }

    // Comprobar si los campos estan completos para no hacer nada
    if ( 
      get_field('descripcion_breve', $user_id_acf) &&
      get_field('titulacion_preparador', $user_id_acf) &&
      empty($alias_author) &&
      get_field('experiencia_desde', $user_id_acf) &&
      get_field('precio_hora_preparador', $user_id_acf) &&
      get_field('conocimiento_interno', $user_id_acf)
    ) {
      return;
    } else {

      $to = $preparador->user_email;
      $subject = 'Por favor, actualiza tu perfil';
      $message = '<p>Hola ' . $current_user->user_login . '</p>';
      $message .= '<p>Nos ponemos en contacto contigo para avisarte del estado de tu perfil, recuerda que completarlo es necesario para que este se publique y genere interés entre los opositores. A continuación te detallamos los campos que faltan por rellenar:</p>'
      $message .= '<ul>';
      $message .= if (!get_field('descripcion_breve', $user_id_acf)) {
        echo '<li>' . $descripcion_breve . '</li>';
      }
      $message .= if (!get_field('titulacion_preparador', $user_id_acf)) {
        echo '<li>' . $titulacion_preparador . '</li>';
      }
      $message .= if (empty($alias_author)) {
        echo '<li>' . $alias_preparador . '</li>';
      }
      $message .= if (!get_field('experiencia_desde', $user_id_acf)) {
        echo '<li>' . $experiencia_desde . '</li>';
      }
      $message .= if (!get_field('precio_hora_preparador', $user_id_acf)) {
        echo '<li>' . $precio_hora_preparador . '</li>';
      }
      $message .= if (!get_field('conocimiento_interno', $user_id_acf)) {
        echo '<li>' . $conocimiento_interno . '</li>';
      }
      $message .= '</ul>';
      $message .= '<p>Por favor, no respondas a este mensaje. Si necesitas ayuda accede a la <a href="example.com/help/">guía de preparadores</a> o ponte en <a href="example.com/contacto/">contacto</a>.';

      $headers[] = 'From: Myname.com <info@example.com>;' . '\r\n';
      $headers[] = 'Bcc: My name <myemail@example.com>'; /* To check if the emails is arriving and how it arrives.*/
      $headers[] = array('Content-Type: text/html; charset=UTF-8');

      wp_mail( $to, $subject, $message, $headers );
    }
  }
}
  • 1
    "I doesn't seem to work" is a bit vague. What doesn't work? You should be able, by echoing intermediate results, to establish where things go wrong. Does the cron job fire? Can you get an email to be send? Are the conditions for sending met? – cjbj Oct 3 '16 at 8:52
  • You're right. Please how can I debug it? @cjbj – Kevin Mamaqi Oct 3 '16 at 8:57
  • 1
    Sorry, this is not the place to give you a private debugging course. The general trick is to put a lot of echo and var_dump statements in your code, run it and see where the output is not what you expected. – cjbj Oct 3 '16 at 9:07
  • I've updated the answer, using echo and if in value Assignment will cause a PHP Fatal Error; it is a not valid syntax. – cybmeta Oct 3 '16 at 16:20
1

At first view, the schefuled task code in your code seems ok. I just would suggest to introduce scheduled tasks clearing on plugin deactivation; this is useful for several reasons and one of them can be the origin of your problem: if you was testing, the scheduled event can be already set and this snippet in your code has no effect to schedule the event again:

if( ! wp_next_scheduled( 'enviar_email_a_preparadores' ) ) {
   wp_schedule_event( 1476118800, 'weekly', 'enviar_email_a_preparadores' );
}

This code should work:

add_filter( 'cron_schedules', 'intervalo_semanal_para_emails' );
function intervalo_semanal_para_emails( $schedules ) {

  $schedules['weekly'] = array(
    'interval' => 604800,
    'display' => __('Once Weekly')
  );

  return $schedules;

}

register_activation_hook( __FILE__, 'cyb_activation' );
function cyb_activation() {
    // Add a scheduled task on plugin activation
    // Fist run at 2016-10-10 17:00:00 UTC
    $time = new DateTime( "2016-10-10 17:00:00", new DateTimeZone( 'UTC' ) );
    if( ! wp_next_scheduled( 'cyb_weekly_event' ) ) {
        wp_schedule_event( $time->getTimestamp(), 'weekly', 'cyb_weekly_event' );
    }

}

register_deactivation_hook( __FILE__, 'cyb_deactivation' );
function cyb_deactivation() {
    // Remove scheduled task on plugin deactivation
    wp_clear_scheduled_hook( 'cyb_weekly_event' );
}

// Hook a task to the scheduled event
add_action( 'cyb_weekly_event', 'send_email_to_uncompleted_profiles' );
function send_email_to_uncompleted_profiles() {
    // log a message to test.
    // Check error.log file in your server
    // See error_log() docuemntation if you want to
    // set a custom error.log file path
    error_log( 'Test!!' );

    /*
    if( true === $condition_to_send_email ) {
        wp_mail( ... );
    }
    */

}

Once you have set up the cron and check that it is working, you can start with the send mail test.

Unfortunately the code you posted include code for third party plugins and can not be tested as it is (also, third party plugins are off-topic here); anyway, you are echoing data and using if inside a value assigment. That makes your code to crash because a PHP syntax fatal error; for example, this code in your answer is wrong:

  $message .= '<ul>';
  $message .= if (! get_field('descripcion_breve', $user_id_acf)) {
    echo '<li>' . $descripcion_breve . '</li>';
  }

There are several ways to concatenate strings, for exmaple, a simple option:

  $message .= '<ul>';
  if ( ! get_field( 'descripcion_breve', $user_id_acf ) ) {
    $message .=  '<li>' . $descripcion_breve . '</li>';
  }

I hope you see the difference.

  • 1
    Crystal clear @cybmeta. Thank you. I'm still debugging it and I will come back as soon as it works. – Kevin Mamaqi Oct 4 '16 at 8:00
  • Nothing, it wont send. Apart from that I am using it in theme functions.php, it is not a plugin so I really don't understand why the activate/deactivate thing. It is for plugins, right? – Kevin Mamaqi Oct 10 '16 at 18:43
  • I would suggest to use a plugin for such kind of functionality; it is a plugin territory in my opinion. Anyway, we still don't know what fails, if it is the cron job not being triggered or if it is the email sending function. You should debug it and provide that info. – cybmeta Oct 11 '16 at 6:53
  • Thanks again @cybmeta, the error was here: $headers[] = 'From: Myname.com <info@example.com> ; ' . '\r\n'; - the semicolon ;. Yet I don't know if wp-cron is working properly or not. – Kevin Mamaqi Oct 11 '16 at 6:57
  • About clearing cron jobs on plugin deactivation: WordPress cron jobs are stored in database; if you don't clear your cron job on plugin deactivation, it will remain in the database. Also, let's see your code; if you set a cron job, while the cron job is enqueued, if( ! wp_next_scheduled( 'cyb_weekly_event' ) ) fails and ` wp_schedule_event( 'cyb_weekly_event' ) is not executed again. That's good, but if you want to set the cron job again with different properties, then you need to clear the previous cron job first or wp_schedule_event() want be executed again with the new properties. – cybmeta Oct 11 '16 at 7:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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