Reference Omeka Classic plugin

Snapshot Storage

The history is in one table, resource_versions (with the installation's table prefix, such as omeka_resource_versions). It has no foreign keys into Omeka's tables, so the history outlives the record, its owner and everything its snapshot refers to.

Columns

Column Type Meaning
id INT UNSIGNED The version's id, used in the admin's addresses
record_type VARCHAR(20) item, collection or file
record_id INT UNSIGNED The record's number
version_num INT UNSIGNED Counted per record, from 1
operation VARCHAR(20) create, update, delete, restore or baseline
snapshot MEDIUMTEXT The JSON snapshot (see Snapshot Format)
snapshot_hash CHAR(64) The SHA-256 used to skip saves that change nothing
record_title VARCHAR(255) The record's title then: its first Dublin Core title, or a file's original filename
user_id, user_name INT, VARCHAR(255) Who made the change, or NULL (no one signed in, and baselines)
is_batch TINYINT(1) 1 for a save made by batch edit or a background job
batch_key VARCHAR(32) A key shared by every save of one request or background job
restored_from INT UNSIGNED For a restore, the version it came from
created_at DATETIME When, in UTC

Indexes cover (record_type, record_id, version_num), (user_id, created_at), created_at, (batch_key, is_batch) and restored_from. A snapshot can be up to 16 MB; snapshots are not compressed.

A second table, resource_version_runs, records the batch rollbacks and prunes run in the background: their criteria, status (queued, running, done, error), result, the batch key of the versions they wrote, who started them, and when.

Operations

Operation Written when
create A record is saved for the first time
update A record is saved and its snapshot differs from its newest version
delete A record is deleted; always written
restore The plugin restores a version, recreates a deleted record, or a rollback does
baseline Just before the first recorded save of a record that has no history yet, with its state before that save

Capture

The plugin listens to Omeka's record hooks for items, collections and files: before_save_* and after_save_*, before_delete_* and after_delete_*. These run for every save, whatever made it: the admin forms, batch edit, the REST API, importers, background jobs, scripts.

  • after_save_* builds one snapshot from the database (four queries for an item, two for a collection or file), compares its hash with the newest version's, read in before_save_*, and inserts one row when it differs.
  • before_save_*, for a record with no history, first keeps its state as a baseline.
  • before_delete_* reads the record's last state while it exists; after_delete_* writes it.
  • Saves of a record made while it is being created (such as the derivative job Omeka runs on a new file) are left to the creation, which records the final state once.
  • Saves made in Omeka's batch edit request (items/batch-edit-save) or in a background job or command-line script are marked as bulk, under the key of that request or process.

An exception in any of this is written to the PHP error log, and to Omeka's log, with the prefix [ResourceVersioning], and dropped: a failure to record never makes a save fail. A batch edit of 50 items takes about 3 ms more per item.

Changes made straight in the database, without saving the record through Omeka, are not recorded. Among Omeka's own:

  • Adding files to an existing item from code (insert_files_for_item()) saves the files, not the item: the files get their create versions at once, and the item's file list is updated at its next save. Adding files from the item form saves the item.
  • Deleting a collection takes its items out of it with a direct update: the items' histories show the change at their next save.
  • Renaming or deleting a tag on the Tags page changes items without saving them.

Admin addresses

All are under /admin/resource-versioning, handled by ResourceVersioning_IndexController.

Address Method Page
/admin/resource-versioning GET Every version; filters record_type, user_id, operation, date_from, date_to (YYYY-MM-DD), page
/admin/resource-versioning/operations GET Bulk operations and rollbacks
/admin/resource-versioning/rollback GET, POST The batch rollback wizard; POST step=preview or step=execute
/admin/resource-versioning/retention GET Retention and prunes
/admin/resource-versioning/prune POST Start a prune
/admin/resource-versioning/record/<type>/<id> GET A record's history (item, collection or file)
/admin/resource-versioning/version/<id> GET A version and its snapshot
/admin/resource-versioning/compare/<a>[/<b>] GET Two versions; b defaults to the one before a, current is the record now
/admin/resource-versioning/restore/<id> GET, POST What a restore changes, then the restore (or recreation)
/admin/resource-versioning/batch/<key> GET The versions of one batch

POST requests need the CSRF token the pages include.

Log in for Support