From 6a2914f5fcc8d546b97e843ea8ee85e25b1b2e48 Mon Sep 17 00:00:00 2001 From: Viktor Miller Date: Wed, 14 Jan 2026 21:09:01 +0900 Subject: [PATCH] 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 --- includes/class-scheduler.php | 108 ++++++++++++++++++++++++++++++++++- 1 file changed, 107 insertions(+), 1 deletion(-) diff --git a/includes/class-scheduler.php b/includes/class-scheduler.php index 565059a..9760837 100644 --- a/includes/class-scheduler.php +++ b/includes/class-scheduler.php @@ -22,7 +22,8 @@ class DDHH_JM_Scheduler { * Initialize 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; } + + /** + * 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 + ) + ); + } }