# `MishkaDocument.Resources.Changes.CloneVersion`
[🔗](https://github.com/mishka-group/mishka_document/blob/v0.0.1/lib/mishka_document/resources/__changes/clone_version.ex#L5)

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

# `event`

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

The event fired after a version is cloned.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
