AdvancedCustomFields / AdvancedCustomFields/acf

Use CPT caps for field groups

Open
#211 8 comments 0 reactions 0 assignees View on GitHub

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

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.