Integrate MLS listings with property map and add smart sync
Property Map: - Replace ACF-based property display with MLS database queries - Use real lat/lng coordinates from MLS (100% coverage) - Create property-card-mls.php template for MLS property cards - Update AJAX handler to filter MLS properties MLS Plugin Enhancements: - Add 'wp mls run' smart sync command (auto-detects full/incremental/resume) - Add database index migrations for lat/lng and composite search indexes - Add comprehensive README.md documentation Documentation: - Update site README.md with sysadmin quick reference - Add FEATURES_PENDING_12_15.md tracking client feature requests 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -34,6 +34,7 @@ class MLS_CLI {
|
||||
WP_CLI::add_command('mls test', array($instance, 'test'));
|
||||
WP_CLI::add_command('mls status', array($instance, 'status'));
|
||||
WP_CLI::add_command('mls sync', array($instance, 'sync'));
|
||||
WP_CLI::add_command('mls run', array($instance, 'run'));
|
||||
WP_CLI::add_command('mls stats', array($instance, 'stats'));
|
||||
WP_CLI::add_command('mls cache', array($instance, 'cache'));
|
||||
WP_CLI::add_command('mls recovery', array($instance, 'recovery'));
|
||||
@@ -369,6 +370,149 @@ class MLS_CLI {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run smart sync - autonomous self-healing sync.
|
||||
*
|
||||
* This is the recommended command for automated/cron usage. It automatically
|
||||
* determines the best action based on current state:
|
||||
*
|
||||
* - If a sync is running: abort (prevents duplicate syncs)
|
||||
* - If a previous sync failed/interrupted: resume it
|
||||
* - If no data exists: run full sync
|
||||
* - Otherwise: run incremental sync
|
||||
*
|
||||
* Failed syncs are automatically recoverable on the next run.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* [--quiet]
|
||||
* : Suppress progress output (still shows status messages)
|
||||
*
|
||||
* [--verbose]
|
||||
* : Show detailed output including API requests
|
||||
*
|
||||
* [--silent]
|
||||
* : Suppress all output except errors (for cron)
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp mls run # Smart sync with progress
|
||||
* wp mls run --quiet # Smart sync, status only
|
||||
* wp mls run --verbose # Smart sync with full details
|
||||
* wp mls run --silent # For cron jobs
|
||||
*
|
||||
* @subcommand run
|
||||
*/
|
||||
public function run($args, $assoc_args) {
|
||||
$quiet = isset($assoc_args['quiet']);
|
||||
$verbose = isset($assoc_args['verbose']);
|
||||
$silent = isset($assoc_args['silent']);
|
||||
|
||||
$sync_engine = $this->plugin->get_sync_engine();
|
||||
|
||||
// Status callback for high-level messages
|
||||
$status_callback = null;
|
||||
if (!$silent) {
|
||||
$status_callback = function($message, $level = 'info') {
|
||||
$timestamp = date('H:i:s');
|
||||
switch ($level) {
|
||||
case 'warning':
|
||||
WP_CLI::warning("[{$timestamp}] {$message}");
|
||||
break;
|
||||
case 'error':
|
||||
WP_CLI::warning("[{$timestamp}] {$message}");
|
||||
break;
|
||||
default:
|
||||
WP_CLI::line("[{$timestamp}] {$message}");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Progress callback for record-level progress
|
||||
$progress_callback = null;
|
||||
if (!$quiet && !$silent) {
|
||||
$progress_callback = function($event, $data = array()) use ($verbose) {
|
||||
if ($verbose) {
|
||||
$this->output_verbose_event($event, $data);
|
||||
} else {
|
||||
switch ($event) {
|
||||
case 'property_created':
|
||||
echo '.';
|
||||
break;
|
||||
case 'property_updated':
|
||||
echo '#';
|
||||
break;
|
||||
case 'property_deleted':
|
||||
echo 'x';
|
||||
break;
|
||||
case 'property_error':
|
||||
echo '!';
|
||||
break;
|
||||
case 'page_complete':
|
||||
echo '|';
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (!$silent) {
|
||||
WP_CLI::line('');
|
||||
WP_CLI::line('=== MLS Smart Sync ===');
|
||||
WP_CLI::line('');
|
||||
}
|
||||
|
||||
// Run smart sync
|
||||
$result = $sync_engine->smart_sync($progress_callback, $status_callback);
|
||||
|
||||
// Handle aborted case (sync already running)
|
||||
if (isset($result['action']) && $result['action'] === 'aborted') {
|
||||
if (!$silent) {
|
||||
WP_CLI::warning('Sync aborted: ' . ($result['reason'] ?? 'Unknown reason'));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Output newline after progress dots
|
||||
if (!$quiet && !$silent && !$verbose) {
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
// Output results
|
||||
if (!$silent) {
|
||||
$action_labels = array(
|
||||
'full' => 'Full sync',
|
||||
'incremental' => 'Incremental sync',
|
||||
'resumed' => 'Resumed sync',
|
||||
);
|
||||
$action_label = $action_labels[$result['action']] ?? 'Sync';
|
||||
|
||||
if ($result['success']) {
|
||||
WP_CLI::success("{$action_label} completed successfully!");
|
||||
} else {
|
||||
WP_CLI::warning("{$action_label} failed: " . ($result['error'] ?? 'Unknown error'));
|
||||
WP_CLI::line('The sync can be resumed on the next run.');
|
||||
}
|
||||
|
||||
if (isset($result['stats'])) {
|
||||
$stats = $result['stats'];
|
||||
WP_CLI::line(sprintf(
|
||||
'Processed: %d | Created: %d | Updated: %d | Deleted: %d | Errors: %d',
|
||||
$stats['processed'],
|
||||
$stats['created'],
|
||||
$stats['updated'],
|
||||
$stats['deleted'],
|
||||
$stats['errors']
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
// Exit with error code if failed (for cron monitoring)
|
||||
if (!$result['success']) {
|
||||
WP_CLI::halt(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print progress legend
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user