Permissions for front-end embeds
The two meta roles introduced in v0.5 are the keys to opening specific gates without making the entire plugin world-readable.
| Meta role | Listing it on the entity / field / action means… |
|---|---|
public | Anyone, anonymous visitors included, passes the gate. |
authenticated | Any logged-in WP user passes, regardless of pfm role. |
Meta roles are never user-assignable (they don't appear in the Group → Roles picker, and set_group_roles drops their ids server-side). Pick them only on the relevant column of the entity, field or action.
How the embeds decide
Every shortcode runs a permission check at render time:
- [pfm_form] checks create if no sys_id is set, otherwise write. - [pfm_list] and [pfm_record] check read. - [pfm_action] checks read on the entity then asks /actions/<entity>/<sys_id> whether the action is visible to the visitor.
If the visitor passes, a mount node is emitted. If they fail and are anonymous, the shortcode renders a sign-in prompt that links to wp_login_url(get_permalink()) so they come back to the page after login. If they fail and are logged in, a static "you do not have permission" message renders.
The prompt copy can be customised via the pfm/auth_prompt filter.
REST gates after relaxation
REST endpoints under /wp-json/pfm/v1/ that previously required the WordPress pfm_* capability now accept any traffic at the permission_callback layer; the resolver inside the handler is the authority. Anonymous traffic 403s unless the entity explicitly grants the required action to public.
| Endpoint | Before v0.6 | From v0.6 |
|---|---|---|
GET /<entity> | pfm_view_records cap | resolver (can_entity('read')) |
POST /<entity> | pfm_create_records cap | resolver (can_entity('create')) + AnonymousGuard |
PATCH /<entity>/<id> | pfm_edit_records cap | resolver (can_entity('write')) + per-field gate |
DELETE /<entity>/<id> | pfm_delete_records cap | resolver (can_entity('delete')) |
POST /<entity>/import-csv | pfm_create_records cap | unchanged — admin-only |
POST /actions/<id>/invoke | logged-in only | resolver-gated |
GET /actions/<entity>/<sys_id> | logged-in only | resolver-gated |
GET /me/perms | logged-in only | resolver-gated (anonymous gets a sensible empty snapshot) |
GET /public/nonce | (new) | always callable — returns a fresh wp_rest nonce |