execute_geocoding(); wp_send_json_success($results); } catch (Exception $e) { wp_send_json_error('Geocoding error: ' . $e->getMessage()); } } /** * Get geocoding statistics */ public function get_geocoding_stats() { // Verify nonce if (!wp_verify_nonce($_POST['nonce'], 'hvac_ajax_nonce')) { wp_send_json_error('Invalid nonce'); return; } // Check permissions if (!current_user_can('hvac_trainer') && !current_user_can('hvac_master_trainer') && !current_user_can('administrator')) { wp_send_json_error('Insufficient permissions'); return; } try { if (!class_exists('HVAC_Trainer_Profile_Settings')) { wp_send_json_error('Profile settings class not available'); return; } $settings = HVAC_Trainer_Profile_Settings::get_instance(); $reflection = new ReflectionClass($settings); $method = $reflection->getMethod('get_profile_statistics'); $method->setAccessible(true); $stats = $method->invoke($settings); wp_send_json_success($stats); } catch (Exception $e) { wp_send_json_error('Statistics error: ' . $e->getMessage()); } } /** * Re-migrate CSV data to trainer profiles */ public function remigrate_csv_data() { // Verify nonce if (!wp_verify_nonce($_POST['nonce'], 'hvac_ajax_nonce')) { wp_send_json_error('Invalid nonce'); return; } // Check permissions if (!current_user_can('hvac_master_trainer') && !current_user_can('administrator')) { wp_send_json_error('Insufficient permissions'); return; } try { // Set execution time limit set_time_limit(300); // 5 minutes $results = $this->execute_csv_remigration(); wp_send_json_success($results); } catch (Exception $e) { wp_send_json_error('Re-migration error: ' . $e->getMessage()); } } /** * Reconstruct CSV import log from existing data */ public function reconstruct_import_log() { // Verify nonce if (!wp_verify_nonce($_POST['nonce'], 'hvac_ajax_nonce')) { wp_send_json_error('Invalid nonce'); return; } // Check permissions if (!current_user_can('hvac_master_trainer') && !current_user_can('administrator')) { wp_send_json_error('Insufficient permissions'); return; } try { $results = $this->execute_log_reconstruction(); wp_send_json_success($results); } catch (Exception $e) { wp_send_json_error('Reconstruction error: ' . $e->getMessage()); } } /** * Run enhanced CSV import */ public function run_enhanced_import() { // Verify nonce if (!wp_verify_nonce($_POST['nonce'], 'hvac_ajax_nonce')) { wp_send_json_error('Invalid nonce'); return; } // Check permissions if (!current_user_can('hvac_master_trainer') && !current_user_can('administrator')) { wp_send_json_error('Insufficient permissions'); return; } try { // Set execution time limit set_time_limit(300); // 5 minutes $results = $this->execute_enhanced_import(); wp_send_json_success($results); } catch (Exception $e) { wp_send_json_error('Enhanced import error: ' . $e->getMessage()); } } /** * Execute geocoding for all profiles * * @return array Results summary */ private function execute_geocoding() { // Check required classes $required_classes = [ 'HVAC_Trainer_Profile_Manager', 'HVAC_Geocoding_Service', 'HVAC_Trainer_Profile_Settings' ]; foreach ($required_classes as $class) { if (!class_exists($class)) { throw new Exception("Required class {$class} not found"); } } // Get geocoding service $geocoding_service = HVAC_Geocoding_Service::get_instance(); // Get all trainer profiles $profiles = get_posts([ 'post_type' => 'trainer_profile', 'post_status' => 'publish', 'posts_per_page' => -1, 'fields' => 'ids' ]); if (empty($profiles)) { throw new Exception('No trainer profiles found'); } $results = [ 'total_profiles' => count($profiles), 'geocoded_count' => 0, 'skipped_count' => 0, 'error_count' => 0, 'details' => [], 'start_time' => current_time('mysql'), 'api_key_valid' => !empty(get_option('hvac_google_maps_api_key')) ]; foreach ($profiles as $profile_id) { $profile = get_post($profile_id); $profile_title = $profile->post_title ?: "Profile #{$profile_id}"; $detail = [ 'id' => $profile_id, 'title' => $profile_title, 'status' => 'processing' ]; // Check if already geocoded $existing_lat = get_post_meta($profile_id, 'latitude', true); $existing_lng = get_post_meta($profile_id, 'longitude', true); if (!empty($existing_lat) && !empty($existing_lng)) { $detail['status'] = 'already_geocoded'; $detail['coordinates'] = ['lat' => $existing_lat, 'lng' => $existing_lng]; $results['geocoded_count']++; $results['details'][] = $detail; continue; } // Get address components $address_parts = []; $city = get_post_meta($profile_id, 'trainer_city', true); $state = get_post_meta($profile_id, 'trainer_state', true); $country = get_post_meta($profile_id, 'trainer_country', true); $address = get_post_meta($profile_id, 'trainer_address', true); if ($address) $address_parts[] = $address; if ($city) $address_parts[] = $city; if ($state) $address_parts[] = $state; if ($country) $address_parts[] = $country; if (empty($address_parts)) { $detail['status'] = 'no_address'; $detail['message'] = 'No address data found'; $results['skipped_count']++; $results['details'][] = $detail; continue; } $full_address = implode(', ', $address_parts); $detail['address'] = $full_address; // Attempt geocoding try { $coordinates = $geocoding_service->geocode_address($full_address); if ($coordinates && isset($coordinates['lat']) && isset($coordinates['lng'])) { // Store coordinates update_post_meta($profile_id, 'latitude', $coordinates['lat']); update_post_meta($profile_id, 'longitude', $coordinates['lng']); update_post_meta($profile_id, 'geocoded_at', current_time('mysql')); update_post_meta($profile_id, 'geocoding_source', $coordinates['source'] ?? 'ajax'); $detail['status'] = 'geocoded'; $detail['coordinates'] = ['lat' => $coordinates['lat'], 'lng' => $coordinates['lng']]; $results['geocoded_count']++; // Small delay to respect API rate limits usleep(500000); // 0.5 seconds } else { $detail['status'] = 'failed'; $detail['message'] = 'No coordinates returned'; $results['error_count']++; } } catch (Exception $e) { $detail['status'] = 'error'; $detail['message'] = $e->getMessage(); $results['error_count']++; } $results['details'][] = $detail; } $results['end_time'] = current_time('mysql'); $results['duration'] = time() - strtotime($results['start_time']); return $results; } /** * Execute CSV re-migration for all profiles * * @return array Results summary */ private function execute_csv_remigration() { // Get the CSV import log $csv_import_log = get_option('hvac_csv_import_log', []); if (empty($csv_import_log)) { throw new Exception('No CSV import log found. Please run the original CSV import first.'); } $results = [ 'total_sessions' => count($csv_import_log), 'profiles_processed' => 0, 'profiles_updated' => 0, 'errors' => 0, 'fields_updated' => 0, 'geocoding_scheduled' => 0, 'details' => [], 'start_time' => current_time('mysql') ]; // Process each import session foreach ($csv_import_log as $session_id => $import_session) { if (!isset($import_session['users']) || !is_array($import_session['users'])) { continue; } foreach ($import_session['users'] as $user_email => $user_data) { $results['profiles_processed']++; $detail = [ 'email' => $user_email, 'status' => 'processing', 'fields_updated' => 0 ]; try { // Get the user $user = get_user_by('email', $user_email); if (!$user) { $detail['status'] = 'user_not_found'; $results['errors']++; $results['details'][] = $detail; continue; } // Get the trainer profile if (!class_exists('HVAC_Trainer_Profile_Manager')) { throw new Exception('Profile manager not available'); } $profile_manager = HVAC_Trainer_Profile_Manager::get_instance(); $profile = $profile_manager->get_trainer_profile($user->ID); if (!$profile) { $detail['status'] = 'profile_not_found'; $results['errors']++; $results['details'][] = $detail; continue; } $detail['profile_id'] = $profile->ID; $detail['name'] = $user->display_name; // Check if CSV data exists if (!isset($user_data['csv_data']) || !is_array($user_data['csv_data'])) { $detail['status'] = 'no_csv_data'; $results['details'][] = $detail; continue; } $csv_data = $user_data['csv_data']; // Apply field mapping logic $field_priority_mappings = [ 'trainer_city' => ['City'], 'trainer_state' => ['State'], 'trainer_country' => ['Country'], 'business_type' => ['mapped_business_type', 'Organizer Category'], 'training_audience' => ['parsed_training_audience', 'Training Audience'], 'date_certified' => ['standardized_date', 'Date Certified,'], 'role' => ['mapped_role', 'Role'], 'organization_name' => ['Company Name'], 'certification_type' => ['Certification Type'], 'certification_status' => ['Certification Status'], 'business_website' => ['Company Website'], 'business_phone' => ['Phone Number'], 'application_details' => ['Application Details'] ]; foreach ($field_priority_mappings as $profile_field => $csv_keys) { $value = null; $used_key = null; // Try each CSV key in priority order foreach ($csv_keys as $csv_key) { if (isset($csv_data[$csv_key]) && !empty(trim($csv_data[$csv_key]))) { $value = trim($csv_data[$csv_key]); $used_key = $csv_key; break; } } if ($value) { if ($profile_field === 'business_type') { // Handle taxonomy $current_terms = wp_get_post_terms($profile->ID, 'business_type', ['fields' => 'names']); if (empty($current_terms) || is_wp_error($current_terms)) { $term = get_term_by('name', $value, 'business_type'); if (!$term) { $term_result = wp_insert_term($value, 'business_type'); if (!is_wp_error($term_result)) { $term = get_term($term_result['term_id'], 'business_type'); } } if ($term && !is_wp_error($term)) { wp_set_post_terms($profile->ID, [$term->term_id], 'business_type'); $detail['fields_updated']++; $results['fields_updated']++; } } } else { // Check if field already has a value $current_value = get_post_meta($profile->ID, $profile_field, true); if (empty($current_value)) { update_post_meta($profile->ID, $profile_field, sanitize_text_field($value)); $detail['fields_updated']++; $results['fields_updated']++; } } } } if ($detail['fields_updated'] > 0) { $results['profiles_updated']++; $detail['status'] = 'updated'; // Check if we should schedule geocoding $city = get_post_meta($profile->ID, 'trainer_city', true); $state = get_post_meta($profile->ID, 'trainer_state', true); $country = get_post_meta($profile->ID, 'trainer_country', true); if (!empty($city) || !empty($state) || !empty($country)) { wp_schedule_single_event(time() + rand(5, 30), 'hvac_geocode_address', [$profile->ID]); $results['geocoding_scheduled']++; $detail['geocoding_scheduled'] = true; } } else { $detail['status'] = 'no_updates_needed'; } } catch (Exception $e) { $detail['status'] = 'error'; $detail['error'] = $e->getMessage(); $results['errors']++; } $results['details'][] = $detail; } } $results['end_time'] = current_time('mysql'); $results['duration'] = time() - strtotime($results['start_time']); return $results; } /** * Execute CSV import log reconstruction * * @return array Results summary */ private function execute_log_reconstruction() { // Try multiple possible locations for the CSV file $possible_csv_paths = [ HVAC_PLUGIN_DIR . 'CSV_Trainers_Import_1Aug2025_FIXED.csv', ABSPATH . 'CSV_Trainers_Import_1Aug2025_FIXED.csv', WP_CONTENT_DIR . '/CSV_Trainers_Import_1Aug2025_FIXED.csv', WP_CONTENT_DIR . '/uploads/CSV_Trainers_Import_1Aug2025_FIXED.csv' ]; $csv_file = null; foreach ($possible_csv_paths as $path) { if (file_exists($path)) { $csv_file = $path; break; } } if (!$csv_file) { throw new Exception("CSV file not found in any of these locations: " . implode(', ', $possible_csv_paths)); } $results = [ 'csv_file' => $csv_file, 'csv_rows_read' => 0, 'matched_users' => 0, 'missing_users' => 0, 'import_log_created' => false, 'session_id' => null, 'start_time' => current_time('mysql') ]; // Parse CSV file $csv_data = []; if (($handle = fopen($csv_file, 'r')) !== FALSE) { $headers = fgetcsv($handle); // Get headers while (($row = fgetcsv($handle)) !== FALSE) { $results['csv_rows_read']++; if (count($row) === count($headers)) { $csv_data[] = array_combine($headers, $row); } } fclose($handle); } else { throw new Exception("Could not open CSV file: {$csv_file}"); } // Create synthetic import log $session_id = 'reconstructed_' . date('Y-m-d_H-i-s'); $results['session_id'] = $session_id; $import_session = [ 'timestamp' => time(), 'file' => basename($csv_file), 'total_rows' => count($csv_data), 'users' => [] ]; // Match CSV data with existing users foreach ($csv_data as $index => $row) { $email = trim($row['Work Email'] ?? ''); if (empty($email)) { continue; } // Check if user exists $user = get_user_by('email', $email); if ($user) { $results['matched_users']++; // Store CSV data for this user $import_session['users'][$email] = [ 'user_id' => $user->ID, 'user_login' => $user->user_login, 'csv_data' => $row, 'imported_at' => time(), 'status' => 'existing_user_matched' ]; } else { $results['missing_users']++; } } // Save the reconstructed import log $import_log = [$session_id => $import_session]; update_option('hvac_csv_import_log', $import_log); // Verify the save $saved_log = get_option('hvac_csv_import_log', []); $results['import_log_created'] = !empty($saved_log); $results['end_time'] = current_time('mysql'); $results['duration'] = time() - strtotime($results['start_time']); return $results; } /** * Execute enhanced CSV import * * @return array Results summary */ private function execute_enhanced_import() { $results = [ 'total_rows' => 0, 'users_created' => 0, 'users_updated' => 0, 'profiles_created' => 0, 'profiles_updated' => 0, 'errors' => 0, 'geocoding_scheduled' => 0, 'session_id' => null, 'import_log_saved' => false, 'start_time' => current_time('mysql') ]; // Complete CSV data from the actual CSV file with correct emails $csv_data = [ ['Name' => 'Brynn', 'Last Name' => 'Cooksey', 'Email' => 'brynn@hvactrain.com', 'City' => 'Southfield', 'State' => 'Michigan', 'Country' => 'United States', 'Company Name' => 'HVAC U', 'Role' => 'Owner', 'Certification Type' => 'Certified measureQuick Trainer', 'Certification Status' => 'Active'], ['Name' => 'Thomas', 'Last Name' => 'Hoffmaster II', 'Email' => 'thoffmaster@hoffmastermechanical.com', 'City' => 'Bunker Hill', 'State' => 'West Virginia', 'Country' => 'United States', 'Company Name' => 'Hoffmaster Mechanical & Consulting LLC', 'Role' => 'Owner', 'Certification Type' => 'Certified measureQuick Trainer', 'Certification Status' => 'Active'], ['Name' => 'Eric', 'Last Name' => 'Kjelshus', 'Email' => 'eric.energy@gmail.com', 'City' => 'Greenwood', 'State' => 'Missouri', 'Country' => 'United States', 'Company Name' => 'Eric Kjelshus Energy Heating And Cooling', 'Role' => 'Owner', 'Certification Type' => 'Certified measureQuick Trainer', 'Certification Status' => 'Active'], ['Name' => 'Marco', 'Last Name' => 'Nantel', 'Email' => 'mnantel@republicsupplyco.com', 'City' => 'Norwood', 'State' => 'Massachusetts', 'Country' => 'United States', 'Company Name' => 'Republic Supply', 'Role' => 'Operations Manager', 'Certification Type' => 'Certified measureQuick Trainer', 'Certification Status' => 'Active'], ['Name' => 'David', 'Last Name' => 'Petz', 'Email' => 'dpetz@johnstonenjpa.com', 'City' => 'Philadelphia', 'State' => 'Pennsylvania', 'Country' => 'United States', 'Company Name' => 'Johnstone Supply', 'Role' => 'Educator/Tech support', 'Certification Type' => 'Certified measureQuick Trainer', 'Certification Status' => 'Active'], ['Name' => 'John', 'Last Name' => 'Anderson', 'Email' => 'janderson@sila.com', 'City' => 'King of Prussia', 'State' => 'Pennsylvania', 'Country' => 'United States', 'Company Name' => 'Sila Services', 'Role' => 'Supervisor', 'Certification Type' => 'Certified measureQuick Trainer', 'Certification Status' => 'Active'], ['Name' => 'David', 'Last Name' => 'Norman', 'Email' => 'david@hvacinstituteinc.com', 'City' => 'Kent', 'State' => 'Washington', 'Country' => 'United States', 'Company Name' => 'Hvac Institute Inc.', 'Role' => 'Technician and Instructor', 'Certification Type' => 'Certified measureQuick Trainer', 'Certification Status' => 'Active'], ['Name' => 'Greg', 'Last Name' => 'Kula', 'Email' => 'Greg.a.kula@gmail.com', 'City' => 'Goshen', 'State' => 'New York', 'Country' => 'United States', 'Company Name' => 'Jones Services', 'Role' => 'Service Manager', 'Certification Type' => 'Certified measureQuick Trainer', 'Certification Status' => 'Active'], ['Name' => 'William', 'Last Name' => 'Ramsey', 'Email' => 'wramsey@wrbristow.com', 'City' => 'Marietta', 'State' => 'Georgia', 'Country' => 'United States', 'Company Name' => 'Bristow University', 'Role' => 'Director of Education', 'Certification Type' => 'Certified measureQuick Trainer', 'Certification Status' => 'Active'], ['Name' => 'Jeremy', 'Last Name' => 'Begley', 'Email' => 'jbegley@hvac2homeperformance.com', 'City' => 'Knoxville', 'State' => 'Tennessee', 'Country' => 'United States', 'Company Name' => 'HVAC 2 Home Performance', 'Role' => 'Founding Shareholder', 'Certification Type' => 'Certified measureQuick Trainer', 'Certification Status' => 'Active'], ['Name' => 'Robert', 'Last Name' => 'Larson', 'Email' => 'robl@generalplumbingsupply.net', 'City' => 'Piscataway', 'State' => 'New Jersey', 'Country' => 'United States', 'Company Name' => 'General plumbing supply', 'Role' => 'HVAC Tech (Therapy) Support', 'Certification Type' => 'Certified measureQuick Trainer', 'Certification Status' => 'Active'], ['Name' => 'William', 'Last Name' => 'Lombard', 'Email' => 'william.lombard@century.edu', 'City' => 'White Bear Lake', 'State' => 'Minnesota', 'Country' => 'United States', 'Company Name' => 'Century College', 'Role' => 'Faculty/Program Director', 'Certification Type' => 'Certified measureQuick Trainer', 'Certification Status' => 'Active'], ['Name' => 'Stephen', 'Last Name' => 'Boane', 'Email' => 'steve@elevationha.com', 'City' => 'Denver', 'State' => 'Colorado', 'Country' => 'United States', 'Company Name' => 'Elevation Heating & Air', 'Role' => 'Chief Executive Officer', 'Certification Type' => 'Certified measureQuick Trainer', 'Certification Status' => 'Active'], ['Name' => 'Scott', 'Last Name' => 'Suddreth', 'Email' => 'scotts@blueskytraining.com', 'City' => 'Fort Collins', 'State' => 'Colorado', 'Country' => 'United States', 'Company Name' => 'Blue Sky Training', 'Role' => 'Director of Training', 'Certification Type' => 'Certified measureQuick Trainer', 'Certification Status' => 'Active'], ['Name' => 'Tom', 'Last Name' => 'Hunt', 'Email' => 'tomhunt@arhvacr.org', 'City' => 'Jacksonville', 'State' => 'Arkansas', 'Country' => 'United States', 'Company Name' => 'Arkansas HVACR Association', 'Role' => 'Executive Director', 'Certification Type' => 'Certified measureQuick Trainer', 'Certification Status' => 'Active'], ['Name' => 'Dan', 'Last Name' => 'Wildenhaus', 'Email' => 'dwildenhaus@mncee.org', 'City' => 'Minneapolis', 'State' => 'Minnesota', 'Country' => 'United States', 'Company Name' => 'Center for Energy and Environment', 'Role' => 'Sr Technical Manager', 'Certification Type' => 'Certified measureQuick Trainer', 'Certification Status' => 'Active'], ['Name' => 'Petro', 'Last Name' => 'Tsynik', 'Email' => 'ptsinyk@sunrisecomfort.com', 'City' => 'Newtown', 'State' => 'Pennsylvania', 'Country' => 'United States', 'Company Name' => 'Sunrise Comfort', 'Role' => 'Operation Manager', 'Certification Type' => 'Certified measureQuick Champion', 'Certification Status' => 'Active'], ['Name' => 'Ben', 'Last Name' => 'Chouinard', 'Email' => 'BChouinard@unifiedakron.com', 'City' => 'Akron', 'State' => 'Ohio', 'Country' => 'United States', 'Company Name' => 'Unified Comfort Systems', 'Role' => 'Vice President', 'Certification Type' => 'Certified measureQuick Trainer', 'Certification Status' => 'Active'], ['Name' => 'Mike', 'Last Name' => 'Edwards', 'Email' => 'tech3@echolsheating.com', 'City' => 'Akron', 'State' => 'Ohio', 'Country' => 'United States', 'Company Name' => 'Echols', 'Role' => 'Owner', 'Certification Type' => 'Certified measureQuick Champion', 'Certification Status' => 'Active'], ['Name' => 'Jason', 'Last Name' => 'Julian', 'Email' => 'jason@julianheatandair.com', 'City' => 'Heber Springs', 'State' => 'Arkansas', 'Country' => 'United States', 'Company Name' => 'Julian Heating & Air', 'Role' => 'Owner', 'Certification Type' => 'Certified measureQuick Champion', 'Certification Status' => 'Active'], ['Name' => 'Abe', 'Last Name' => 'Engholm', 'Email' => 'abe@julianheatandair.com', 'City' => 'Heber Springs', 'State' => 'Arkansas', 'Country' => 'United States', 'Company Name' => 'Julian Heating & Air', 'Role' => 'Trainer', 'Certification Type' => 'Certified measureQuick Champion', 'Certification Status' => 'Active'], ['Name' => 'Robert', 'Last Name' => 'McKeraghan', 'Email' => 'bob@cancoclimatecare.com', 'City' => 'Newmarket', 'State' => 'Ontario', 'Country' => 'Canada', 'Company Name' => 'Canco ClimateCare', 'Role' => 'President', 'Certification Type' => 'Certified measureQuick Trainer', 'Certification Status' => 'Active'], ['Name' => 'Shaun', 'Last Name' => 'Penny', 'Email' => 'shaun@pennyairsolutions.com', 'City' => 'Cave Springs', 'State' => 'Arkansas', 'Country' => 'United States', 'Company Name' => 'Penny Air Solutions', 'Role' => 'Owner/Operator', 'Certification Type' => 'Certified measureQuick Champion', 'Certification Status' => 'Active'], ['Name' => 'Andrew', 'Last Name' => 'Godby', 'Email' => 'andrew.godby88@gmail.com', 'City' => 'Hilliard', 'State' => 'Ohio', 'Country' => 'United States', 'Company Name' => 'The Eco Plumbers', 'Role' => 'Service Technician', 'Certification Type' => 'Certified measureQuick Champion', 'Certification Status' => 'Active'], ['Name' => 'Hunter', 'Last Name' => 'Heavilin', 'Email' => 'hunter@simpsonsalute.com', 'City' => 'New Philadelphia', 'State' => 'Ohio', 'Country' => 'United States', 'Company Name' => 'Simpson Salute Heating & Air', 'Role' => 'Install Technician', 'Certification Type' => 'Certified measureQuick Champion', 'Certification Status' => 'Active'], ['Name' => 'Gary', 'Last Name' => 'Ranallo', 'Email' => 'granallo@stackheating.com', 'City' => 'Cleveland', 'State' => 'Ohio', 'Country' => 'United States', 'Company Name' => 'Stack Heating, Cooling and Electric', 'Role' => 'Senior Trainer', 'Certification Type' => 'Certified measureQuick Champion', 'Certification Status' => 'Active'], ['Name' => 'Edward', 'Last Name' => 'Wronski', 'Email' => 'edward.wronski@stylecrest.net', 'City' => 'Melbourne', 'State' => 'Florida', 'Country' => 'United States', 'Company Name' => 'Style Crest Heating & Air Conditioning', 'Role' => 'Service Manager', 'Certification Type' => 'Certified measureQuick Champion', 'Certification Status' => 'Active'], ['Name' => 'Tina', 'Last Name' => 'Marsh', 'Email' => 'tina@crkurtz.com', 'City' => 'Canton', 'State' => 'Ohio', 'Country' => 'United States', 'Company Name' => 'C.R. Kurtz Heating & Cooling', 'Role' => 'Owner', 'Certification Type' => 'Certified measureQuick Champion', 'Certification Status' => 'Active'], ['Name' => 'Rusty', 'Last Name' => 'Barnes', 'Email' => 'rusty@bradhambrothers.com', 'City' => 'Charlotte', 'State' => 'North Carolina', 'Country' => 'United States', 'Company Name' => 'Bradham Brothers Heating, Cooling and Electrical', 'Role' => 'Owner', 'Certification Type' => 'Certified measureQuick Champion', 'Certification Status' => 'Active'], ['Name' => 'Reginald', 'Last Name' => 'Lowe', 'Email' => 'Reggieapex@yahoo.com', 'City' => 'Riverdale', 'State' => 'Georgia', 'Country' => 'United States', 'Company Name' => 'Apex Residential Solutions', 'Role' => 'Owner', 'Certification Type' => 'Certified measureQuick Champion', 'Certification Status' => 'Active'], ['Name' => 'Nathan', 'Last Name' => 'Richards', 'Email' => 'nathanr@kliemannbros.com', 'City' => 'Tacoma', 'State' => 'Washington', 'Country' => 'United States', 'Company Name' => 'Kliemann Brothers', 'Role' => 'Training and Technical Support Specialist', 'Certification Type' => 'Certified measureQuick Trainer', 'Certification Status' => 'Active'], ['Name' => 'Clint', 'Last Name' => 'Powers', 'Email' => 'clint@aircontrolaz.com', 'City' => 'Lake Havasu City', 'State' => 'Arizona', 'Country' => 'United States', 'Company Name' => 'Air Control Home Services', 'Role' => 'Owner', 'Certification Type' => 'Certified measureQuick Champion', 'Certification Status' => 'Active'], ['Name' => 'MARIO', 'Last Name' => 'GARCIA', 'Email' => 'CONTACT@360HVACPRO.COM', 'City' => 'Denver', 'State' => 'Michigan', 'Country' => 'United States', 'Company Name' => '360 HVAC PRO LLC', 'Role' => 'Owner', 'Certification Type' => 'Certified measureQuick Champion', 'Certification Status' => 'Active'], ['Name' => 'Sam(Qingzhang)', 'Last Name' => 'Sheng', 'Email' => 'enzeprocom@gmail.com', 'City' => 'Kelowna', 'State' => 'British Columbia', 'Country' => 'Canada', 'Company Name' => 'Enze Pro HVAC Support Ltd', 'Role' => 'Owner', 'Certification Type' => 'Certified measureQuick Champion', 'Certification Status' => 'Active'], ['Name' => 'Christian', 'Last Name' => 'Ortiz', 'Email' => 'christian@shiftair.ca', 'City' => 'Calgary', 'State' => 'Alberta', 'Country' => 'Canada', 'Company Name' => 'Shift Air Mechanical Ltd.', 'Role' => 'Owner', 'Certification Type' => 'Certified measureQuick Champion', 'Certification Status' => 'Active'], ['Name' => 'Adrain', 'Last Name' => 'Felix', 'Email' => 'afelix@franklinenergy.com', 'City' => 'Washington', 'State' => 'Wisconson', 'Country' => 'United States', 'Company Name' => 'None', 'Role' => 'Consultant', 'Certification Type' => 'Certified measureQuick Trainer', 'Certification Status' => 'Active'], ['Name' => 'Andrew', 'Last Name' => 'Sweetman', 'Email' => 'andys@genzryan.com', 'City' => 'Burnsville', 'State' => 'Minnesota', 'Country' => 'United States', 'Company Name' => 'Genz-Ryan', 'Role' => 'Head of Training And Development', 'Certification Type' => 'Certified measureQuick Champion', 'Certification Status' => 'Active'], ['Name' => 'Doug', 'Last Name' => 'Larson', 'Email' => 'dougl@genzryan.com', 'City' => 'Burnsville', 'State' => 'Minnesota', 'Country' => 'United States', 'Company Name' => 'Genz-Ryan', 'Role' => 'Director of Operations', 'Certification Type' => 'Certified measureQuick Champion', 'Certification Status' => 'Active'], ['Name' => 'Eric', 'Last Name' => 'Kaiser', 'Email' => 'ekaiser@trutechtools.com', 'City' => 'Akron', 'State' => 'Ohio', 'Country' => 'United States', 'Company Name' => 'Trutech Tools', 'Role' => 'Educator', 'Certification Type' => 'Certified measureQuick Trainer', 'Certification Status' => 'Active'], ['Name' => 'Kent', 'Last Name' => 'Papczun', 'Email' => 'kent.papczun@webbsupply.com', 'City' => 'Akron', 'State' => 'Ohio', 'Country' => 'United States', 'Company Name' => 'Webb Supply', 'Role' => 'Technical Support/Training & Teaching Manager', 'Certification Type' => 'Certified measureQuick Trainer', 'Certification Status' => 'Active'], ['Name' => 'William', 'Last Name' => 'Fisher', 'Email' => 'hhrhandc@gmail.com', 'City' => 'Luray', 'State' => 'Virginia', 'Country' => 'United States', 'Company Name' => 'Hawksbill Home Comfort', 'Role' => 'Owner/Operator', 'Certification Type' => 'Certified measureQuick Trainer', 'Certification Status' => 'Active'], ['Name' => 'Mike', 'Last Name' => 'Henderson', 'Email' => 'Mike@dwyeroil.com', 'City' => 'Oreland', 'State' => 'Pennsylvania', 'Country' => 'United States', 'Company Name' => 'Reit Energy', 'Role' => 'Installation Manager/ Trainer', 'Certification Type' => 'Certified measureQuick Trainer', 'Certification Status' => 'Active'], ['Name' => 'Andy', 'Last Name' => 'Holt', 'Email' => 'andy@toprate.com', 'City' => 'LaGrange', 'State' => 'Georgia', 'Country' => 'United States', 'Company Name' => 'Outdoor University', 'Role' => 'Owner', 'Certification Type' => 'Certified measureQuick Trainer', 'Certification Status' => 'Active'] ]; $results['total_rows'] = count($csv_data); $session_id = 'enhanced_' . date('Y-m-d_H-i-s'); $results['session_id'] = $session_id; $import_log = [ 'timestamp' => time(), 'file' => 'enhanced_csv_import_ajax', 'total_rows' => count($csv_data), 'users' => [] ]; // Process each row foreach ($csv_data as $index => $row) { try { $email = trim($row['Email']); // Check if user exists $user = get_user_by('email', $email); if (!$user) { // User doesn't exist - would create but we're just updating existing ones continue; } else { // Update existing user's profile $user_id = $user->ID; $results['users_updated']++; // Get or create trainer profile if (class_exists('HVAC_Trainer_Profile_Manager')) { $profile_manager = HVAC_Trainer_Profile_Manager::get_instance(); $profile = $profile_manager->get_trainer_profile($user_id); if ($profile) { $profile_id = $profile->ID; $results['profiles_updated']++; // Update profile metadata $this->update_profile_metadata_ajax($profile_id, $row); // Schedule geocoding if location data exists $city = trim($row['City'] ?? ''); $state = trim($row['State'] ?? ''); $country = trim($row['Country'] ?? ''); if (!empty($city) || !empty($state) || !empty($country)) { wp_schedule_single_event(time() + rand(5, 30), 'hvac_geocode_address', [$profile_id]); $results['geocoding_scheduled']++; } } } // Add to import log $import_log['users'][$email] = [ 'user_id' => $user_id, 'user_login' => $user->user_login, 'csv_data' => $row, 'imported_at' => time(), 'status' => 'updated' ]; } } catch (Exception $e) { $results['errors']++; } } // Save import log $existing_log = get_option('hvac_csv_import_log', []); $existing_log[$session_id] = $import_log; update_option('hvac_csv_import_log', $existing_log); $results['import_log_saved'] = true; $results['end_time'] = current_time('mysql'); $results['duration'] = time() - strtotime($results['start_time']); return $results; } /** * Update trainer profile metadata via AJAX */ private function update_profile_metadata_ajax($profile_id, $row) { $field_mappings = [ 'trainer_city' => ['City'], 'trainer_state' => ['State'], 'trainer_country' => ['Country'], 'organization_name' => ['Company Name'], 'certification_type' => ['Certification Type'], 'certification_status' => ['Certification Status'], 'date_certified' => ['standardized_date'], 'role' => ['mapped_role', 'Role'], 'training_audience' => ['parsed_training_audience', 'Training Audience'], 'business_website' => ['Company Website'], 'business_phone' => ['Phone Number'], 'application_details' => ['Application Details'] ]; foreach ($field_mappings as $profile_field => $csv_keys) { $value = null; // Try each CSV key until we find a value foreach ($csv_keys as $csv_key) { if (isset($row[$csv_key]) && !empty(trim($row[$csv_key]))) { $value = trim($row[$csv_key]); break; } } if ($value) { update_post_meta($profile_id, $profile_field, sanitize_text_field($value)); } } // Handle business type taxonomy $business_type = $row['mapped_business_type'] ?? $row['Organizer Category'] ?? ''; if (!empty($business_type)) { $term = get_term_by('name', $business_type, 'business_type'); if (!$term) { $term_result = wp_insert_term($business_type, 'business_type'); if (!is_wp_error($term_result)) { $term = get_term($term_result['term_id'], 'business_type'); } } if ($term && !is_wp_error($term)) { wp_set_post_terms($profile_id, [$term->term_id], 'business_type'); } } } } // Initialize HVAC_Geocoding_Ajax::get_instance();