csv_file_path = ABSPATH . 'wp-content/plugins/hvac-community-events/CSV_Trainers_Import_1Aug2025.csv'; $this->results = [ 'total_rows' => 0, 'users_created' => 0, 'users_updated' => 0, 'profiles_created' => 0, 'profiles_updated' => 0, 'taxonomies_assigned' => 0, 'venues_created' => 0, 'organizers_created' => 0, 'errors' => 0, 'details' => [], 'start_time' => current_time('mysql') ]; } /** * Execute the enhanced import */ public function execute_import() { try { // Check if CSV file exists if (!file_exists($this->csv_file_path)) { throw new Exception('CSV file not found: ' . $this->csv_file_path); } // Open CSV file $handle = fopen($this->csv_file_path, 'r'); if (!$handle) { throw new Exception('Cannot open CSV file'); } // Get headers $headers = fgetcsv($handle, 0, ',', '"', '\\'); if (!$headers) { throw new Exception('Cannot read CSV headers'); } // Clean headers $headers = array_map('trim', $headers); // Process each row $row_number = 1; while (($row = fgetcsv($handle, 0, ',', '"', '\\')) !== FALSE) { $row_number++; $this->results['total_rows']++; try { $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()); } } fclose($handle); $this->results['end_time'] = current_time('mysql'); return $this->results; } catch (Exception $e) { $this->results['fatal_error'] = $e->getMessage(); error_log("CSV Import Fatal Error: " . $e->getMessage()); return $this->results; } } /** * Process a single CSV row */ private function process_row($headers, $row, $row_number) { // Create associative array from headers and row data $data = []; foreach ($headers as $index => $header) { $data[$header] = isset($row[$index]) ? trim($row[$index]) : ''; } // Skip rows with missing email if (empty($data['Email'])) { throw new Exception("Missing email address"); } $email = sanitize_email($data['Email']); $first_name = sanitize_text_field($data['Name'] ?? ''); $last_name = sanitize_text_field($data['Last Name'] ?? ''); $username = sanitize_user($data['User ID'] ?? ''); if (empty($username)) { $username = sanitize_user(strtolower($first_name . '.' . $last_name)); } // Check if user exists $user = get_user_by('email', $email); if (!$user) { $user = get_user_by('login', $username); } if (!$user) { // Create new user $user_id = $this->create_user($data, $username, $email, $first_name, $last_name); $this->results['users_created']++; } else { // Update existing user $user_id = $user->ID; $this->update_user($user_id, $data, $first_name, $last_name); $this->results['users_updated']++; } // Create or update trainer profile $profile_id = $this->create_or_update_profile($user_id, $data); // Assign taxonomies $this->assign_taxonomies($profile_id, $data); // Create venue and organizer if requested $this->create_venue_organizer_if_needed($user_id, $data); $this->results['details'][] = "Row $row_number: Processed $email successfully"; } /** * Create new user */ private function create_user($data, $username, $email, $first_name, $last_name) { // Generate a random password $password = wp_generate_password(12, false); $user_data = [ 'user_login' => $username, 'user_email' => $email, 'user_pass' => $password, 'first_name' => $first_name, 'last_name' => $last_name, 'display_name' => $first_name . ' ' . $last_name, 'role' => 'hvac_trainer' ]; $user_id = wp_insert_user($user_data); if (is_wp_error($user_id)) { throw new Exception('User creation failed: ' . $user_id->get_error_message()); } // Store additional user meta if (!empty($data['Phone Number'])) { update_user_meta($user_id, 'phone_number', sanitize_text_field($data['Phone Number'])); } if (!empty($data['Role'])) { update_user_meta($user_id, 'personal_role', sanitize_text_field($data['Role'])); } return $user_id; } /** * Update existing user */ private function update_user($user_id, $data, $first_name, $last_name) { // Update basic user info wp_update_user([ 'ID' => $user_id, 'first_name' => $first_name, 'last_name' => $last_name, 'display_name' => $first_name . ' ' . $last_name ]); // Update user meta if (!empty($data['Phone Number'])) { update_user_meta($user_id, 'phone_number', sanitize_text_field($data['Phone Number'])); } if (!empty($data['Role'])) { update_user_meta($user_id, 'personal_role', sanitize_text_field($data['Role'])); } } /** * Create or update trainer profile */ private function create_or_update_profile($user_id, $data) { // Check if profile already exists $existing_profiles = get_posts([ 'post_type' => 'trainer_profile', 'meta_query' => [ [ 'key' => 'user_id', 'value' => $user_id, 'compare' => '=' ] ], 'posts_per_page' => 1 ]); $first_name = sanitize_text_field($data['Name'] ?? ''); $last_name = sanitize_text_field($data['Last Name'] ?? ''); $display_name = trim($first_name . ' ' . $last_name); // Prepare profile data $profile_data = [ 'post_type' => 'trainer_profile', 'post_status' => 'publish', 'post_title' => $display_name, 'post_content' => sanitize_textarea_field($data['Application Details'] ?? ''), 'post_author' => $user_id ]; if (!empty($existing_profiles)) { // Update existing profile $profile_id = $existing_profiles[0]->ID; $profile_data['ID'] = $profile_id; wp_update_post($profile_data); $this->results['profiles_updated']++; } else { // Create new profile $profile_id = wp_insert_post($profile_data); if (is_wp_error($profile_id)) { throw new Exception('Profile creation failed: ' . $profile_id->get_error_message()); } $this->results['profiles_created']++; } // Update profile meta fields $meta_fields = [ 'user_id' => $user_id, 'trainer_first_name' => $first_name, 'trainer_last_name' => $last_name, 'trainer_display_name' => $display_name, 'trainer_email' => sanitize_email($data['Email']), 'trainer_phone' => sanitize_text_field($data['Phone Number'] ?? ''), 'trainer_city' => sanitize_text_field($data['City'] ?? ''), 'trainer_state' => sanitize_text_field($data['State'] ?? ''), 'trainer_country' => sanitize_text_field($data['Country'] ?? ''), 'company_name' => sanitize_text_field($data['Company Name'] ?? ''), 'organization_name' => sanitize_text_field($data['Company Name'] ?? ''), 'organization_website' => esc_url_raw($data['Company Website'] ?? ''), 'personal_role' => sanitize_text_field($data['Role'] ?? ''), 'application_details' => sanitize_textarea_field($data['Application Details'] ?? ''), 'certification_type' => sanitize_text_field($data['Certification Type'] ?? ''), 'certification_status' => sanitize_text_field($data['Certification Status'] ?? ''), ]; // Handle date certified if (!empty($data['Date Certified,'])) { $date_str = trim($data['Date Certified,'], ','); $date_certified = $this->parse_date($date_str); if ($date_certified) { $meta_fields['date_certified'] = $date_certified; } } // Update all meta fields foreach ($meta_fields as $key => $value) { if (!empty($value)) { update_post_meta($profile_id, $key, $value); } } return $profile_id; } /** * Assign taxonomies to profile */ private function assign_taxonomies($profile_id, $data) { // Business Type taxonomy if (!empty($data['Business Type'])) { $business_types = $this->parse_comma_separated($data['Business Type']); $this->assign_taxonomy_terms($profile_id, 'business_type', $business_types); } // Training Audience taxonomy if (!empty($data['Training Audience'])) { $training_audiences = $this->parse_comma_separated($data['Training Audience']); $this->assign_taxonomy_terms($profile_id, 'training_audience', $training_audiences); } $this->results['taxonomies_assigned']++; } /** * Parse comma-separated values */ private function parse_comma_separated($value) { $items = explode(',', $value); return array_map('trim', $items); } /** * Assign taxonomy terms to profile */ private function assign_taxonomy_terms($profile_id, $taxonomy, $terms) { if (empty($terms)) { return; } $term_ids = []; foreach ($terms as $term_name) { if (empty($term_name)) { continue; } // Get or create term $term = get_term_by('name', $term_name, $taxonomy); if (!$term) { $term_data = wp_insert_term($term_name, $taxonomy); if (!is_wp_error($term_data)) { $term_ids[] = $term_data['term_id']; } } else { $term_ids[] = $term->term_id; } } if (!empty($term_ids)) { wp_set_object_terms($profile_id, $term_ids, $taxonomy); } } /** * Create venue and organizer if needed */ private function create_venue_organizer_if_needed($user_id, $data) { // Create venue if requested if (!empty($data['Create Venue']) && strtolower($data['Create Venue']) === 'yes') { $this->create_venue($user_id, $data); $this->results['venues_created']++; } // Create organizer if requested if (!empty($data['Create Organizer']) && strtolower($data['Create Organizer']) === 'yes') { $this->create_organizer($user_id, $data); $this->results['organizers_created']++; } } /** * Create venue for trainer */ private function create_venue($user_id, $data) { $company_name = sanitize_text_field($data['Company Name'] ?? ''); if (empty($company_name)) { return; } // Check if venue already exists $existing_venue = get_posts([ 'post_type' => 'tribe_venue', 'title' => $company_name, 'post_status' => 'publish', 'posts_per_page' => 1 ]); if (!empty($existing_venue)) { return; // Venue already exists } // Create venue $venue_data = [ 'post_type' => 'tribe_venue', 'post_status' => 'publish', 'post_title' => $company_name, 'post_author' => $user_id ]; $venue_id = wp_insert_post($venue_data); if (is_wp_error($venue_id)) { error_log('Venue creation failed: ' . $venue_id->get_error_message()); return; } // Add venue meta update_post_meta($venue_id, '_VenueAddress', sanitize_text_field($data['City'] ?? '')); update_post_meta($venue_id, '_VenueCity', sanitize_text_field($data['City'] ?? '')); update_post_meta($venue_id, '_VenueStateProvince', sanitize_text_field($data['State'] ?? '')); update_post_meta($venue_id, '_VenueCountry', sanitize_text_field($data['Country'] ?? '')); if (!empty($data['Company Website'])) { update_post_meta($venue_id, '_VenueURL', esc_url_raw($data['Company Website'])); } if (!empty($data['Phone Number'])) { update_post_meta($venue_id, '_VenuePhone', sanitize_text_field($data['Phone Number'])); } } /** * Create organizer for trainer */ private function create_organizer($user_id, $data) { $first_name = sanitize_text_field($data['Name'] ?? ''); $last_name = sanitize_text_field($data['Last Name'] ?? ''); $display_name = trim($first_name . ' ' . $last_name); if (empty($display_name)) { return; } // Check if organizer already exists $existing_organizer = get_posts([ 'post_type' => 'tribe_organizer', 'title' => $display_name, 'post_status' => 'publish', 'posts_per_page' => 1 ]); if (!empty($existing_organizer)) { return; // Organizer already exists } // Create organizer $organizer_data = [ 'post_type' => 'tribe_organizer', 'post_status' => 'publish', 'post_title' => $display_name, 'post_author' => $user_id ]; $organizer_id = wp_insert_post($organizer_data); if (is_wp_error($organizer_id)) { error_log('Organizer creation failed: ' . $organizer_id->get_error_message()); return; } // Add organizer meta update_post_meta($organizer_id, '_OrganizerEmail', sanitize_email($data['Email'])); if (!empty($data['Phone Number'])) { update_post_meta($organizer_id, '_OrganizerPhone', sanitize_text_field($data['Phone Number'])); } if (!empty($data['Company Website'])) { update_post_meta($organizer_id, '_OrganizerWebsite', esc_url_raw($data['Company Website'])); } } /** * Parse date string to Y-m-d format */ private function parse_date($date_str) { // Handle various date formats $formats = ['d-M-y', 'd-M-Y', 'm/d/Y', 'Y-m-d']; foreach ($formats as $format) { $date = DateTime::createFromFormat($format, $date_str); if ($date !== false) { return $date->format('Y-m-d'); } } return null; } } // Function to execute the import (can be called from AJAX or CLI) function execute_enhanced_csv_import() { $importer = new HVAC_Enhanced_CSV_Import(); return $importer->execute_import(); } ?>