=== Connect for Mobilox === Contributors: naiches Tags: mobilox, hexon, vehicles, inventory, sync Requires at least: 7.0 Tested up to: 7.1 Requires PHP: 8.4 Stable tag: 1.1.4 License: GPLv2 or later License URI: https://www.gnu.org/licenses/gpl-2.0.html Sync your Mobilox/Hexon vehicle inventory to WordPress — real-time incremental sync and bulk XML import. == Description == Connect for Mobilox syncs your vehicle inventory from the Mobilox/Hexon dealer management system to your WordPress site. Vehicles are stored as a configurable post type with full data available to your theme. **Features:** * Real-time sync — vehicles are added, updated, and removed automatically via the DV incremental XML feed. * Configurable post type — sync to the built-in "Vehicle" post type or any existing custom post type in your theme. * Full data storage — every field Mobilox sends is stored in a custom table as JSON, accessible via template helpers. * Image management — diff-based: only new images are downloaded, unchanged images keep their attachment IDs, removed images are cleaned up. * Endpoint security — protect your sync endpoint with a secret token or HTTP Basic Auth. * Status dashboard — see synced vehicle count, errors, last sync time, and a full activity log. * Read-only meta box — view all vehicle data grouped by category on the post editor. **For theme developers:** Field names are the Dutch element names of the Mobilox DV `voertuig` schema, exactly as the feed sends them. $vehicle = mobilox_get_vehicle(); echo esc_html( $vehicle->merk . ' ' . $vehicle->model ); Or field by field, using dot notation for nested elements: echo esc_html( mobilox_get_field( 'bouwjaar' ) ); echo esc_html( mobilox_get_field( 'tellerstand' ) ); echo esc_html( mobilox_get_field( 'verkoopprijs_particulier.bedrag' ) ); Both helpers default to the current post in the loop, and accept a post ID as a second argument. To see exactly which fields your own feed delivers, open a synced vehicle in the editor and look at the **Mobilox Vehicle Data** meta box. == Installation == 1. Upload the plugin to `/wp-content/plugins/` or install via Plugins → Add New. 2. Activate the plugin. 3. Go to **Mobilox → Settings** and select a post type. 4. Copy the endpoint URL from the **Mobilox → Dashboard** page into your DV management tool. 5. Vehicles will sync automatically as Mobilox pushes updates. == Frequently Asked Questions == = Which post type should I choose? = If your theme already has a vehicle/occasion post type, select that. Otherwise, use the built-in "Mobilox Vehicle" type. You can change this at any time — existing vehicles will continue to work. = How do I access vehicle data in my theme? = Use `mobilox_get_vehicle( $post_id )` to get the full data object, or `mobilox_get_field( 'merk' )` for a single field. Field names match the Dutch Mobilox DV XML element names (e.g. `merk`, `model`, `bouwjaar`, `tellerstand`), and dot notation reaches nested elements (e.g. `verkoopprijs_particulier.bedrag`). The **Mobilox Vehicle Data** meta box on any synced vehicle lists every field your feed actually sends. = Vehicle updates stopped arriving after I updated the plugin = Before this release, a site that never had a token configured had an open sync endpoint. The update generates a token for you and closes the endpoint, which changes the endpoint URL. Copy the new URL from **Mobilox → Dashboard** into your DV configuration. The plugin shows a notice on its own pages until you confirm you have done so. = My security plugin blocks the REST API — does sync still work? = Yes. Mobilox pushes without a WordPress login, so plugins that reject all anonymous REST requests would normally block it. This plugin lets a request through that lock-down only when it is addressed to the sync route and carries valid credentials; everything else stays blocked. = Is the sync endpoint secure? = The endpoint requires authentication. Activation generates a secret token for you: copy it from Settings into Mobilox, or replace it with HTTP Basic Auth credentials. Requests without valid credentials are rejected. == Screenshots == 1. The Mobilox dashboard — vehicle count, sync status, endpoint URL, and activity log. 2. Settings — post type selector, endpoint security, and log retention. == Changelog == = 1.1.4 = * Fix: if creating the vehicle tables failed — no permission, a full disk, a table the database would not reconcile — the update recorded itself as finished anyway and never tried again. Every vehicle Mobilox pushed afterwards was written into nothing, with an empty dashboard and no error anywhere to explain it. The update is now only marked done once the tables are confirmed present, so the next page load tries again. * Security: the vehicle sync endpoint accepted any request when no auth token and no Basic Auth user were configured, which is the state every site starts in. The Generate button that was supposed to create a token had been silently broken since 1.1.1 — a field rename left it looking for an input that no longer existed, so it did nothing at all when clicked and produced no error. Anyone who had not typed a token by hand was left with an open endpoint and no working way to close it. The endpoint now refuses unauthenticated requests, the Generate button works again, and a new installation gets a token automatically. * New: if no credentials are set, the Mobilox dashboard and settings screens now say so plainly and explain that sync is being rejected until a token is entered, with a link to create one. Existing sites that were relying on the open endpoint need to generate a token and enter the same value in Mobilox. * Fix: the plugin had no upgrade routine at all. WordPress does not run the activation hook when a plugin updates, so sites that updated from an older version never got the vehicle and log tables created — every vehicle Mobilox pushed was stored as a brand-new duplicate post and the dashboard showed nothing at all. Tables, the auth token and scheduled maintenance are now brought up to date automatically, once, the first time the updated plugin loads. * Fix: that upgrade routine now actually runs on sites already on 1.1.3. It compared the plugin's version against the version it had last upgraded to, and on a site that installed 1.1.3 those were the same value, so it did nothing at all — no tables, no auth token, no notice — while the newly required authentication rejected every push from Mobilox. The dealer saw sync simply stop, with nothing on screen explaining why. * New: when an update turns authentication on for a site that had none, the Mobilox screens explain that the endpoint address has changed and that the new URL has to be copied into Mobilox. The notice stays until dismissed. * Fix: a vehicle whose post was deleted in WordPress could never sync again — every push from Mobilox failed with "Invalid post ID", forever. The plugin now notices the post is gone and recreates the vehicle. Deleting a vehicle post also cleans up its record and photos instead of leaving them behind. * Fix: two Mobilox pushes for the same vehicle arriving at the same time could leave a published duplicate that nothing could ever remove. Failed database writes are now detected, the half-created post is removed, and the push is reported as failed so Mobilox retries. * Fix: deleting the plugin no longer wipes the dealer's inventory. Vehicles, photos and settings are kept unless the new "Delete all vehicle data when the plugin is deleted" option under Settings is switched on. Previously an uninstall destroyed every vehicle and photo with no warning and no way to get them back. * Fix: the log retention setting did nothing — the activity log grew forever. Old entries are now pruned once a day to the configured number of days. * Fix: the documented theme helpers `mobilox_get_vehicle()` and `mobilox_get_field()` were not actually available to themes, so following the documentation caused a fatal error. They now exist as documented, and `mobilox_get_field()` can reach nested fields such as `verkoopprijs_particulier.bedrag`. The readme examples have been corrected to the real Dutch field names. * Fix: the Generate and Copy buttons did nothing on sites not served over HTTPS, which is exactly where an admin is most likely to be setting the plugin up. Both now work, and Copy falls back to selecting the URL if the browser refuses. * Fix: vehicle photos were deleted and downloaded again on every single sync when the feed put whitespace around an image address, and a sync interrupted halfway left orphaned photos that were downloaded again on the retry. Image addresses are now compared consistently and progress is saved after each photo. * Fix: the vehicle data meta box grouped fields by names from an older feed format, so every field landed under "Other" and the photo list was dumped as raw JSON. Fields are now grouped under meaningful headings, and the group names are translatable. * Fix: the built-in Vehicle post type could not be reached from any menu. It now appears under Mobilox when it is the configured type. * Fix: saving settings re-submitted the form on a browser refresh, and a post type that no longer exists (after a theme switch) could be saved, leaving the plugin creating posts nothing renders. Saving now redirects, and an unavailable post type is refused with an explanation. * Fix: activity log timestamps were recorded in the database server's timezone but displayed as if they were UTC, so "Last Sync" was wrong on hosts whose database does not run on UTC. * Fix: a vehicle title changed by Mobilox no longer rewrites the page address of an existing vehicle or overrides a slug set by hand. * Fix: oversized or malformed values from the feed (an over-long vehicle number, an out-of-range year or mileage, text that is not valid UTF-8) were written to the database silently truncated or not at all. They are now reported in the activity log instead. * Fix: the vehicle count on the dashboard counted every post of the configured type, which was wrong when vehicles share a post type with ordinary content. It now counts synced vehicles. For the same reason the vehicle data box no longer appears on posts that are not vehicles. * Performance: repeated `mobilox_get_field()` calls in a theme loop now reuse one decoded copy of the vehicle data per request instead of querying and decoding for every call. * Fix: the activity log on the dashboard only ever showed the newest 50 entries, with no way to reach anything older, even though the log is kept for as long as the retention setting says. The log is now paged, and the status filter is kept while paging. * Fix: a daily scheduled job left behind by an earlier build kept running with nothing listening to it. It is now removed automatically, and deleting the plugin clears it too. = 1.1.3 = * Fix: the consumer price was read from the wrong DV element (`verkoopprijs_particulier` → `prijs` → `bedrag`), but the DV schema places it directly at `verkoopprijs_particulier` → `bedrag`, so prices were stored as 0. The price is now read from the correct element, with a fallback for feeds that wrap it in a `` node. * New: the vehicle description (`opmerkingen`) is now saved to the post content, so themes that render `the_content()` show the full description. * Fix: an "Undefined array key" notice when a vehicle had no `` element. = 1.1.2 = * Fix: incremental sync did not import vehicles from the standard DV ("Doorlinken Voorraad") feed. The XML parser now reads the flat `voertuig.xsd` (2.21) element names — `voertuignr_hexon`, `merk`, `model`, `tellerstand`, `verkoopprijs_particulier`, `afbeeldingen`, `verkocht` — so make, model, price, mileage, fuel, build year, sold status, and photos are stored correctly. * Fix: the sync endpoint returned a JSON-quoted response (`"1"`), which the DV client rejected as "Answer unequal to '1'" — every push was reported as failed even when the vehicle was stored. The endpoint now returns a bare `1` / `0`. = 1.1.1 = * Fix: saving the Settings page could fail with "Cannot load mobilox-settings." — the Post Type field was named `post_type`, which shadows a reserved WordPress admin request variable used to resolve the current admin page, making the page-hook lookup fail on save. All settings fields are now plugin-prefixed so they can't collide with core request vars or other plugins. = 1.1.0 = * Complete rewrite — OOP architecture with namespaced classes. * Custom database table for vehicle data (no postmeta bloat). * Configurable post type — sync to any existing CPT or the built-in one. * XML-only sync (v2.23+ compatible) — dropped legacy POST field support. * Diff-based image handling — only downloads new/changed images. * Secured REST endpoint with token and HTTP Basic Auth. * Admin dashboard with stats, activity log, and endpoint URL. * Read-only meta box showing all vehicle data grouped by category. * Template helper functions for theme developers. * Full uninstall cleanup (tables, posts, attachments, options). = 1.0.0 = * Initial version.