upskill-event-manager/includes/class-hvac-dashboard-data-refactored.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

335 lines
No EOL
8.2 KiB
PHP

<?php
/**
* HVAC Community Events Dashboard Data Handler - Refactored
*
* Optimized version with better caching and query optimization
*
* @package HVAC_Community_Events
* @subpackage Includes
* @since 1.1.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Class HVAC_Dashboard_Data_Refactored
*/
class HVAC_Dashboard_Data_Refactored {
/**
* The ID of the trainer user.
*
* @var int
*/
private int $user_id;
/**
* Cache group for dashboard data
*
* @var string
*/
private $cache_group = 'hvac_dashboard';
/**
* Cache expiration time (5 minutes)
*
* @var int
*/
private $cache_expiration = 300;
/**
* Constructor.
*
* @param int $user_id The ID of the trainer user.
*/
public function __construct( int $user_id ) {
$this->user_id = $user_id;
}
/**
* Get all dashboard stats in a single cached object
*
* @return array
*/
public function get_all_stats() : array {
$cache_key = 'stats_' . $this->user_id;
$stats = wp_cache_get( $cache_key, $this->cache_group );
if ( false === $stats ) {
$stats = array(
'total_events' => $this->calculate_total_events_count(),
'upcoming_events' => $this->calculate_upcoming_events_count(),
'past_events' => $this->calculate_past_events_count(),
'total_tickets' => $this->calculate_total_tickets_sold(),
'total_revenue' => $this->calculate_total_revenue(),
'revenue_target' => $this->get_annual_revenue_target(),
);
wp_cache_set( $cache_key, $stats, $this->cache_group, $this->cache_expiration );
HVAC_Logger::info( 'Dashboard stats calculated and cached', 'Dashboard', array( 'user_id' => $this->user_id ) );
}
return $stats;
}
/**
* Clear cache for a specific user
*
* @return void
*/
public function clear_cache() {
$cache_key = 'stats_' . $this->user_id;
wp_cache_delete( $cache_key, $this->cache_group );
HVAC_Logger::info( 'Dashboard cache cleared', 'Dashboard', array( 'user_id' => $this->user_id ) );
}
/**
* Calculate total events count (optimized)
*
* @return int
*/
private function calculate_total_events_count() : int {
global $wpdb;
// Direct query is more efficient for simple counts
$count = $wpdb->get_var( $wpdb->prepare(
"SELECT COUNT(ID) FROM {$wpdb->posts}
WHERE post_type = %s
AND post_author = %d
AND post_status IN ('publish', 'future', 'draft', 'pending', 'private')",
Tribe__Events__Main::POSTTYPE,
$this->user_id
) );
return (int) $count;
}
/**
* Calculate upcoming events count
*
* @return int
*/
private function calculate_upcoming_events_count() : int {
global $wpdb;
$today = current_time( 'mysql' );
// Query using post_author and meta data
$count = $wpdb->get_var( $wpdb->prepare(
"SELECT COUNT(DISTINCT p.ID)
FROM {$wpdb->posts} p
INNER JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id
WHERE p.post_type = %s
AND p.post_author = %d
AND p.post_status IN ('publish', 'future')
AND pm.meta_key = '_EventStartDate'
AND pm.meta_value >= %s",
Tribe__Events__Main::POSTTYPE,
$this->user_id,
$today
) );
return (int) $count;
}
/**
* Calculate past events count
*
* @return int
*/
private function calculate_past_events_count() : int {
global $wpdb;
$today = current_time( 'mysql' );
$count = $wpdb->get_var( $wpdb->prepare(
"SELECT COUNT(DISTINCT p.ID)
FROM {$wpdb->posts} p
INNER JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id
WHERE p.post_type = %s
AND p.post_author = %d
AND p.post_status IN ('publish', 'private')
AND pm.meta_key = '_EventEndDate'
AND pm.meta_value < %s",
Tribe__Events__Main::POSTTYPE,
$this->user_id,
$today
) );
return (int) $count;
}
/**
* Calculate total tickets sold (optimized with single query)
*
* @return int
*/
private function calculate_total_tickets_sold() : int {
global $wpdb;
// Get all event IDs in one query
$event_ids = $wpdb->get_col( $wpdb->prepare(
"SELECT ID FROM {$wpdb->posts}
WHERE post_type = %s
AND post_author = %d
AND post_status IN ('publish', 'future', 'draft', 'pending', 'private')",
Tribe__Events__Main::POSTTYPE,
$this->user_id
) );
if ( empty( $event_ids ) ) {
return 0;
}
// Get sum of tickets sold in one query
$placeholders = array_fill( 0, count( $event_ids ), '%d' );
$sql = $wpdb->prepare(
"SELECT SUM(meta_value)
FROM {$wpdb->postmeta}
WHERE meta_key = '_tribe_tickets_sold'
AND post_id IN (" . implode( ',', $placeholders ) . ")",
$event_ids
);
$total = $wpdb->get_var( $sql );
return (int) $total;
}
/**
* Calculate total revenue (optimized)
*
* @return float
*/
private function calculate_total_revenue() : float {
global $wpdb;
// Get all event IDs in one query
$event_ids = $wpdb->get_col( $wpdb->prepare(
"SELECT ID FROM {$wpdb->posts}
WHERE post_type = %s
AND post_author = %d
AND post_status IN ('publish', 'future', 'draft', 'pending', 'private')",
Tribe__Events__Main::POSTTYPE,
$this->user_id
) );
if ( empty( $event_ids ) ) {
return 0.0;
}
// Get sum of revenue in one query
$placeholders = array_fill( 0, count( $event_ids ), '%d' );
$sql = $wpdb->prepare(
"SELECT SUM(meta_value)
FROM {$wpdb->postmeta}
WHERE meta_key = '_tribe_revenue_total'
AND post_id IN (" . implode( ',', $placeholders ) . ")",
$event_ids
);
$total = $wpdb->get_var( $sql );
return (float) $total;
}
/**
* Get annual revenue target
*
* @return float|null
*/
private 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 events table data (optimized)
*
* @param string $filter_status Status filter
* @return array
*/
public function get_events_table_data( string $filter_status = 'all' ) : array {
global $wpdb;
$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 );
// Convert to SQL-safe string
$status_placeholders = array_fill( 0, count( $post_status ), '%s' );
$status_sql = implode( ',', $status_placeholders );
// Get all events with their metadata in fewer queries
$sql = $wpdb->prepare(
"SELECT p.ID, p.post_title, p.post_status, p.guid,
MAX(CASE WHEN pm.meta_key = '_EventStartDate' THEN pm.meta_value END) as start_date,
MAX(CASE WHEN pm.meta_key = '_EventOrganizerID' THEN pm.meta_value END) as organizer_id,
MAX(CASE WHEN pm.meta_key = '_tribe_tickets_sold' THEN pm.meta_value END) as tickets_sold,
MAX(CASE WHEN pm.meta_key = '_tribe_revenue_total' THEN pm.meta_value END) as revenue
FROM {$wpdb->posts} p
LEFT JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id
WHERE p.post_type = %s
AND p.post_author = %d
AND p.post_status IN ($status_sql)
GROUP BY p.ID
ORDER BY start_date DESC",
array_merge(
array( Tribe__Events__Main::POSTTYPE, $this->user_id ),
$post_status
)
);
$events = $wpdb->get_results( $sql );
$events_data = array();
foreach ( $events as $event ) {
// Get ticket capacity
$capacity = $this->get_event_capacity( $event->ID );
$events_data[] = array(
'id' => $event->ID,
'status' => $event->post_status,
'name' => $event->post_title,
'link' => get_permalink( $event->ID ),
'start_date_ts' => strtotime( $event->start_date ),
'organizer_id' => (int) $event->organizer_id,
'capacity' => $capacity,
'sold' => (int) $event->tickets_sold,
'revenue' => (float) $event->revenue,
);
}
return $events_data;
}
/**
* Get event capacity
*
* @param int $event_id Event ID
* @return string|int
*/
private function get_event_capacity( $event_id ) {
if ( ! function_exists( 'tribe_get_tickets' ) ) {
return 0;
}
$tickets = tribe_get_tickets( $event_id );
$total_capacity = 0;
foreach ( $tickets as $ticket ) {
$capacity = $ticket->capacity();
if ( $capacity === -1 ) {
return 'Unlimited';
}
if ( is_numeric( $capacity ) ) {
$total_capacity += $capacity;
}
}
return $total_capacity;
}
}