upskill-event-manager/includes/class-attendee-profile.php
bengizmo 2cb37d0285 fix: Ensure trainer registration page is publicly accessible
- Added explicit checks to prevent authentication redirects on registration page
- Added ensure_registration_page_public() method with priority 1 to run before other auth checks
- Included registration-pending and training-login pages in public pages list
- Added fallback function in main plugin file to remove auth hooks on registration page

This ensures that users can access /trainer/registration/ without being logged in, as intended for new trainer signups.
2025-07-28 10:30:54 -03:00

413 lines
No EOL
15 KiB
PHP

<?php
/**
* Attendee Profile Handler
*
* Handles the display and data retrieval for attendee profile pages
*
* @package HVAC_Community_Events
* @since 1.0.0
*/
// Exit if accessed directly
if (!defined('ABSPATH')) {
exit;
}
/**
* Attendee Profile class
*/
class HVAC_Attendee_Profile {
/**
* Instance of this class
*
* @var HVAC_Attendee_Profile
*/
protected static $instance = null;
/**
* Get instance
*/
public static function instance() {
if (is_null(self::$instance)) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Constructor
*/
public function __construct() {
add_action('init', array($this, 'register_shortcode'));
add_action('wp_enqueue_scripts', array($this, 'enqueue_scripts'));
add_action('wp_ajax_hvac_get_attendee_timeline', array($this, 'ajax_get_timeline'));
add_action('wp_ajax_nopriv_hvac_get_attendee_timeline', array($this, 'ajax_get_timeline'));
}
/**
* Register shortcode
*/
public function register_shortcode() {
add_shortcode('hvac_attendee_profile', array($this, 'render_attendee_profile'));
}
/**
* Enqueue scripts and styles
*/
public function enqueue_scripts() {
if (!is_page('attendee-profile')) {
return;
}
// Enqueue custom styles and scripts
wp_enqueue_style(
'hvac-attendee-profile',
HVAC_CE_PLUGIN_URL . 'assets/css/hvac-attendee-profile.css',
array(),
HVAC_CE_VERSION
);
wp_enqueue_script(
'hvac-attendee-profile',
HVAC_CE_PLUGIN_URL . 'assets/js/hvac-attendee-profile.js',
array('jquery'),
HVAC_CE_VERSION,
true
);
wp_localize_script('hvac-attendee-profile', 'hvac_attendee', array(
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('hvac_attendee_nonce')
));
}
/**
* Render attendee profile
*/
public function render_attendee_profile($atts) {
// Check permissions - trainers and admins only
if (!current_user_can('manage_hvac_events') && !current_user_can('manage_options')) {
return '<p>You do not have permission to view attendee profiles.</p>';
}
// Get attendee ID from URL parameter
$attendee_id = isset($_GET['attendee_id']) ? intval($_GET['attendee_id']) : 0;
if (!$attendee_id) {
return '<p>No attendee specified. Please provide an attendee ID.</p>';
}
// Get attendee data
$attendee_data = $this->get_attendee_data($attendee_id);
if (!$attendee_data) {
return '<p>Attendee not found.</p>';
}
ob_start();
include HVAC_CE_PLUGIN_DIR . 'templates/attendee/template-attendee-profile.php';
return ob_get_clean();
}
/**
* Get comprehensive attendee data
*/
public function get_attendee_data($attendee_id) {
global $wpdb;
// First, try to get attendee as a user
$user = null;
$attendee_email = '';
// Check if this is an attendee post ID
$attendee_post = get_post($attendee_id);
if ($attendee_post && in_array($attendee_post->post_type, array('tribe_tpp_attendees', 'tec_tc_attendee', 'tribe_rsvp_attendees'))) {
// Get email from attendee meta
$email_keys = array(
'_tec_tickets_commerce_email',
'_tribe_tpp_email',
'_tribe_tickets_email',
'_tribe_tpp_attendee_email'
);
foreach ($email_keys as $key) {
$email = get_post_meta($attendee_id, $key, true);
if ($email && is_email($email)) {
$attendee_email = $email;
break;
}
}
// Try to find user by email
if ($attendee_email) {
$user = get_user_by('email', $attendee_email);
}
} else {
// Maybe this is a user ID
$user = get_user_by('id', $attendee_id);
if ($user) {
$attendee_email = $user->user_email;
}
}
if (!$attendee_email) {
return false;
}
// Get profile information
$profile_data = $this->get_profile_info($attendee_email, $user);
// Get statistics
$stats = $this->get_attendee_statistics($attendee_email);
// Get timeline data
$timeline = $this->get_attendee_timeline($attendee_email);
return array(
'profile' => $profile_data,
'stats' => $stats,
'timeline' => $timeline,
'attendee_id' => $attendee_id,
'user_id' => $user ? $user->ID : 0
);
}
/**
* Get profile information
*/
private function get_profile_info($email, $user = null) {
global $wpdb;
$profile = array(
'name' => '',
'email' => $email,
'phone' => '',
'company' => '',
'state' => '',
'avatar_url' => ''
);
// If we have a user, get their data
if ($user) {
$profile['name'] = $user->display_name;
$profile['phone'] = get_user_meta($user->ID, 'phone', true);
$profile['company'] = get_user_meta($user->ID, 'company', true);
$profile['state'] = get_user_meta($user->ID, 'state', true);
$profile['avatar_url'] = get_avatar_url($user->ID, array('size' => 150));
}
// Try to get name from attendee records if not set
if (empty($profile['name'])) {
$name = $wpdb->get_var($wpdb->prepare("
SELECT COALESCE(
MAX(CASE WHEN pm.meta_key = '_tec_tickets_commerce_full_name' THEN pm.meta_value END),
MAX(CASE WHEN pm.meta_key = '_tribe_tpp_full_name' THEN pm.meta_value END),
MAX(CASE WHEN pm.meta_key = '_tribe_tickets_full_name' THEN pm.meta_value END)
)
FROM {$wpdb->posts} p
JOIN {$wpdb->postmeta} pm_email ON p.ID = pm_email.post_id
JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id
WHERE p.post_type IN ('tribe_tpp_attendees', 'tec_tc_attendee', 'tribe_rsvp_attendees')
AND pm_email.meta_value = %s
AND pm_email.meta_key IN ('_tec_tickets_commerce_email', '_tribe_tpp_email', '_tribe_tickets_email')
AND pm.meta_key IN ('_tec_tickets_commerce_full_name', '_tribe_tpp_full_name', '_tribe_tickets_full_name')
LIMIT 1
", $email));
if ($name) {
$profile['name'] = $name;
}
}
// If still no name, use email prefix
if (empty($profile['name'])) {
$email_parts = explode('@', $email);
$profile['name'] = ucwords(str_replace(array('.', '_', '-'), ' ', $email_parts[0]));
}
return $profile;
}
/**
* Get attendee statistics
*/
private function get_attendee_statistics($email) {
global $wpdb;
// Get total purchases (unique events registered)
$total_purchases = $wpdb->get_var($wpdb->prepare("
SELECT COUNT(DISTINCT p.post_parent)
FROM {$wpdb->posts} p
JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id
WHERE p.post_type IN ('tribe_tpp_attendees', 'tec_tc_attendee', 'tribe_rsvp_attendees')
AND pm.meta_key IN ('_tec_tickets_commerce_email', '_tribe_tpp_email', '_tribe_tickets_email', '_tribe_tpp_attendee_email')
AND pm.meta_value = %s
AND p.post_status = 'publish'
", $email));
// Get events registered for
$events_registered = $total_purchases; // Same as purchases for now
// Get events checked in
$events_checked_in = $wpdb->get_var($wpdb->prepare("
SELECT COUNT(DISTINCT p.post_parent)
FROM {$wpdb->posts} p
JOIN {$wpdb->postmeta} pm_email ON p.ID = pm_email.post_id
JOIN {$wpdb->postmeta} pm_checkin ON p.ID = pm_checkin.post_id
WHERE p.post_type IN ('tribe_tpp_attendees', 'tec_tc_attendee', 'tribe_rsvp_attendees')
AND pm_email.meta_key IN ('_tec_tickets_commerce_email', '_tribe_tpp_email', '_tribe_tickets_email', '_tribe_tpp_attendee_email')
AND pm_email.meta_value = %s
AND pm_checkin.meta_key = '_tribe_tickets_attendee_checked_in'
AND pm_checkin.meta_value = '1'
AND p.post_status = 'publish'
", $email));
// Get certificates earned
$certificates_earned = 0;
if (class_exists('HVAC_Certificate_Manager')) {
$certificate_manager = HVAC_Certificate_Manager::instance();
// Get all attendee IDs for this email
$attendee_ids = $wpdb->get_col($wpdb->prepare("
SELECT p.ID
FROM {$wpdb->posts} p
JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id
WHERE p.post_type IN ('tribe_tpp_attendees', 'tec_tc_attendee', 'tribe_rsvp_attendees')
AND pm.meta_key IN ('_tec_tickets_commerce_email', '_tribe_tpp_email', '_tribe_tickets_email', '_tribe_tpp_attendee_email')
AND pm.meta_value = %s
AND p.post_status = 'publish'
", $email));
// Count certificates for these attendees
foreach ($attendee_ids as $att_id) {
$certs = $wpdb->get_var($wpdb->prepare("
SELECT COUNT(*) FROM {$wpdb->prefix}hvac_certificates
WHERE attendee_id = %d
", $att_id));
$certificates_earned += $certs;
}
}
return array(
'total_purchases' => intval($total_purchases),
'events_registered' => intval($events_registered),
'events_checked_in' => intval($events_checked_in),
'certificates_earned' => intval($certificates_earned)
);
}
/**
* Get attendee timeline data
*/
private function get_attendee_timeline($email) {
global $wpdb;
$timeline_events = array();
// Get all attendee records for this email
$attendee_records = $wpdb->get_results($wpdb->prepare("
SELECT
p.ID as attendee_id,
p.post_parent as event_id,
p.post_date as registration_date,
event.post_title as event_title,
event_date.meta_value as event_date,
checkin.meta_value as checked_in
FROM {$wpdb->posts} p
JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id
JOIN {$wpdb->posts} event ON p.post_parent = event.ID
LEFT JOIN {$wpdb->postmeta} event_date ON event.ID = event_date.post_id AND event_date.meta_key = '_EventStartDate'
LEFT JOIN {$wpdb->postmeta} checkin ON p.ID = checkin.post_id AND checkin.meta_key = '_tribe_tickets_attendee_checked_in'
WHERE p.post_type IN ('tribe_tpp_attendees', 'tec_tc_attendee', 'tribe_rsvp_attendees')
AND pm.meta_key IN ('_tec_tickets_commerce_email', '_tribe_tpp_email', '_tribe_tickets_email', '_tribe_tpp_attendee_email')
AND pm.meta_value = %s
AND p.post_status = 'publish'
ORDER BY p.post_date DESC
", $email));
foreach ($attendee_records as $record) {
// Registration event
$timeline_events[] = array(
'type' => 'registration',
'title' => 'Registered for ' . $record->event_title,
'date' => $record->registration_date,
'event_id' => $record->event_id,
'icon' => 'fas fa-ticket-alt',
'color' => '#007cba'
);
// Event attendance (if event date has passed)
if ($record->event_date && strtotime($record->event_date) < current_time('timestamp')) {
$timeline_events[] = array(
'type' => 'event',
'title' => 'Attended ' . $record->event_title,
'date' => $record->event_date,
'event_id' => $record->event_id,
'checked_in' => $record->checked_in == '1',
'icon' => 'fas fa-calendar-check',
'color' => $record->checked_in == '1' ? '#28a745' : '#6c757d'
);
}
// Certificate earned
if (class_exists('HVAC_Certificate_Manager')) {
$cert = $wpdb->get_row($wpdb->prepare("
SELECT certificate_number, date_generated
FROM {$wpdb->prefix}hvac_certificates
WHERE attendee_id = %d
LIMIT 1
", $record->attendee_id));
if ($cert) {
$timeline_events[] = array(
'type' => 'certificate',
'title' => 'Certificate earned for ' . $record->event_title,
'date' => $cert->date_generated,
'event_id' => $record->event_id,
'certificate_number' => $cert->certificate_number,
'icon' => 'fas fa-certificate',
'color' => '#ffc107'
);
}
}
}
// Sort timeline by date
usort($timeline_events, function($a, $b) {
return strtotime($b['date']) - strtotime($a['date']);
});
return $timeline_events;
}
/**
* AJAX handler for timeline data
*/
public function ajax_get_timeline() {
check_ajax_referer('hvac_attendee_nonce', 'nonce');
if (!current_user_can('manage_hvac_events') && !current_user_can('manage_options')) {
wp_die('Unauthorized');
}
$attendee_id = isset($_POST['attendee_id']) ? intval($_POST['attendee_id']) : 0;
if (!$attendee_id) {
wp_send_json_error('Invalid attendee ID');
}
$attendee_data = $this->get_attendee_data($attendee_id);
if (!$attendee_data) {
wp_send_json_error('Attendee not found');
}
wp_send_json_success(array(
'timeline' => $attendee_data['timeline']
));
}
}
// Initialize
HVAC_Attendee_Profile::instance();