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.:createkeeps 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 givencopy_pages: falsecopies 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
@spec event() :: String.t()
The event fired after a version is cloned.