// AJAX Handler: Update Selected Clinics with Progress Tracking & Logging function update_selected_clinics_ajax() { if (!isset($_POST['clinic_ids']) || empty($_POST['clinic_ids'])) { wp_die("No clinics selected."); } $clinic_ids = explode(',', sanitize_text_field($_POST['clinic_ids'])); $total = count($clinic_ids); $updated_count = 0; $log_file = plugin_dir_path(__FILE__) . 'clinic_updates.log'; file_put_contents($log_file, "Clinic Update Log - " . date("Y-m-d H:i:s") . "\n", FILE_APPEND); ob_start(); foreach ($clinic_ids as $index => $clinic_id) { $clinic_name = get_the_title($clinic_id); $api_response = my_google_places_api_fetch($clinic_name); if ($api_response) { update_post_meta($clinic_id, '_last_updated', current_time('mysql')); update_post_meta($clinic_id, '_google_place_id', $api_response['place_id'] ?? ''); update_post_meta($clinic_id, '_rating', $api_response['rating'] ?? ''); update_post_meta($clinic_id, '_reviews', $api_response['reviews'] ?? ''); file_put_contents($log_file, "✅ Updated: $clinic_name\n", FILE_APPEND); echo "

✅ Updated (" . ($updated_count + 1) . "/$total): " . esc_html($clinic_name) . "

"; $updated_count++; } else { file_put_contents($log_file, "❌ Failed: $clinic_name\n", FILE_APPEND); echo "

❌ Failed (" . ($updated_count + 1) . "/$total): " . esc_html($clinic_name) . "

"; } sleep(1); // Slow down requests to prevent API blocking ob_flush(); flush(); } echo ob_get_clean(); wp_die(); } add_action('wp_ajax_update_selected_clinics', 'update_selected_clinics_ajax'); // Update Selected Clinics function update_selected_clinics($clinic_ids) { echo "

Updating " . count($clinic_ids) . " clinics...

