COMPREHENSIVE CSV IMPORT SYSTEM REDESIGN Problem Resolved: - Trainer profiles missing critical information from CSV_Trainers_Import_1Aug2025.csv - Existing import system used hardcoded data instead of reading actual CSV file - Missing 19 fields of professional information including phone numbers, websites, certifications Solution Implemented: - Complete enhanced CSV import system reading actual CSV file with 43 trainer records - Full taxonomy integration for business_type and training_audience classifications - Comprehensive field mapping for all 19 available CSV fields - Multi-value taxonomy handling for comma-separated fields - Automatic venue/organizer creation based on CSV flags Key Components Added: - includes/enhanced-csv-import-from-file.php: Main CSV import class with comprehensive processing - Updated includes/class-hvac-geocoding-ajax.php: Enhanced AJAX integration - includes/taxonomy-migration.php: Safe data migration utilities - Comprehensive error handling, progress tracking, and logging Fields Now Imported: - Contact: Name, Email, Phone, Website - Professional: Company, Role, Certification details (date, type, status) - Location: Country, State, City - Taxonomies: Business Type, Training Audience with multi-value support - System: Application Details, User ID, Venue/Organizer creation flags Testing Results: - 43 CSV rows processed successfully - 43 trainer profiles updated with enhanced data - Proper taxonomy assignments with comma-separated value handling - Automatic venue/organizer creation - Zero errors during import process - Complete data integrity preserved TAXONOMY SYSTEM ENHANCEMENTS Trainer Profile Taxonomy Implementation: - WordPress taxonomies for business_type and training_audience - Dynamic form loading from taxonomy terms with fallback support - Multi-value checkbox and radio interfaces - Safe data migration from text fields to taxonomies Template Updates: - templates/template-edit-profile.php: Dynamic taxonomy loading - templates/page-master-trainer-profile-edit.php: Enhanced taxonomy management - templates/page-master-dashboard.php: Fixed critical PHP fatal error Critical Bug Fixes: - Fixed HVAC_Community_Events::get_instance() undefined method error - Master dashboard template now uses correct instance() method - Eliminated PHP fatal errors preventing master trainer access COMPREHENSIVE TESTING & VALIDATION E2E Testing with Playwright: - 87.5% test pass rate (7/8 tests passing) - Registration form taxonomy integration verified - Profile editing with taxonomy selections confirmed - Data persistence across sessions validated - Comprehensive visual evidence captured Documentation Updates: - docs/API-REFERENCE.md: Complete CSV import AJAX endpoint documentation - docs/DEVELOPMENT-GUIDE.md: CSV import architecture and best practices - docs/README.md: Enhanced system overview with CSV import features - CLAUDE.md: Comprehensive memory entry for future reference Production Impact: - Complete trainer profiles with professional information - Enhanced business categorization through taxonomy system - Automatic event management preparation with venues/organizers - Improved master trainer dashboard functionality - Zero data loss with comprehensive error handling 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
17 KiB
17 KiB
HVAC Plugin Development Guide
Table of Contents
- Development Setup
- Coding Standards
- Architecture Principles
- Development Workflow
- Testing Guidelines
- Deployment Process
- Security Best Practices
- Performance Optimization
Development Setup
Prerequisites
- PHP 7.4+ (8.0+ recommended)
- Node.js 16+ and npm
- Composer
- WP-CLI
- Git
Local Environment Setup
- Clone Repository
git clone <repository-url>
cd upskill-event-manager
- Install Dependencies
# PHP dependencies
composer install
# Node dependencies
npm install
# Create .env file
cp .env.example .env
# Edit .env with your environment details
- Configure WordPress
- Install WordPress locally
- Create database
- Configure wp-config.php
- Install The Events Calendar plugin
- Activate Plugin
wp plugin activate hvac-community-events
Coding Standards
PHP Standards
- Follow WordPress Coding Standards
// Good
function hvac_get_trainer_events( $trainer_id ) {
$args = array(
'post_type' => 'tribe_events',
'posts_per_page' => -1,
'meta_query' => array(
array(
'key' => '_EventTrainerID',
'value' => $trainer_id,
'compare' => '='
)
)
);
return get_posts( $args );
}
// Bad
function getTrainerEvents($trainerId) {
$args = [
'post_type' => 'tribe_events',
'posts_per_page' => -1,
'meta_query' => [
['key' => '_EventTrainerID', 'value' => $trainerId, 'compare' => '=']
]
];
return get_posts($args);
}
- Namespace Usage
// Use prefixes instead of PHP namespaces for WordPress compatibility
class HVAC_Event_Manager {
// Class implementation
}
- Security First
// Always escape output
echo esc_html( $trainer_name );
echo esc_url( $profile_url );
echo esc_attr( $css_class );
// Sanitize input
$trainer_id = absint( $_GET['trainer_id'] );
$search = sanitize_text_field( $_POST['search'] );
// Verify nonces
if ( ! wp_verify_nonce( $_POST['hvac_nonce'], 'hvac_action' ) ) {
wp_die( 'Security check failed' );
}
JavaScript Standards
- jQuery Usage
// Always use jQuery in no-conflict mode
jQuery(document).ready(function($) {
// $ is now safe to use
$('.hvac-button').on('click', function(e) {
e.preventDefault();
// Handle click
});
});
- AJAX Requests
jQuery.ajax({
url: hvac_ajax.ajax_url,
type: 'POST',
data: {
action: 'hvac_update_profile',
nonce: hvac_ajax.nonce,
data: formData
},
success: function(response) {
if (response.success) {
// Handle success
} else {
// Handle error
console.error(response.data.message);
}
}
});
CSS Standards
- BEM Methodology
/* Block */
.hvac-trainer-card {}
/* Element */
.hvac-trainer-card__header {}
.hvac-trainer-card__content {}
/* Modifier */
.hvac-trainer-card--featured {}
- Specificity Rules
/* Avoid overly specific selectors */
/* Bad */
body.logged-in .hvac-wrapper div.container .hvac-trainer-card {}
/* Good */
.hvac-trainer-card {}
/* When specificity is needed for theme overrides */
.hvac-astra-integrated .hvac-trainer-card {}
Architecture Principles
1. Single Responsibility Principle
Each class should have one primary responsibility:
// Good - Focused classes
class HVAC_Certificate_Generator {} // Only handles PDF generation
class HVAC_Event_Manager {} // Only manages events
class HVAC_Email_Sender {} // Only sends emails
// Bad - Kitchen sink class
class HVAC_Everything {} // Does certificates, events, emails, etc.
2. Dependency Injection
class HVAC_Certificate_Service {
private $generator;
private $emailer;
public function __construct( $generator, $emailer ) {
$this->generator = $generator;
$this->emailer = $emailer;
}
}
3. Hook-Driven Architecture
// Use WordPress hooks for extensibility
do_action( 'hvac_before_event_save', $event_data );
$event_data = apply_filters( 'hvac_event_data', $event_data );
do_action( 'hvac_after_event_save', $event_id );
4. Singleton Pattern (where appropriate)
class HVAC_Plugin {
private static $instance = null;
public static function instance() {
if ( null === self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
private function __construct() {
// Initialize
}
}
Development Workflow
1. Feature Development
# Create feature branch
git checkout -b feature/new-trainer-dashboard
# Make changes
# Test thoroughly
# Commit with meaningful messages
git add .
git commit -m "feat: Add advanced filtering to trainer dashboard
- Add date range picker
- Add event status filter
- Add export functionality"
# Push and create PR
git push origin feature/new-trainer-dashboard
2. Git Commit Messages
Follow conventional commits:
feat:New featurefix:Bug fixdocs:Documentationstyle:Formatting changesrefactor:Code restructuringtest:Test additions/changeschore:Maintenance tasks
3. Code Review Checklist
- Follows WordPress coding standards
- Security measures implemented (escaping, sanitization)
- Performance impact considered
- Backward compatibility maintained
- Documentation updated
- Tests written/updated
Testing Guidelines
1. Unit Testing
class Test_HVAC_Event_Manager extends WP_UnitTestCase {
public function test_create_event() {
$event_data = array(
'post_title' => 'Test Event',
'EventStartDate' => '2025-08-15 09:00:00'
);
$event_id = HVAC_Event_Manager::create_event( $event_data );
$this->assertIsInt( $event_id );
$this->assertGreaterThan( 0, $event_id );
}
}
2. E2E Testing with Playwright
test('Trainer can create event', async ({ page }) => {
// Login
await loginAsTrainer(page);
// Navigate to event creation
await page.goto('/trainer/event/manage/');
// Fill form
await page.fill('#event-title', 'HVAC Training Session');
await page.selectOption('#event-venue', 'Main Campus');
// Submit
await page.click('button[type="submit"]');
// Verify
await expect(page).toHaveURL(/event-created/);
});
3. Manual Testing Checklist
- Test on staging before production
- Test with different user roles
- Test on mobile devices
- Test with different themes (especially Astra)
- Test with caching enabled
Deployment Process
1. Pre-Deployment Checks
# Run validation
bin/pre-deployment-check.sh
# Run tests
npm test
phpunit
2. Staging Deployment
# Deploy to staging
scripts/deploy.sh staging
# Verify deployment
scripts/verify-plugin-fixes.sh
3. Production Deployment
# Only when explicitly requested
scripts/deploy.sh production
# Requires double confirmation
4. Post-Deployment
- Monitor error logs
- Check critical functionality
- Be ready to rollback if needed
Security Best Practices
1. Data Validation
// Input validation
if ( ! is_email( $email ) ) {
wp_die( 'Invalid email address' );
}
// Type checking
$event_id = absint( $_POST['event_id'] );
if ( ! $event_id ) {
wp_die( 'Invalid event ID' );
}
2. SQL Queries
// Always use prepared statements
global $wpdb;
$results = $wpdb->get_results(
$wpdb->prepare(
"SELECT * FROM {$wpdb->posts} WHERE post_author = %d AND post_type = %s",
$user_id,
'tribe_events'
)
);
3. File Uploads
// Validate file types
$allowed_types = array( 'jpg', 'jpeg', 'png', 'pdf' );
$file_type = wp_check_filetype( $file['name'] );
if ( ! in_array( $file_type['ext'], $allowed_types ) ) {
wp_die( 'Invalid file type' );
}
4. Capability Checks
// Always verify user permissions
if ( ! current_user_can( 'manage_own_events' ) ) {
wp_die( 'Insufficient permissions' );
}
Performance Optimization
1. Database Queries
// Cache expensive queries
$cache_key = 'hvac_trainer_events_' . $trainer_id;
$events = wp_cache_get( $cache_key );
if ( false === $events ) {
$events = get_posts( $args );
wp_cache_set( $cache_key, $events, '', 3600 ); // 1 hour
}
2. Asset Loading
// Load assets only where needed
public function enqueue_scripts() {
if ( ! $this->is_plugin_page() ) {
return;
}
wp_enqueue_script( 'hvac-dashboard' );
}
3. AJAX Optimization
// Debounce search requests
let searchTimeout;
$('#search').on('keyup', function() {
clearTimeout(searchTimeout);
searchTimeout = setTimeout(function() {
performSearch();
}, 300);
});
4. Image Optimization
- Use appropriate image sizes
- Lazy load images
- Compress before upload
- Use WebP format when possible
Common Patterns
1. AJAX Handler Pattern
class HVAC_Ajax_Handler {
public function __construct() {
add_action( 'wp_ajax_hvac_action', array( $this, 'handle_request' ) );
}
public function handle_request() {
// Verify nonce
if ( ! wp_verify_nonce( $_POST['nonce'], 'hvac_nonce' ) ) {
wp_send_json_error( 'Invalid nonce' );
}
// Check capabilities
if ( ! current_user_can( 'required_capability' ) ) {
wp_send_json_error( 'Insufficient permissions' );
}
// Process request
$result = $this->process_data( $_POST['data'] );
// Return response
if ( $result ) {
wp_send_json_success( $result );
} else {
wp_send_json_error( 'Processing failed' );
}
}
}
2. Settings Page Pattern
class HVAC_Settings {
public function __construct() {
add_action( 'admin_menu', array( $this, 'add_menu' ) );
add_action( 'admin_init', array( $this, 'register_settings' ) );
}
public function add_menu() {
add_options_page(
'HVAC Settings',
'HVAC Events',
'manage_options',
'hvac-settings',
array( $this, 'render_page' )
);
}
public function register_settings() {
register_setting( 'hvac_settings', 'hvac_options' );
}
}
Access Control Patterns
Role-Based Field Access
The plugin implements sophisticated role-based access control for sensitive data:
// Check permissions for certification field editing
$can_edit_certifications = current_user_can('administrator') || current_user_can('hvac_master_trainer');
if ( $can_edit_certifications ) {
// Allow editing certification fields
update_user_meta($user_id, 'certification_status', sanitize_text_field($_POST['certification_status']));
} else {
// Show read-only display for regular trainers
echo '<div class="hvac-read-only-field">' . esc_html($certification_status) . '</div>';
}
Field-Level Access Control Implementation
// Different access levels for different user types
if ( current_user_can('hvac_trainer') && ! current_user_can('hvac_master_trainer') ) {
// Trainer: read-only access to certification fields
echo '<input type="hidden" name="certification_type" value="' . esc_attr($certification_type) . '" />';
echo '<div class="hvac-read-only-field">' . esc_html($certification_type) . '</div>';
} else if ( current_user_can('administrator') || current_user_can('hvac_master_trainer') ) {
// Admin/Master Trainer: full edit access
echo '<select name="certification_type">';
// ... render editable dropdown
echo '</select>';
}
Access Control Best Practices
- Always validate permissions server-side - Never rely on frontend-only restrictions
- Use capability checks - Check specific capabilities rather than user roles when possible
- Implement graceful degradation - Show read-only versions rather than hiding fields entirely
- Visual indicators - Clearly indicate when fields are read-only
- Consistent patterns - Use the same access control patterns throughout the plugin
CSV Import System
Enhanced CSV Import Architecture
The plugin includes a comprehensive CSV import system designed to process trainer profile data with full taxonomy integration.
File Structure
includes/
├── enhanced-csv-import-from-file.php # Main CSV import class
├── class-hvac-geocoding-ajax.php # AJAX handlers (updated)
└── taxonomy-migration.php # Taxonomy migration utilities
CSV Import Class
class HVAC_Enhanced_CSV_Import {
/**
* Execute comprehensive CSV import
* @return array Import results and statistics
*/
public function execute_import()
/**
* Process individual CSV row
* @param array $headers CSV headers
* @param array $row CSV row data
* @param int $row_number Row number for error reporting
*/
private function process_row($headers, $row, $row_number)
/**
* Create or update trainer profile
* @param int $user_id WordPress user ID
* @param array $data CSV row data
* @return int Profile post ID
*/
private function create_or_update_profile($user_id, $data)
/**
* Assign taxonomy terms to profile
* @param int $profile_id Profile post ID
* @param array $data CSV row data
*/
private function assign_taxonomies($profile_id, $data)
}
Supported CSV Fields
The import system processes 19 CSV fields:
Contact Information:
Name,Last Name,Email,Phone Number
Professional Data:
Company Name,Role,Company Website
Location Data:
Country,State,City
Certification Information:
Date Certified,Certification Type,Certification Status
Taxonomy Fields:
Business Type→business_typetaxonomyTraining Audience→training_audiencetaxonomy
System Fields:
User ID,Application Details,Create Venue,Create Organizer
Multi-Value Taxonomy Handling
The system handles comma-separated taxonomy values:
// Input: "Educator,Consultant"
// Output: Two taxonomy terms assigned to profile
private function parse_comma_separated($value) {
$items = explode(',', $value);
return array_map('trim', $items);
}
private function assign_taxonomy_terms($profile_id, $taxonomy, $terms) {
foreach ($terms as $term_name) {
// Get or create term
$term = get_term_by('name', $term_name, $taxonomy);
if (!$term) {
$term_data = wp_insert_term($term_name, $taxonomy);
}
}
wp_set_object_terms($profile_id, $term_ids, $taxonomy);
}
AJAX Integration
The CSV import integrates with the existing AJAX system:
// Execute enhanced CSV import
jQuery.post(hvac_ajax.ajax_url, {
action: 'hvac_run_enhanced_import',
nonce: hvac_ajax.nonce
}, function(response) {
if (response.success) {
console.log('Import completed:', response.data);
// Display results to user
}
});
Error Handling and Logging
try {
$results = $this->process_row($headers, $row, $row_number);
} catch (Exception $e) {
$this->results['errors']++;
$this->results['details'][] = "Row $row_number error: " . $e->getMessage();
error_log("CSV Import Row $row_number Error: " . $e->getMessage());
}
Testing the CSV Import
# Test import locally
php test-enhanced-csv-import.php
# Test on staging
ssh user@staging-server "cd /path/to/plugin && php test-csv-import.php"
Development Best Practices for CSV Import
- Always validate CSV structure before processing
- Handle missing/malformed data gracefully
- Use transactions for large imports when possible
- Provide detailed progress feedback to users
- Log all import activities for debugging
- Test with various CSV formats and edge cases