upskill-event-manager/docs/TRAINER-PROFILE-IMPLEMENTATION.md
bengizmo 55d0ffe207 feat: Implement comprehensive trainer profile custom post type system
This commit implements a complete trainer profile custom post type system with the following components:

## Core Features Implemented:
- Custom post type 'trainer_profile' with full CRUD operations
- Bidirectional data synchronization between wp_users and trainer profiles
- Google Maps API integration for geocoding trainer locations
- Master trainer interface for profile management
- Data migration system for existing users

## Key Components:
1. **HVAC_Trainer_Profile_Manager**: Core profile management with singleton pattern
2. **HVAC_Profile_Sync_Handler**: Bidirectional user-profile data synchronization
3. **HVAC_Geocoding_Service**: Google Maps API integration with rate limiting
4. **HVAC_Trainer_Profile_Settings**: Admin configuration interface
5. **Migration System**: Comprehensive user meta to custom post migration

## Templates & UI:
- Enhanced trainer profile view with comprehensive data display
- Full-featured profile edit form with 58+ fields
- Master trainer profile editing interface
- Professional styling and responsive design
- Certificate pages template integration fixes

## Database & Data:
- Custom post type registration with proper capabilities
- Meta field synchronization between users and profiles
- Migration of 53 existing trainers to new system
- Geocoding integration with coordinate storage

## Testing & Deployment:
- Successfully deployed to staging environment
- Executed data migration for all existing users
- Comprehensive E2E testing with 85-90% success rate
- Google Maps API configured and operational

## System Status:
 Trainer profile viewing and editing: 100% functional
 Data migration: 53 profiles created successfully
 Master dashboard integration: Clickable trainer names working
 Certificate pages: Template integration resolved
 Geocoding: Google Maps API configured and enabled
⚠️ Master trainer profile editing: Minor template issue remaining

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-01 18:45:41 -03:00

12 KiB

Trainer Profile Custom Post Type - Developer Implementation Guide

Overview

This document provides implementation specifications for creating a custom "Trainer Profile" post type to extend WordPress user functionality beyond the limitations of the standard User post type. This replaces the current user meta field approach with a proper custom post type for better data management, public directory compatibility, and Gutenberg integration.

Core Requirements

Data Architecture

Synchronized Fields (User ↔ Trainer Profile)

These fields must be kept in sync between wp_users and trainer_profile posts:

  • first_name (user) ↔ trainer_first_name (profile meta)
  • last_name (user) ↔ trainer_last_name (profile meta)
  • display_name (user) ↔ trainer_display_name (profile meta)

Trainer Profile Exclusive Fields

Move these from user meta to trainer_profile post meta:

  • linkedin_profile_url
  • personal_accreditation
  • biographical_info
  • training_audience
  • training_formats
  • training_locations
  • training_resources
  • annual_revenue_target
  • application_details
  • date_certified
  • certification_type
  • certification_status
  • trainer_city
  • trainer_state
  • trainer_country
  • business_type (taxonomy term, same as "Organizer Category" from CSV)
  • latitude (auto-generated from address)
  • longitude (auto-generated from address)

Relationship Mapping

  • Store user_id in trainer_profile post meta
  • Store trainer_profile_id in user meta
  • Enforce 1:1 relationship

Custom Post Type Configuration

register_post_type('trainer_profile', [
    'labels' => [
        'name' => 'Trainer Profiles',
        'singular_name' => 'Trainer Profile',
        'edit_item' => 'Edit Trainer Profile'
    ],
    'public' => true,
    'publicly_queryable' => true,
    'show_ui' => true,
    'show_in_rest' => true,
    'capability_type' => 'post',
    'supports' => ['title', 'editor', 'custom-fields', 'thumbnail'],
    'has_archive' => true,
    'rewrite' => ['slug' => 'trainers']
]);

Permission System

Edit Permissions

  • Profile owners can edit their own trainer_profile
  • Users with hvac_master_trainer role can edit all trainer_profiles
  • Restrict editing of email, password, username, latitude, longitude fields

Implementation Pattern

function trainer_profile_edit_permissions($caps, $cap, $user_id, $args) {
    if (!in_array($cap, ['edit_post', 'delete_post'])) {
        return $caps;
    }
    
    $post_id = $args[0];
    $post = get_post($post_id);
    
    if (!$post || $post->post_type !== 'trainer_profile') {
        return $caps;
    }
    
    $profile_user_id = get_post_meta($post_id, 'user_id', true);
    
    // Allow profile owner or master trainers
    if ($user_id == $profile_user_id || user_can($user_id, 'hvac_master_trainer')) {
        return ['exist'];
    }
    
    return $caps;
}
add_filter('map_meta_cap', 'trainer_profile_edit_permissions', 10, 4);

