Darstellung
Submit actions
Phase 6 runs configured actions after a submission is stored. The first built-in type is email.
Honeypot hits never reach ad_form_after_submission, so they never send mail.
Mail failures are logged and never fail the public submit. The entry stays stored.
Document shape
definition.actions is a list:
json
{
"id": "action_a1b2c3d4",
"type": "email",
"enabled": true,
"settings": {
"to": "{admin:email}",
"cc": "",
"bcc": "",
"from_name": "",
"from_email": "",
"reply_to": "{field:email}",
"subject": "New submission: {form:title}",
"message": "{all_fields}"
},
"conditions": {
"enabled": false,
"effect": "show",
"logic": "all",
"rules": []
}
}Action IDs are stable (action_ + 8 hex). New forms created via Add New get one enabled email action to {admin:email} with {all_fields}.
Optional conditions use the same group as fields (see CONDITIONS.md). Actions ignore effect: when the group is enabled and the rules do not match, the action is skipped (debug log, not a failure).
Merge tags
| Tag | Value |
|---|---|
{field:key} | Submitted value for that field key |
{form:title} {form:id} {form:slug} | Form identity |
{entry:id} {entry:uuid} {entry:created_at} | Stored entry (UTC timestamp) |
{admin:email} | admin_email option |
{user:email} {user:display_name} | Logged-in submitter, otherwise empty |
{all_fields} | All input fields (submit buttons omitted) |
Unknown tags are left unchanged. Add-ons can append keys via ad_form_merge_tags.
Field values in HTML bodies are escaped. Header fields (to, cc, bcc, subject, from, reply-to) have CR/LF stripped after expansion. Recipients are split on comma/semicolon, validated with is_email, and capped at 10 per field.
from_email is a literal address only. Merge tags are not expanded there; an empty value uses the WordPress default From header.
Runtime
SubmitServicestores the entry and firesad_form_after_submission.ActionRunnerwalks enabled actions whose conditions match.ad_form_before_action/ad_form_after_actionwrap each type.- Unknown types and exceptions are logged on channel
actions. Email failures use channelmail.
PHP:
Dingfelder\AdForm\Actions\ActionInterfaceDingfelder\AdForm\Actions\ActionRegistryDingfelder\AdForm\Actions\ActionRunnerDingfelder\AdForm\Actions\MergeTagEngineDingfelder\AdForm\Actions\Types\EmailActionDingfelder\AdForm\Notifications\WpMailer
Register extra types:
php
add_filter( 'ad_form_actions', function( array $actions, $registry ) {
$actions['webhook'] = new MyWebhookAction();
return $actions;
}, 10, 2 );REST catalogue: GET /wp-json/ad-form/v1/actions (capability edit_ad_form_forms).