Skip to main content

Members-only forms

The Access panel in the form editor decides who may fill a form in, as opposed to Registration limits, which decides when and how many.

Who can fill it in​

The panel offers three choices, from open to narrow:

ChoiceWho gets in
Anyone with the linkNo sign-in needed. How every form works unless you change it.
Anyone signed in to this siteAny account, whatever its role.
Only these rolesOnly the roles you tick.

Picking Only these roles reveals a list of every role on the site. Administrator is not in it, because administrators can always fill in any form

Ticking no roles behaves like "anyone signed in" rather than like "nobody". An empty list means a form somebody has not finished configuring, and reading it as "everyone" would be the one interpretation that quietly opens a form up.

What people are shown​

Someone who cannot fill the form in sees its title, a message, and - only if they are not signed in - a Sign in button that brings them back to the page they came from. Someone signed in with the wrong role gets no button, because it would only send them round a loop they are already at the end of.

Write your own Message for people who cannot fill it in to say what to do about it ("Ask your coordinator to be added"), which beats the default wording for anyone who is not already an insider.

The form's description and its event card are held back along with the questions. Only the title is shown, so a restricted form does not publish what it is about to everyone with the link.

It is enforced, not hidden​

The check is the same one the closing dates and the capacity cap go through, so it applies wherever the form appears - its own page, the [localform] shortcode and the LocalForm block alike - and a submission from someone who may not fill it in is refused by the server. A stale browser tab, or a page served from a cache, cannot get past it. A restricted form is also marked uncacheable, so a full-page cache does not serve the signed-out version to someone who is signed in, or the other way round.

note

Signing in is WordPress's own login screen. LocalForm does not add a registration flow, so this is for forms answered by people who already have an account - staff, members, students - rather than a way to gate a public form behind a sign-up.

Previewing​

Anyone who can manage forms is let through any restriction, so you can open a members-only form and see it working without keeping a test account.

Because being quietly let through is its own trap - you would see the form working and have no way to tell that everybody else is being turned away - LocalForm says so, in a notice above the form that only you can see:

Only these roles can fill this form in: Editor. You can see it because you manage forms.

Your own submission is a real response, so use a draft form rather than a live one if you want to test the whole flow.

A form limited to a role that no longer exists - a role from a plugin that has been turned off, say - would match nobody and quietly stop collecting. The editor warns you instead, and the role is kept rather than dropped, so turning that plugin back on restores the setting.

The forms list marks restricted forms too, as Signed in only or Restricted, so you can tell at a glance which ones are not open to everyone.

Who submitted​

Whenever somebody is signed in, the response records which account left it - on a gated form and on a public one alike.

A Submitted by column then appears:

  • in the responses list under LocalForm → Responses,
  • in the Excel and CSV exports,
  • and on the printout of a single response.

The column shows up only once a form actually has a response from a signed-in visitor, so a public form never grows an empty column - and relaxing a form's access later does not hide the names already collected. If the account has since been deleted, the response still reads Deleted user (#12) rather than losing the attribution silently.

This is what makes a quiz usable as a training record: the score, the questions answered and the person who answered them, on one printable page.

caution

The recorded account is a name to read, and nothing more. No permission anywhere is decided by it, and it does not let the person who submitted come back and edit their response.

Elsewhere​

  • Webhooks. The payload carries user_id, or null when nobody was signed in. Turning that ID into a name or an address is deliberately left to localform_webhook_payload - it is a choice about what leaves your site.
  • Privacy tools. Tools → Export Personal Data and Tools → Erase Personal Data match responses by the account as well as by an address written into an answer, which is the only way to reach a response to a form that never asked for an address.
  • Backups. A backup keeps the account ID with each response and restores it. Restored onto a different site the ID may name a different account or none at all, since account IDs are per-site.
  • MCP. An AI assistant can read and set all three settings, as access (public / members / roles), access_roles and access_message.

Developers​

The gate runs inside Form::is_accepting(), ahead of not_open, closed and full - a visitor who may not see the form is not told whether it is also fully booked. It reports one of two reasons, because the remedy differs:

ReasonWho gets itWhat they are offered
login_requirednot signed inmessage + Sign in button
role_requiredsigned in, wrong rolemessage only

For a rule roles cannot express - a membership tier, a group, a course enrolment - use localform_user_may_submit. It runs only on a restricted form, after the role check, and never on a public one:

add_filter( 'localform_user_may_submit', function ( $may, $form, $user ) {
if ( 'staff-incident-report' !== $form->slug ) {
return $may;
}

return $may && my_plugin_user_is_on_ward( $user->ID, 'b' );
}, 10, 3 );

localform_is_accepting still has the final say over everything, including the access check, so it can close a form LocalForm left open - or reopen one it closed. Check the reason before overriding.

Useful methods on Form, all taking the form record:

  • access_mode() - public, members or roles
  • is_restricted() - anything but public
  • access_roles() / access_role_names() / missing_access_roles()
  • user_may_submit( $form, $user_id = null ) - the honest answer, with no manage-forms allowance
  • access_bypassed() - true when the current user is only getting in because they manage forms