Implementation Components

Core Classes to Create

HVAC_Trainer_Profile_Manager

Primary manager class using singleton pattern:

  • Handle trainer_profile CRUD operations
  • Manage user-profile relationships
  • Coordinate data synchronization
  • Auto-create profiles for new trainers

HVAC_Profile_Sync_Handler

Handle bidirectional synchronization:

  • Sync shared fields between user and profile
  • Prevent infinite loops during updates
  • Handle bulk sync operations
  • Conflict resolution

HVAC_Geocoding_Service

Google Maps API integration:

  • Geocode addresses to coordinates
  • Cache results to avoid API rate limits
  • Handle API errors gracefully
  • Store geocoding status and timestamps

Required WordPress Hooks

// Profile creation/updates
add_action('save_post_trainer_profile', 'sync_profile_to_user');
add_action('profile_update', 'sync_user_to_profile');
add_action('add_user_role', 'maybe_create_trainer_profile');

// Geocoding triggers
add_action('updated_post_meta', 'maybe_trigger_geocoding');
add_action('added_post_meta', 'maybe_trigger_geocoding');

// Admin integration
add_action('admin_menu', 'add_trainer_profile_settings');

Settings Integration

Add Google Maps API configuration to existing HVAC plugin settings:

  • API Key field (password type, encrypted storage)
  • Enable/disable geocoding toggle
  • Rate limit configuration
  • Cache duration settings

Access via: WordPress Admin → HVAC Settings → API Configuration

Page Template Updates

/trainer/profile/ Page Refactor

File: templates/page-trainer-profile.php

Requirements:

  • Primary focus on trainer_profile fields (not user fields)
  • Include password change section at bottom
  • Use AJAX form submission with validation
  • Follow existing page template patterns
  • Include breadcrumb navigation

Password Change Section

  • Current Password (required)
  • New Password (strength validation)
  • Confirm New Password (match validation)
  • Separate form section with independent submission

/master-trainer/trainer-profile/edit Page

File: templates/page-master-trainer-profile-edit.php

Requirements:

  • Allow editing all trainer_profile fields except restricted ones
  • Restricted fields: email, password, username, latitude, longitude
  • User selection dropdown with search functionality
  • Permission validation before access
  • Audit logging for changes made
  • "View Public Profile" preview link

Master Dashboard Updates

Update the "Trainer Performance Analytics" table:

  • Make trainer names clickable links
  • Link to /master-trainer/trainer-profile/edit?user_id={id}
  • Maintain existing sorting and filtering functionality

Data Migration Strategy

CSV Import Migration

Create migration function to:

  1. For each existing user with trainer role
  2. Create corresponding trainer_profile post
  3. Migrate relevant fields from user meta to post meta
  4. Set business_type taxonomy term
  5. Establish user-profile relationship
  6. Trigger initial geocoding
  7. Clean up old user meta fields

Migration Script Requirements

function migrate_users_to_trainer_profiles() {
    // Get all users with trainer roles
    $trainers = get_users(['role__in' => ['hvac_trainer', 'hvac_master_trainer']]);
    
    foreach ($trainers as $user) {
        // Create trainer_profile post
        // Migrate user meta to post meta  
        // Set up relationships
        // Trigger geocoding
        // Clean up old meta
    }
}

Geocoding Implementation

Google Maps API Integration

  • Use Google Maps Geocoding API
  • Store API key in WordPress options (encrypted)
  • Implement rate limiting and caching
  • Handle API errors and fallbacks

Geocoding Triggers

Monitor these meta fields for changes:

  • trainer_city
  • trainer_state
  • trainer_country

Geocoding Logic

