init_hooks();
}
/**
* Check if we're in production environment
*/
private function is_production() {
// Check if we're on upskillhvac.com domain (production)
$site_url = get_site_url();
return strpos($site_url, 'upskillhvac.com') !== false;
}
/**
* Debug logging wrapper
*/
private function debug_log($message) {
if (!$this->is_production() && defined('WP_DEBUG') && WP_DEBUG) {
error_log('HVAC MapGeo: ' . $message);
}
}
/**
* Initialize hooks
*/
private function init_hooks() {
// Hook into MapGeo data filter - modify layout and inject trainer modal data
add_filter('igm_add_meta', [$this, 'modify_map_layout'], 10, 2);
// Hook into MapGeo marker data to add our trainer information
add_filter('igm_marker_data', [$this, 'inject_trainer_modal_data'], 10, 2);
// AJAX handlers for our own filtering
add_action('wp_ajax_hvac_filter_trainers', [$this, 'ajax_filter_trainers']);
add_action('wp_ajax_nopriv_hvac_filter_trainers', [$this, 'ajax_filter_trainers']);
// AJAX handler to get trainer certification type for Champions check
add_action('wp_ajax_hvac_get_trainer_certification', [$this, 'ajax_get_trainer_certification']);
add_action('wp_ajax_nopriv_hvac_get_trainer_certification', [$this, 'ajax_get_trainer_certification']);
// AJAX handler to get complete trainer profile data
add_action('wp_ajax_hvac_get_trainer_profile', [$this, 'ajax_get_trainer_profile']);
add_action('wp_ajax_nopriv_hvac_get_trainer_profile', [$this, 'ajax_get_trainer_profile']);
add_action('wp_ajax_hvac_search_trainers', [$this, 'ajax_search_trainers']);
add_action('wp_ajax_nopriv_hvac_search_trainers', [$this, 'ajax_search_trainers']);
// Add JavaScript to handle MapGeo marker clicks
add_action('wp_footer', [$this, 'add_mapgeo_click_handlers']);
}
/**
* Debug MapGeo integration
*/
public function debug_mapgeo_integration() {
if (isset($_GET['debug_mapgeo']) && current_user_can('manage_options')) {
$this->debug_log('Debug: Integration loaded');
$this->debug_log('Debug: Filters registered for igm_add_meta');
}
}
/**
* Modify map layout to prevent sidebar display and inject trainer profile IDs
*
* @param array $meta Map metadata
* @param int $map_id Map ID
* @return array Modified metadata
*/
public function modify_map_layout($meta, $map_id = null) {
// Only process if meta is an array
if (!is_array($meta)) {
return $meta;
}
// Only process for our specific map (5872)
if ($map_id && $map_id != $this->map_id) {
return $meta;
}
error_log('HVAC MapGeo: Processing map layout modification for map ' . $map_id);
error_log('HVAC MapGeo: Meta keys: ' . implode(', ', array_keys($meta)));
error_log('HVAC MapGeo: Full meta structure: ' . print_r($meta, true));
// Check for different marker types that MapGeo might use
$marker_types = ['roundMarkers', 'iconMarkers', 'markers', 'customMarkers'];
foreach ($marker_types as $marker_type) {
if (isset($meta[$marker_type]) && is_array($meta[$marker_type])) {
error_log('HVAC MapGeo: Found ' . count($meta[$marker_type]) . ' markers of type: ' . $marker_type);
foreach ($meta[$marker_type] as $index => &$marker) {
// Log marker structure for debugging
error_log('HVAC MapGeo: Marker ' . $index . ' keys: ' . implode(', ', array_keys($marker)));
// Check if this marker has trainer data we can identify
$trainer_name = null;
if (isset($marker['title']) && !empty($marker['title'])) {
$trainer_name = $marker['title'];
} elseif (isset($marker['name']) && !empty($marker['name'])) {
$trainer_name = $marker['name'];
}
if ($trainer_name) {
error_log('HVAC MapGeo: Looking for trainer profile for: ' . $trainer_name);
// Try to find matching trainer profile by name
$trainer_profile_id = $this->find_trainer_profile_by_name($trainer_name);
if ($trainer_profile_id) {
error_log('HVAC MapGeo: Found profile ID ' . $trainer_profile_id . ' for trainer: ' . $trainer_name);
// Set custom click action for trainer modal with profile ID
$marker['action'] = 'hvac_show_trainer_modal';
$marker['hvac_profile_id'] = $trainer_profile_id;
// Also add to marker ID for easy identification
$marker['id'] = 'trainer_' . $trainer_profile_id;
// Remove sidebar display if it was set
if (isset($marker['action']) && $marker['action'] === 'igm_display_right_1_3') {
$marker['action'] = 'hvac_show_trainer_modal';
}
error_log('HVAC MapGeo: Configured marker for trainer ' . $trainer_name . ' with profile ID ' . $trainer_profile_id);
} else {
error_log('HVAC MapGeo: No profile found for trainer: ' . $trainer_name);
// Fallback to tooltip for non-trainer markers
if (isset($marker['action']) && $marker['action'] === 'igm_display_right_1_3') {
$marker['action'] = 'tooltip';
}
}
} else {
error_log('HVAC MapGeo: Marker ' . $index . ' has no identifiable trainer name');
}
}
}
}
error_log('HVAC MapGeo: Map layout modification complete');
return $meta;
}
/**
* Find trainer profile ID by trainer name
*
* @param string $trainer_name
* @return int|false Profile ID or false if not found
*/
private function find_trainer_profile_by_name($trainer_name) {
$args = [
'post_type' => 'trainer_profile',
'posts_per_page' => 1,
'post_status' => 'publish',
'meta_query' => [
[
'key' => 'trainer_display_name',
'value' => $trainer_name,
'compare' => '='
]
]
];
$query = new WP_Query($args);
if ($query->have_posts()) {
return $query->posts[0]->ID;
}
wp_reset_postdata();
return false;
}
/**
* AJAX handler to get trainer certification type
*/
public function ajax_get_trainer_certification() {
// Verify nonce
if (!wp_verify_nonce($_POST['nonce'], 'hvac_find_trainer')) {
wp_send_json_error('Invalid nonce');
return;
}
$profile_id = intval($_POST['profile_id']);
if (!$profile_id) {
wp_send_json_error('Invalid profile ID');
return;
}
// Get the certification type and color for this profile
$certification_type = get_post_meta($profile_id, 'certification_type', true);
$certification_color = get_post_meta($profile_id, 'certification_color', true);
wp_send_json_success([
'certification_type' => $certification_type ?: 'HVAC Trainer',
'certification_color' => $certification_color ?: '#f0f7e8'
]);
}
/**
* AJAX handler to get complete trainer profile data
*/
public function ajax_get_trainer_profile() {
error_log('HVAC MapGeo: ajax_get_trainer_profile called');
// Verify nonce
if (!wp_verify_nonce($_POST['nonce'], 'hvac_find_trainer')) {
error_log('HVAC MapGeo: Invalid nonce in ajax_get_trainer_profile');
wp_send_json_error('Invalid nonce');
return;
}
$profile_id = intval($_POST['profile_id']);
error_log('HVAC MapGeo: Processing profile ID: ' . $profile_id);
if (!$profile_id) {
error_log('HVAC MapGeo: Invalid profile ID: ' . $profile_id);
wp_send_json_error('Invalid profile ID');
return;
}
// Get the trainer profile post
$profile_post = get_post($profile_id);
if (!$profile_post || $profile_post->post_type !== 'trainer_profile') {
error_log('HVAC MapGeo: Invalid trainer profile - post type: ' . ($profile_post ? $profile_post->post_type : 'null'));
wp_send_json_error('Invalid trainer profile');
return;
}
error_log('HVAC MapGeo: Valid profile found: ' . $profile_post->post_title);
// Get user ID for event count
$user_id = get_post_meta($profile_id, 'user_id', true);
// Get event count
$event_count = 0;
if ($user_id && function_exists('tribe_get_events')) {
$events = tribe_get_events([
'author' => $user_id,
'eventDisplay' => 'all',
'posts_per_page' => -1,
'fields' => 'ids'
]);
$event_count = count($events);
}
// Build complete trainer data structure
try {
// Get business type safely
$business_types = wp_get_post_terms($profile_id, 'business_type', ['fields' => 'names']);
$business_type = 'Independent Contractor';
if (!is_wp_error($business_types) && !empty($business_types)) {
$business_type = implode(', ', $business_types);
} else {
$business_type_meta = get_post_meta($profile_id, 'business_type', true);
if ($business_type_meta) {
$business_type = $business_type_meta;
}
}
error_log('HVAC MapGeo: Business type: ' . $business_type);
// Get training formats safely
$formats = wp_get_post_terms($profile_id, 'training_format', ['fields' => 'names']);
$training_formats = 'In-Person, Virtual';
if (!is_wp_error($formats) && !empty($formats)) {
$training_formats = implode(', ', $formats);
}
error_log('HVAC MapGeo: Training formats: ' . $training_formats);
// Get training locations safely
$resources = wp_get_post_terms($profile_id, 'training_resources', ['fields' => 'names']);
$training_locations = 'On-site, Remote';
if (!is_wp_error($resources) && !empty($resources)) {
$training_locations = implode(', ', $resources);
}
error_log('HVAC MapGeo: Training locations: ' . $training_locations);
$trainer_data = [
'profile_id' => $profile_id,
'user_id' => $user_id,
'name' => get_post_meta($profile_id, 'trainer_display_name', true) ?: $profile_post->post_title,
'city' => get_post_meta($profile_id, 'trainer_city', true) ?: 'Location not available',
'state' => get_post_meta($profile_id, 'trainer_state', true) ?: '',
'certification_type' => get_post_meta($profile_id, 'certification_type', true) ?: 'HVAC Trainer',
'profile_image' => get_post_meta($profile_id, 'profile_image_url', true) ?: '',
'business_type' => $business_type,
'event_count' => $event_count,
'training_formats' => $training_formats,
'training_locations' => $training_locations,
'upcoming_events' => []
];
error_log('HVAC MapGeo: Successfully built trainer data for: ' . $trainer_data['name']);
wp_send_json_success($trainer_data);
} catch (Exception $e) {
error_log('HVAC MapGeo: Error building trainer data: ' . $e->getMessage());
wp_send_json_error('Error building trainer data: ' . $e->getMessage());
} catch (Error $e) {
error_log('HVAC MapGeo: Fatal error building trainer data: ' . $e->getMessage());
wp_send_json_error('Fatal error building trainer data: ' . $e->getMessage());
}
}
/**
* Add JavaScript to handle MapGeo custom click actions
*/
public function add_mapgeo_click_handlers() {
// Only add on find trainer page
if (!is_page() || get_post_field('post_name') !== 'find-a-trainer') {
return;
}
?>
%s
%s, %s
%s
View Profile
',
esc_html($trainer_name),
esc_html($city),
esc_html($state),
esc_html($certification),
$profile_id
);
return [
'id' => 'trainer_' . $profile_id,
'coordinates' => [
'lat' => floatval($lat),
'lng' => floatval($lng)
],
'tooltipContent' => $tooltip,
'action' => 'tooltip', // Changed from 'none' to 'tooltip' to show tooltip on click
'value' => '1',
'radius' => '10',
'fill' => $certification === 'Certified measureQuick Champion' ? '#FFD700' : '#0073aa',
'fillOpacity' => '0.8',
'borderColor' => '#005a87',
'borderWidth' => '2'
];
}
/**
* Get all geocoded trainers
*
* @return array
*/
private function get_geocoded_trainers() {
$args = [
'post_type' => 'trainer_profile',
'posts_per_page' => -1,
'post_status' => 'publish',
'meta_query' => [
'relation' => 'AND',
[
'key' => 'is_public_profile',
'value' => '1',
'compare' => '='
],
[
'key' => 'latitude',
'compare' => 'EXISTS'
],
[
'key' => 'longitude',
'compare' => 'EXISTS'
]
]
];
// Add user status filter
$this->add_user_status_filter($args);
$query = new WP_Query($args);
$trainers = [];
if ($query->have_posts()) {
while ($query->have_posts()) {
$query->the_post();
$trainers[] = get_the_ID();
}
}
wp_reset_postdata();
return $trainers;
}
/**
* Format trainer data as map marker
*
* @param int $profile_id Trainer profile post ID
* @return array Marker data
*/
private function format_trainer_marker($profile_id) {
$user_id = get_post_meta($profile_id, 'user_id', true);
$trainer_name = get_post_meta($profile_id, 'trainer_display_name', true);
$city = get_post_meta($profile_id, 'trainer_city', true);
$state = get_post_meta($profile_id, 'trainer_state', true);
$lat = get_post_meta($profile_id, 'latitude', true);
$lng = get_post_meta($profile_id, 'longitude', true);
$certification = get_post_meta($profile_id, 'certification_type', true);
$profile_image = get_post_meta($profile_id, 'profile_image_url', true);
// Get taxonomies
$business_types = wp_get_post_terms($profile_id, 'business_type', ['fields' => 'names']);
$training_formats = wp_get_post_terms($profile_id, 'training_formats', ['fields' => 'names']);
$training_resources = wp_get_post_terms($profile_id, 'training_resources', ['fields' => 'names']);
// Count upcoming events
$event_count = $this->get_trainer_event_count($user_id);
return [
'id' => 'trainer_' . $profile_id,
'title' => $trainer_name,
'lat' => floatval($lat),
'lng' => floatval($lng),
'icon' => $this->get_marker_icon($certification),
'content' => $this->generate_marker_popup($profile_id),
'data' => [
'trainer_id' => $user_id,
'profile_id' => $profile_id,
'name' => $trainer_name,
'city' => $city,
'state' => $state,
'certification' => $certification,
'business_type' => $business_types,
'training_formats' => $training_formats,
'training_resources' => $training_resources,
'event_count' => $event_count,
'profile_image' => $profile_image
]
];
}
/**
* Generate marker popup content
*
* @param int $profile_id Trainer profile post ID
* @return string HTML content
*/
private function generate_marker_popup($profile_id) {
$trainer_name = get_post_meta($profile_id, 'trainer_display_name', true);
$city = get_post_meta($profile_id, 'trainer_city', true);
$state = get_post_meta($profile_id, 'trainer_state', true);
$certification = get_post_meta($profile_id, 'certification_type', true);
$profile_image = get_post_meta($profile_id, 'profile_image_url', true);
ob_start();
?>
,
No trainers found matching your criteria. Try adjusting your filters.
HVAC Plugin Warning: The following plugins may conflict with MapGeo integration: