[ 'name' => 'Trainer Profiles', 'singular_name' => 'Trainer Profile', 'edit_item' => 'Edit Trainer Profile', 'add_new_item' => 'Add New Trainer Profile', 'view_item' => 'View Trainer Profile', 'search_items' => 'Search Trainer Profiles', 'not_found' => 'No trainer profiles found', 'not_found_in_trash' => 'No trainer profiles found in trash' ], 'public' => true, 'publicly_queryable' => true, 'show_ui' => true, 'show_in_menu' => 'hvac-settings', 'show_in_rest' => true, 'rest_base' => 'trainer-profiles', 'capability_type' => 'post', 'supports' => ['title', 'editor', 'custom-fields', 'thumbnail'], 'has_archive' => true, 'rewrite' => ['slug' => 'trainers'], 'menu_icon' => 'dashicons-groups' ]); } public function register_taxonomies() { register_taxonomy('business_type', 'trainer_profile', [ 'labels' => [ 'name' => 'Business Types', 'singular_name' => 'Business Type', 'add_new_item' => 'Add New Business Type', 'edit_item' => 'Edit Business Type' ], 'public' => true, 'hierarchical' => false, 'show_in_rest' => true, 'rewrite' => ['slug' => 'business-type'] ]); // Populate default business types $this->create_default_business_types(); } private function create_default_business_types() { $business_types = [ 'HVAC Contractor', 'Training Organization', 'Educational Institution', 'Consulting Firm', 'Equipment Manufacturer', 'Service Company', 'Independent Trainer', 'Other' ]; foreach ($business_types as $type) { if (!term_exists($type, 'business_type')) { wp_insert_term($type, 'business_type'); } } } public function maybe_create_trainer_profile($user_id, $role, $old_roles = null) { $trainer_roles = ['hvac_trainer', 'hvac_master_trainer']; if (in_array($role, $trainer_roles)) { $this->create_trainer_profile($user_id); } } public function create_trainer_profile($user_id, $csv_data = null) { // Check if profile already exists $existing_profile_id = get_user_meta($user_id, 'trainer_profile_id', true); if ($existing_profile_id && get_post($existing_profile_id)) { return $existing_profile_id; } $user = get_userdata($user_id); if (!$user) { return false; } // Create trainer profile post $profile_data = [ 'post_type' => 'trainer_profile', 'post_title' => $user->display_name . ' - Trainer Profile', 'post_status' => 'publish', 'post_author' => $user_id, 'post_content' => get_user_meta($user_id, 'biographical_info', true) ?: '' ]; $profile_id = wp_insert_post($profile_data); if (is_wp_error($profile_id)) { error_log('HVAC Trainer Profile: Failed to create profile for user ' . $user_id . ': ' . $profile_id->get_error_message()); return false; } // Establish relationships update_post_meta($profile_id, 'user_id', $user_id); update_user_meta($user_id, 'trainer_profile_id', $profile_id); // Migrate user meta to profile meta $this->migrate_user_meta_to_profile($user_id, $profile_id, $csv_data); // Set default visibility update_post_meta($profile_id, 'is_public_profile', '1'); return $profile_id; } private function migrate_user_meta_to_profile($user_id, $profile_id, $csv_data = null) { $user = get_userdata($user_id); // Synchronized fields (user ↔ profile) $sync_fields = [ 'first_name' => 'trainer_first_name', 'last_name' => 'trainer_last_name', 'display_name' => 'trainer_display_name' ]; foreach ($sync_fields as $user_field => $profile_field) { $value = $user->$user_field; if ($csv_data && isset($csv_data[$user_field])) { $value = $csv_data[$user_field]; } update_post_meta($profile_id, $profile_field, $value); } // Profile-exclusive fields $profile_fields = [ 'linkedin_profile_url', 'personal_accreditation', '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' ]; foreach ($profile_fields as $field) { $value = ''; // Use CSV data if available if ($csv_data && isset($csv_data[$field])) { $value = $csv_data[$field]; } else { // Migrate from user meta $value = get_user_meta($user_id, $field, true); } if ($value) { update_post_meta($profile_id, $field, $value); } } // Set business type from CSV if available if ($csv_data && !empty($csv_data['business_type'])) { $term = get_term_by('name', $csv_data['business_type'], 'business_type'); if ($term) { wp_set_post_terms($profile_id, [$term->term_id], 'business_type'); } } // Set default certification status if not provided if (!get_post_meta($profile_id, 'certification_status', true)) { update_post_meta($profile_id, 'certification_status', 'Active'); } // Clean up old user meta fields to prevent confusion foreach ($profile_fields as $field) { delete_user_meta($user_id, $field); } } public function trainer_profile_edit_permissions($caps, $cap, $user_id, $args) { if (!in_array($cap, ['edit_post', 'delete_post'])) { return $caps; } if (empty($args[0])) { 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, master trainers, or administrators if ($user_id == $profile_user_id || user_can($user_id, 'hvac_master_trainer') || user_can($user_id, 'administrator')) { return ['exist']; } return $caps; } public function get_trainer_profile($user_id) { $profile_id = get_user_meta($user_id, 'trainer_profile_id', true); if (!$profile_id) { return false; } $profile = get_post($profile_id); if (!$profile || $profile->post_type !== 'trainer_profile') { return false; } return $profile; } public function get_profile_meta($profile_id, $key = null) { if ($key) { return get_post_meta($profile_id, $key, true); } // Return all profile meta $meta = get_post_meta($profile_id); $clean_meta = []; foreach ($meta as $key => $value) { $clean_meta[$key] = is_array($value) && count($value) === 1 ? $value[0] : $value; } return $clean_meta; } public function update_profile($profile_id, $data, $user_id = null) { $profile = get_post($profile_id); if (!$profile || $profile->post_type !== 'trainer_profile') { return new WP_Error('invalid_profile', 'Invalid trainer profile'); } // Check permissions if ($user_id) { $profile_user_id = get_post_meta($profile_id, 'user_id', true); if (!($user_id == $profile_user_id || user_can($user_id, 'hvac_master_trainer') || user_can($user_id, 'administrator'))) { return new WP_Error('insufficient_permissions', 'Insufficient permissions to edit this profile'); } } // Update post content if biographical_info is provided if (isset($data['biographical_info'])) { wp_update_post([ 'ID' => $profile_id, 'post_content' => wp_kses_post($data['biographical_info']) ]); unset($data['biographical_info']); } // Update meta fields foreach ($data as $key => $value) { if ($key === 'business_type') { // Handle taxonomy $term = get_term_by('name', $value, 'business_type'); if ($term) { wp_set_post_terms($profile_id, [$term->term_id], 'business_type'); } } else { update_post_meta($profile_id, $key, sanitize_text_field($value)); } } // Trigger geocoding if address fields changed $address_fields = ['trainer_city', 'trainer_state', 'trainer_country']; if (array_intersect_key($data, array_flip($address_fields))) { do_action('hvac_profile_address_updated', $profile_id); } return true; } public function create_profiles_for_existing_trainers() { $trainers = get_users([ 'role__in' => ['hvac_trainer', 'hvac_master_trainer'], 'meta_query' => [ [ 'key' => 'trainer_profile_id', 'compare' => 'NOT EXISTS' ] ] ]); foreach ($trainers as $trainer) { $this->create_trainer_profile($trainer->ID); } } public function get_all_trainer_profiles($args = []) { $default_args = [ 'post_type' => 'trainer_profile', 'post_status' => 'publish', 'posts_per_page' => -1, 'meta_query' => [] ]; // Filter public profiles only for non-privileged users if (!current_user_can('hvac_master_trainer') && !current_user_can('administrator')) { $default_args['meta_query'][] = [ 'key' => 'is_public_profile', 'value' => '1', 'compare' => '=' ]; } $args = wp_parse_args($args, $default_args); return get_posts($args); } public function delete_trainer_profile($profile_id, $user_id = null) { $profile = get_post($profile_id); if (!$profile || $profile->post_type !== 'trainer_profile') { return new WP_Error('invalid_profile', 'Invalid trainer profile'); } // Check permissions if ($user_id) { $profile_user_id = get_post_meta($profile_id, 'user_id', true); if (!($user_id == $profile_user_id || user_can($user_id, 'administrator'))) { return new WP_Error('insufficient_permissions', 'Insufficient permissions to delete this profile'); } } // Clean up relationships $profile_user_id = get_post_meta($profile_id, 'user_id', true); if ($profile_user_id) { delete_user_meta($profile_user_id, 'trainer_profile_id'); } // Delete the post return wp_delete_post($profile_id, true); } public function ajax_save_trainer_profile() { check_ajax_referer('hvac_profile_nonce', 'nonce'); if (!current_user_can('hvac_trainer') && !current_user_can('hvac_master_trainer') && !current_user_can('administrator')) { wp_send_json_error('Insufficient permissions'); } $user_id = get_current_user_id(); $profile_id = get_user_meta($user_id, 'trainer_profile_id', true); if (!$profile_id) { wp_send_json_error('No trainer profile found'); } // Collect form data $profile_data = []; $user_data = ['ID' => $user_id]; // Handle synchronized fields if (isset($_POST['trainer_first_name'])) { $profile_data['trainer_first_name'] = sanitize_text_field($_POST['trainer_first_name']); $user_data['first_name'] = $profile_data['trainer_first_name']; } if (isset($_POST['trainer_last_name'])) { $profile_data['trainer_last_name'] = sanitize_text_field($_POST['trainer_last_name']); $user_data['last_name'] = $profile_data['trainer_last_name']; } if (isset($_POST['trainer_display_name'])) { $profile_data['trainer_display_name'] = sanitize_text_field($_POST['trainer_display_name']); $user_data['display_name'] = $profile_data['trainer_display_name']; } // Handle profile-exclusive fields $profile_fields = [ 'linkedin_profile_url', 'personal_accreditation', 'training_audience', 'training_formats', 'training_locations', 'training_resources', 'annual_revenue_target', 'application_details', 'trainer_city', 'trainer_state', 'trainer_country' ]; foreach ($profile_fields as $field) { if (isset($_POST[$field])) { $profile_data[$field] = sanitize_text_field($_POST[$field]); } } // Handle biographical info (rich text) if (isset($_POST['biographical_info'])) { $profile_data['biographical_info'] = wp_kses_post($_POST['biographical_info']); } // Handle certification fields (restricted access) if (current_user_can('hvac_master_trainer') || current_user_can('administrator')) { $cert_fields = ['date_certified', 'certification_type', 'certification_status']; foreach ($cert_fields as $field) { if (isset($_POST[$field])) { $profile_data[$field] = sanitize_text_field($_POST[$field]); } } } // Update user data if (count($user_data) > 1) { wp_update_user($user_data); } // Update profile $result = $this->update_profile($profile_id, $profile_data, $user_id); if (is_wp_error($result)) { wp_send_json_error($result->get_error_message()); } $response_data = ['message' => 'Profile updated successfully']; // Check if geocoding was triggered $address_fields = ['trainer_city', 'trainer_state', 'trainer_country']; if (array_intersect_key($_POST, array_flip($address_fields))) { $response_data['geocoding_triggered'] = true; } wp_send_json_success($response_data); } public function ajax_auto_save_profile() { check_ajax_referer('hvac_profile_nonce', 'nonce'); if (!current_user_can('hvac_trainer') && !current_user_can('hvac_master_trainer') && !current_user_can('administrator')) { wp_send_json_error('Insufficient permissions'); } $user_id = get_current_user_id(); $profile_id = get_user_meta($user_id, 'trainer_profile_id', true); if (!$profile_id) { wp_send_json_error('No trainer profile found'); } // Auto-save only basic fields to prevent conflicts $safe_fields = [ 'linkedin_profile_url', 'training_locations', 'training_resources', 'application_details', 'trainer_city', 'trainer_state', 'trainer_country' ]; $profile_data = []; foreach ($safe_fields as $field) { if (isset($_POST[$field])) { $profile_data[$field] = sanitize_text_field($_POST[$field]); } } if (!empty($profile_data)) { $this->update_profile($profile_id, $profile_data, $user_id); } wp_send_json_success('Auto-saved successfully'); } public function render_profile_view() { if (!is_user_logged_in()) { return '
You must be logged in to view this page.
'; } $user_id = get_current_user_id(); $profile = $this->get_trainer_profile($user_id); if (!$profile) { return 'No trainer profile found. Please contact an administrator.
'; } // Get profile metadata and user data $profile_meta = $this->get_profile_meta($profile->ID); $user = get_userdata($user_id); // Get coordinates if available $geocoding_service = class_exists('HVAC_Geocoding_Service') ? HVAC_Geocoding_Service::get_instance() : null; $coordinates = $geocoding_service ? $geocoding_service->get_coordinates($profile->ID) : null; ob_start(); ?>No trainer profile found. Please contact an administrator.
'; } // Use the existing, working profile edit form from HVAC_Registration if (class_exists('HVAC_Registration')) { $registration = new HVAC_Registration(); return $registration->render_edit_profile_form(); } // Fallback if registration class not available return 'Profile editing functionality is currently unavailable. Please contact an administrator.
'; } } // Initialize the manager HVAC_Trainer_Profile_Manager::get_instance();