get_results($wpdb->prepare( "SELECT ID, post_title, post_date FROM {$wpdb->posts} WHERE post_type = 'tribe_events' AND post_author = %d AND post_status = 'publish' ORDER BY post_date DESC", $current_user_id )); // If event is selected, get attendees if ($event_id > 0) { // Verify the event belongs to the current user $event_found = false; foreach ($events as $event) { if ($event->ID == $event_id) { $event_found = true; $selected_event_title = $event->post_title; break; } } if ($event_found) { // Get attendees using the same query as the AJAX handler $attendees = $wpdb->get_results($wpdb->prepare( "SELECT p.ID as attendee_id, p.post_parent as event_id, COALESCE(tec_full_name.meta_value, tpp_full_name.meta_value, tickets_full_name.meta_value, 'Unknown Attendee') as holder_name, COALESCE(tec_email.meta_value, tpp_email.meta_value, tickets_email.meta_value, tpp_attendee_email.meta_value, 'no-email@example.com') as holder_email, COALESCE(checked_in.meta_value, '0') as check_in FROM {$wpdb->posts} p LEFT JOIN {$wpdb->postmeta} tec_full_name ON p.ID = tec_full_name.post_id AND tec_full_name.meta_key = '_tec_tickets_commerce_full_name' LEFT JOIN {$wpdb->postmeta} tpp_full_name ON p.ID = tpp_full_name.post_id AND tpp_full_name.meta_key = '_tribe_tpp_full_name' LEFT JOIN {$wpdb->postmeta} tickets_full_name ON p.ID = tickets_full_name.post_id AND tickets_full_name.meta_key = '_tribe_tickets_full_name' LEFT JOIN {$wpdb->postmeta} tec_email ON p.ID = tec_email.post_id AND tec_email.meta_key = '_tec_tickets_commerce_email' LEFT JOIN {$wpdb->postmeta} tpp_email ON p.ID = tpp_email.post_id AND tpp_email.meta_key = '_tribe_tpp_email' LEFT JOIN {$wpdb->postmeta} tickets_email ON p.ID = tickets_email.post_id AND tickets_email.meta_key = '_tribe_tickets_email' LEFT JOIN {$wpdb->postmeta} tpp_attendee_email ON p.ID = tpp_attendee_email.post_id AND tpp_attendee_email.meta_key = '_tribe_tpp_attendee_email' LEFT JOIN {$wpdb->postmeta} checked_in ON p.ID = checked_in.post_id AND checked_in.meta_key = '_tribe_tickets_attendee_checked_in' WHERE p.post_type IN ('tec_tc_attendee', 'tribe_tpp_attendees') AND p.post_parent = %d ORDER BY p.ID ASC", $event_id )); // Check certificate status for each attendee if (!empty($attendees) && class_exists('HVAC_Certificate_Manager')) { $certificate_manager = HVAC_Certificate_Manager::instance(); foreach ($attendees as $attendee) { // Get the actual certificate data, not just boolean $certificate = $certificate_manager->get_certificate_by_attendee($event_id, $attendee->attendee_id); $attendee->has_certificate = !empty($certificate); $attendee->certificate_data = $certificate; } } // Log for debugging if needed if (defined('WP_DEBUG') && WP_DEBUG) { error_log('Generate Certificates - Event ID: ' . $event_id . ', Attendees: ' . count($attendees)); } } } } catch (Exception $e) { error_log('Generate Certificates Error: ' . $e->getMessage()); } ?>
render_trainer_menu(); } ?> render_breadcrumbs(); } ?>

Generate Certificates

Generate certificates for attendees of your events.

Step 1: Select Event

You don't have any events yet. Create your first event to start generating certificates.

Create Event

0) : ?>

Step 2: Select Attendees for ""

This event has no attendees yet.

Attendees are created when people register for your event through the ticket system.

has_certificate)) { $has_certificate_count++; } } if ($has_certificate_count > 0) : ?>

Note: attendee(s) already have certificates. These will be skipped to prevent duplicates.

Attendees with existing certificates are marked with ✓ and cannot be selected.

check_in); $checked_in_class = $checked_in ? 'hvac-checked-in' : ''; $status_class = $checked_in ? 'hvac-status-checked-in' : 'hvac-status-not-checked-in'; $status_text = $checked_in ? 'Checked In' : 'Not Checked In'; $attendee_name = $attendee->holder_name ?: 'Unknown'; $attendee_email = $attendee->holder_email ?: 'No email'; $has_certificate = !empty($attendee->has_certificate); $cert_status_class = $has_certificate ? 'hvac-has-certificate' : ''; ?>
Attendee Name Email Check-in Status Certificate Status
> certificate_data)) : ?> $attendee->certificate_data->file_path, 'event_name' => $selected_event_title, 'attendee_name' => $attendee_name, 'certificate_id' => $attendee->certificate_data->certificate_id ); $certificate_url = $security->generate_download_token( $attendee->certificate_data->certificate_id, $cert_data, 3600 // 1 hour validity ); } ?> Certificate Issued Certificate Issued No Certificate