# `MishkaCmsCore.Runtime.Resources.Notifiers.PluginHook`
[🔗](https://github.com/mishka-group/mishka_cms_core/blob/v0.0.1/lib/mishka_cms_core/runtime/resources/__notifiers/plugin_hook.ex#L5)

A reusable Ash notifier that emits a MishkaInstaller plugin event after every action
(`create` / `update` / `destroy`, including custom-named actions) on any resource it is added to.

Add it to a resource's notifier list — and because it lives in `mishka_cms_core` (a dependency of
every extension), all extensions share the exact same hook mechanism:

    use Ash.Resource,
      ...,
      notifiers: [Ash.Notifier.PubSub, MishkaCmsCore.Runtime.Resources.Notifiers.PluginHook]

It fires `"<app>:<resource>:after_<action>"` — e.g. `"blog:comment:after_create"`,
`"blog:post_rating:after_remove"`, `"document:section:after_update"` — handing the resulting record
to plugins, plus a read-only `meta: %{actor:, site_id:}`.

A plugin that listens on one of these names its event with `event_name/2` rather than spelling the
string, so the name it listens on is the name fired:

    use MishkaInstaller.Event.Hook,
      event: PluginHook.event_name(MishkaBlog.BlogPost, :publish)

One event is one action. A master user runs the action's `master_*` twin, which fires its own
event (`"blog:blog_post:after_master_publish"`), so reacting to both takes a plugin on each.

## After any save

A `create` or `update` action — whatever its name, a master's twin included — also fires
`"<app>:<resource>:after_save"` (`save_event_name/1`), after its own event, with the same record
and `meta`. A plugin that reacts to the record being written, however it was written, listens
there once:

    use MishkaInstaller.Event.Hook, event: PluginHook.save_event_name(MishkaBlog.BlogPost)

Because notifiers run **after the transaction commits**, the action stays **atomic** — adding this
changes no authorization or atomicity behaviour (no `require_atomic? false`, no 403→404). This is why
it works uniformly for `destroy` actions too.

For `before`/reject seams (which a notifier cannot do), use a `before_action` change on the specific
action instead. See `MishkaInstaller.Event.Hook`.

# `event_name`

```elixir
@spec event_name(module(), atom()) :: String.t()
```

The event this notifier fires when `action_name` runs on `resource`:
`event_name(MishkaBlog.BlogPost, :publish)` is `"blog:blog_post:after_publish"`.

# `save_event_name`

```elixir
@spec save_event_name(module()) :: String.t()
```

The event fired after any `create` or `update` action on `resource`:
`save_event_name(MishkaBlog.BlogPost)` is `"blog:blog_post:after_save"`.

---

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