Refactor MLS sync to Active/Pending only with on-demand media

Major changes to sync strategy following MLS Grid best practices:

- Initial sync now fetches only Active/Pending properties (~30K vs 1.3M)
- Replication (incremental) fetches all changes, deletes non-Active/Pending
- On-demand media fetching replaces background queue (avoids rate limits)
- Media downloaded and cached when first viewed, not during sync
- Updated CLI commands: wp mls media status/fetch/clear
- Comprehensive documentation with troubleshooting guide

This fixes the "Value out of range" API error caused by high $skip values.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Hanson.xyz Dev
2025-12-15 08:25:37 -06:00
parent 6eadf3d266
commit b9cddd2f64
6 changed files with 538 additions and 874 deletions
@@ -271,17 +271,21 @@ function mls_get_property_media($listing_key) {
}
/**
* Get primary image URL for a listing
* Get primary image URL for a listing (on-demand fetching)
*
* Images are fetched from MLS Grid and cached locally on first request.
* Per MLS Grid rules, images must be served from our own server.
*
* @param string $listing_key The listing key
* @param bool $fetch_if_missing Whether to fetch from MLS Grid if not cached (default: true)
* @return string|null Image URL or null
*/
function mls_get_property_image($listing_key) {
function mls_get_property_image($listing_key, $fetch_if_missing = true) {
$plugin = mls_plugin();
if (!$plugin->get_query()) {
if (!$plugin->get_media_handler()) {
return null;
}
return $plugin->get_query()->get_primary_image($listing_key);
return $plugin->get_media_handler()->get_primary_image($listing_key, $fetch_if_missing);
}
/**
@@ -324,3 +328,34 @@ function mls_get_property_count($args = array()) {
}
return $plugin->get_query()->get_count($args);
}
/**
* Get all images for a listing (on-demand fetching)
*
* Returns all media records with local_url populated where cached.
* Can optionally fetch first N uncached images on-demand.
*
* @param string $listing_key The listing key
* @param int $fetch_limit Max images to fetch on-demand (default: 1, 0 = none)
* @return array Array of media objects
*/
function mls_get_property_images($listing_key, $fetch_limit = 1) {
$plugin = mls_plugin();
if (!$plugin->get_media_handler()) {
return array();
}
return $plugin->get_media_handler()->get_listing_images($listing_key, $fetch_limit);
}
/**
* Get media cache statistics
*
* @return array Stats with total_media, cached, uncached counts
*/
function mls_get_cache_stats() {
$plugin = mls_plugin();
if (!$plugin->get_media_handler()) {
return array('total_media' => 0, 'cached' => 0, 'uncached' => 0);
}
return $plugin->get_media_handler()->get_cache_stats();
}