NewWe open-sourced 50+ Laravel packages
Custom AI apps, agents and automation — Roundly ConsultingRoundly
All packages
Forms for Laravel

Reading submissions

Forms::submissions($form) returns a fluent reader that assembles the per-field rows back into one keyed [field_key => value] set per submission, in form order (groups, then fields, by order). Answers given to a field that was soft-deleted later are still read:

$answers = Forms::submissions($form)
    ->forSender($user)   // optional
    ->latest()           // or ->oldest()
    ->get();             // Collection<AssembledSubmission>

$answers->first()->values;          // ['name' => 'Jane', 'email' => '[email protected]']
$answers->first()->value('name');   // 'Jane'

Drafts are excluded unless you call ->withDrafts(). Results are newest first by default. Narrow further by uuid or by review outcome — the reader is always scoped to its form, so another form’s uuid matches nothing:

Forms::submissions($form)->whereUuid($result->uuid)->first(); // one submission
Forms::submissions($form)->pendingApproval()->get();          // awaiting review
Forms::submissions($form)->approved()->get();                 // or ->rejected()

One submission by uuid

Forms::submission() addresses one submission — or draft — by the uuid submit() or draft() returned, or by its FormSubmission model. An unknown or malformed uuid throws SubmissionNotFoundException:

$submission = Forms::submission($result->uuid);   // or Forms::submission($formSubmission)

$submission->uuid();         // the reference uuid
$submission->get();          // AssembledSubmission (a draft's values included)
$submission->model();        // the FormSubmission aggregate: status, sender, form
$submission->finalize();     // promote a draft
$submission->review();       // open a review (see Submission review)

Reader and AssembledSubmission

Forms::submissions($form)->withDrafts()->get();  // include unfinished drafts
Forms::submissions($form)->first();               // ?AssembledSubmission (newest)
Forms::submissions($form)->count();               // int

$answer = Forms::submissions($form)->first();

$answer->uuid;                  // submission reference id
$answer->values;                // [field_key => typed value]
$answer->value('email', 'n/a'); // a single answer, with a default
$answer->senderId;              // int|string|null — stored as the sender returns it
$answer->senderType;            // ?string — the sender's morph class
$answer->submittedAt;           // CarbonInterface

A field key that two groups of the form share is keyed group_key.field_key instead, so neither answer overwrites the other (['applicant.name' => 'Kid', 'guardian.name' => 'Parent']). Values come back typed — an int for number fields, a bool for checkboxes, a CarbonImmutable for dates — see Typed field values.

Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

More ways to support, including crypto

By donating, you agree to our donation terms.

Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.