AdvancedCustomFields / AdvancedCustomFields/acf
Use CPT caps for field groups
Nobody has claimed this yet.
- Dominant language
- PHP
- Stars
- 945
- Forks
- 197
- PR merge metrics
- No merged PRs in 30d
Description
I'm creating a plugin that bridges the Members role editor and ACF. One of the issues I've run into is that ACF hardcodes acf_get_setting( 'capability' ) any time it needs to check a capability.
Instead, it should use get_post_type_object( 'acf-field-group' )->cap->{$capname} when checking directly if a user can do something. acf_get_setting( 'capability' ) should be set at the register_post_type() level. That way, it trickles down.
The biggest place this is an issue is in the save_post callback for field groups: https://github.com/AdvancedCustomFields/acf/blob/master/includes/admin/admin-field-group.php#L461-L464
Instead of checking the ACF cap, it should check current_user_can( 'edit_post', $post_id ) and let WP map this meta capability back to the CPT's primitive caps.
I've managed to code a workaround by filtering the capability setting and faking it during this callback and removing the filter afterward. However, that's not future proof and could fall apart whenever there's an update to the underlying ACF code to do the same cap check elsewhere.
Longer term
Ideally, any action that a user could take when editing or deleting either a field group or a field itself would be tied directly into the CPT caps for these two post types. By default, ACF could set all of its CPT caps to acf_get_setting( 'capability' ).
Doing this wouldn't change how ACF works internally. However, it'd make it flexible enough for third-party developers to do some really cool stuff with caps.
I'd be happy to look over any work with this if you decide to make the changes.
Quick example of doing this during the CPT registration process:
$cap = acf_get_setting( 'capability' );
register_post_type( 'acf-field-group', [
'map_meta_cap' => true,
'capabilities' => [
// meta caps (don't assign these to roles)
'edit_post' => 'edit_acf_field_group',
'read_post' => 'read_acf_field_group',
'delete_post' => 'delete_acf_field_group',
// primitive caps
'create_posts' => $cap,
'edit_posts' => $cap,
'edit_others_posts' => $cap,
'publish_posts' => $cap,
'read_private_posts' => $cap,
'read' => 'read',
'delete_posts' => $cap,
'delete_private_posts' => $cap,
'delete_published_posts' => $cap,
'delete_others_posts' => $cap,
'edit_private_posts' => $cap,
'edit_published_posts' => $cap
]
] );
Extra
The "active" status for a field group should only be available to users who can $type->cap->publish_posts. Otherwise, it should fall back to "inactive". Sort of like how draft posts work.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in includes/admin/admin-field-group.php at the save_post callback, then inspect the field-group and field post-type registration and other capability checks. Trace how the CPT capabilities map to WordPress meta capabilities, including the publish-status behavior. Done means direct actions use the registered CPT caps consistently without changing the default capability setting behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- php
- Domain
- authorization, backend
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100