feat(06-03): implement async batch email processor callback
Add process_mentor_notification_batch() method to process Action Scheduler callbacks. Sends German email notifications with job details (title, location, type, permalink) to batches of opted-in mentors. Includes rate limit delay (0.1s between emails), error logging for failures, and unsubscribe hint in email body. Registered callback for 'ddhh_jm_send_mentor_notification_batch' hook. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -22,7 +22,8 @@ class DDHH_JM_Scheduler {
|
|||||||
* Initialize hooks.
|
* Initialize hooks.
|
||||||
*/
|
*/
|
||||||
public static function setup_hooks() {
|
public static function setup_hooks() {
|
||||||
// Phase 06-03 will register async action callbacks here.
|
// Register async action callback for mentor notification batches
|
||||||
|
add_action( 'ddhh_jm_send_mentor_notification_batch', array( __CLASS__, 'process_mentor_notification_batch' ), 10, 2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -81,4 +82,109 @@ class DDHH_JM_Scheduler {
|
|||||||
|
|
||||||
return $batch_count;
|
return $batch_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process mentor notification batch (async callback).
|
||||||
|
*
|
||||||
|
* Sends emails to batch of users about a newly published job.
|
||||||
|
* Includes rate limiting delay between sends to avoid provider limits.
|
||||||
|
*
|
||||||
|
* @param array $user_ids Array of user IDs in this batch.
|
||||||
|
* @param int $job_id Job post ID.
|
||||||
|
*/
|
||||||
|
public static function process_mentor_notification_batch( $user_ids, $job_id ) {
|
||||||
|
// Validate inputs
|
||||||
|
if ( empty( $user_ids ) || empty( $job_id ) ) {
|
||||||
|
error_log( 'DDHH_JM_Scheduler: Cannot process batch - missing user IDs or job ID' );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get job post
|
||||||
|
$post = get_post( $job_id );
|
||||||
|
if ( ! $post || 'job_offer' !== $post->post_type ) {
|
||||||
|
error_log( sprintf( 'DDHH_JM_Scheduler: Invalid job_id %d in batch processing', $job_id ) );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get job details
|
||||||
|
$job_title = $post->post_title;
|
||||||
|
$job_location = get_field( 'job_location', $job_id );
|
||||||
|
$job_type = get_field( 'job_type', $job_id );
|
||||||
|
$job_link = get_permalink( $job_id );
|
||||||
|
|
||||||
|
// Track successful sends
|
||||||
|
$sent_count = 0;
|
||||||
|
|
||||||
|
// Process each user in batch
|
||||||
|
foreach ( $user_ids as $user_id ) {
|
||||||
|
// Get user data
|
||||||
|
$user = get_userdata( $user_id );
|
||||||
|
if ( ! $user ) {
|
||||||
|
error_log( sprintf( 'DDHH_JM_Scheduler: User ID %d not found, skipping', $user_id ) );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get user email
|
||||||
|
$user_email = $user->user_email;
|
||||||
|
if ( empty( $user_email ) ) {
|
||||||
|
error_log( sprintf( 'DDHH_JM_Scheduler: User ID %d has no email, skipping', $user_id ) );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare German email subject
|
||||||
|
$subject = sprintf( 'Neues Stellenangebot: %s', $job_title );
|
||||||
|
|
||||||
|
// Prepare German email body
|
||||||
|
$body = sprintf(
|
||||||
|
"Hallo,\n\n" .
|
||||||
|
"ein neues Stellenangebot wurde veröffentlicht:\n\n" .
|
||||||
|
"Stelle: %s\n" .
|
||||||
|
"Standort: %s\n" .
|
||||||
|
"Art: %s\n\n" .
|
||||||
|
"Sie können das Angebot hier ansehen:\n%s\n\n" .
|
||||||
|
"Um keine weiteren Benachrichtigungen zu erhalten, können Sie diese in Ihrem Profil deaktivieren.\n\n" .
|
||||||
|
"---\n" .
|
||||||
|
"Diese E-Mail wurde automatisch gesendet.",
|
||||||
|
$job_title,
|
||||||
|
$job_location ? $job_location : 'Nicht angegeben',
|
||||||
|
$job_type ? $job_type : 'Nicht angegeben',
|
||||||
|
$job_link
|
||||||
|
);
|
||||||
|
|
||||||
|
// Set email headers
|
||||||
|
$headers = array( 'Content-Type: text/html; charset=UTF-8' );
|
||||||
|
|
||||||
|
// Convert plain text to HTML with line breaks
|
||||||
|
$html_body = nl2br( esc_html( $body ) );
|
||||||
|
|
||||||
|
// Send email
|
||||||
|
$sent = wp_mail( $user_email, $subject, $html_body, $headers );
|
||||||
|
|
||||||
|
// Log failures
|
||||||
|
if ( ! $sent ) {
|
||||||
|
error_log(
|
||||||
|
sprintf(
|
||||||
|
'DDHH_JM_Scheduler: Failed to send mentor notification to user %d for job %d',
|
||||||
|
$user_id,
|
||||||
|
$job_id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$sent_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rate limit delay: 0.1 seconds between emails
|
||||||
|
usleep( 100000 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log batch completion
|
||||||
|
error_log(
|
||||||
|
sprintf(
|
||||||
|
'DDHH_JM_Scheduler: Processed notification batch: %d emails sent for job %d "%s"',
|
||||||
|
$sent_count,
|
||||||
|
$job_id,
|
||||||
|
$job_title
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user