Documentation · Technical Documentation
Import Engine
This document describes how the ADP Car Market Hub plugin imports vehicle listings from the AutoScout24 API into WordPress. It covers the responsibilities of the importer classes, the per-listing flow, change detection, full-sync deletion and the public hook that fires after a vehicle is imported.
When to use this document
Read this document if you need to:
- Understand what happens during an import run.
- Diagnose why a vehicle was inserted, updated, skipped or removed.
- Build a custom integration that reacts to imports via the
as24ci_vehicle_importedaction. - Plan capacity or hosting requirements for large catalogues.
For scheduling and cron details, see Cron Events And Scheduler. For image handling, see Image Importer And Queue.
Overview
The import engine consists of several classes that work together:
AS24CI\Client— issues authenticated HTTP requests to the AutoScout24 API, manages OAuth tokens (including theas24ci_access_tokentransient cache) and exposes helpers for preview pages and per-listing equipment.AS24CI\Importer— coordinates per-listing import. Decides whether to insert, update or skip and writes the vehicle's post, postmeta and image references. Owns change detection.AS24CI\Mapper— maps the raw AutoScout24 payload to the fields stored in theas24_vehiclestable viaAS24CI\Vehicle_Repository. Maintains backwards-compatible postmeta keys.AS24CI\Vehicle_Repository— persists vehicle field data in the dedicated{$wpdb->prefix}as24_vehiclestable.AS24CI\Image_Importer— downloads images, optionally converts them to WebP, and attaches them to the vehicle post. See Image Importer And Queue.AS24CI\Scheduler— wrapsImporter::import_all_for_seller()in a locking, retry-safe runner used by WP-Cron, the REST cron endpoint and the manual "Run now" button.
The same Importer instance is reused by the manual Batch-Wizard,
the cron runner and the REST cron endpoint.
Requirements or prerequisites
Before running an import you need:
- Valid AutoScout24 API credentials configured in the plugin
(
as24ci_base_url,as24ci_token_url,as24ci_client_id,as24ci_client_secret,as24ci_token_audience). - One or more seller IDs in
as24ci_seller_ids(comma-separated). - A WordPress user designated as the default post author
(
as24ci_default_post_author); imports fall back to the current user when no default is set. - Working outbound HTTPS access from the WordPress server to the AutoScout24 API and to the image hosts referenced in the API response.
- Sufficient PHP execution time. The scheduler raises the time limit
to
300seconds viaset_time_limit(300)for cron and REST runs; some hosts may override this.
Per-listing flow
AS24CI\Importer::upsert_post_from_listing() is the central
per-listing routine. The simplified flow is:
- Validate the listing has an
id. Skip otherwise. - Skip listings whose API status is not
activatedor whoseliveflag is empty. - Look up an existing vehicle post by listing ID
(
find_post_id_by_listing_id()). - Run change detection (see below). If nothing has changed, write
_as24ci_last_syncand returnskipped. - Build the post title, excerpt and content. If the AI Lock
(
_as24ci_ai_locked = 'yes') is active, do not overwrite the post excerpt or content. - Insert or update the WordPress post with the configured default post status and author.
- Write backwards-compatibility postmeta:
_as24ci_listing_id,_as24ci_seller_id,_as24ci_last_modified(when the API supplies it) and_as24ci_last_sync. - Ensure the slug ends with the listing ID
(
ensure_slug_has_listing_id()). - Map the listing payload via
AS24CI\Mapper::map_listing_to_post()so the typed fields are written to theas24_vehiclestable. - Fetch equipment via
Client::get_listing_equipment()and map it to the post viaMapper::map_equipment_to_post(). Errors are logged but do not fail the listing. - Import images (subject to the
as24ci_import_imagestoggle andas24ci_max_imagescap). The image flow is described in detail in Image Importer And Queue. - Update
_as24ci_content_hashand_as24ci_original_description. - Fire the
as24ci_vehicle_importedaction with the post ID, the raw API listing and a boolean$is_update. - Return one of the strings
inserted,updated,skippedorerror(onwp_insert_post/wp_update_postfailure).
Change detection
The importer skips listings that have not changed since the previous run, using two cascading checks:
- Primary: the
lastModifiedDatefield returned by the API. If the local_as24ci_last_modifiedpostmeta matches the remote value, the listing is treated as unchanged. The importer still refreshes_as24ci_last_syncso that full-sync logic knows the listing exists remotely. - Fallback: when
lastModifiedDateis missing, the importer computes an MD5 of the JSON-encoded payload and compares it against the stored_as24ci_content_hash.
Image change detection runs independently and is described in the image importer documentation.
AI Lock
When _as24ci_ai_locked is 'yes', the importer keeps the existing
post_content and post_excerpt so AI-generated copy survives a
re-import. All other fields, taxonomy assignments, equipment and
images are still updated. The original API description is also
preserved separately in _as24ci_original_description.
Slug stability
ensure_slug_has_listing_id() updates the post slug to end with
-<listing_id> whenever the slug changes. This keeps URLs stable
across re-imports and avoids accidental redirects when titles change.
Bulk operations
AS24CI\Importer exposes the following high-level methods:
get_seller_ids()— returns the cleaned list of configured seller IDs.get_all_preview_listings_for_seller( $seller_id, $max_pages = 20, $page_size = 50 )— pages through the API and returns the full set of activated, live listings for a single seller.preview_listings_for_seller( $seller_id, $page = 1, $per_page = 50 )— paginated preview used by the wizard's UI.import_selected_listings( $seller_id, $listing_ids, $max_vehicles = 0 )— imports the given listing IDs. Honours the$max_vehiclesbudget; skipped vehicles do not consume budget.import_all_for_seller( $seller_id, $max_vehicles = 0 )— fetches the full preview list for a seller and delegates toimport_selected_listings(). Returns counts pluslisting_ids(the full set seen this run) andapi_active(number of active listings the API returned).full_sync_after_import( array $remote_listing_ids )— deletes localas24ci_carposts whose_as24ci_listing_idis not in the given remote set. Skipped if the remote set is empty as a safety guard against accidental wipe.hard_delete_listing( $listing_id )— manual destructive delete for a single listing; goes through the sameVehicle_Deletercleanup as native WordPress delete.
The "All-in-One" version of the plugin imposes no listing cap;
get_free_import_limit() and get_free_slots_left() return
PHP_INT_MAX.
Vehicle deletion
Every permanent delete path flows through AS24CI\Vehicle_Deleter:
- WordPress native "Delete permanently" on the Cars list.
- Importer full sync (
full_sync_after_import()). - Bulk actions (
AS24CI\Bulk_Actions). - Manual
Importer::hard_delete_listing().
The deleter runs on before_delete_post / deleted_post and:
- Removes attachments tracked in
_as24ci_image_ids. - Removes the corresponding row in
{$wpdb->prefix}as24_vehicles. - Fires the
as24ci_vehicle_deletedaction.
Manual gallery attachments (_as24ci_manual_image_ids) and other
attachments not tracked by the importer are intentionally preserved.
Public hooks
The import engine fires the following hooks. Verify hook signatures in the current plugin version before relying on them.
| Hook | When it fires |
|---|---|
as24ci_vehicle_imported | After upsert_post_from_listing() finishes. Args: $post_id, $listing, $is_update. |
as24ci_vehicle_deleted | After a vehicle and its tracked attachments are removed via Vehicle_Deleter. |
The plugin also reads the as24ci_webp_quality filter when
converting images; see the image importer documentation.
Configuration reference
| Option | Effect | Default |
|---|---|---|
as24ci_seller_ids | Comma-separated seller IDs to import. | (none) |
as24ci_default_post_status | Post status for newly inserted vehicles. | draft |
as24ci_default_post_author | Default author user ID for inserted vehicles. | (none → current user) |
as24ci_import_images | Whether to import images. | (toggle in admin) |
as24ci_max_images | Max images per vehicle. 0 = no plugin-side cap. | 30 |
as24ci_full_sync | Delete local vehicles missing from the API after each import. | 0 |
as24ci_cron_image_queue | Use the image queue during cron/REST runs. | 1 |
as24ci_cron_max_vehicles | Vehicle cap per cron/REST run. 0 = unlimited. | (Scheduler default 50) |
as24ci_verbose_logging | Log a line per vehicle and image action. | 1 |
as24ci_mapping_overrides | Per-field label and visibility overrides used by the admin UI. | (empty) |
Operational notes
- The importer never throws on a single bad listing. Errors from
wp_insert_post,wp_update_post,Client::get_listing_equipmentand the image importer are logged viaAS24CI\Loggerand counted but do not abort the run. - Change detection means a full re-import of an unchanged catalogue is inexpensive: most listings are skipped and image downloads are not re-issued.
- The mapper writes to the
as24_vehiclestable via the repository, not towp_postmeta, except for the small backwards-compat key set documented in Data Model. - Full-sync is opt-in. If
as24ci_full_syncis enabled, ensure the configured seller IDs cover the entire catalogue you want to keep online; vehicles whose listings disappear from the API are permanently deleted. - Verbose logging produces detailed log lines and grows quickly on large catalogues. The plugin enforces a 10 MB log cap with rotation; adjust verbose logging to balance diagnostics with storage.
Troubleshooting
- No vehicles imported. Confirm the API credentials, that
as24ci_seller_idsis non-empty, and that the API returns listings withstatus = activatedandlive = true. Check the plugin log for HTTP errors fromAS24CI\Client. - Listings remain in
draftstatus. The plugin defaultsas24ci_default_post_statustodraftso administrators can review mappings. Change the option topublishonce you are satisfied, or publish individual vehicles from the admin list. - Repeated re-imports keep updating the same vehicles. Verify
that the API supplies a stable
lastModifiedDate. When it is missing, the fallback content hash detects changes; the hash will change whenever the API payload changes for any reason. - A vehicle disappeared after a cron run. Check whether
as24ci_full_syncis enabled. With full sync on, any listing missing from the API is permanently deleted (its imported attachments included). Importer ran but no images were downloaded.Checkas24ci_import_imagesandas24ci_max_images. In cron/REST runs withas24ci_cron_image_queue = 1, only the first image is downloaded immediately and the rest are deferred to the image queue worker.Skipping listing_id=… : lastModifiedDate unchanged.This is the expected verbose log line for unchanged listings; it confirms change detection is working.