feat: Enhance certificate design with logo, trainer name, and improved attendee name retrieval
- Add Upskill HVAC logo support with multiple fallback paths - Display instructor/trainer name prominently on certificates - Fix attendee name retrieval by checking all possible meta keys used by TEC plugins - Improve certificate layout with decorative elements - Increase attendee name font size for better visibility - Add comprehensive fallbacks for missing attendee data Co-Authored-By: Ben Reed <ben@tealmaker.com>
This commit is contained in:
parent
3ea3135468
commit
9e44217c5e
1 changed files with 225 additions and 40 deletions
|
|
@ -337,23 +337,26 @@ class HVAC_Certificate_Generator {
|
||||||
// Set background image if available
|
// Set background image if available
|
||||||
$this->add_certificate_background($pdf);
|
$this->add_certificate_background($pdf);
|
||||||
|
|
||||||
|
// Add Upskill HVAC logo at the top
|
||||||
|
$this->add_upskill_logo($pdf);
|
||||||
|
|
||||||
// Certificate title
|
// Certificate title
|
||||||
$pdf->SetFont('helvetica', 'B', 30);
|
$pdf->SetFont('helvetica', 'B', 30);
|
||||||
$pdf->SetTextColor(0, 77, 155); // Blue
|
$pdf->SetTextColor(0, 77, 155); // Blue
|
||||||
$pdf->SetY(30);
|
$pdf->SetY(45); // Moved down to accommodate logo
|
||||||
$pdf->Cell(0, 20, 'CERTIFICATE OF COMPLETION', 0, 1, 'C');
|
$pdf->Cell(0, 20, 'CERTIFICATE OF COMPLETION', 0, 1, 'C');
|
||||||
|
|
||||||
// Description text
|
// Description text
|
||||||
$pdf->SetFont('helvetica', '', 12);
|
$pdf->SetFont('helvetica', '', 12);
|
||||||
$pdf->SetTextColor(77, 77, 77); // Dark gray
|
$pdf->SetTextColor(77, 77, 77); // Dark gray
|
||||||
$pdf->SetY(55);
|
$pdf->SetY(70);
|
||||||
$pdf->Cell(0, 10, 'This certificate is awarded to', 0, 1, 'C');
|
$pdf->Cell(0, 10, 'This certificate is awarded to', 0, 1, 'C');
|
||||||
|
|
||||||
// Attendee name
|
// Attendee name - prominently displayed
|
||||||
$attendee_name = $certificate_data['attendee_name'] ?? 'Attendee Name';
|
$attendee_name = $certificate_data['attendee_name'] ?? 'Attendee Name';
|
||||||
$pdf->SetFont('helvetica', 'B', 24);
|
$pdf->SetFont('helvetica', 'B', 26);
|
||||||
$pdf->SetTextColor(0, 0, 0); // Black
|
$pdf->SetTextColor(0, 0, 0); // Black
|
||||||
$pdf->Cell(0, 15, $attendee_name, 0, 1, 'C');
|
$pdf->Cell(0, 20, $attendee_name, 0, 1, 'C');
|
||||||
|
|
||||||
// Course completion text
|
// Course completion text
|
||||||
$pdf->SetFont('helvetica', '', 12);
|
$pdf->SetFont('helvetica', '', 12);
|
||||||
|
|
@ -372,44 +375,52 @@ class HVAC_Certificate_Generator {
|
||||||
$pdf->SetTextColor(77, 77, 77); // Dark gray
|
$pdf->SetTextColor(77, 77, 77); // Dark gray
|
||||||
$pdf->Cell(0, 10, 'on ' . $event_date, 0, 1, 'C');
|
$pdf->Cell(0, 10, 'on ' . $event_date, 0, 1, 'C');
|
||||||
|
|
||||||
// Draw a line
|
// Get instructor/trainer name properly
|
||||||
|
$instructor_name = $certificate_data['instructor_name'] ?? '';
|
||||||
|
if (empty($instructor_name) && !empty($certificate_data['trainer_name'])) {
|
||||||
|
$instructor_name = $certificate_data['trainer_name'];
|
||||||
|
}
|
||||||
|
if (empty($instructor_name)) {
|
||||||
|
// Try to get from event organizer
|
||||||
|
$instructor_name = $certificate_data['organization_name'] ?? 'Instructor';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw a line for signature
|
||||||
$pdf->SetDrawColor(0, 77, 155); // Blue
|
$pdf->SetDrawColor(0, 77, 155); // Blue
|
||||||
$pdf->SetLineWidth(0.5);
|
$pdf->SetLineWidth(0.5);
|
||||||
$pdf->Line(70, 150, 190, 150);
|
$pdf->Line(70, 155, 190, 155);
|
||||||
|
|
||||||
// Instructor name and signature
|
|
||||||
$instructor_name = $certificate_data['instructor_name'] ?? 'Instructor Name';
|
|
||||||
|
|
||||||
// Add instructor signature if available
|
// Add instructor signature if available
|
||||||
if (!empty($certificate_data['instructor_signature'])) {
|
if (!empty($certificate_data['instructor_signature'])) {
|
||||||
$signature_path = $certificate_data['instructor_signature'];
|
$signature_path = $certificate_data['instructor_signature'];
|
||||||
if (file_exists($signature_path)) {
|
if (file_exists($signature_path)) {
|
||||||
$pdf->Image($signature_path, 110, 130, 40, 0, '', '', '', false, 300);
|
$pdf->Image($signature_path, 110, 135, 40, 0, '', '', '', false, 300);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$pdf->SetY(155);
|
// Instructor name and title
|
||||||
$pdf->SetFont('helvetica', 'B', 12);
|
$pdf->SetY(160);
|
||||||
|
$pdf->SetFont('helvetica', 'B', 14);
|
||||||
$pdf->SetTextColor(0, 0, 0); // Black
|
$pdf->SetTextColor(0, 0, 0); // Black
|
||||||
$pdf->Cell(0, 10, $instructor_name, 0, 1, 'C');
|
$pdf->Cell(0, 10, $instructor_name, 0, 1, 'C');
|
||||||
|
|
||||||
$pdf->SetFont('helvetica', '', 10);
|
$pdf->SetFont('helvetica', '', 11);
|
||||||
$pdf->SetTextColor(77, 77, 77); // Dark gray
|
$pdf->SetTextColor(77, 77, 77); // Dark gray
|
||||||
$pdf->Cell(0, 10, 'Instructor', 0, 1, 'C');
|
$pdf->Cell(0, 8, 'Instructor / Trainer', 0, 1, 'C');
|
||||||
|
|
||||||
// Add organization name
|
// Add organization name
|
||||||
$organization_name = $certificate_data['organization_name'] ?? 'Upskill HVAC';
|
$organization_name = 'Upskill HVAC';
|
||||||
$pdf->SetY(175);
|
$pdf->SetY(180);
|
||||||
$pdf->SetFont('helvetica', 'B', 10);
|
$pdf->SetFont('helvetica', 'B', 11);
|
||||||
$pdf->SetTextColor(0, 0, 0); // Black
|
$pdf->SetTextColor(0, 0, 0); // Black
|
||||||
$pdf->Cell(0, 10, $organization_name, 0, 1, 'C');
|
$pdf->Cell(0, 8, $organization_name, 0, 1, 'C');
|
||||||
|
|
||||||
// Add venue info
|
// Add venue info if available
|
||||||
$venue_name = $certificate_data['venue_name'] ?? '';
|
$venue_name = $certificate_data['venue_name'] ?? '';
|
||||||
if (!empty($venue_name)) {
|
if (!empty($venue_name)) {
|
||||||
$pdf->SetFont('helvetica', '', 10);
|
$pdf->SetFont('helvetica', '', 10);
|
||||||
$pdf->SetTextColor(77, 77, 77); // Dark gray
|
$pdf->SetTextColor(77, 77, 77); // Dark gray
|
||||||
$pdf->Cell(0, 10, $venue_name, 0, 1, 'C');
|
$pdf->Cell(0, 8, $venue_name, 0, 1, 'C');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add certificate details at the bottom
|
// Add certificate details at the bottom
|
||||||
|
|
@ -418,8 +429,8 @@ class HVAC_Certificate_Generator {
|
||||||
$pdf->SetY(195);
|
$pdf->SetY(195);
|
||||||
$pdf->Cell(0, 10, 'Certificate #: ' . $certificate->certificate_number . ' | Issue Date: ' . date('F j, Y', strtotime($certificate->date_generated)), 0, 1, 'C');
|
$pdf->Cell(0, 10, 'Certificate #: ' . $certificate->certificate_number . ' | Issue Date: ' . date('F j, Y', strtotime($certificate->date_generated)), 0, 1, 'C');
|
||||||
|
|
||||||
// Add logo
|
// Add decorative elements (optional)
|
||||||
$this->add_logo($pdf);
|
$this->add_decorative_elements($pdf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -466,6 +477,72 @@ class HVAC_Certificate_Generator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add Upskill HVAC logo to certificate.
|
||||||
|
*
|
||||||
|
* @param TCPDF $pdf The TCPDF instance.
|
||||||
|
*/
|
||||||
|
protected function add_upskill_logo($pdf) {
|
||||||
|
// Check for uploaded logo in WordPress uploads directory
|
||||||
|
$upload_dir = wp_upload_dir();
|
||||||
|
$logo_path = $upload_dir['basedir'] . '/2025/05/UpskillHVAC-Logo_Black_NoOutline.png';
|
||||||
|
|
||||||
|
// Fallback to 2024 directory if 2025 doesn't exist
|
||||||
|
if (!file_exists($logo_path)) {
|
||||||
|
$logo_path = $upload_dir['basedir'] . '/2024/05/UpskillHVAC-Logo_Black_NoOutline.png';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check plugin assets directory as another fallback
|
||||||
|
if (!file_exists($logo_path)) {
|
||||||
|
$logo_path = HVAC_CE_PLUGIN_DIR . 'assets/images/upskill-hvac-logo.png';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file_exists($logo_path)) {
|
||||||
|
// Add logo at top center
|
||||||
|
// Calculate center position - assuming letter size landscape (279.4mm wide)
|
||||||
|
$page_width = $pdf->getPageWidth();
|
||||||
|
$logo_width = 50; // 50mm wide logo
|
||||||
|
$x_position = ($page_width - $logo_width) / 2;
|
||||||
|
|
||||||
|
$pdf->Image($logo_path, $x_position, 10, $logo_width, 0, '', '', '', false, 300);
|
||||||
|
} else {
|
||||||
|
// If no logo found, add text branding
|
||||||
|
$pdf->SetFont('helvetica', 'B', 16);
|
||||||
|
$pdf->SetTextColor(0, 77, 155); // Blue
|
||||||
|
$pdf->SetY(15);
|
||||||
|
$pdf->Cell(0, 10, 'UPSKILL HVAC', 0, 1, 'C');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add decorative elements to certificate.
|
||||||
|
*
|
||||||
|
* @param TCPDF $pdf The TCPDF instance.
|
||||||
|
*/
|
||||||
|
protected function add_decorative_elements($pdf) {
|
||||||
|
// Add decorative corner elements
|
||||||
|
$pdf->SetDrawColor(0, 77, 155); // Blue
|
||||||
|
$pdf->SetLineWidth(0.5);
|
||||||
|
|
||||||
|
// Top left corner
|
||||||
|
$pdf->Line(10, 10, 30, 10);
|
||||||
|
$pdf->Line(10, 10, 10, 30);
|
||||||
|
|
||||||
|
// Top right corner
|
||||||
|
$page_width = $pdf->getPageWidth();
|
||||||
|
$pdf->Line($page_width - 30, 10, $page_width - 10, 10);
|
||||||
|
$pdf->Line($page_width - 10, 10, $page_width - 10, 30);
|
||||||
|
|
||||||
|
// Bottom left corner
|
||||||
|
$page_height = $pdf->getPageHeight();
|
||||||
|
$pdf->Line(10, $page_height - 30, 10, $page_height - 10);
|
||||||
|
$pdf->Line(10, $page_height - 10, 30, $page_height - 10);
|
||||||
|
|
||||||
|
// Bottom right corner
|
||||||
|
$pdf->Line($page_width - 30, $page_height - 10, $page_width - 10, $page_height - 10);
|
||||||
|
$pdf->Line($page_width - 10, $page_height - 30, $page_width - 10, $page_height - 10);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get attendee data from Event Tickets.
|
* Get attendee data from Event Tickets.
|
||||||
*
|
*
|
||||||
|
|
@ -483,12 +560,91 @@ class HVAC_Certificate_Generator {
|
||||||
return $attendee_data;
|
return $attendee_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get attendee meta for Event Tickets
|
// Try multiple meta keys for attendee name (matching the template query)
|
||||||
$attendee_name = get_post_meta($attendee_id, '_tribe_tickets_full_name', true);
|
$meta_keys_for_name = array(
|
||||||
$attendee_email = get_post_meta($attendee_id, '_tribe_tickets_email', true);
|
'_tec_tickets_commerce_full_name', // TEC Commerce
|
||||||
$user_id = 0;
|
'_tribe_tpp_full_name', // Tribe PayPal Tickets
|
||||||
|
'_tribe_tickets_full_name', // Event Tickets
|
||||||
|
'_tribe_rsvp_full_name', // RSVP
|
||||||
|
'attendee_full_name', // Legacy
|
||||||
|
'_name', // Generic
|
||||||
|
'name' // Generic
|
||||||
|
);
|
||||||
|
|
||||||
|
$attendee_name = '';
|
||||||
|
foreach ($meta_keys_for_name as $meta_key) {
|
||||||
|
$name = get_post_meta($attendee_id, $meta_key, true);
|
||||||
|
if (!empty($name)) {
|
||||||
|
$attendee_name = $name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If still no name, try first and last name separately
|
||||||
|
if (empty($attendee_name)) {
|
||||||
|
$first_name_keys = array(
|
||||||
|
'_tribe_tickets_first_name',
|
||||||
|
'_tribe_tpp_first_name',
|
||||||
|
'_tec_tickets_commerce_first_name',
|
||||||
|
'attendee_first_name',
|
||||||
|
'first_name'
|
||||||
|
);
|
||||||
|
|
||||||
|
$last_name_keys = array(
|
||||||
|
'_tribe_tickets_last_name',
|
||||||
|
'_tribe_tpp_last_name',
|
||||||
|
'_tec_tickets_commerce_last_name',
|
||||||
|
'attendee_last_name',
|
||||||
|
'last_name'
|
||||||
|
);
|
||||||
|
|
||||||
|
$first_name = '';
|
||||||
|
$last_name = '';
|
||||||
|
|
||||||
|
foreach ($first_name_keys as $key) {
|
||||||
|
$fname = get_post_meta($attendee_id, $key, true);
|
||||||
|
if (!empty($fname)) {
|
||||||
|
$first_name = $fname;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($last_name_keys as $key) {
|
||||||
|
$lname = get_post_meta($attendee_id, $key, true);
|
||||||
|
if (!empty($lname)) {
|
||||||
|
$last_name = $lname;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($first_name) || !empty($last_name)) {
|
||||||
|
$attendee_name = trim($first_name . ' ' . $last_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try multiple meta keys for email (matching the template query)
|
||||||
|
$meta_keys_for_email = array(
|
||||||
|
'_tec_tickets_commerce_email',
|
||||||
|
'_tribe_tpp_email',
|
||||||
|
'_tribe_tickets_email',
|
||||||
|
'_tribe_tpp_attendee_email',
|
||||||
|
'_tribe_rsvp_email',
|
||||||
|
'attendee_email',
|
||||||
|
'_email',
|
||||||
|
'email'
|
||||||
|
);
|
||||||
|
|
||||||
|
$attendee_email = '';
|
||||||
|
foreach ($meta_keys_for_email as $meta_key) {
|
||||||
|
$email = get_post_meta($attendee_id, $meta_key, true);
|
||||||
|
if (!empty($email) && is_email($email)) {
|
||||||
|
$attendee_email = $email;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Try to find user by email
|
// Try to find user by email
|
||||||
|
$user_id = 0;
|
||||||
if (!empty($attendee_email)) {
|
if (!empty($attendee_email)) {
|
||||||
$user = get_user_by('email', $attendee_email);
|
$user = get_user_by('email', $attendee_email);
|
||||||
if ($user) {
|
if ($user) {
|
||||||
|
|
@ -496,18 +652,13 @@ class HVAC_Certificate_Generator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If name is empty, try alternative meta keys
|
// If still no name, use email prefix or "Attendee"
|
||||||
if (empty($attendee_name)) {
|
if (empty($attendee_name)) {
|
||||||
$attendee_name = get_post_meta($attendee_id, '_tribe_rsvp_full_name', true);
|
if (!empty($attendee_email)) {
|
||||||
|
$email_parts = explode('@', $attendee_email);
|
||||||
// If still empty, check for first and last name separately
|
$attendee_name = ucwords(str_replace(array('.', '_', '-'), ' ', $email_parts[0]));
|
||||||
if (empty($attendee_name)) {
|
} else {
|
||||||
$first_name = get_post_meta($attendee_id, '_tribe_tickets_first_name', true);
|
$attendee_name = 'Attendee #' . $attendee_id;
|
||||||
$last_name = get_post_meta($attendee_id, '_tribe_tickets_last_name', true);
|
|
||||||
|
|
||||||
if (!empty($first_name) || !empty($last_name)) {
|
|
||||||
$attendee_name = trim($first_name . ' ' . $last_name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -519,6 +670,11 @@ class HVAC_Certificate_Generator {
|
||||||
'user_id' => $user_id
|
'user_id' => $user_id
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Log for debugging
|
||||||
|
if (defined('WP_DEBUG') && WP_DEBUG && empty($attendee_name)) {
|
||||||
|
error_log("Certificate Generator: No name found for attendee ID $attendee_id");
|
||||||
|
}
|
||||||
|
|
||||||
return $attendee_data;
|
return $attendee_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -550,7 +706,34 @@ class HVAC_Certificate_Generator {
|
||||||
// Get organizer details
|
// Get organizer details
|
||||||
$organizer_id = tribe_get_organizer_id($event_id);
|
$organizer_id = tribe_get_organizer_id($event_id);
|
||||||
$organizer_name = tribe_get_organizer($event_id);
|
$organizer_name = tribe_get_organizer($event_id);
|
||||||
$instructor_name = $organizer_name; // Default instructor is the organizer
|
|
||||||
|
// Get trainer/instructor name
|
||||||
|
// First check if this event has a trainer/author
|
||||||
|
$trainer_id = $event->post_author;
|
||||||
|
$trainer = get_userdata($trainer_id);
|
||||||
|
$instructor_name = '';
|
||||||
|
|
||||||
|
if ($trainer) {
|
||||||
|
// Try to get display name first
|
||||||
|
$instructor_name = $trainer->display_name;
|
||||||
|
|
||||||
|
// If no display name, try full name
|
||||||
|
if (empty($instructor_name) || $instructor_name == $trainer->user_login) {
|
||||||
|
$first_name = get_user_meta($trainer_id, 'first_name', true);
|
||||||
|
$last_name = get_user_meta($trainer_id, 'last_name', true);
|
||||||
|
if ($first_name || $last_name) {
|
||||||
|
$instructor_name = trim($first_name . ' ' . $last_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback to organizer name if still empty
|
||||||
|
if (empty($instructor_name)) {
|
||||||
|
$instructor_name = $organizer_name;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Use organizer name as fallback
|
||||||
|
$instructor_name = $organizer_name;
|
||||||
|
}
|
||||||
|
|
||||||
// Build event data
|
// Build event data
|
||||||
$event_data = array(
|
$event_data = array(
|
||||||
|
|
@ -562,7 +745,9 @@ class HVAC_Certificate_Generator {
|
||||||
'venue_name' => $venue_name,
|
'venue_name' => $venue_name,
|
||||||
'organizer_id' => $organizer_id,
|
'organizer_id' => $organizer_id,
|
||||||
'organization_name' => $organizer_name,
|
'organization_name' => $organizer_name,
|
||||||
'instructor_name' => $instructor_name
|
'instructor_name' => $instructor_name,
|
||||||
|
'trainer_name' => $instructor_name, // Also include as trainer_name for compatibility
|
||||||
|
'trainer_id' => $trainer_id
|
||||||
);
|
);
|
||||||
|
|
||||||
return $event_data;
|
return $event_data;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue