'tribe_tpp_attendees', 'posts_per_page' => -1, 'meta_query' => [ [ 'key' => '_tribe_tpp_event', 'value' => $this->event_id, 'compare' => '=', ], ], ]); if ($attendees_query->have_posts()) { while ($attendees_query->have_posts()) { $attendees_query->the_post(); $attendee_id = get_the_ID(); // Get associated ticket $ticket_id = get_post_meta($attendee_id, '_tribe_tpp_product', true); // Get price from ticket $price = 0; if ($ticket_id) { $price_meta = get_post_meta($ticket_id, '_price', true); if (is_numeric($price_meta)) { $price = (float)$price_meta; } } // Get order info $order_id = get_post_meta($attendee_id, '_tribe_tpp_order', true); // Get purchaser details $purchaser_name = get_post_meta($attendee_id, '_tribe_tickets_full_name', true); if (empty($purchaser_name)) { $purchaser_name = get_post_meta($attendee_id, '_tribe_tpp_full_name', true); } $purchaser_email = get_post_meta($attendee_id, '_tribe_tickets_email', true); if (empty($purchaser_email)) { $purchaser_email = get_post_meta($attendee_id, '_tribe_tpp_email', true); } // Check check-in status $checked_in = false; $check_in = get_post_meta($attendee_id, '_tribe_tpp_checkin', true); if (!empty($check_in)) { $checked_in = true; } else { $check_in = get_post_meta($attendee_id, 'check_in', true); if (!empty($check_in)) { $checked_in = true; } } // Check certificate status $certificate_status = 'Not Generated'; if ($certificate_manager) { $certificate = $certificate_manager->get_certificate_by_attendee($this->event_id, $attendee_id); if ($certificate) { if ($certificate->revoked) { $certificate_status = 'Revoked'; } else { $certificate_status = $certificate->email_sent ? 'Sent' : 'Generated'; } } } $transactions[] = [ 'attendee_id' => $attendee_id, 'order_id' => $order_id, 'ticket_type_id' => $ticket_id, 'ticket_type_name'=> $ticket_id ? get_the_title($ticket_id) : 'N/A', 'purchaser_name' => $purchaser_name, 'purchaser_email' => $purchaser_email, 'security_code' => get_post_meta($attendee_id, '_tribe_tpp_security_code', true), 'checked_in' => $checked_in, 'price' => $price, 'certificate_status' => $certificate_status, ]; } wp_reset_postdata(); } } /** * The ID of the event post. * * @var int|null */ private $event_id = null; /** * The event post object. * * @var WP_Post|null */ private $event_post = null; /** * Constructor. * * @param int $event_id The ID of the event to retrieve data for. */ public function __construct( $event_id ) { $this->event_id = absint( $event_id ); if ( $this->event_id > 0 ) { $this->event_post = get_post( $this->event_id ); // Ensure it's an event post type (adjust post type if needed) if ( ! $this->event_post || get_post_type( $this->event_post ) !== Tribe__Events__Main::POSTTYPE ) { $this->event_id = null; $this->event_post = null; } } } /** * Check if the event is valid. * * @return bool True if the event ID is valid and the post exists, false otherwise. */ public function is_valid_event() { // First check if the event post exists if (is_null($this->event_post)) { return false; } // Additional validation could be added here return true; } /** * Check if the current user has permission to view this event. * * @return bool True if the user has permission, false otherwise. */ public function user_can_view_event() { // User must be logged in if (!is_user_logged_in()) { return false; } // Event must be valid if (!$this->is_valid_event()) { return false; } // User must be the event author or have edit_posts capability $current_user_id = get_current_user_id(); return ($this->event_post->post_author == $current_user_id || current_user_can('edit_posts')); } /** * Get basic event details. * * @return array|null An array of event details or null if the event is invalid. */ public function get_event_details() { if ( ! $this->is_valid_event() ) { return null; } $details = [ 'id' => $this->event_id, 'title' => get_the_title( $this->event_id ), 'description' => apply_filters( 'the_content', get_post_field( 'post_content', $this->event_id ) ), 'excerpt' => get_the_excerpt( $this->event_id ), 'permalink' => get_permalink( $this->event_id ), 'start_date' => null, 'end_date' => null, 'cost' => null, 'is_all_day' => false, 'is_recurring'=> false, 'timezone' => null, ]; // Use TEC functions if available if ( function_exists( 'tribe_get_start_date' ) ) { $details['start_date'] = tribe_get_start_date( $this->event_id, true, 'Y-m-d H:i:s' ); // Get raw date/time } if ( function_exists( 'tribe_get_end_date' ) ) { $details['end_date'] = tribe_get_end_date( $this->event_id, true, 'Y-m-d H:i:s' ); // Get raw date/time } if ( function_exists( 'tribe_get_cost' ) ) { $details['cost'] = tribe_get_cost( $this->event_id, true ); } if ( function_exists( 'tribe_event_is_all_day' ) ) { $details['is_all_day'] = tribe_event_is_all_day( $this->event_id ); } if ( function_exists( 'tribe_is_recurring_event' ) ) { $details['is_recurring'] = tribe_is_recurring_event( $this->event_id ); } if ( function_exists( 'tribe_get_timezone' ) ) { $details['timezone'] = tribe_get_timezone( $this->event_id ); } return $details; } /** * Get event venue details. * * @return array|null An array of venue details or null if the event is invalid or has no venue. */ public function get_event_venue_details() { if ( ! $this->is_valid_event() ) { return null; } $venue_details = null; $venue_id = null; if ( function_exists( 'tribe_get_venue_id' ) ) { $venue_id = tribe_get_venue_id( $this->event_id ); } if ( $venue_id && function_exists( 'tribe_get_venue_details' ) ) { // tribe_get_venue_details is deprecated, use individual functions $venue_details = [ 'id' => $venue_id, 'name' => function_exists('tribe_get_venue') ? tribe_get_venue( $venue_id ) : get_the_title( $venue_id ), 'address' => function_exists('tribe_get_full_address') ? tribe_get_full_address( $venue_id ) : null, 'street' => function_exists('tribe_get_address') ? tribe_get_address( $venue_id ) : null, 'city' => function_exists('tribe_get_city') ? tribe_get_city( $venue_id ) : null, 'stateprovince' => function_exists('tribe_get_stateprovince') ? tribe_get_stateprovince( $venue_id ) : null, // Use stateprovince for consistency 'state' => function_exists('tribe_get_state') ? tribe_get_state( $venue_id ) : null, 'province' => function_exists('tribe_get_province') ? tribe_get_province( $venue_id ) : null, 'zip' => function_exists('tribe_get_zip') ? tribe_get_zip( $venue_id ) : null, 'country' => function_exists('tribe_get_country') ? tribe_get_country( $venue_id ) : null, 'phone' => function_exists('tribe_get_phone') ? tribe_get_phone( $venue_id ) : null, 'website' => function_exists('tribe_get_venue_website_link') ? tribe_get_venue_website_link( $venue_id, false ) : null, // Get URL only 'map_link' => function_exists('tribe_get_map_link') ? tribe_get_map_link( $venue_id ) : null, 'directions_link' => function_exists('tribe_get_directions_link') ? tribe_get_directions_link( $venue_id ) : null, ]; } return $venue_details; } /** * Get event organizer details. * * @return array|null An array of organizer details or null if the event is invalid or has no organizer. */ public function get_event_organizer_details() { if ( ! $this->is_valid_event() ) { return null; } $organizer_details = null; $organizer_ids = []; if ( function_exists( 'tribe_get_organizer_ids' ) ) { $organizer_ids = tribe_get_organizer_ids( $this->event_id ); } // Get details for the first organizer found if ( ! empty( $organizer_ids ) && is_array( $organizer_ids ) ) { $organizer_id = $organizer_ids[0]; if ( $organizer_id > 0 ) { $organizer_details = [ 'id' => $organizer_id, 'name' => function_exists('tribe_get_organizer') ? tribe_get_organizer( $organizer_id ) : get_the_title( $organizer_id ), 'phone' => function_exists('tribe_get_organizer_phone') ? tribe_get_organizer_phone( $organizer_id ) : null, 'website' => function_exists('tribe_get_organizer_website_link') ? tribe_get_organizer_website_link( $organizer_id, false ) : null, // Get URL only 'email' => function_exists('tribe_get_organizer_email') ? tribe_get_organizer_email( $organizer_id ) : null, 'permalink' => function_exists('tribe_get_event_link') ? tribe_get_event_link( $organizer_id, false, false ) : get_permalink( $organizer_id ), // Link to organizer post ]; } } return $organizer_details; } /** * Get transaction data associated with the event. * Requires Event Tickets / Event Tickets Plus. * * @return array An array of transaction data (e.g., orders, attendees). Empty array if none or invalid event. */ public function get_event_transactions() { if ( ! $this->is_valid_event() ) { return []; } $transactions = []; // Load certificate manager if it exists $certificate_manager = null; if (class_exists('HVAC_Certificate_Manager')) { require_once HVAC_PLUGIN_DIR . 'includes/certificates/class-certificate-manager.php'; $certificate_manager = HVAC_Certificate_Manager::instance(); } // Check if Event Tickets is active and the necessary class/method exists if ( class_exists( 'Tribe__Tickets__Tickets_Handler' ) && method_exists( Tribe__Tickets__Tickets_Handler::instance(), 'get_attendees_by_id' ) ) { $attendees = Tribe__Tickets__Tickets_Handler::instance()->get_attendees_by_id( $this->event_id ); if ( is_array( $attendees ) ) { foreach ( $attendees as $attendee ) { // Extract relevant data - structure might vary based on ticket provider (Woo, EDD, RSVP, Tribe) $order_id = isset( $attendee['order_id'] ) ? $attendee['order_id'] : null; $ticket_type_id = isset( $attendee['product_id'] ) ? $attendee['product_id'] : null; // product_id often holds ticket type ID $attendee_id = isset( $attendee['attendee_id'] ) ? $attendee['attendee_id'] : null; // Unique ID for the attendee record // Get purchaser info (might be stored differently depending on provider) $purchaser_name = isset( $attendee['holder_name'] ) ? $attendee['holder_name'] : null; $purchaser_email = isset( $attendee['holder_email'] ) ? $attendee['holder_email'] : null; if ( empty( $purchaser_name ) && isset( $attendee['purchaser_name'] ) ) { $purchaser_name = $attendee['purchaser_name']; } if ( empty( $purchaser_email ) && isset( $attendee['purchaser_email'] ) ) { $purchaser_email = $attendee['purchaser_email']; } // Get price if available (might vary based on provider) $price = 0; if (isset($attendee['price']) && is_numeric($attendee['price'])) { $price = (float) $attendee['price']; } elseif (isset($attendee['price_paid']) && is_numeric($attendee['price_paid'])) { $price = (float) $attendee['price_paid']; } // Check if a certificate exists for this attendee $certificate_status = 'Not Generated'; if ($certificate_manager) { $certificate = $certificate_manager->get_certificate_by_attendee($this->event_id, $attendee_id); if ($certificate) { if ($certificate->revoked) { $certificate_status = 'Revoked'; } else { $certificate_status = $certificate->email_sent ? 'Sent' : 'Generated'; } } } // Check attendance status from multiple possible fields $checked_in = false; if (isset($attendee['check_in']) && $attendee['check_in']) { $checked_in = true; } elseif (isset($attendee['checked_in']) && $attendee['checked_in']) { $checked_in = true; } elseif (isset($attendee['_tribe_tpp_checkin']) && $attendee['_tribe_tpp_checkin']) { $checked_in = true; } elseif (isset($attendee['meta']) && is_array($attendee['meta'])) { if (isset($attendee['meta']['_tribe_tpp_checkin']) && $attendee['meta']['_tribe_tpp_checkin']) { $checked_in = true; } } $transactions[] = [ 'attendee_id' => $attendee_id, 'order_id' => $order_id, 'ticket_type_id' => $ticket_type_id, 'ticket_type_name'=> $ticket_type_id ? get_the_title( $ticket_type_id ) : 'N/A', 'purchaser_name' => $purchaser_name, 'purchaser_email' => $purchaser_email, 'security_code' => isset( $attendee['security_code'] ) ? $attendee['security_code'] : null, 'checked_in' => $checked_in, 'price' => $price, 'certificate_status' => $certificate_status, ]; } } } else { // Fallback if Event Tickets Handler is not available - use direct queries $this->get_event_transactions_fallback($transactions, $certificate_manager); } // If transactions were found, update event meta for dashboard stats if (!empty($transactions)) { $total_sold = count($transactions); $total_revenue = 0; foreach ($transactions as $transaction) { $total_revenue += $transaction['price']; } // Update the meta for future dashboard reference update_post_meta($this->event_id, '_tribe_tickets_sold', $total_sold); update_post_meta($this->event_id, '_tribe_revenue_total', $total_revenue); } return $transactions; } }