Scheduled and on-demand content backups for WordPress — a WXR export of your posts & pages plus a manifest of your uploads directory, with retention pruning, a clean admin UI, and multisite-safe per-blog backups.
inklura-backups is a small, dependency-free WordPress plugin (usable as a normal
plugin or a must-use plugin) that produces portable content backups you can store,
download, and re-import. Each backup is a directory containing:
content.xml— a WXR (WordPress eXtended RSS) export of your posts and pages, built via WordPress core's ownexport_wp()(with a self-contained fallback). It imports straight back through Tools → Import → WordPress.media-manifest.json— an inventory of your uploads directory: every file's relative path, size, and modification time (plus totals + any excluded count).archive.zip— a single, downloadable package ofcontent.xml+ the JSON metadata, and (optionally) the actual upload files. Built withZipArchive; skipped gracefully if that extension is unavailable.meta.json— a summary: item counts, sizes, site URL, blog id, what was included, andsha256checksums of the durable files for integrity checking.
Backups land in a protected folder (wp-content/uploads/inklura-backups/<Y-m-d-His>/),
guarded by an index.html and a best-effort .htaccess deny.
| Feature | What it does |
|---|---|
| Content export | WXR export of posts & pages (via core export_wp() or a built-in fallback) + a JSON manifest of the uploads dir + a meta.json summary. |
Single .zip |
Each backup is packaged into one archive.zip (content + metadata, and optionally upload files), with a per-file size cap, a total-size cap, and graceful fallback if ZipArchive is unavailable. |
| Integrity | sha256 checksums of the durable files are recorded in meta.json; the admin list shows Verified / Modified / Missing per backup. |
| Exclude patterns | A glob list (e.g. cache/*, *.log) skips matching uploads in both the manifest and the .zip. |
| Email notifications (opt-in) | Email on backup completion (success and failure), configurable recipient; sent via the bext mail path when available, falling back to wp_mail(). |
| Restore | Re-import a backup's WXR into the live site behind a typed confirmation + capability + nonce. Media is not restored (content-only). |
| Backup now | One-click on-demand backup from the admin page (nonce + capability checked). |
| Scheduled backups | A wp-cron event runs the export daily / weekly / off. |
| Retention | Keep the last N backups; older ones are pruned automatically after each run. |
| Admin UI | Tools → Inklura Backups: list backups (date, size, archive size, integrity, item counts) with Download .zip / XML / Manifest, Restore, and Delete actions, plus the "Backup now" button and a settings section. |
| Multisite | Per-blog backups (separate dir + cron per blog), multisite-safe, with an optional network defaults page. |
| Queue offload (opt-in) | Heavy scheduled exports can be offloaded to the bext queue over loopback; a direct wp-cron run remains the reliable baseline. |
| Auto-update | Self-hosted updates for normal-plugin installs — "update available" + one-click update from a manifest, like a wordpress.org plugin. |
Put the repository in wp-content/plugins/inklura-backups/ and activate Inklura Backups.
On activation it creates the protected backups directory and schedules the cron event.
Copy the package into wp-content/mu-plugins/inklura-backups/ and load
inklura-backups.php from an mu-loader. (Must-use installs update out of band; the
self-hosted updater is skipped automatically.)
Open Tools → Inklura Backups and set:
- Schedule — Off / Daily / Weekly.
- Keep last N backups — retention count (1–365).
- Include — Posts, Pages, Uploads manifest.
- Archive (.zip) — package each backup as a single
.zip; optionally include the actual upload files; set per-file and total uploads size caps (MB;0= unlimited). Disabled automatically ifZipArchiveisn't available. - Exclude from uploads — one glob pattern per line (matched against each
upload-relative path), applied to the manifest and the
.zip. - Email notifications — email on completion (success and failure) to a chosen recipient (blank = site admin email).
- Advanced — offload scheduled exports to the bext queue when reachable.
On multisite, network admins can set defaults for all of the above under Network Admin → Settings → Inklura Backups; each site may override them locally.
define( 'INKLURA_BACKUPS_ENABLE', false ); // master kill switch
define( 'INKLURA_BACKUPS_UPDATE_URL', 'https://…' ); // override the update manifest URL
define( 'INKLURA_BACKUPS_KEEP_FILES_ON_UNINSTALL', true ); // keep backups on deleteThere are two ways to restore:
- In-plugin Restore — the Restore action on a backup row re-imports that
backup's
content.xmlinto the live site. It requires a typed confirmation (RESTORE), theimport/manage_optionscapability, and a nonce. It uses the WordPress Importer plugin (install/activate "WordPress Importer" first) and runs content-only (fetch_attachments = false) — media files are not restored; this is a content recovery, not a full-site restore. A clear error is shown if the importer isn't installed. - Manual — a backup's
content.xmlis a standard WXR file: import it via Tools → Import → WordPress, or unziparchive.zip. Themedia-manifest.jsonlets you verify or reconcile uploaded files; if you enabled "include upload files" the.zipcarries them underuploads/.
Each backup's integrity (sha256 of its durable files) is shown in the admin list, so you can confirm an archive hasn't been tampered with before restoring.
for t in tests/unit/*.php; do php "$t"; done # WP-free unit tests
bash -n bin/build-zip.sh # syntax-check the build script
bin/build-zip.sh /tmp/inklura-backups.zip # build an installable ZIPCI lints on PHP 7.4/8.1/8.3 and runs the unit tests. See CONTRIBUTING.
Inklura Backups is built and maintained with the support of:
- webdesign29 — web agency (Brest, France).
- Inklura — WordPress-compatible CMS & hosting.
Interested in sponsoring? Use the Sponsor button or open an issue.
GPL-2.0-or-later — see LICENSE.