## Major Enhancements ### 🏗️ Architecture & Infrastructure - Implement comprehensive Docker testing infrastructure with hermetic environment - Add Forgejo Actions CI/CD pipeline for automated deployments - Create Page Object Model (POM) testing architecture reducing test duplication by 90% - Establish security-first development patterns with input validation and output escaping ### 🧪 Testing Framework Modernization - Migrate 146+ tests from 80 duplicate files to centralized architecture - Add comprehensive E2E test suites for all user roles and workflows - Implement WordPress error detection with automatic site health monitoring - Create robust browser lifecycle management with proper cleanup ### 📚 Documentation & Guides - Add comprehensive development best practices guide - Create detailed administrator setup documentation - Establish user guides for trainers and master trainers - Document security incident reports and migration guides ### 🔧 Core Plugin Features - Enhance trainer profile management with certification system - Improve find trainer functionality with advanced filtering - Strengthen master trainer area with content management - Add comprehensive venue and organizer management ### 🛡️ Security & Reliability - Implement security-first patterns throughout codebase - Add comprehensive input validation and output escaping - Create secure credential management system - Establish proper WordPress role-based access control ### 🎯 WordPress Integration - Strengthen singleton pattern implementation across all classes - Enhance template hierarchy with proper WordPress integration - Improve page manager with hierarchical URL structure - Add comprehensive shortcode and menu system ### 🔍 Developer Experience - Add extensive debugging and troubleshooting tools - Create comprehensive test data seeding scripts - Implement proper error handling and logging - Establish consistent code patterns and standards ### 📊 Performance & Optimization - Optimize database queries and caching strategies - Improve asset loading and script management - Enhance template rendering performance - Streamline user experience across all interfaces 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
		
			
				
	
	
		
			228 lines
		
	
	
		
			No EOL
		
	
	
		
			8.2 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			228 lines
		
	
	
		
			No EOL
		
	
	
		
			8.2 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| /**
 | |
|  * PHP script to create sample certification data
 | |
|  * Run this on the staging server to test the new certification system
 | |
|  */
 | |
| 
 | |
| // This script should be run from the WordPress root directory
 | |
| // php test-create-sample-certifications.php
 | |
| 
 | |
| // Load WordPress
 | |
| if (!defined('ABSPATH')) {
 | |
|     require_once(dirname(__FILE__) . '/wp-config.php');
 | |
| }
 | |
| 
 | |
| if (!defined('ABSPATH')) {
 | |
|     die("Could not load WordPress. Make sure this script is in the WordPress root directory.\n");
 | |
| }
 | |
| 
 | |
| echo "🚀 Testing HVAC Certification System...\n";
 | |
| echo "=====================================\n\n";
 | |
| 
 | |
| // Test 1: Check if our classes are loaded
 | |
| echo "📋 1. Checking if certification classes are loaded...\n";
 | |
| 
 | |
| $classes_to_check = [
 | |
|     'HVAC_Trainer_Certification_Manager',
 | |
|     'HVAC_Certification_Migrator', 
 | |
|     'HVAC_Certification_Admin',
 | |
|     'HVAC_Trainer_Profile_Manager'
 | |
| ];
 | |
| 
 | |
| $loaded_classes = [];
 | |
| $missing_classes = [];
 | |
| 
 | |
| foreach ($classes_to_check as $class_name) {
 | |
|     if (class_exists($class_name)) {
 | |
|         $loaded_classes[] = $class_name;
 | |
|         echo "   ✅ {$class_name}: Loaded\n";
 | |
|     } else {
 | |
|         $missing_classes[] = $class_name;
 | |
|         echo "   ❌ {$class_name}: NOT LOADED\n";
 | |
|     }
 | |
| }
 | |
| 
 | |
| echo "\n";
 | |
| 
 | |
| // Test 2: Check post type registration
 | |
| echo "📋 2. Checking post type registration...\n";
 | |
| $post_types = get_post_types(['public' => true], 'objects');
 | |
| if (isset($post_types['trainer_certification'])) {
 | |
|     echo "   ✅ trainer_certification post type: Registered\n";
 | |
|     echo "      Label: " . $post_types['trainer_certification']->label . "\n";
 | |
| } else {
 | |
|     echo "   ❌ trainer_certification post type: NOT REGISTERED\n";
 | |
| }
 | |
