MishkaDocument.Resources.Changes.CloneVersion (Mishka Document v0.0.1)

Copy Markdown View Source

Writes a new version of a document as a copy of one of its versions: every page of the source with its notes and tags, in the source's tree, in one transaction with the new version itself.

The version to copy is the action's source_version_id argument, read with the action's actor: under the action's tenant, or on any site for a master's action with none (:master_get). The new version names the source as source_version_id, and a MishkaDocument.WorkspaceVersionLineage row records the copy. Nothing is copied when the argument is empty.

Options

  • :as — :clone (the default) writes the new version into the source's workspace and site, a draft, not the latest and not published, and refuses a source it cannot read. :create keeps what the action was given and refuses a source of another workspace, leaving a source of another site, or of none, to the action's own reference checks; an action given copy_pages: false copies nothing.

What is copied

  • Every page the source's readers reach (MishkaDocument.Section's :copy): its title, slug, content, order, the front page and group flags, its language, permissions, SEO tags, structured data, review statuses and change version, under the copy of its parent. The content facts are worked out again by the page's own changes. Each copy names the page it came from (source_section_id) and keeps that page's lineage (section_lineage_id). A page under an archived page is not reached by a reader of the source, and is not copied.
  • The language groups, remapped: each copy starts a group of its own, and once every page is written a copy whose source was grouped with another page of the source joins that page's copy's group (MishkaDocument.Section's :copy_language_group). The copies of a group led from another version are grouped under one of them.
  • Every note of each copied page (MishkaDocument.Note's :copy) and every tag on it (MishkaDocument.SectionTag's :assign).
  • Drafts of pages and notes are not copied.

The pages are read and written a tree level at a time, 50 rows a batch, through Ash.bulk_create/4; the notes and tags of 25 pages a batch. Every write is made with the action's actor, so it needs the section area as well as the workspace area. Any refusal or failure rolls the whole copy back.

The event

Once the transaction is committed, "document:version:cloned" is fired through MishkaInstaller.Event.Hook.call/3 with

%{
  version_id: "…",
  source_version_id: "…",
  workspace_id: "…",
  site_id: "…",
  pages: 172,
  notes: 1004,
  tags: 30
}

and meta: %{actor: actor, site_id: site_id}. What a plugin answers is not used.

The returned version carries cloned: %{pages: n, notes: n, tags: n, from: "0.0.9"} in its metadata, from being the source's version number.

Usage

create :clone do
  accept [:version_number, :version_name, :description]
  argument :source_version_id, :uuid, allow_nil?: false
  change MishkaDocument.Resources.Changes.CloneVersion
end

create :create do
  argument :source_version_id, :uuid
  argument :copy_pages, :boolean, default: true
  change {MishkaDocument.Resources.Changes.CloneVersion, as: :create}
end

Summary

Functions

The event fired after a version is cloned.

Functions

event()

@spec event() :: String.t()

The event fired after a version is cloned.