agentsclimarketplace

Fluentform submission lifecycle

Skill Lonsdale201/wp-agent-skills/fluentform/fluentform-submission-lifecycle

Implements and audits Fluent Forms server-side submission behavior from parsed field data through sanitization, validation, persistence, entry details, notifications, integrations, and confirmation. Selects the correct fluentform/input_data_*, fluentform/validation_errors, fluentform/insert_response_data, fluentform/submission_inserted, and fluentform/submission_confirmation hook and explains their timing. Use when adding cross-field validation, normalizing submitted values, reacting to an entry, debugging missing submission data, preventing duplicate side effects, or distinguishing a Pro partial draft from a completed submission.From its SKILL.md

Install
npx -y skills add Lonsdale201/wp-agent-skills --skill fluentform-submission-lifecycle

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 21 stars21 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

7.9 KB, ~1.6k tokens by cl100k_base, as published. Nobody here has run it

Fluent Forms submission lifecycle

Choose hooks from the actual server-side order. Browser data is untrusted, and an action that sounds “before insert” is not a replacement for validation.

Read hook-order.md before changing stored values, adding a remote side effect, handling payment forms, or reacting to Pro drafts.

Canonical lifecycle

raw serialized request
  -> form field parsing and accepted-key allowlist
  -> recursive Fluent Forms sanitization
  -> restrictions / CAPTCHA / input normalization / validation
  -> spam checks
  -> response-data and insert-row filters
  -> submission row insert
  -> before-actions hook
  -> entry-details projection
  -> submission-inserted hooks and feeds
  -> confirmation filters

Unknown request keys are removed before validation unless explicitly placed on Fluent Forms' protocol-key allowlist. The accepted $formData is therefore not the same object as raw $_POST or the controller's parsed input.

Hook selection

NeedUseImportant timing
Normalize one element before rulesfluentform/input_data_{element}Before validator
Change rule/message definitionsfluentform/validationsBefore validator
Add cross-field errorsfluentform/validation_errorsBefore rejection/insert
Change accepted response datafluentform/insert_response_dataAfter validation, before JSON encode
Change DB row columnsfluentform/filter_insert_dataLow-level, immediately before insert
Observe imminent insertfluentform/before_insert_submissionAction, after validation; cannot return changed data
React to a durable entryfluentform/submission_insertedRow and entry details exist
Change browser confirmationfluentform/submission_confirmationLast response stage

Do not use fluentform/before_insert_submission for normal validation. In 6.2.7 it is an action after handleValidation() and receives $insertData by value. Use validation filters so the browser gets field-shaped errors and no row is created.

Form-scoped cross-field validation

add_filter(
    'fluentform/validation_errors',
    static function ($errors, $formData, $form, $fields) {
        if ((int) $form->id !== 42) {
            return $errors;
        }

        $start = (string) ($formData['start_date'] ?? '');
        $end   = (string) ($formData['end_date'] ?? '');

        if ($start !== '' && $end !== '' && $end < $start) {
            $errors['end_date'][] = __(
                'The end date must not precede the start date.',
                'acme-addon'
            );
        }

        return $errors;
    },
    10,
    4
);

Use exact field names from the form definition. Preserve existing errors and return an array keyed by the input name. Validate dates or numbers semantically; the short comparison above is valid only for normalized ISO dates.

Stored-value transformation

add_filter(
    'fluentform/insert_response_data',
    static function ($formData, $formId, $inputConfigs) {
        if ((int) $formId !== 42 || !isset($formData['customer_code'])) {
            return $formData;
        }

        $formData['customer_code'] = strtoupper(
            sanitize_text_field((string) $formData['customer_code'])
        );

        return $formData;
    },
    10,
    3
);

This filter runs after field validation. Revalidate any materially changed value, or normalize it earlier with input_data_{element}. Never inject secrets, payment tokens, raw request bodies, or unbounded payloads into response.

Durable side effects

add_action(
    'fluentform/submission_inserted',
    static function ($entryId, $formData, $form): void {
        if ((int) $form->id !== 42) {
            return;
        }

        $alreadyDone = \FluentForm\App\Helpers\Helper::getSubmissionMeta(
            $entryId,
            '_acme_synced',
            false
        );

        if ($alreadyDone) {
            return;
        }

        // Queue a bounded background job with $entryId as its idempotency key.
    },
    20,
    3
);

Prefer Fluent Forms feed integrations for configurable external delivery. If a plain hook is enough, queue slow HTTP/email work and design for replay. Do not assume the full submission process is one database transaction.

Security and correctness rules

  • Treat Fluent Forms sanitization as input normalization, not authorization or business validation. Enforce ownership/capabilities in privileged custom flows.
  • Public forms do not become authenticated because a WordPress nonce exists. In 6.2.7 submission nonce verification defaults off; rate limits, CAPTCHA, validation, and service-specific anti-abuse controls remain relevant.
  • Keep fluentform/submission_form_data pure: current 6.2.7 applies it twice in processSubmissionData(). Never send mail, charge, or call an API from it.
  • Preserve existing filter data. Do not replace another addon's fields or errors.
  • Scope every callback by form ID and, where needed, element key or form type.
  • Use namespaced slash hooks. Deprecated underscore aliases remain for compatibility but should not be used in new code.
  • Do not treat notify_on_form_submit as “all processing completed”; it fires directly after the submission row insert and before entry-detail recording.

Pro boundary

Normal completed submissions and the hooks above are Free-core behavior. fluentform_draft_submissions, Save Progress, partial-entry administration, and the fluentform/partial_submission_* hooks are Pro features in 6.2.7. A partial draft is not a completed entry and must not trigger fulfillment, enrollment, charging, or irreversible delivery.

Payment fields exist in the Free codebase, but gateway execution, order items, transactions, recurring subscriptions, and several payment hooks depend on the configured payment feature/addon. Do not infer successful payment from submission_inserted; react to the appropriate verified payment-status hook.

Cross-references

  • Use fluentform-custom-fields for element-specific normalization/validation.
  • Use fluentform-entries-data for response, detail-row, and meta semantics.
  • Use fluentform-feed-integration for configurable asynchronous delivery.

References

What ships with it: 2 files

5.6 KB alongside SKILL.md

agents/

references/

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.