| 
 | |
| echo "\n";
 | |
| 
 | |
| // Test 3: Find a test trainer
 | |
| echo "📋 3. Finding test trainer...\n";
 | |
| $trainers = get_users([
 | |
|     'role' => 'hvac_trainer',
 | |
|     'number' => 5,
 | |
|     'fields' => ['ID', 'user_login', 'user_email']
 | |
| ]);
 | |
| 
 | |
| if (empty($trainers)) {
 | |
|     echo "   ❌ No HVAC trainers found. Looking for any users...\n";
 | |
|     $trainers = get_users(['number' => 5, 'fields' => ['ID', 'user_login', 'user_email']]);
 | |
| }
 | |
| 
 | |
| if (empty($trainers)) {
 | |
|     die("   💥 No users found in the system. Cannot proceed with test.\n");
 | |
| }
 | |
| 
 | |
| $test_trainer = $trainers[0];
 | |
| echo "   ✅ Using test trainer: {$test_trainer->user_login} (ID: {$test_trainer->ID})\n";
 | |
| echo "\n";
 | |
| 
 | |
| // Test 4: Create sample certifications (only if classes are loaded)
 | |
| if (in_array('HVAC_Trainer_Certification_Manager', $loaded_classes)) {
 | |
|     echo "📋 4. Creating sample certifications...\n";
 | |
|     
 | |
|     $cert_manager = HVAC_Trainer_Certification_Manager::instance();
 | |
|     
 | |
|     $sample_certifications = [
 | |
|         [
 | |
|             'type' => 'measureQuick Certified Trainer',
 | |
|             'status' => 'active',
 | |
|             'issue_date' => '2024-01-15',
 | |
|             'expiration_date' => '2026-01-15',
 | |
|             'certification_number' => 'MQT-TEST-001',
 | |
|             'notes' => 'Test certification - Active and valid'
 | |
|         ],
 | |
|         [
 | |
|             'type' => 'measureQuick Certified Champion',
 | |
|             'status' => 'active',
 | |
|             'issue_date' => '2024-06-01',
 | |
|             'expiration_date' => '2025-01-15', // Expiring soon
 | |
|             'certification_number' => 'MQC-TEST-001', 
 | |
|             'notes' => 'Test certification - Expiring soon'
 | |
|         ],
 | |
|         [
 | |
|             'type' => 'measureQuick Certified Trainer',
 | |
|             'status' => 'expired',
 | |
|             'issue_date' => '2022-03-10',
 | |
|             'expiration_date' => '2024-03-10', // Already expired
 | |
|             'certification_number' => 'MQT-TEST-EXPIRED',
 | |
|             'notes' => 'Test certification - Expired'
 | |
|         ]
 | |
|     ];
 | |
|     
 | |
|     $created_certifications = [];
 | |
|     
 | |
|     foreach ($sample_certifications as $i => $cert_data) {
 | |
|         echo "   📝 Creating certification " . ($i + 1) . ": {$cert_data['type']} ({$cert_data['status']})...\n";
 | |
|         
 | |
|         try {
 | |
|             $result = $cert_manager->create_certification(
 | |
|                 $test_trainer->ID,
 | |
|                 $cert_data['type'],
 | |
|                 [
 | |
|                     'status' => $cert_data['status'],
 | |
|                     'issue_date' => $cert_data['issue_date'],
 | |
|                     'expiration_date' => $cert_data['expiration_date'],
 | |
|                     'certification_number' => $cert_data['certification_number'],
 | |
|                     'notes' => $cert_data['notes'],
 | |
|                     'issued_by' => get_current_user_id() ?: 1
 | |
|                 ]
 | |
|             );
 | |
|             
 | |
|             if (is_wp_error($result)) {
 | |
|                 echo "      ❌ Failed: " . $result->get_error_message() . "\n";
 | |
|             } else {
 | |
|                 echo "      ✅ Created post ID: {$result}\n";
 | |
|                 $created_certifications[] = $result;
 | |
|                 
 | |
|                 // Mark as test data for cleanup
 | |
|                 update_post_meta($result, '_test_certification', true);
 | |
|             }
 | |
|             
 | |
|         } catch (Exception $e) {
 | |
|             echo "      💥 Exception: " . $e->getMessage() . "\n";
 | |
|         }
 | |
|     }
 | |
|     
 | |
|     echo "\n";
 | |
|     
 | |
|     // Test 5: Verify created data
 | |
|     if (!empty($created_certifications)) {
 | |
|         echo "📋 5. Verifying created certifications...\n";
 | |
|         
 | |
|         $trainer_certs = $cert_manager->get_trainer_certifications($test_trainer->ID);
 | |
|         echo "   📊 Found " . count($trainer_certs) . " certifications for trainer {$test_trainer->user_login}\n";
 | |
|         
 | |
|         foreach ($trainer_certs as $cert) {
 | |
|             $cert_type = get_post_meta($cert->ID, 'certification_type', true);
 | |
|             $status = get_post_meta($cert->ID, 'status', true);
 | |
|             $exp_date = get_post_meta($cert->ID, 'expiration_date', true);
 | |
|             
 | |
|             echo "      🏆 {$cert->post_title}\n";
 | |
|             echo "         Type: {$cert_type}\n";
 | |
|             echo "         Status: {$status}\n";
 | |
|             echo "         Expires: {$exp_date}\n";
 | |
|         }
 | |
|         
 | |
|         echo "\n";
 | |
|         
 | |
|         // Test 6: Test the profile manager display method
 | |
|         if (in_array('HVAC_Trainer_Profile_Manager', $loaded_classes)) {
 | |
|             echo "📋 6. Testing profile manager display method...\n";
 | |
|             
 | |
|             $profile_manager = HVAC_Trainer_Profile_Manager::get_instance();
 | |
|             
 | |
|             if (method_exists($profile_manager, 'get_trainer_certifications')) {
 | |
|                 $formatted_certs = $profile_manager->get_trainer_certifications($test_trainer->ID);
 | |
|                 echo "   📊 Profile manager returned " . count($formatted_certs) . " formatted certifications\n";
 | |
|                 
 | |
|                 foreach ($formatted_certs as $cert) {
 | |
|                     echo "      🎴 {$cert['title']}\n";
 | |
|                     echo "         Type: {$cert['type']}\n";
 | |
|                     echo "         Status: {$cert['status']}\n";
 | |
|                     echo "         Expiration Status: {$cert['expiration_status']}\n";
 | |
|                     echo "         Display Color: {$cert['display_color']}\n";
 | |
|                     if (isset($cert['days_until_expiration'])) {
 | |
|                         echo "         Days until expiration: {$cert['days_until_expiration']}\n";
 | |
|                     }
 | |
|                     echo "\n";
 | |
|                 }
 | |
|             } else {
 | |
|                 echo "   ❌ get_trainer_certifications method not found in profile manager\n";
 | |
|             }
 | |
|             
 | |
|             echo "\n";
 | |
|         }
 | |
|     }
 | |
|     
 | |
| } else {
 | |
|     echo "📋 4. SKIPPED: Creating sample certifications (certification manager not loaded)\n\n";
 | |
| }
 | |
