upskill-event-manager/includes/community/class-event-summary-data.php
bengizmo 37f4180e1c feat: Add massive missing plugin infrastructure to repository
🚨 CRITICAL: Fixed deployment blockers by adding missing core directories:

**Community System (CRITICAL)**
- includes/community/ - Login_Handler and all community classes
- templates/community/ - Community login forms

**Certificate System (CRITICAL)**
- includes/certificates/ - 8+ certificate classes and handlers
- templates/certificates/ - Certificate reports and generation templates

**Core Individual Classes (CRITICAL)**
- includes/class-hvac-event-summary.php
- includes/class-hvac-trainer-profile-manager.php
- includes/class-hvac-master-dashboard-data.php
- Plus 40+ other individual HVAC classes

**Major Feature Systems (HIGH)**
- includes/database/ - Training leads database tables
- includes/find-trainer/ - Find trainer directory and MapGeo integration
- includes/google-sheets/ - Google Sheets integration system
- includes/zoho/ - Complete Zoho CRM integration
- includes/communication/ - Communication templates system

**Template Infrastructure**
- templates/attendee/, templates/email-attendees/
- templates/event-summary/, templates/status/
- templates/template-parts/ - Shared template components

**Impact:**
- 70+ files added covering 10+ missing directories
- Resolves ALL deployment blockers and feature breakdowns
- Plugin activation should now work correctly
- Multi-machine deployment fully supported

🔧 Generated with Claude Code

Co-Authored-By: Ben Reed <ben@tealmaker.com>
2025-08-11 13:30:11 -03:00

408 lines
No EOL
18 KiB
PHP

<?php
/**
* Handles data retrieval for the Event Summary page.
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
class HVAC_Event_Summary_Data {
/**
* Fallback method to get transactions by direct database queries
* Used when the Tribe__Tickets__Tickets_Handler is not available
*
* @param array &$transactions The transactions array to populate
* @param object $certificate_manager The certificate manager instance
*/
private function get_event_transactions_fallback(&$transactions, $certificate_manager) {
// Query for attendees directly from the database
$attendees_query = new WP_Query([
'post_type' => '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;
}
}