// 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"); } } } Peace and Harmony Pain Management Center - ⚕️Local Pain Clinics
Image of a pain clinic nurse consulting a patient

Peace and Harmony Pain Management Center

(Updated: February 5, 2024)
83 Main St
Ashland, MA USA

(617) 209-9762

Clinic Hours

Recent Reviews for Peace and Harmony Pain Management Center