v1.5.0 — Media de-duplication & settings tabs
Media de-duplication, a reorganised settings page, and the reliability/security work accumulated since 1.3.5.
Install: download churchtools-wp-sync-1.5.0.zip below and upload it under Plugins → Add New → Upload Plugin (or extract into wp-content/plugins/). Requires the Events Manager plugin and PHP 8.2+.
New in 1.5.0 — media de-duplication & admin UX
Duplicate images/flyers are no longer created
Older versions re-downloaded and re-uploaded the same ChurchTools image (and flyer) for every event and every repeating occurrence. WordPress renamed each collision to name-1.jpg, name-2.jpg, … (each with a full set of generated thumbnail sizes), so the media library filled up with near-identical copies.
- Imported attachments are now stamped (
_ctwpsync_ct_image_id/_ctwpsync_ct_flyer_id) and reused library-wide — the same CT image maps to a single shared attachment across every event that uses it, regardless of upload month. The mapping'swp_image_idis now persisted.
New "Tools" tab: clean up the duplicates you already have
- Image de-duplication — Scan for duplicates (a safe dry-run estimate) and Clean up duplicates. It finds even orphaned copies that no event still points at, confirms they are byte-identical before deleting, keeps one shared copy, and re-points every event's featured image to it.
- Flyers (optional) — the same for flyer PDFs (rewrites the flyer links in event descriptions to the shared file). Kept separate because it edits published event content — back up first.
- The clean-up runs in automatic, time-boxed batches ("Cleaning up… N deleted so far") so even a very large library completes without hitting server timeouts, and it's safe to re-run.
Settings page reorganised into tabs
The long single-column page is now five tabs — Connection · Sync Options · Status · Tools · Logs — with a persistent Save / Sync Now bar.
Observability
- De-duplication scans and clean-ups are written to the plugin log at INFO level.
- The de-duplication actions are hardened: output buffering (so a stray PHP notice can't corrupt the response), a raised memory limit, and a shutdown handler that logs any fatal (out-of-memory / execution-time kill) with peak memory so aborts are diagnosable.
Also included since 1.3.5
1.4.0 — reliability & observability (rate-limited / constrained hosts)
- Fixed: sync silently stopped on rate-limited ChurchTools servers. A single
429 Too many requestsaborted the whole sync every cycle (the ChurchTools API library has no retry logic). A Guzzle retry/backoff middleware now retries429/5xxup to 5× (honouringRetry-After, otherwise exponential 1/2/4/8/16 s), and each retry is logged. - Fixed: the "Sync Now" button did nothing. The one-time sync ran with no logged-in user and bailed out; it now restores the admin user like the hourly cron does.
- Robustness: explicit per-request HTTP timeouts, a 30 s image-download timeout, a refreshed execution-time budget per appointment, and a concurrency guard (heartbeat lease) that prevents overlapping syncs and self-heals after a hard kill.
- New: dashboard warnings when syncs keep failing or when a sync is aborted mid-run; a configurable log level (Errors / Info / Debug) and an in-admin log viewer (refresh / download / clear); sync-status times shown in the site timezone.
1.3.6 — metadata
composer.jsonPHP constraint corrected to^8.2(matching Requires PHP: 8.2); Tested up to WordPress 7.0.1.
1.3.5 — security (dependencies)
- Updated the Guzzle HTTP stack to clear 5 Dependabot advisories (
guzzlehttp/guzzle7.10.0→7.14.1,guzzlehttp/psr72.8.0→2.12.5,guzzlehttp/promises2.3.0→2.5.1). The release ZIP installs dependencies fromcomposer.lockat build time.
The full, detailed changelog is in CHANGELOG.md.