Интеграция произвольных полей с WordPress REST API

Предисловие

С версии 5.11 Advanced Custom Fields включает поддержку просмотра и обновления пользовательских полей через WordPress REST API. Интеграция работает для стандартных полей ACF по-умолчанию, а также для большинства типов полей, зарегистрированных другими плагинами. Однако, в зависимости от того, как зарегистрированы пользовательские типы полей, возможно потребуется некоторый дополнительный код для их полной интеграции с REST API.

Этот документ расскажет о добавлении/удалении пользовательского типа поля в REST API, а также добавлении/изменении типа поля schema.

Добавление пользовательского типа поля в REST API

Типы полей, зарегистрированные путем создания нового класса типа поля, который расширяет класс acf_field, а затем регистрации этого класса с помощью функции acf_register_field_type(), должны работать с REST API автоматически. Однако это верно только при условии, что новый класс типа поля, расширяющий acf_field, не устанавливает свойство show_in_rest в значение false.

class hfm_font_size extends acf_field {

    // Установите $show_in_rest в true, чтобы разрешить отображение поля в REST API.
    // Это свойство также устанавливается по-умолчанию в true в классе acf_field.
    public $show_in_rest = false;

    ...

Поля, которые не зарегистрированы с помощью acf_register_field_type(), такие, которые создаются просто внутри action-хука acf/include_field_types, можно включить в REST API с помощью фильтра acf/rest/get_fields, как показано ниже:

add_filter( 'acf/rest/get_fields', function ( $fields, $resource, $http_method ) {
    if ( ! is_array( $fields ) ) {
        return $fields;
    }

    // Получаем наш тип поля по его имени.
    $field_type = acf_get_field_type( 'font_size' );

    // Если наш тип поля не был зарегистрирован и инициализирован ACF, сделаем это сейчас.
    if ( ! $field_type instanceof acf_field ) {
        // Инициализируем класс с нашим пользовательским типом поля. Если есть какие-либо аргументы функции, их также нужно передать.
        $field = new hfm_font_size();
        acf_register_field_type( $field );
    }

    // Получите массив с полем (по имени поля) и добавьте его в массив полей, поддерживаемых REST.
    $fields[] = acf_get_field( 'font_size');

    return $fields;
}, 10, 3 );

Приведенный выше пример добавляет пользовательский тип поля font_size в REST API. Для этого он извлекает тип поля из ACF, конструирует класс hfm_font_size, расширяющий acf_field, если это еще не было сделано, а затем добавляет поле в массив полей, доступных для REST API.

Добавление или обновление schema для пользовательских типов полей

По-умолчанию, ACF добавит базовую schema для пользовательских типов полей, расширяющих класс acf_field. Он делает это в методе acf_field::get_rest_schema(), который может быть переопределен в классе, расширяющем acf_field:

class hfm_font_size extends acf_field {

    // переопределим метод acf_field::get_rest_schema()
    public function get_rest_schema( array $field ) {
        $schema = array(
            'type'     => array( 'int', 'null' ),
            'required' => true,
        );

        if ( isset( $field['default_value'] ) && '' !== $field['default_value'] ) {
            $schema['default'] = $field['default_value'];
        }

        return $schema;
    }}

Кроме того, вы можете установить schema с помощью фильтра acf/rest/get_field_schema

Исключение типа поля из REST API

Если поле уже зарегистрировано с помощью acf_register_field_type() и расширяет класс acf_field, вы можете использовать свойство $show_in_rest, чтобы предотвратить его отображение в REST API:

class hfm_font_size extends acf_field {

    // Установим $show_in_rest в false, чтобы предотвратить его отображение в REST API.
    public $show_in_rest = false;

    ...
}

Как и при регистрации полей, также можно исключить тип поля с помощью фильтра acf/rest/get_fields:

add_filter( 'acf/rest/get_fields', function ( $fields, $resource, $http_method ) {
    if ( ! is_array( $fields ) ) {
        return $fields;
    }

    foreach ( $fields as $field_key => $field_array ) {
        if ( 'font_size'  === $field_array['name'] ) {
            unset( $fields[ $field_key ] );
        }
    }

    return $fields;
}, 10, 3 );