Finishes the deferred 'duplicate' conflict mode. Inserts snapshot content
as brand-new records with remapped IDs, leaving existing content
untouched — for master->slave 'push as new copies'.
- Uses Joomla's Table API (bootComponent MVCFactory) for Article,
Category and Module so assets, UCM entries, category/tag nested-sets
and alias uniqueness are handled by core rather than hand-rolled.
- Remaps category parent_id (parents first), article catid, module menu
assignments, and custom-field-value item_id; re-features articles.
- Tags are reused/created by title (resolveTagIds) and assigned via the
article table's newTags so UCM/tag-map stay correct.
- uniqueAlias() avoids alias collisions per scope.
- DEFENSIVE: every item is wrapped in try/catch — a bad item is skipped
and logged, never fatal — so an untested/partial import degrades
gracefully instead of corrupting content.
NOTE: still needs a real test pass on a dev site before relying on it.
Refs #237
Claude-Session: https://claude.ai/code/session_01WbGBN9VyRK61zczYWcCQ2i
Adds the first increment of snapshot transfer:
- SnapshotPortable engine: package a snapshot into a portable .msbsnap
(zip of manifest.json + snapshot.json + sha256), and ingest one back
(from a zip upload or an inline payload) by materialising a local
snapshot record.
- Admin: per-row 'Download portable snapshot' + an Import modal
(upload .msbsnap) on the Snapshots page.
- API: POST /snapshot/inject — master pushes a snapshot payload into a
slave's Web Services API; gated by a new 'Allow Snapshot Injection'
option. Route added to the webservices plugin.
- Restore engine: new 'create' mode (skip existing, insert only new) and
mode-name normalisation (overwrite->replace, create, duplicate). The
'duplicate' (insert-as-new-with-remapped-IDs) mode returns a clear
'not yet available' — deferred to a dedicated, tested pass.
- Options: 'Snapshot Transfer' fieldset — default conflict mode +
allow-inject toggle. Language keys added (en-GB fallback).
Reuses the existing mokosuitebackup.snapshot.manage ACL. NOTE: untested
end-to-end (no dev build this session) — verify download/import/inject
on a dev build.
Refs #237
Claude-Session: https://claude.ai/code/session_01WbGBN9VyRK61zczYWcCQ2i