"; foreach ($clinic_ids as $clinic_id) { update_clinic_from_google_places($clinic_id); // Uses existing update function } } // Single Clinic API Update Function function update_clinic_from_google_places($clinic_id) { $options = get_option('cup_options'); $api_key = $options['api_key'] ?? ''; if (empty($api_key)) { error_log("❌ Google Cloud API key is missing. Please configure it in the plugin settings."); return; } global $wpdb; $clinic_name = get_the_title($clinic_id); // Update post title with Google’s name if (!empty($clinic_name)) { wp_update_post([ 'ID' => $clinic_id, 'post_title' => sanitize_text_field($clinic_name) ]); error_log("✅ Title Updated: $clinic_name"); } $clinic_city = get_post_meta($clinic_id, 'city', true) ?: 'Unknown City'; $clinic_state = get_post_meta($clinic_id, 'state', true) ?: 'Unknown State'; $search_query = urlencode("$clinic_name $clinic_city $clinic_state pain clinic USA"); $place_search_url = "https://maps.googleapis.com/maps/api/place/findplacefromtext/json?input=$search_query&inputtype=textquery&fields=place_id&key=$api_key"; $response = wp_remote_get($place_search_url); $body = json_decode(wp_remote_retrieve_body($response), true); if (empty($body['candidates'][0]['place_id'])) { error_log("❌ No Place ID found for: $clinic_name ($clinic_city, $clinic_state)"); return; } $place_id = $body['candidates'][0]['place_id']; $details_url = "https://maps.googleapis.com/maps/api/place/details/json?place_id=$place_id&fields=name,formatted_address,address_components,formatted_phone_number,website,opening_hours,rating,reviews,geometry,photos,editorial_summary,types&key=$api_key"; $details_response = wp_remote_get($details_url); $details_data = json_decode(wp_remote_retrieve_body($details_response), true); if (empty($details_data['result'])) { error_log("❌ No details found for: $clinic_name"); return; } $data = $details_data['result']; // Force overwrite by deleting existing values first $meta_keys = [ 'street-address', 'city', 'state', 'zip-code', 'phone', 'website', 'plus-code', 'lattitude', 'longitude', 'map-location', 'clinic-hours', 'reviews-static' ]; foreach ($meta_keys as $key) { delete_post_meta($clinic_id, $key); } // Store Full Address update_post_meta($clinic_id, 'address', sanitize_text_field($data['formatted_address'] ?? '')); // Extract Address Components $street_address = $city = $state = $zip_code = ''; if (!empty($data['address_components'])) { foreach ($data['address_components'] as $component) { if (in_array("street_number", $component['types'])) { $street_address = sanitize_text_field($component['long_name']); } if (in_array("route", $component['types'])) { $street_address .= " " . sanitize_text_field($component['long_name']); } if (in_array("locality", $component['types'])) { $city = sanitize_text_field($component['long_name']); } if (in_array("administrative_area_level_1", $component['types'])) { $state = sanitize_text_field($component['short_name']); } if (in_array("postal_code", $component['types'])) { $zip_code = sanitize_text_field($component['long_name']); } } } // Store Address Details update_post_meta($clinic_id, 'street-address', $street_address); update_post_meta($clinic_id, 'city', $city); update_post_meta($clinic_id, 'state', $state); update_post_meta($clinic_id, 'zip-code', $zip_code); update_post_meta($clinic_id, 'phone', sanitize_text_field($data['formatted_phone_number'] ?? '')); update_post_meta($clinic_id, 'website', esc_url($data['website'] ?? '')); // Store Google Plus Code update_post_meta($clinic_id, 'plus-code', sanitize_text_field($data['plus_code']['global_code'] ?? '')); // Store Latitude & Longitude $latitude = $data['geometry']['location']['lat'] ?? ''; $longitude = $data['geometry']['location']['lng'] ?? ''; update_post_meta($clinic_id, 'lattitude', $latitude); update_post_meta($clinic_id, 'longitude', $longitude); // Merge Latitude & Longitude into "map-location" field if (!empty($latitude) && !empty($longitude)) { update_post_meta($clinic_id, 'map-location', "$latitude,$longitude"); } // Assign Clinic Type from Google Places API to Taxonomy if (!empty($data['types'])) { $clinic_types = array_map('sanitize_text_field', $data['types']); wp_set_object_terms($clinic_id, $clinic_types, 'clinic-type'); } // Assign State and City to Taxonomy if (!empty($state)) { wp_set_object_terms($clinic_id, sanitize_text_field($state), 'state-tx'); } if (!empty($city)) { wp_set_object_terms($clinic_id, sanitize_text_field($city), 'city-name'); } // Store Ratings & Review Count update_post_meta($clinic_id, 'rating', sanitize_text_field($data['rating'] ?? '')); update_post_meta($clinic_id, 'reviews', count($data['reviews'] ?? [])); // Store Most Recent 5 Reviews in `reviews-static` Repeater if (!empty($data['reviews'])) { $reviews = []; $latest_reviews = array_slice($data['reviews'], 0, 5); foreach ($latest_reviews as $review) { $reviews[] = [ 'date-reviewed' => date("Y-m-d", $review['time']), 'full-review' => sanitize_textarea_field($review['text']), 'rating' => sanitize_text_field($review['rating']) ]; } update_post_meta($clinic_id, 'reviews-static', $reviews); } error_log("✅ Clinic Updated: $clinic_name"); } // Store Clinic Hours in `clinic-hours` Repeater error_log("DEBUG: Clinic ID: $clinic_id | Name: $clinic_name | API Opening Hours Response: " . print_r($data['opening_hours'], true)); if (!empty($data['opening_hours']['periods'])) { $clinic_hours = []; $days_of_week = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]; foreach ($data['opening_hours']['periods'] as $period) { $weekday = isset($period['open']['day']) ? $days_of_week[$period['open']['day']] : null; $open_time = isset($period['open']['time']) ? substr_replace($period['open']['time'], ':', -2, 0) : null; $close_time = isset($period['close']['time']) ? substr_replace($period['close']['time'], ':', -2, 0) : null; if ($weekday !== null && $open_time !== null && $close_time !== null) { $clinic_hours[] = [ 'weekday' => $weekday, 'open_time' => $open_time, 'close_time' => $close_time ]; } } if (!empty($clinic_hours)) { $merged_hours = []; foreach ($clinic_hours as $hour) { $weekday = $hour['weekday']; $open_time = $hour['open_time']; $close_time = $hour['close_time']; if (!isset($merged_hours[$weekday])) { $merged_hours[$weekday] = []; } $merged_hours[$weekday][] = "$open_time - $close_time"; } $repeater_data = []; $count = 0; foreach ($merged_hours as $day => $hours) { $repeater_data["item-$count"] = [ 'weekday' => $day, 'open_time' => implode(" & ", $hours), 'close_time' => '' ]; $count++; } update_post_meta($clinic_id, 'clinic-hours', $repeater_data); error_log("✅ Merged Hours updated for: $clinic_name"); } else { error_log("⚠️ No valid hours found in `periods[]` for: $clinic_name"); } } // If `periods` is missing, try `weekday_text` if (empty($clinic_hours) && !empty($data['opening_hours']['weekday_text'])) { $formatted_hours = implode(", ", $data['opening_hours']['weekday_text']); update_post_meta($clinic_id, 'hours-full', $formatted_hours); error_log("📅 Stored formatted hours for: $clinic_name"); } // Store Last Updated Time update_post_meta($clinic_id, '_last_updated', time()); // Fetch and force update the clinic description $description = isset($data['editorial_summary']['overview']) && !empty(trim($data['editorial_summary']['overview'])) ? trim($data['editorial_summary']['overview']) : null; if (!empty($description)) { error_log("✅ API has a description for: $clinic_name"); } else { error_log("⚠️ No API description found for: $clinic_name"); } // Get current post content $current_content = get_post_field('post_content', $clinic_id); // Define unwanted default messages that trigger an update $default_messages = [ "If you are the Owner of", "are growing in numbers. Make sure you are getting the correct treatment" ]; // Check if post content contains any of the default messages $update_description = false; foreach ($default_messages as $message) { if (strpos($current_content, $message) !== false) { $update_description = true; break; } } // Only update the description if one of the default messages is found if ($update_description && !empty($description) && $description !== "No description available.") { wp_update_post([ 'ID' => $clinic_id, 'post_content' => $description ]); error_log("✅ Description Updated for: $clinic_name"); } else { error_log("⚠️ Skipped update for: $clinic_name (No valid API description)"); } // Check if Google provides photos and set the first one as Featured Image if (!empty($data['photos'][0]['photo_reference'])) { $photo_reference = $data['photos'][0]['photo_reference']; $photo_url = "https://maps.googleapis.com/maps/api/place/photo?maxwidth=1200&photoreference=$photo_reference&key=$api_key"; error_log("DEBUG: Clinic ID: $clinic_id | Name: $clinic_name | API Data: " . print_r($data, true)); $image_id = upload_external_image($photo_url, $clinic_name); if ($image_id) { set_post_thumbnail($clinic_id, $image_id); error_log("✅ Fallback Image Replaced for: $clinic_name"); } } /** * Upload an external image to WordPress and return the image ID. * * @param string $image_url Image URL. * @param string $title Title for the image. * @return int|false Image ID on success, false on failure. */ function upload_external_image($image_url, $title) { require_once(ABSPATH . 'wp-admin/includes/file.php'); require_once(ABSPATH . 'wp-admin/includes/media.php'); require_once(ABSPATH . 'wp-admin/includes/image.php'); $tmp = download_url($image_url); if (is_wp_error($tmp) || !$tmp) { return false; } $file_array = [ 'name' => sanitize_title($title) . '.jpg', 'tmp_name' => $tmp ]; $image_id = media_handle_sideload($file_array, 0); @unlink($tmp); return (!is_wp_error($image_id)) ? $image_id : false; } // Ensure current Featured Image is not fallback $current_image_id = get_post_thumbnail_id($clinic_id); $current_image_url = $current_image_id ? wp_get_attachment_url($current_image_id) : ''; $fallback_url = 'https://painclinics.com/wp-content/uploads/2022/08/painclinics-fallback.jpg'; if (empty($current_image_id) || $current_image_url === $fallback_url) { if (!empty($data['photos'][0]['photo_reference'])) { $photo_reference = $data['photos'][0]['photo_reference']; $photo_url = "https://maps.googleapis.com/maps/api/place/photo?maxwidth=1200&photoreference=$photo_reference&key=$api_key"; $image_id = upload_external_image($photo_url, $clinic_name); if ($image_id) { set_post_thumbnail($clinic_id, $image_id); error_log("✅ Fallback Image Replaced for: $clinic_name"); } } } Kyle - ⚕️Local Pain Clinics - Page 3 of 10

