PluginProbe ʕ •ᴥ•ʔ
Advanced Custom Fields (ACF®) / 6.8.9
Advanced Custom Fields (ACF®) v6.8.9
6.8.9 6.8.8 6.8.7 6.8.6 6.8.5 6.8.4 6.8.3 6.8.2 6.8.1 5.8.5 5.8.6 5.8.7 5.8.8 5.8.9 5.9.0 5.9.1 5.9.2 5.9.3 5.9.4 5.9.5 5.9.6 5.9.7 5.9.8 5.9.9 6.0.0 6.0.1 6.0.2 6.0.3 6.0.4 6.0.5 6.0.6 6.0.7 6.1.0 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.1.6 6.1.7 6.1.8 6.2.0 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.2.6 6.2.6.1 6.2.7 6.2.8 6.2.9 6.3.0 6.3.1 6.3.10.2 6.3.11 6.3.12 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.6.1 6.4.0 6.4.0.1 6.4.1 6.4.2 6.4.3 6.5.0 6.5.1 6.6.0 6.6.1 6.6.2 6.7.0 6.7.1 6.7.2 6.8.0 trunk 1.0.0 1.0.2 1.0.3 1.0.5 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.1.1 2.1.3 2.1.4 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.6 3.0.7 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 3.2.0 3.2.2 3.2.3 3.2.4 3.2.5 3.2.6 3.2.7 3.2.8 3.2.9 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7 3.3.8 3.3.9 3.4.0 3.4.1 3.4.2 3.4.3 3.5.0 3.5.1 3.5.2 3.5.3 3.5.4 3.5.5 3.5.6 3.5.7 3.5.8 4.0.0 4.0.1 4.0.2 4.0.3 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4 4.1.5 4.1.6 4.1.8 4.2.0 4.2.1 4.2.2 4.3.0 4.3.1 4.3.2 4.3.3 4.3.4 4.3.5 4.3.6 4.3.7 4.3.8 4.3.9 4.4.0 4.4.1 4.4.10 4.4.11 4.4.12 4.4.2 4.4.3 4.4.4 4.4.5 4.4.6 4.4.7 4.4.8 4.4.9 5.10 5.10.1 5.10.2 5.11 5.11.1 5.11.2 5.11.3 5.11.4 5.12 5.12.1 5.12.2 5.12.3 5.12.4 5.12.5 5.12.6 5.6.10 5.6.2 5.6.3 5.6.4 5.6.5 5.6.6 5.6.7 5.6.8 5.6.9 5.7.0 5.7.1 5.7.10 5.7.12 5.7.13 5.7.2 5.7.3 5.7.4 5.7.5 5.7.6 5.7.7 5.7.8 5.7.9 5.8.0 5.8.1 5.8.10 5.8.11 5.8.12 5.8.13 5.8.14 5.8.2 5.8.3 5.8.4
advanced-custom-fields / src / AI / Abilities / AbstractAbilityGroup.php
advanced-custom-fields / src / AI / Abilities Last commit date
ACF_REST_Ability.php 5 months ago Abilities.php 5 months ago AbstractAbilityGroup.php 5 months ago FieldGroup.php 3 months ago PostType.php 5 months ago Taxonomy.php 3 months ago
AbstractAbilityGroup.php
223 lines
1 <?php
2 /**
3 * @package ACF
4 * @author WP Engine
5 *
6 * © 2026 Advanced Custom Fields (ACF®). All rights reserved.
7 * "ACF" is a trademark of WP Engine.
8 * Licensed under the GNU General Public License v2 or later.
9 * https://www.gnu.org/licenses/gpl-2.0.html
10 */
11
12 namespace ACF\AI\Abilities;
13
14 use WP_REST_Request;
15 use WP_Error;
16
17 // Exit if accessed directly.
18 defined( 'ABSPATH' ) || exit;
19
20 /**
21 * Abstract Ability Group
22 *
23 * Base class for all ability groups.
24 */
25 abstract class AbstractAbilityGroup {
26
27 const REST_ABILITY_CLASS = 'ACF\AI\Abilities\ACF_REST_Ability';
28
29 /**
30 * Register abilities for this ability group
31 *
32 * @since 6.8.0
33 *
34 * @return void
35 */
36 abstract public function register_abilities();
37
38 /**
39 * Check if the WordPress Abilities API is available
40 *
41 * @since 6.8.0
42 *
43 * @return boolean
44 */
45 protected function is_abilities_api_available() {
46 return function_exists( 'wp_register_ability' );
47 }
48
49 /**
50 * Register an ability with error handling.
51 *
52 * @since 6.8.0
53 *
54 * @param string $id Ability ID.
55 * @param array $ability_args Ability arguments.
56 * @return object|null Registered ability object or null on failure.
57 */
58 protected function register_ability( $id, $ability_args ) {
59 if ( ! $this->is_abilities_api_available() ) {
60 return null;
61 }
62
63 // Ensure meta array exists.
64 if ( ! isset( $ability_args['meta'] ) ) {
65 $ability_args['meta'] = array();
66 }
67
68 // Ensure mcp array exists.
69 if ( ! isset( $ability_args['meta']['mcp'] ) ) {
70 $ability_args['meta']['mcp'] = array();
71 }
72
73 // Set public to true by default for MCP exposure.
74 if ( ! isset( $ability_args['meta']['mcp']['public'] ) ) {
75 $ability_args['meta']['mcp']['public'] = true;
76 }
77
78 return wp_register_ability( $id, $ability_args );
79 }
80
81 /**
82 * Retrieves the AI-enabled ACF fields for the provided object.
83 *
84 * @since 6.8.0
85 *
86 * @param string $object_type The object type being queried.
87 * @param integer|string $object_id The object to get ACF fields for.
88 * @return array
89 */
90 protected function get_acf_fields_for_object( $object_type, $object_id ) {
91 // Get field groups that show on this object.
92 $field_groups = acf_get_field_groups(
93 array(
94 $object_type => $object_id,
95 )
96 );
97
98 $acf_fields = array();
99
100 foreach ( $field_groups as $field_group ) {
101 // Only include AI-accessible field groups that are exposed in REST.
102 if ( empty( $field_group['allow_ai_access'] ) || empty( $field_group['show_in_rest'] ) ) {
103 continue;
104 }
105
106 $fields = acf_get_fields( $field_group['key'] );
107
108 if ( $fields ) {
109 $acf_fields[ $field_group['key'] ] = array(
110 'title' => $field_group['title'],
111 'key' => $field_group['key'],
112 'fields' => $this->format_acf_fields_for_schema( $fields ),
113 );
114 }
115 }
116
117 return $acf_fields;
118 }
119
120 /**
121 * A helper function to format ACF fields for schema output.
122 *
123 * @since 6.8.0
124 *
125 * @param array $fields The ACF fields array.
126 * @return array
127 */
128 protected function format_acf_fields_for_schema( array $fields ): array {
129 $formatted_fields = array();
130
131 foreach ( $fields as $field ) {
132 $field_schema = array(
133 'key' => $field['key'],
134 'name' => $field['name'],
135 'label' => $field['label'],
136 'field_type' => $field['type'],
137 );
138
139 // Add description if available
140 if ( ! empty( $field['instructions'] ) ) {
141 $field_schema['description'] = $field['instructions'];
142 }
143
144 $field_schema = array_merge(
145 $field_schema,
146 acf_get_field_rest_schema( $field )
147 );
148
149 $formatted_fields[] = $field_schema;
150 }
151
152 return $formatted_fields;
153 }
154
155 /**
156 * Adds ACF fields to a schema.
157 *
158 * @since 6.8.0
159 *
160 * @param array $schema The schema to add fields to.
161 * @param array $acf_fields The ACF fields to add.
162 * @return array
163 */
164 protected function add_acf_fields_to_schema( array $schema, array $acf_fields ): array {
165 if ( empty( $acf_fields ) ) {
166 return $schema;
167 }
168
169 $schema['properties']['acf'] = array(
170 'type' => 'object',
171 'description' => 'ACF field values',
172 'required' => false,
173 'properties' => array(),
174 );
175
176 foreach ( $acf_fields as $field_group ) {
177 foreach ( $field_group['fields'] as $field ) {
178 $schema['properties']['acf']['properties'][ $field['name'] ] = $field;
179 }
180 }
181
182 return $schema;
183 }
184
185 /**
186 * Execute a REST API request.
187 *
188 * @since 6.8.0
189 *
190 * @param string $method HTTP method (GET, POST, PUT, DELETE).
191 * @param string $rest_base REST API base.
192 * @param array $input Input parameters.
193 * @param integer $item_id Optional item ID for single item operations.
194 * @return array|WP_Error Response data or error.
195 */
196 protected function execute_rest_request( string $method, string $rest_base, $input = array(), $item_id = null ) {
197 $endpoint = '/wp/v2/' . $rest_base;
198
199 if ( $item_id ) {
200 $endpoint .= '/' . intval( $item_id );
201 }
202
203 $request = new WP_REST_Request( $method, $endpoint );
204
205 // Set all input parameters.
206 foreach ( $input as $key => $value ) {
207 // Skip the ID since it's in the URL for single item operations.
208 if ( $key === 'id' && $item_id ) {
209 continue;
210 }
211 $request->set_param( $key, $value );
212 }
213
214 $response = rest_do_request( $request );
215
216 if ( $response->is_error() ) {
217 return $response->as_error();
218 }
219
220 return $response->get_data();
221 }
222 }
223