2
Snapshot-Transfer
Jonathan Miller edited this page 2026-07-15 01:31:23 +00:00

Snapshot Transfer

Applies to MokoSuiteBackup 02.64.00. Introduced in 02.59.00 (#237).

A content snapshot captures selected Joomla content (articles, categories, modules, and their tags / custom-field values / featured flags) into a JSON payload you can restore later. Snapshot Transfer lets you move a snapshot between sites three ways:

  1. Download a snapshot as a portable .msbsnap file and Import it on another site.
  2. Inject a snapshot directly from a master site into a slave site over the Web Services API.

This is content-level transfer (not a full-site archive — see Backup Profiles for those).

The portable .msbsnap format

A .msbsnap is a ZIP produced by SnapshotPortable::package() containing:

Entry Contents
manifest.json Format id (msbsnap) + format_version (currently 1), generator, created timestamp, source (host, Joomla version, DB prefix), a snapshot summary (description, content types, article/category/module counts), and a payload.sha256 integrity hash.
snapshot.json The snapshot's content data verbatim — the same shape the snapshot engine writes: {version, content_types, tables}.

On import, ingestZip() validates the archive before doing anything:

  • The archive must contain both entries.
  • manifest.format must be msbsnap, and its format_version must not be newer than this site supports (a newer-version file is refused).
  • The payload is checked against manifest.payload.sha256 with a constant-time compare — a failed checksum aborts the import.
  • The payload must be structurally valid content data (tables and content_types arrays present).

If the source Joomla major version differs from this site's, the import still proceeds but attaches a non-blocking compatibility warning ("content tables may differ; review after restoring").

A successful import materialises a local snapshot record (writes the payload into the backup directory and inserts a #__mokosuitebackup_snapshots row with status complete). It does not restore anything by itself — you then restore that record from the Snapshots page like any other snapshot.

Download & Import (Snapshots page)

On the Snapshots page each snapshot row offers a Download action (streams a .msbsnap named like snapshot-<id>-<YYYYMMDD_HHMMSS>.msbsnap) and the page has an Import button that accepts an uploaded .msbsnap and runs it through ingestZip(). The imported snapshot appears as a new record you can restore.

The API also exposes GET …/snapshot/:id/download, which streams the raw snapshot.json payload (JSON, not the zipped .msbsnap).

Direct master → slave injection (API)

A master site can push a snapshot straight into a slave's Web Services API:

POST /api/index.php/v1/mokosuitebackup/snapshot/inject

Request body:

{
  "snapshot":      { "version": 1, "content_types": ["articles"], "tables": { "...": [] } },
  "mode":          "overwrite",
  "content_types": ["articles"],
  "description":   "Injected from master"
}
  • snapshot (required) — the payload inline ({version, content_types, tables}), the same shape as snapshot.json.
  • mode (optional) — conflict mode; if omitted, the receiving site's default (snapshot_inject_mode) is used.
  • content_types (optional) — filter to restore only some types.
  • description (optional) — defaults to Injected snapshot.

The endpoint:

  1. Requires the mokosuitebackup.snapshot.manage permission (403 otherwise).
  2. Requires the receiving site to opt in via snapshot_allow_inject — if injection is disabled it returns 403 "Snapshot injection is disabled on this site".
  3. Ingests the inline payload into a local record (SnapshotPortable::ingestData(); 422 if the payload is invalid), then restores it via SnapshotRestoreEngine in the chosen mode, returning the resulting snapshot_id and any compatibility warnings.

Conflict modes

Selectable per inject call, or defaulted in Options → Snapshot Transfer (snapshot_inject_mode):

Mode Behaviour
overwrite Replace matching items by ID — the master wins.
create Skip items whose ID already exists; add only new ones.
duplicate Insert everything as brand-new records with remapped IDs (articles, categories, modules — plus their tags, custom-field values and featured flags) via Joomla's Table API, so assets / UCM / nested-set data stays valid.

Transactional behaviour: overwrite, create (and the legacy replace/merge) run inside a DB transaction. duplicate is intentionally best-effort, not transactional — Joomla's Nested tables (categories, tags) issue LOCK TABLES, which implicitly commits any open InnoDB transaction, so wrapping duplicate mode would be a false atomicity promise. Instead each item is inserted defensively: a bad item is skipped and logged, never fatal.

Configuration (Options → Snapshot Transfer)

Option Param Default Meaning
Default injection mode snapshot_inject_mode overwrite Mode used when an inject call omits mode. Values: overwrite, create, duplicate.
Allow Snapshot Injection snapshot_allow_inject No (0) Must be Yes for this (slave) site to accept /snapshot/inject calls.

Snapshot retention (independent of transfer) is under Options → Snapshot Retention: snapshot_retention_count (default 20) and snapshot_retention_days (default 30); 0 = unlimited for that setting.

GET    /api/index.php/v1/mokosuitebackup/snapshots            List snapshots
POST   /api/index.php/v1/mokosuitebackup/snapshot             Create a snapshot
POST   /api/index.php/v1/mokosuitebackup/snapshot/:id/restore Restore a snapshot
POST   /api/index.php/v1/mokosuitebackup/snapshot/inject      Inject (master → slave)
DELETE /api/index.php/v1/mokosuitebackup/snapshot/:id         Delete a snapshot
GET    /api/index.php/v1/mokosuitebackup/snapshot/:id/download Download snapshot JSON

All snapshot endpoints require the mokosuitebackup.snapshot.manage permission.