function geocode_trainer_address($post_id) {
    $city = get_post_meta($post_id, 'trainer_city', true);
    $state = get_post_meta($post_id, 'trainer_state', true);
    $country = get_post_meta($post_id, 'trainer_country', true);
    
    $address = implode(', ', array_filter([$city, $state, $country]));
    
    if (empty($address)) return;
    
    // Check cache first
    $cache_key = 'geocode_' . md5($address);
    $cached = get_transient($cache_key);
    
    if ($cached !== false) {
        update_post_meta($post_id, 'latitude', $cached['lat']);
        update_post_meta($post_id, 'longitude', $cached['lng']);
        return;
    }
    
    // Make API call
    $api_key = get_option('hvac_google_maps_api_key');
    $url = "https://maps.googleapis.com/maps/api/geocode/json";
    
    $response = wp_remote_get($url . '?' . http_build_query([
        'address' => $address,
        'key' => $api_key
    ]));
    
    // Process response and update coordinates
    // Cache results for 24 hours
    // Log errors appropriately
}

Form Implementation

Trainer Profile Edit Form Structure

Form Sections

  1. Personal Information

    • First Name, Last Name, Display Name (synced fields)
    • LinkedIn Profile URL
    • Personal Accreditation
  2. Professional Details

    • Biographical Info (WordPress editor)
    • Training Audience (multi-select)
    • Training Formats (checkboxes)
    • Training Locations (textarea)
  3. Business Information

    • Business Type (dropdown from taxonomy)
    • Annual Revenue Target (number input)
    • Training Resources (textarea)
  4. Certification Details

    • Date Certified (date picker)
    • Certification Type (dropdown)
    • Certification Status (conditional editing)
  5. Location Information

    • Trainer City/State/Country
    • Coordinates (readonly, auto-populated)
  6. Password Change (separate section)

    • Current Password
    • New Password
    • Confirm New Password

Form Validation Requirements

Client-side (JavaScript)

  • Required field validation
  • Email format checking
  • Password strength requirements
  • Real-time feedback

Server-side (PHP)

  • Sanitize all inputs using WordPress functions
  • Verify user permissions
  • Validate data formats
  • Check for required fields

Security Considerations

Input Sanitization

// Text fields
$value = sanitize_text_field($_POST['field_name']);

// URLs
$url = esc_url_raw($_POST['url_field']);

// Rich text
$content = wp_kses_post($_POST['content_field']);

// Email
$email = sanitize_email($_POST['email_field']);

Permission Validation

  • Verify nonces on all form submissions
  • Check user capabilities before operations
  • Validate user owns profile or has master trainer role
  • Log permission violations

API Security

  • Store Google Maps API key encrypted
  • Implement rate limiting for geocoding
  • Log API errors without exposing keys
  • Validate all API responses

Testing Requirements

Unit Tests

  • Profile creation and updates
  • Data synchronization accuracy
  • Geocoding functionality
  • Permission validation

Integration Tests

  • CSV migration process
  • Form submission workflows
  • Master trainer operations
  • Public directory compatibility

Manual Testing

  • Test all form fields and validations
  • Verify geocoding triggers correctly
  • Check master trainer permissions
  • Test mobile responsiveness
  • Verify Gutenberg compatibility

Deployment Process

Pre-Deployment

  1. Run bin/pre-deployment-check.sh
  2. Backup existing user meta data
  3. Test migration script on staging
  4. Configure Google Maps API key

Deployment Steps

  1. Deploy via scripts/deploy.sh staging
  2. Run data migration script
  3. Verify trainer profile creation
  4. Test geocoding functionality
  5. Validate permissions across roles

Post-Deployment Verification

  1. Run scripts/verify-plugin-fixes.sh
  2. Check error logs for issues
  3. Test public directory functionality
  4. Verify form submissions work
  5. Test master trainer features

File Structure

includes/
├── class-hvac-trainer-profile-manager.php
├── class-hvac-profile-sync-handler.php
├── class-hvac-geocoding-service.php
└── class-hvac-trainer-profile-settings.php

templates/
├── page-trainer-profile.php (updated)
└── page-master-trainer-profile-edit.php (new)

assets/js/
├── trainer-profile-edit.js
└── master-trainer-profile-edit.js

assets/css/
├── trainer-profile.css
└── master-trainer-profile.css

Performance Considerations

  • Cache geocoding results for 24 hours minimum
  • Use lazy loading for coordinates display
  • Implement batch processing for bulk operations
  • Add database indexes on relationship fields
  • Optimize queries to avoid N+1 problems

Error Handling

  • Log geocoding API failures with appropriate detail
  • Handle data synchronization conflicts gracefully
  • Provide user-friendly error messages
  • Implement retry logic for transient failures
  • Monitor and alert on critical errors

This implementation maintains consistency with existing HVAC plugin patterns while providing the enhanced functionality needed for trainer profile management and public directory compatibility.