| 
 | |
| // Summary
 | |
| echo "📋 Test Summary:\n";
 | |
| echo "===============\n";
 | |
| echo "✅ Classes loaded: " . count($loaded_classes) . "/" . count($classes_to_check) . "\n";
 | |
| echo "✅ Test trainer found: {$test_trainer->user_login}\n";
 | |
| 
 | |
| if (isset($created_certifications)) {
 | |
|     echo "✅ Certifications created: " . count($created_certifications) . "\n";
 | |
| }
 | |
| 
 | |
| if (!empty($missing_classes)) {
 | |
|     echo "\n⚠️ Missing classes that need attention:\n";
 | |
|     foreach ($missing_classes as $class) {
 | |
|         echo "   - {$class}\n";
 | |
|     }
 | |
| }
 | |
| 
 | |
| echo "\n🎉 Test completed!\n";
 | |
| 
 | |
| // Cleanup instructions
 | |
| if (isset($created_certifications) && !empty($created_certifications)) {
 | |
|     echo "\n🧹 To cleanup test data, run:\n";
 | |
|     echo "DELETE FROM wp_posts WHERE post_type = 'trainer_certification' AND ID IN (" . implode(',', $created_certifications) . ");\n";
 | |
|     echo "DELETE FROM wp_postmeta WHERE post_id IN (" . implode(',', $created_certifications) . ");\n";
 | |
| }
 | |
| 
 | |
| ?>
 |