Add on-demand media URL refresh for expired MLS Grid tokens
MLS Grid media URLs expire after ~24 hours. Instead of running scheduled syncs, this adds on-demand refresh when images are requested: - Add is_url_expired() to parse expires timestamp from media URLs - Add refresh_media_urls() to fetch fresh URLs from API for one listing - Add get_property_media() API method using ListingId filter - Image endpoint checks URL expiration before fetching - If expired, refreshes URLs from API then proceeds with fetch This is more efficient than scheduled full syncs because: - Only refreshes URLs for listings actually being viewed - Zero overhead for unviewed listings - Scales naturally with traffic 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -494,6 +494,87 @@ class MLS_Media_Handler {
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a media URL has expired
|
||||
*
|
||||
* MLS Grid media URLs contain an 'expires' parameter with Unix timestamp.
|
||||
* Returns true if the URL is expired or will expire within the buffer time.
|
||||
*
|
||||
* @param string $media_url The media URL to check
|
||||
* @param int $buffer_seconds Buffer time before actual expiration (default: 300 = 5 min)
|
||||
* @return bool True if expired or expiring soon
|
||||
*/
|
||||
public function is_url_expired($media_url, $buffer_seconds = 300) {
|
||||
if (empty($media_url)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Extract expires parameter from URL
|
||||
if (preg_match('/expires=(\d+)/', $media_url, $matches)) {
|
||||
$expires = (int) $matches[1];
|
||||
return (time() + $buffer_seconds) >= $expires;
|
||||
}
|
||||
|
||||
// If no expires param found, assume expired to be safe
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh media URLs for a listing from the API
|
||||
*
|
||||
* Fetches fresh media data from MLS Grid and updates the database.
|
||||
* This is used when cached URLs have expired.
|
||||
*
|
||||
* Note: MLS Grid API only allows filtering by ListingId, not ListingKey.
|
||||
* This method looks up the listing_id from the local database first.
|
||||
*
|
||||
* @param string $listing_key Listing key
|
||||
* @return bool True on success, false on failure
|
||||
*/
|
||||
public function refresh_media_urls($listing_key) {
|
||||
global $wpdb;
|
||||
|
||||
$plugin = mls_plugin();
|
||||
$api_client = $plugin->get_api_client();
|
||||
|
||||
// Look up listing_id from database (MLS Grid API requires ListingId for filtering)
|
||||
$listing_id = $wpdb->get_var($wpdb->prepare(
|
||||
"SELECT listing_id FROM {$this->db->properties_table()} WHERE listing_key = %s",
|
||||
$listing_key
|
||||
));
|
||||
|
||||
if (!$listing_id) {
|
||||
$this->logger->warning('Cannot refresh media: listing_id not found', array(
|
||||
'listing_key' => $listing_key,
|
||||
));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Fetch property with media from API using ListingId
|
||||
$property = $api_client->get_property_media($listing_id);
|
||||
|
||||
if (is_wp_error($property) || !$property) {
|
||||
$this->logger->warning('Failed to refresh media URLs', array(
|
||||
'listing_key' => $listing_key,
|
||||
'listing_id' => $listing_id,
|
||||
'error' => is_wp_error($property) ? $property->get_error_message() : 'Property not found',
|
||||
));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Update media records with fresh URLs
|
||||
if (isset($property['Media']) && is_array($property['Media'])) {
|
||||
$this->sync_property_media($listing_key, $property['Media']);
|
||||
$this->logger->debug('Refreshed media URLs', array(
|
||||
'listing_key' => $listing_key,
|
||||
'media_count' => count($property['Media']),
|
||||
));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up orphaned media files (files without database records)
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user