// 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
Skip to main content
Skip to footer
Peace and Harmony Pain Management Center
(Updated: February 5, 2024)
83 Main St
Ashland, MA USA
Recent Reviews for Peace and Harmony Pain Management Center