batch_size = apply_filters('hvac_announcement_email_batch_size', 50); $this->init_hooks(); } /** * Initialize hooks */ private function init_hooks() { // Watch for status changes add_action('transition_post_status', array($this, 'handle_status_transition'), 10, 3); // Cron action for batch sending add_action('hvac_send_announcement_email_batch', array($this, 'send_email_batch'), 10, 2); } /** * Handle post status transitions * * @param string $new_status New post status * @param string $old_status Old post status * @param WP_Post $post Post object */ public function handle_status_transition($new_status, $old_status, $post) { // Only handle our post type if ($post->post_type !== HVAC_Announcements_CPT::get_post_type()) { return; } // Only send email when publishing for the first time if ($new_status === 'publish' && $old_status !== 'publish') { // Check if email was already sent for this announcement $email_sent = get_post_meta($post->ID, '_hvac_announcement_email_sent', true); if (!$email_sent) { $this->queue_announcement_emails($post->ID); } } } /** * Queue announcement emails for batch processing * * @param int $post_id Announcement post ID */ private function queue_announcement_emails($post_id) { // Get active trainers $trainers = HVAC_Announcements_Permissions::get_active_trainers(); if (empty($trainers)) { return; } // Store recipient IDs $recipient_ids = array(); foreach ($trainers as $trainer) { if (HVAC_Announcements_Permissions::user_should_receive_emails($trainer->ID)) { $recipient_ids[] = $trainer->ID; } } // Save recipient list update_post_meta($post_id, '_hvac_announcement_email_recipients', $recipient_ids); update_post_meta($post_id, '_hvac_announcement_email_send_date', current_time('mysql')); // Process in batches $batches = array_chunk($recipient_ids, $this->batch_size); foreach ($batches as $index => $batch) { // Schedule immediate sending (can be delayed using wp_schedule_single_event) wp_schedule_single_event( time() + ($index * 10), // Stagger by 10 seconds per batch 'hvac_send_announcement_email_batch', array($post_id, $batch) ); } } /** * Send email batch * * @param int $post_id Announcement post ID * @param array $recipient_ids Array of user IDs */ public function send_email_batch($post_id, $recipient_ids) { $post = get_post($post_id); if (!$post || $post->post_type !== HVAC_Announcements_CPT::get_post_type()) { return; } // Get email content $subject = $this->get_email_subject($post); $body = $this->get_email_body($post); $headers = $this->get_email_headers(); $successful_sends = array(); $failed_sends = array(); foreach ($recipient_ids as $user_id) { $user = get_user_by('id', $user_id); if (!$user || !$user->user_email) { $failed_sends[] = $user_id; continue; } // Validate email address if (!is_email($user->user_email)) { $failed_sends[] = $user_id; // Log invalid email $this->log_email_send($post_id, $user_id, 'invalid_email'); continue; } // Send email $sent = wp_mail($user->user_email, $subject, $body, $headers); if ($sent) { $successful_sends[] = $user_id; // Log successful send $this->log_email_send($post_id, $user_id, 'success'); } else { $failed_sends[] = $user_id; // Log failed send $this->log_email_send($post_id, $user_id, 'failed'); // Schedule retry (max 3 attempts) $this->maybe_schedule_retry($post_id, $user_id); } } // Mark as sent if all batches are complete $all_sent = get_post_meta($post_id, '_hvac_announcement_email_sent', true); if (!$all_sent && empty($failed_sends)) { update_post_meta($post_id, '_hvac_announcement_email_sent', true); } } /** * Get email subject * * @param WP_Post $post Announcement post * @return string */ private function get_email_subject($post) { $subject = sprintf( 'Upskill HVAC Trainer Announcement: %s', $post->post_title ); return apply_filters('hvac_announcement_email_subject', $subject, $post); } /** * Get email body * * @param WP_Post $post Announcement post * @return string */ private function get_email_body($post) { // Get template $template_path = plugin_dir_path(dirname(__FILE__)) . 'templates/email/announcement-notification.php'; if (!file_exists($template_path)) { // Fallback to simple HTML return $this->get_fallback_email_body($post); } // Start output buffering ob_start(); // Set up template variables $announcement_title = $post->post_title; $announcement_content = apply_filters('the_content', $post->post_content); $publish_date = get_the_date('F j, Y', $post); $site_url = home_url(); $resources_url = home_url('/trainer/resources/'); // Get featured image $featured_image = ''; if (has_post_thumbnail($post->ID)) { $featured_image = get_the_post_thumbnail($post->ID, 'large', array( 'style' => 'max-width: 100%; height: auto; display: block; margin: 20px 0;' )); } // Get categories and tags $categories = wp_get_post_terms($post->ID, HVAC_Announcements_CPT::get_category_taxonomy(), array('fields' => 'names')); $tags = wp_get_post_terms($post->ID, HVAC_Announcements_CPT::get_tag_taxonomy(), array('fields' => 'names')); $categories_tags = ''; if (!empty($categories) || !empty($tags)) { $categories_tags = '
Categories: ' . implode(', ', $categories) . '
'; } if (!empty($tags)) { $categories_tags .= 'Tags: ' . implode(', ', $tags) . '
'; } $categories_tags .= 'Posted on ' . get_the_date('F j, Y', $post) . '
'; // Featured image if (has_post_thumbnail($post->ID)) { $html .= get_the_post_thumbnail($post->ID, 'large', array( 'style' => 'max-width: 100%; height: auto; display: block; margin: 20px 0;' )); } // Content $html .= 'You received this email because you are registered as an HVAC Trainer.
'; $html .= ''; $html .= '