#!/bin/bash # Exit on error set -e # Source environment variables if [ -f ".env" ]; then source .env else echo "Error: .env file not found. Please create it with the required variables." exit 1 fi echo "===== Complete Dashboard Restoration =====" # Create a working dashboard data class from scratch WORKING_CLASS='user_id = $user_id; } /** * Get the total number of events created by the trainer. * * @return int */ public function get_total_events_count() : int { global $wpdb; // Use direct database query to avoid TEC query hijacking $count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) 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; } /** * Get the number of upcoming events for the trainer. * * @return int */ public function get_upcoming_events_count() : int { global $wpdb; $today = date( "Y-m-d H:i:s" ); // Use direct database query to avoid TEC query hijacking $count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->posts} p LEFT JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id AND pm.meta_key = \"_EventStartDate\" WHERE p.post_type = %s AND p.post_author = %d AND p.post_status IN (\"publish\", \"future\") AND (pm.meta_value >= %s OR pm.meta_value IS NULL)", Tribe__Events__Main::POSTTYPE, $this->user_id, $today ) ); return (int) $count; } /** * Get the number of past events for the trainer. * * @return int */ public function get_past_events_count() : int { global $wpdb; $today = date( "Y-m-d H:i:s" ); // Use direct database query to avoid TEC query hijacking $count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->posts} p LEFT JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id AND pm.meta_key = \"_EventEndDate\" WHERE p.post_type = %s AND p.post_author = %d AND p.post_status IN (\"publish\", \"private\") AND pm.meta_value < %s", Tribe__Events__Main::POSTTYPE, $this->user_id, $today ) ); return (int) $count; } /** * 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, // Use author instead of meta query "post_status" => array( "publish", "future", "draft", "pending", "private" ), "posts_per_page" => -1, "fields" => "ids", ); $event_ids = get_posts( $args ); if ( ! empty( $event_ids ) ) { foreach ( $event_ids as $event_id ) { // Check both meta keys that might store sold count $sold = get_post_meta( $event_id, "_tribe_tickets_sold", true ); if (!is_numeric($sold)) { $sold = get_post_meta( $event_id, "_tribe_ticket_sold_count", true ); } if ( is_numeric( $sold ) ) { $total_tickets += (int) $sold; } else { // If no sold count metadata found, count attendees directly $attendees_count = $this->count_event_attendees($event_id); if ($attendees_count > 0) { $total_tickets += $attendees_count; update_post_meta($event_id, "_tribe_tickets_sold", $attendees_count); } } } } 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, // Use author instead of meta query "post_status" => array( "publish", "future", "draft", "pending", "private" ), "posts_per_page" => -1, "fields" => "ids", ); $event_ids = get_posts( $args ); if ( ! empty( $event_ids ) ) { foreach ( $event_ids as $event_id ) { $revenue = get_post_meta( $event_id, "_tribe_revenue_total", true ); if ( is_numeric( $revenue ) ) { $total_revenue += (float) $revenue; } else { $event_revenue = $this->calculate_event_revenue($event_id); if ($event_revenue > 0) { $total_revenue += $event_revenue; update_post_meta($event_id, "_tribe_revenue_total", $event_revenue); } } } } return $total_revenue; } /** * Get the data needed for the events table on the dashboard. * * @param string $filter_status The status to filter events by * @return array An array of event data */ 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, "post_status" => $post_status, "posts_per_page" => -1, "orderby" => "meta_value", "meta_key" => "_EventStartDate", "order" => "DESC", ); $query = new WP_Query( $args ); if ( $query->have_posts() ) { while ( $query->have_posts() ) { $query->the_post(); $event_id = get_the_ID(); $sold = get_post_meta( $event_id, "_tribe_tickets_sold", true ); if (!is_numeric($sold)) { $sold = get_post_meta( $event_id, "_tribe_ticket_sold_count", true ); if (!is_numeric($sold)) { $sold = $this->count_event_attendees($event_id); if ($sold > 0) { update_post_meta($event_id, "_tribe_tickets_sold", $sold); } } } $revenue = get_post_meta( $event_id, "_tribe_revenue_total", true ); if (!is_numeric($revenue)) { $revenue = $this->calculate_event_revenue($event_id); if ($revenue > 0) { update_post_meta($event_id, "_tribe_revenue_total", $revenue); } } $events_data[] = array( "id" => $event_id, "status" => get_post_status( $event_id ), "name" => get_the_title(), "link" => get_permalink( $event_id ), "start_date_ts" => strtotime( get_post_meta( $event_id, "_EventStartDate", true ) ), "organizer_id" => (int) get_post_meta( $event_id, "_EventOrganizerID", true ), "capacity" => "Unlimited", "sold" => is_numeric( $sold ) ? (int) $sold : 0, "revenue" => is_numeric( $revenue ) ? (float) $revenue : 0.0, ); } wp_reset_postdata(); } return $events_data; } /** * Count the number of attendees for an event * * @param int $event_id Event ID * @return int Number of attendees */ private function count_event_attendees(int $event_id) : int { $attendees_query = new WP_Query([ "post_type" => "tribe_tpp_attendees", "posts_per_page" => -1, "fields" => "ids", "meta_query" => [ [ "key" => "_tribe_tpp_event", "value" => $event_id, "compare" => "=", ], ], ]); return $attendees_query->found_posts; } /** * Calculate total revenue for an event * * @param int $event_id Event ID * @return float Total revenue */ private function calculate_event_revenue(int $event_id) : float { $total_revenue = 0.0; $tickets_query = new WP_Query([ "post_type" => "tribe_tpp_tickets", "posts_per_page" => -1, "meta_query" => [ [ "key" => "_tribe_tpp_for_event", "value" => $event_id, "compare" => "=", ], ], ]); if ($tickets_query->have_posts()) { while ($tickets_query->have_posts()) { $tickets_query->the_post(); $ticket_id = get_the_ID(); $price = get_post_meta($ticket_id, "_price", true); $sold = get_post_meta($ticket_id, "_tribe_tpp_sold", true); if (is_numeric($price) && is_numeric($sold)) { $total_revenue += ((float)$price * (int)$sold); } } wp_reset_postdata(); } return $total_revenue; } } // End class HVAC_Dashboard_Data' # Upload the working class echo "Creating working dashboard data class..." sshpass -p "$UPSKILL_STAGING_PASS" ssh -o StrictHostKeyChecking=no "$UPSKILL_STAGING_SSH_USER@$UPSKILL_STAGING_IP" "cd $UPSKILL_STAGING_PATH && cat > wp-content/plugins/hvac-community-events/includes/class-hvac-dashboard-data.php << 'EOF' $WORKING_CLASS EOF" # Create and execute test script TEST_SCRIPT=" 'tribe_events', 'author' => \$user->ID, 'posts_per_page' => 1 )); if (empty(\$events)) { echo \"Creating test data...\\n\"; \$event_id = wp_insert_post(array( 'post_title' => 'HVAC Certification Training', 'post_content' => 'Comprehensive HVAC certification training course.', 'post_status' => 'publish', 'post_type' => 'tribe_events', 'post_author' => \$user->ID )); if (\$event_id) { update_post_meta(\$event_id, '_EventStartDate', date('Y-m-d H:i:s', strtotime('+1 week'))); update_post_meta(\$event_id, '_EventEndDate', date('Y-m-d H:i:s', strtotime('+1 week +8 hours'))); update_post_meta(\$event_id, '_tribe_tickets_sold', 18); update_post_meta(\$event_id, '_tribe_revenue_total', 1800.00); echo \"Created test event with ID: \$event_id\\n\"; } } // Test dashboard data \$dashboard_data = new HVAC_Dashboard_Data(\$user->ID); echo \"\\nDashboard Results:\\n\"; echo \"Total Events: \" . \$dashboard_data->get_total_events_count() . \"\\n\"; echo \"Upcoming Events: \" . \$dashboard_data->get_upcoming_events_count() . \"\\n\"; echo \"Past Events: \" . \$dashboard_data->get_past_events_count() . \"\\n\"; echo \"Total Tickets: \" . \$dashboard_data->get_total_tickets_sold() . \"\\n\"; echo \"Total Revenue: $\" . \$dashboard_data->get_total_revenue() . \"\\n\"; echo \"\\nDashboard restoration complete!\\n\"; " # Execute test echo "Testing dashboard after restoration..." sshpass -p "$UPSKILL_STAGING_PASS" ssh -o StrictHostKeyChecking=no "$UPSKILL_STAGING_SSH_USER@$UPSKILL_STAGING_IP" "cd $UPSKILL_STAGING_PATH && cat > test-dashboard-restore.php << 'EOF' $TEST_SCRIPT EOF" sshpass -p "$UPSKILL_STAGING_PASS" ssh -o StrictHostKeyChecking=no "$UPSKILL_STAGING_SSH_USER@$UPSKILL_STAGING_IP" "cd $UPSKILL_STAGING_PATH && php test-dashboard-restore.php" # Clean up sshpass -p "$UPSKILL_STAGING_PASS" ssh -o StrictHostKeyChecking=no "$UPSKILL_STAGING_SSH_USER@$UPSKILL_STAGING_IP" "cd $UPSKILL_STAGING_PATH && rm test-dashboard-restore.php" echo -e "\n===== Dashboard Restoration Complete =====" echo "The dashboard has been completely restored and should now work correctly." echo "Please refresh the dashboard page to see the updated data."