#!/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 "===== Debugging Dashboard Data Issues =====" # Check dashboard data echo "1. Checking dashboard data for test_trainer..." sshpass -p "$UPSKILL_STAGING_PASS" ssh -o StrictHostKeyChecking=no "$UPSKILL_STAGING_SSH_USER@$UPSKILL_STAGING_IP" "cd $UPSKILL_STAGING_PATH && cat > debug-dashboard-data.php << 'EOF' ID}\\n\"; echo \"Username: {\$user->user_login}\\n\"; echo \"User roles: \" . implode(', ', \$user->roles) . \"\\n\"; // Check for events associated with this user echo \"\\nEvents by author:\\n\"; \$events_by_author = get_posts(array( 'post_type' => 'tribe_events', 'author' => \$user->ID, 'posts_per_page' => -1, 'post_status' => array('publish', 'future', 'draft', 'pending', 'private') )); echo \"Found \" . count(\$events_by_author) . \" events by author\\n\"; if (count(\$events_by_author) > 0) { foreach (\$events_by_author as \$event) { echo \"- {\$event->ID}: {\$event->post_title} ({\$event->post_status})\\n\"; // Check for tickets associated with this event \$tickets = get_posts(array( 'post_type' => 'tribe_tpp_tickets', 'posts_per_page' => -1, 'meta_query' => array( array( 'key' => '_tribe_tpp_for_event', 'value' => \$event->ID ) ) )); echo \" Tickets: \" . count(\$tickets) . \"\\n\"; // Check for attendees \$attendees = get_posts(array( 'post_type' => 'tribe_tpp_attendees', 'posts_per_page' => -1, 'meta_query' => array( array( 'key' => '_tribe_tpp_event', 'value' => \$event->ID ) ) )); echo \" Attendees: \" . count(\$attendees) . \"\\n\"; } } // Check events by organizer echo \"\\nEvents by organizer meta:\\n\"; \$events_by_organizer = get_posts(array( 'post_type' => 'tribe_events', 'posts_per_page' => -1, 'post_status' => array('publish', 'future', 'draft', 'pending', 'private'), 'meta_query' => array( array( 'key' => '_EventOrganizerID', 'value' => \$user->ID ) ) )); echo \"Found \" . count(\$events_by_organizer) . \" events by organizer\\n\"; // Analyze the dashboard data class echo \"\\nAnalyzing dashboard data class:\\n\"; \$dashboard_data_path = WP_CONTENT_DIR . '/plugins/hvac-community-events/includes/class-hvac-dashboard-data.php'; if (file_exists(\$dashboard_data_path)) { // Load the class if it's not already loaded if (!class_exists('HVAC_Dashboard_Data')) { require_once \$dashboard_data_path; } // Create instance \$dashboard_data = new HVAC_Dashboard_Data(\$user->ID); // Get counts \$total_events = \$dashboard_data->get_total_events_count(); \$upcoming_events = \$dashboard_data->get_upcoming_events_count(); \$past_events = \$dashboard_data->get_past_events_count(); \$total_tickets = \$dashboard_data->get_total_tickets_sold(); \$total_revenue = \$dashboard_data->get_total_revenue(); echo \"Dashboard Data Results:\\n\"; echo \"- Total Events: {\$total_events}\\n\"; echo \"- Upcoming Events: {\$upcoming_events}\\n\"; echo \"- Past Events: {\$past_events}\\n\"; echo \"- Total Tickets: {\$total_tickets}\\n\"; echo \"- Total Revenue: {\$total_revenue}\\n\"; // Examine the methods echo \"\\nExamining get_total_events_count method:\\n\"; \$query = new WP_Query(array( 'post_type' => 'tribe_events', 'author' => \$user->ID, 'posts_per_page' => -1, 'post_status' => array('publish', 'future', 'draft', 'pending', 'private') )); echo \"Direct WP_Query count: \" . \$query->found_posts . \"\\n\"; // Try direct database query global \$wpdb; \$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', \$user->ID )); echo \"Direct SQL count: {\$count}\\n\"; // Examine get_total_tickets_sold method echo \"\\nExamining get_total_tickets_sold method:\\n\"; // Get all events by this author \$events = get_posts(array( 'post_type' => 'tribe_events', 'author' => \$user->ID, 'posts_per_page' => -1, 'post_status' => array('publish', 'future', 'draft', 'pending', 'private') )); \$total_tickets_direct = 0; foreach (\$events as \$event) { // Get attendees for this event \$attendees = get_posts(array( 'post_type' => 'tribe_tpp_attendees', 'posts_per_page' => -1, 'meta_query' => array( array( 'key' => '_tribe_tpp_event', 'value' => \$event->ID ) ) )); \$total_tickets_direct += count(\$attendees); } echo \"Direct ticket count: {\$total_tickets_direct}\\n\"; // Test if there's a mismatch between the dashboard data and our direct counts if (\$total_events != \$count || \$total_tickets != \$total_tickets_direct) { echo \"\\nDetected mismatch between dashboard data and direct counts!\\n\"; // Fix the dashboard data class \$dashboard_data_content = file_get_contents(\$dashboard_data_path); // Check if we're using the right post author vs organizer field if (strpos(\$dashboard_data_content, '_EventOrganizerID') !== false) { echo \"Class is using _EventOrganizerID meta instead of post_author\\n\"; // Fix get_total_events_count to use post_author \$new_get_total_events_count = '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; }'; // Fix get_upcoming_events_count to use post_author \$new_get_upcoming_events_count = 'public function get_upcoming_events_count() : int { global $wpdb; // Get current date in MySQL format $now = current_time(\'mysql\'); // Use direct database query to avoid TEC query hijacking $count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->posts} p 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\', \'draft\', \'pending\', \'private\') AND pm.meta_key = \'_EventStartDate\' AND pm.meta_value >= %s", Tribe__Events__Main::POSTTYPE, $this->user_id, $now ) ); return (int) $count; }'; // Fix get_past_events_count to use post_author \$new_get_past_events_count = 'public function get_past_events_count() : int { global $wpdb; // Get current date in MySQL format $now = current_time(\'mysql\'); // Use direct database query to avoid TEC query hijacking $count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->posts} p 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\', \'draft\', \'pending\', \'private\') AND pm.meta_key = \'_EventStartDate\' AND pm.meta_value < %s", Tribe__Events__Main::POSTTYPE, $this->user_id, $now ) ); return (int) $count; }'; // Update the class content \$dashboard_data_content = preg_replace( '/public function get_total_events_count\\(\\).*?\\{.*?\\}/s', \$new_get_total_events_count, \$dashboard_data_content ); \$dashboard_data_content = preg_replace( '/public function get_upcoming_events_count\\(\\).*?\\{.*?\\}/s', \$new_get_upcoming_events_count, \$dashboard_data_content ); \$dashboard_data_content = preg_replace( '/public function get_past_events_count\\(\\).*?\\{.*?\\}/s', \$new_get_past_events_count, \$dashboard_data_content ); // Save the updated class if (file_put_contents(\$dashboard_data_path, \$dashboard_data_content)) { echo \"Updated dashboard data class to use post_author consistently\\n\"; } else { echo \"Failed to update dashboard data class\\n\"; } } } } else { echo \"Dashboard data class not found at: {\$dashboard_data_path}\\n\"; } echo \"\\n===== Dashboard Data Debug Complete =====\\n\"; EOF" # Execute the dashboard data debug script echo "Executing dashboard data debug script..." sshpass -p "$UPSKILL_STAGING_PASS" ssh -o StrictHostKeyChecking=no "$UPSKILL_STAGING_SSH_USER@$UPSKILL_STAGING_IP" "cd $UPSKILL_STAGING_PATH && php debug-dashboard-data.php" # Clean up sshpass -p "$UPSKILL_STAGING_PASS" ssh -o StrictHostKeyChecking=no "$UPSKILL_STAGING_SSH_USER@$UPSKILL_STAGING_IP" "cd $UPSKILL_STAGING_PATH && rm debug-dashboard-data.php" # Now check the certificate reports page error echo -e "\n2. Debugging certificate reports critical error..." sshpass -p "$UPSKILL_STAGING_PASS" ssh -o StrictHostKeyChecking=no "$UPSKILL_STAGING_SSH_USER@$UPSKILL_STAGING_IP" "cd $UPSKILL_STAGING_PATH && cat > debug-certificate-reports.php << 'EOF' getMessage()}\\n\"; } } else { echo \"HVAC_Certificate_Manager class not found after loading file\\n\"; } } catch (Exception \$e) { echo \"Error loading Certificate Manager: {\$e->getMessage()}\\n\"; } } // Check the certificate reports template if (file_exists(\$cert_reports_template)) { echo \"\\nAnalyzing certificate reports template...\\n\"; \$template_content = file_get_contents(\$cert_reports_template); // Look for common issues in the template \$issues = array(); // Check for undefined variables preg_match_all('/\\$([a-zA-Z0-9_]+)/', \$template_content, \$matches); \$vars = \$matches[1]; \$defined_vars = array(); preg_match_all('/\\$([a-zA-Z0-9_]+)\\s*=/', \$template_content, \$def_matches); \$defined_vars = \$def_matches[1]; \$undefined_vars = array_diff(array_unique(\$vars), array_unique(\$defined_vars)); // Exclude common globals \$globals = array('post', 'wp_query', 'wpdb', 'current_user', 'user_ID'); \$undefined_vars = array_diff(\$undefined_vars, \$globals); if (count(\$undefined_vars) > 0) { \$issues[] = \"Potentially undefined variables: \" . implode(', ', \$undefined_vars); } // Check for debug statements if (preg_match('/var_dump|print_r|echo.*debug/i', \$template_content)) { \$issues[] = \"Contains debug statements that might be causing issues\"; } // Check for missing includes \$required_classes = array('HVAC_Certificate_Manager', 'HVAC_Certificate_Security'); foreach (\$required_classes as \$class) { if (strpos(\$template_content, \$class) !== false && strpos(\$template_content, \"new {\$class}\") !== false) { if (strpos(\$template_content, \"require_once\") === false) { \$issues[] = \"Uses {\$class} but doesn't include required files\"; } } } // Output issues if (count(\$issues) > 0) { echo \"Potential issues found in template:\\n\"; foreach (\$issues as \$issue) { echo \"- {\$issue}\\n\"; } // Try to fix issues echo \"\\nAttempting to fix template issues...\\n\"; // Remove debug statements \$fixed_content = preg_replace('/(var_dump|print_r)\\s*\\([^;]*\\);/', '', \$template_content); // Fix undefined variables foreach (\$undefined_vars as \$var) { // Only fix if not common variables if (!\in_array(\$var, array('user', 'event', 'page'))) { \$fixed_content = preg_replace('/\\$' . \$var . '\\b(?!\\s*=)/', '\\$' . \$var . ' = array(); // Auto-fixed undefined variable\\n\\$' . \$var, \$fixed_content, 1); } } // Add missing requires if (strpos(\$fixed_content, 'HVAC_Certificate_Manager') !== false && strpos(\$fixed_content, 'require_once') === false) { \$fixed_content = \"