upskill-event-manager/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/includes/class-hvac-dashboard-data.php
bengizmo 5d45ed594d docs: Update README with event creation testing status 2025-05-19
- Document enhanced event creation testing improvements
- Add Breeze cache clearing script and integration
- Detail form field mapping discoveries
- Note current validation issues with description field
- Include multiple test approaches implemented
- Update error handling and debugging capabilities
2025-05-19 06:55:34 -03:00

276 lines
No EOL
8.8 KiB
PHP

<?php
/**
* HVAC Community Events Dashboard Data Handler
*
* Retrieves and calculates data needed for the Trainer Dashboard.
*
* @package HVAC Community Events
* @subpackage Includes
* @author Roo
* @version 1.0.0
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Class HVAC_Dashboard_Data
*
* Handles fetching and processing data for the trainer dashboard.
*/
class HVAC_Dashboard_Data {
/**
* The ID of the trainer user.
*
* @var int
*/
private int $user_id;
/**
* Constructor.
*
* @param int $user_id The ID of the trainer user.
*/
public function __construct( int $user_id ) {
$this->user_id = $user_id;
}
/**
* Get the total number of events created by the trainer.
*
* @return int
*/
public function get_total_events_count() : int {
$args = array(
'post_type' => Tribe__Events__Main::POSTTYPE,
'author' => $this->user_id, // Query by post author, not organizer
'post_status' => array( 'publish', 'future', 'draft', 'pending', 'private' ),
'posts_per_page' => -1,
'fields' => 'ids', // Only need the count
);
$query = new WP_Query( $args );
return (int) $query->found_posts;
}
/**
* Get the number of upcoming events for the trainer.
*
* @return int
*/
public function get_upcoming_events_count() : int {
$today = date( 'Y-m-d H:i:s' );
$args = array(
'post_type' => Tribe__Events__Main::POSTTYPE,
// 'author' => $this->user_id, // Query by organizer instead
'post_status' => array( 'publish', 'future' ), // Only published or scheduled future events
'posts_per_page' => -1,
'fields' => 'ids', // Only need the count
'meta_query' => array(
'relation' => 'AND', // Combine organizer and date query
array(
'key' => '_EventOrganizerID',
'value' => $this->user_id,
'compare' => '=',
'type' => 'NUMERIC', // Specify numeric comparison
),
array(
'key' => '_EventStartDate',
'value' => $today,
'compare' => '>=',
'type' => 'DATETIME',
),
),
'orderby' => 'event_date',
'order' => 'ASC',
);
$query = new WP_Query( $args );
return (int) $query->found_posts;
}
/**
* Get the number of past events for the trainer.
*
* @return int
*/
public function get_past_events_count() : int {
$today = date( 'Y-m-d H:i:s' );
$args = array(
'post_type' => Tribe__Events__Main::POSTTYPE,
// 'author' => $this->user_id, // Query by organizer instead
'post_status' => array( 'publish', 'private' ), // Count published or private past events
'posts_per_page' => -1,
'fields' => 'ids', // Only need the count
'meta_query' => array(
'relation' => 'AND', // Combine organizer and date query
array(
'key' => '_EventOrganizerID',
'value' => $this->user_id,
'compare' => '=',
'type' => 'NUMERIC', // Specify numeric comparison
),
array(
'key' => '_EventEndDate', // Use end date to determine if it's truly past
'value' => $today,
'compare' => '<',
'type' => 'DATETIME',
),
),
);
$query = new WP_Query( $args );
return (int) $query->found_posts;
}
/**
* Get the total number of tickets sold across all the trainer's events.
*
* @return int
*/
public function get_total_tickets_sold() : int {
$total_tickets = 0;
$args = array(
'post_type' => Tribe__Events__Main::POSTTYPE,
// 'author' => $this->user_id, // Query by organizer instead
'post_status' => array( 'publish', 'future', 'draft', 'pending', 'private' ), // Include all statuses for historical data
'posts_per_page' => -1,
'fields' => 'ids', // Only need the IDs
'meta_key' => '_EventOrganizerID',
'meta_value' => $this->user_id,
'meta_compare' => '=', // Explicitly set compare
'meta_type' => 'NUMERIC', // Specify numeric comparison
'meta_compare' => '=', // Explicitly set compare
'meta_type' => 'NUMERIC', // Specify numeric comparison
);
$event_ids = get_posts( $args );
if ( ! empty( $event_ids ) ) {
foreach ( $event_ids as $event_id ) {
// Event Tickets Plus often stores sold count in '_tribe_tickets_sold' meta
$sold = get_post_meta( $event_id, '_tribe_tickets_sold', true );
if ( is_numeric( $sold ) ) {
$total_tickets += (int) $sold;
}
// Fallback or alternative check if needed (e.g., querying attendee posts)
// Depending on the exact ticket plugin setup, this might need adjustment.
}
}
return $total_tickets;
}
/**
* Get the total revenue generated across all the trainer's events.
*
* @return float
*/
public function get_total_revenue() : float {
$total_revenue = 0.0;
$args = array(
'post_type' => Tribe__Events__Main::POSTTYPE,
// 'author' => $this->user_id, // Query by organizer instead
'post_status' => array( 'publish', 'future', 'draft', 'pending', 'private' ), // Include all statuses for historical data
'posts_per_page' => -1,
'fields' => 'ids', // Only need the IDs
'meta_key' => '_EventOrganizerID',
'meta_value' => $this->user_id,
);
$event_ids = get_posts( $args );
if ( ! empty( $event_ids ) ) {
foreach ( $event_ids as $event_id ) {
// Event Tickets Plus often stores total revenue in '_tribe_revenue_total' meta
$revenue = get_post_meta( $event_id, '_tribe_revenue_total', true );
if ( is_numeric( $revenue ) ) {
$total_revenue += (float) $revenue;
}
// Depending on the exact ticket plugin setup, this might need adjustment.
}
}
return $total_revenue;
}
/**
* Get the annual revenue target set by the trainer.
*
* @return float|null Returns the target as a float, or null if not set.
*/
public function get_annual_revenue_target() : ?float {
$target = get_user_meta( $this->user_id, 'annual_revenue_target', true );
return ! empty( $target ) && is_numeric( $target ) ? (float) $target : null;
}
/**
* Get the data needed for the events table on the dashboard.
*
* @param string $filter_status The status to filter events by ('all', 'publish', 'future', 'draft', 'pending', 'private'). Defaults to 'all'.
* @return array An array of event data arrays/objects, each containing keys like: id, status, name, link, date, organizer, capacity, sold, revenue.
*/
public function get_events_table_data( string $filter_status = 'all' ) : array {
$events_data = [];
$valid_statuses = array( 'publish', 'future', 'draft', 'pending', 'private' );
$post_status = ( 'all' === $filter_status || ! in_array( $filter_status, $valid_statuses, true ) )
? $valid_statuses
: array( $filter_status );
$args = array(
'post_type' => Tribe__Events__Main::POSTTYPE,
'author' => $this->user_id, // Query by post author
'post_status' => $post_status,
'posts_per_page' => -1,
'orderby' => 'meta_value', // Order by start date
'meta_key' => '_EventStartDate', // Specify the meta key for ordering
'order' => 'DESC', // Show most recent first
);
$query = new WP_Query( $args );
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
$query->the_post();
$event_id = get_the_ID();
// Get Capacity - Sum capacity of all tickets for this event
$total_capacity = 0;
if ( function_exists( 'tribe_get_tickets' ) ) {
$tickets = tribe_get_tickets( $event_id );
if ( $tickets ) {
foreach ( $tickets as $ticket ) {
$capacity = $ticket->capacity();
// -1 often means unlimited capacity for Tribe Tickets
if ( $capacity === -1 ) {
$total_capacity = -1; // Mark as unlimited
break; // No need to sum further if one is unlimited
}
if ( is_numeric( $capacity ) ) {
$total_capacity += $capacity;
}
}
}
}
$sold = get_post_meta( $event_id, '_tribe_tickets_sold', true );
$revenue = get_post_meta( $event_id, '_tribe_revenue_total', true );
$events_data[] = array(
'id' => $event_id,
'status' => get_post_status( $event_id ),
'name' => get_the_title(),
// Return raw data instead of calling TEC functions here
'link' => get_permalink( $event_id ), // Use standard WP permalink
'start_date_ts' => strtotime( get_post_meta( $event_id, '_EventStartDate', true ) ), // Return timestamp
'organizer_id' => (int) get_post_meta( $event_id, '_EventOrganizerID', true ), // Return organizer ID
'capacity' => ( $total_capacity === -1 ) ? 'Unlimited' : (int) $total_capacity,
'sold' => is_numeric( $sold ) ? (int) $sold : 0,
'revenue' => is_numeric( $revenue ) ? (float) $revenue : 0.0,
);
}
wp_reset_postdata(); // Restore original Post Data
}
return $events_data;
}
} // End class HVAC_Dashboard_Data