Welcome To Pain Clinics.
Find Top Rated Pain Management Nearby.

Press The Button Below And Allow Access To Your Current Location
(Results will load in the map below!)

Kyle Featured Pain Clinics

FIND NEARBY CLINICS

Lake Camp Lake Harvey

828 Route 636,Harvey New Brunswick E6K3G4

2.brooklynabortionclinic

Center for Vascular Medicine

7474 Greenway Center Dr., Greenbelt, Maryland, 20771

Image of a pain clinic nurse consulting a patient

Advanced Sports & Spine

Advanced Sports & Spine

advanced-sport-and-spine.jpg

Dunes Pain Specialists

101 Tower Rd #103, Dakota Dunes, SD 57049

AF1QipPEI8n3x-zi5gatr-70UYuwm56J5KdMrYGnduKI=w408-h408-k-no

Dr. Sunny R. Kim, MD

6005 Rockwell Dr NE, Cedar Rapids, IA 52402

Image of a pain clinic nurse consulting a patient

The Iowa Clinic Spine Center - West Des Moines Campus

5950 University Ave, West Des Moines, IA 50266

Image of a pain clinic nurse consulting a patient

Medical Center Anesthesiologists, P.C.

411 Laurel St, Des Moines, IA 50314

Image of a pain clinic nurse consulting a patient

Steindler Orthopedic Clinic

2751 Northgate Dr, Iowa City, IA 52245

AF1QipMiMjVAnz8pWvSdQ7H5j1SC_MfA1KP-hu3ZycAY=w408-h259-k-no

Audra Ramsey, DO

1761 Hickman Rd, Des Moines, IA 50314

AF1QipPODCGNlIfYDAUXlCX1FQSpsIdB9z9SgaVEJadv=w408-h273-k-no

International Spine & Pain

618 Broad St APT B, Story City, IA 50248

Image of a pain clinic nurse consulting a patient

Morgan Brown, ARNP

1761 Hickman Rd, Des Moines, IA 50314

AF1QipOCm6n_Bz6ig9ctDJVZHZYRRDz9GuBYHNwJz0U=w408-h273-k-no

Jennifer Trevillyan, ARNP

1111 6th Avenue, West Building, Level 3, Des Moines, IA 50315

AF1QipMJQMuaCIOuiEp38SxX2h_J_IjDtodopSDsJa6y=w408-h582-k-no