WP Manifestindependent plugin directory
manifest / integrations / madgp-xml-sync

MADGP XML Sync

WordPress plugin syncing property listings from an XML feed into Easy Property Listings (EPL), with per-property change detection, geocoding cost optimization, and a chunked, resumable import pipeline.

by madgp.fr · github.com/tchakoumi/madgp-xml-sync

★ 0stars
0forks

Install

No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:

wp plugin install https://github.com/tchakoumi/madgp-xml-sync/archive/refs/heads/main.zip

WordPress plugin that syncs property listings from an XML feed (AC3-Distribution / Immo-Facile format) into Easy Property Listings (property and rental post types), replacing an older WP All-Import based pipeline.

Why this exists

The previous pipeline (theme-level cron scripts + WP All-Import) re-downloaded and re-processed the entire feed on every run, geocoded every property on every run regardless of whether its address had changed, and had no visibility into whether a scheduled run actually executed. This plugin was built to fix all three:

  • Per-property change detection — a property whose feed data is byte-identical to last run is skipped entirely; only new/changed/removed properties reach the WordPress import step.
  • Geocoding as a last resort, not a default — the feed already supplies coordinates for effectively every property. Google Geocoding is only called when the feed gives none and no still-valid cached result exists for that property (cache keyed by an address fingerprint, so a real address change is still detected).
  • A single, persistent run-history table in the admin UI, so a silently-failed cron trigger is visibly distinguishable from a normal no-op run.

Architecture

Two-part pipeline, run as separate WP-Cron-scheduled steps so neither one risks hitting a PHP execution-time limit:

  1. Fetch (Madgp_Sync_Fetcher) — downloads the raw feed, flattens/normalizes each property the same way the old theme script did, diffs against the last-seen hash per property, resolves coordinates (feed-first, geocode-fallback), and writes nf_sell.XML / nf_rent.XML containing only what changed.
  2. Import (Madgp_Sync_Runner) — chunked and resumable: reads the two files above, upserts changed properties into EPL via Madgp_Sync_Upserter, syncs images via Madgp_Sync_Images, and deletes listings no longer present in the feed. Chunking means a large first-run image backfill can't time out a single request — it picks up where it left off on the next WP-Cron tick.

Both steps are triggered by hitting one REST endpoint (/wp-json/madgp-sync/v1/run, token-authenticated) from an external cron service; WP-Cron's own opportunistic nature (it only fires on real pageviews) means a second external ping at wp-cron.php is recommended as a backstop on low-traffic sites.

Key files

File Responsibility
includes/class-madgp-sync-fetcher.php Step 1: download, normalize, diff, geocode-if-needed, split into sell/rent
includes/class-madgp-sync-runner.php Step 2: chunked upsert + delete-missing, resumable via stored state
includes/class-madgp-sync-parser.php Feed XML → normalized PHP array, field mapping mirrors the proven All-Import config
includes/class-madgp-sync-upserter.php Normalized array → EPL post + postmeta, dry-run capable
includes/class-madgp-sync-images.php Matches/downloads/reorders/deletes property images, sets featured image
includes/class-madgp-sync-image-cleanup.php One-off tool for duplicate images left over from the old pipeline
includes/class-madgp-sync-geocoder.php Google Geocoding API wrapper
includes/class-madgp-sync-run-history.php Persistent run log (status, duration, stats) shown in the admin UI
includes/class-madgp-sync-paths.php Standalone working-file location (see below)
includes/rest-endpoint.php Trigger endpoint + diagnostic routes (/dry-run, /review-batch, connectivity test)
includes/admin-page.php Two-tab admin UI: Suivi (operational) / Configuration (settings)

Requirements

  • WordPress with Easy Property Listings active (property / rental post types and their meta fields).
  • An external cron service (e.g. cron-job.org) to hit the trigger URL on a schedule — WP-Cron alone is not reliable on low-traffic sites.
  • A Google Geocoding API key, only needed as a fallback for properties the feed doesn't supply coordinates for.

Setup

  1. Activate the plugin.
  2. Go to Settings → MADGP XML Sync → Configuration:
    • Set the XML feed source URL (only needs changing if the feed provider's URL ever changes).
    • Set the Google Geocoding API key.
    • Choose whether newly-imported properties are created as Draft or Published.
    • Generate a trigger token, then copy the trigger URL into your external cron service.
  3. On an install migrated from an older version of this plugin, use "Migrer vers les fichiers autonomes" on the Configuration tab to copy any working files still sitting at the legacy theme-coupled location into the new standalone one.

Operational notes

  • Working files live in wp-content/uploads/madgp-xml-sync/, not inside any theme — deliberately, so a theme switch, theme update, or theme deletion can never affect this plugin's state. See class-madgp-sync-paths.php.
  • Single entry point, no bypass: only one way to start a run (the REST trigger) and only one way to recover a stuck one (the admin page's "Libérer le verrou bloqué"). This is intentional — running the fetch and import steps concurrently would corrupt the intermediate nf_sell.XML / nf_rent.XML files.
  • Self-healing: if a property is deleted directly in wp-admin (bypassing this plugin) but the feed still lists it, the next run detects and recreates it, even if the feed's data for that property hasn't changed.
  • The only plugin dependency is EPL. Two postmeta keys (property_building_carrez, property_level) are written specifically because the current site's theme template reads those exact keys for display — harmless on another theme, just inert.