| Server IP : 62.72.47.131 / Your IP : 216.73.217.34 Web Server : Apache/2.4.66 (Debian) System : Linux 975cdb959a49 5.14.0-611.55.1.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Tue May 19 15:19:29 EDT 2026 x86_64 User : ( 501) PHP Version : 8.3.30 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : OFF | Perl : ON | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : /var/www/html/wp-content/plugins/advanced-custom-fields/src/AI/Abilities/ |
Upload File : |
<?php
/**
* @package ACF
* @author WP Engine
*
* © 2026 Advanced Custom Fields (ACF®). All rights reserved.
* "ACF" is a trademark of WP Engine.
* Licensed under the GNU General Public License v2 or later.
* https://www.gnu.org/licenses/gpl-2.0.html
*/
namespace ACF\AI\Abilities;
use WP_REST_Request;
use WP_Error;
// Exit if accessed directly.
defined( 'ABSPATH' ) || exit;
/**
* Abstract Ability Group
*
* Base class for all ability groups.
*/
abstract class AbstractAbilityGroup {
const REST_ABILITY_CLASS = 'ACF\AI\Abilities\ACF_REST_Ability';
/**
* Register abilities for this ability group
*
* @since 6.8.0
*
* @return void
*/
abstract public function register_abilities();
/**
* Check if the WordPress Abilities API is available
*
* @since 6.8.0
*
* @return boolean
*/
protected function is_abilities_api_available() {
return function_exists( 'wp_register_ability' );
}
/**
* Register an ability with error handling.
*
* @since 6.8.0
*
* @param string $id Ability ID.
* @param array $ability_args Ability arguments.
* @return object|null Registered ability object or null on failure.
*/
protected function register_ability( $id, $ability_args ) {
if ( ! $this->is_abilities_api_available() ) {
return null;
}
// Ensure meta array exists.
if ( ! isset( $ability_args['meta'] ) ) {
$ability_args['meta'] = array();
}
// Ensure mcp array exists.
if ( ! isset( $ability_args['meta']['mcp'] ) ) {
$ability_args['meta']['mcp'] = array();
}
// Set public to true by default for MCP exposure.
if ( ! isset( $ability_args['meta']['mcp']['public'] ) ) {
$ability_args['meta']['mcp']['public'] = true;
}
return wp_register_ability( $id, $ability_args );
}
/**
* Retrieves the AI-enabled ACF fields for the provided object.
*
* @since 6.8.0
*
* @param string $object_type The object type being queried.
* @param integer|string $object_id The object to get ACF fields for.
* @return array
*/
protected function get_acf_fields_for_object( $object_type, $object_id ) {
// Get field groups that show on this object.
$field_groups = acf_get_field_groups(
array(
$object_type => $object_id,
)
);
$acf_fields = array();
foreach ( $field_groups as $field_group ) {
// Only include AI-accessible field groups that are exposed in REST.
if ( empty( $field_group['allow_ai_access'] ) || empty( $field_group['show_in_rest'] ) ) {
continue;
}
$fields = acf_get_fields( $field_group['key'] );
if ( $fields ) {
$acf_fields[ $field_group['key'] ] = array(
'title' => $field_group['title'],
'key' => $field_group['key'],
'fields' => $this->format_acf_fields_for_schema( $fields ),
);
}
}
return $acf_fields;
}
/**
* A helper function to format ACF fields for schema output.
*
* @since 6.8.0
*
* @param array $fields The ACF fields array.
* @return array
*/
protected function format_acf_fields_for_schema( array $fields ): array {
$formatted_fields = array();
foreach ( $fields as $field ) {
$field_schema = array(
'key' => $field['key'],
'name' => $field['name'],
'label' => $field['label'],
'field_type' => $field['type'],
);
// Add description if available
if ( ! empty( $field['instructions'] ) ) {
$field_schema['description'] = $field['instructions'];
}
$field_schema = array_merge(
$field_schema,
acf_get_field_rest_schema( $field )
);
$formatted_fields[] = $field_schema;
}
return $formatted_fields;
}
/**
* Adds ACF fields to a schema.
*
* @since 6.8.0
*
* @param array $schema The schema to add fields to.
* @param array $acf_fields The ACF fields to add.
* @return array
*/
protected function add_acf_fields_to_schema( array $schema, array $acf_fields ): array {
if ( empty( $acf_fields ) ) {
return $schema;
}
$schema['properties']['acf'] = array(
'type' => 'object',
'description' => 'ACF field values',
'required' => false,
'properties' => array(),
);
foreach ( $acf_fields as $field_group ) {
foreach ( $field_group['fields'] as $field ) {
$schema['properties']['acf']['properties'][ $field['name'] ] = $field;
}
}
return $schema;
}
/**
* Execute a REST API request.
*
* @since 6.8.0
*
* @param string $method HTTP method (GET, POST, PUT, DELETE).
* @param string $rest_base REST API base.
* @param array $input Input parameters.
* @param integer $item_id Optional item ID for single item operations.
* @return array|WP_Error Response data or error.
*/
protected function execute_rest_request( string $method, string $rest_base, $input = array(), $item_id = null ) {
$endpoint = '/wp/v2/' . $rest_base;
if ( $item_id ) {
$endpoint .= '/' . intval( $item_id );
}
$request = new WP_REST_Request( $method, $endpoint );
// Set all input parameters.
foreach ( $input as $key => $value ) {
// Skip the ID since it's in the URL for single item operations.
if ( $key === 'id' && $item_id ) {
continue;
}
$request->set_param( $key, $value );
}
$response = rest_do_request( $request );
if ( $response->is_error() ) {
return $response->as_error();
}
return $response->get_data();
}
}