Как получить произвольные мета-данные записи через REST API
Я пытаюсь создать REST API для моего WordPress сайта, который используется для листинга объектов с помощью плагина WordPress Job Manager.
Я зарегистрировал свой пользовательский тип записи и таксономии в \plugins\rest-api\plugin.php.
API ниже выдает мне все листинги со стандартным ответом.
http://localhost/sports/wp-json/wp/v2/joblisting/
Я хотел добавить мета-данные записи в JSON ответ, используя код ниже.
function slug_register_phone_number() {
register_rest_field( 'job_listing',
'phone',
array(
'get_callback' => 'slug_get_phone_number',
'update_callback' => null,
'schema' => null,
)
);
}
function slug_get_phone_number($post, $field_name, $request) {
return get_post_meta($post->id, '_phone' );
}
}
Используя код выше, я могу добавить "phone" в REST ответ, но я всегда получаю phone = false в ответе. Он не показывает корректные данные из таблицы wp_postmeta.
Я использовал следующие ссылки для справки:
http://v2.wp-api.org/extending/modifying/
Детали плагинов: 1. WP Job Manager 2. rest-api
Любая помощь будет очень полезна.

WP API предоставляет фильтр rest_prepare_post
(или rest_prepare_CPT
при работе с пользовательскими типами записей), который можно использовать для модификации JSON-ответа.
В вашем случае это будет rest_prepare_joblisting
.
function filter_joblisting_json( $data, $post, $context ) {
$phone = get_post_meta( $post->ID, '_phone', true );
if( $phone ) {
$data->data['phone'] = $phone;
}
return $data;
}
add_filter( 'rest_prepare_joblisting', 'filter_joblisting_json', 10, 3 );
Используя этот же фильтр, вы также можете удалять поля/данные из ответа и выполнять любые манипуляции с данными.

$post
в функции обратного вызова является массивом, а не объектом. Поэтому вы не можете использовать $post->id
. Измените это на $post['id']
, и всё должно заработать:
function slug_get_phone_number($post, $field_name, $request)
{
return get_post_meta($post['id'], '_phone', true);
}
Рекомендую изменить _phone
на phone_number
или что-то другое без префикса в виде подчёркивания. Потому что _
часто используется для приватных мета-ключей. Попробуйте добавить произвольное поле с мета-ключом, начинающимся с _
, напрямую к вашему посту, и вы поймёте, что я имею в виду.

Просто добавьте эти методы в файл function.php
add_action( 'rest_api_init', 'create_api_posts_meta_field' );
function create_api_posts_meta_field() {
// register_rest_field ( 'тип-записи', 'название-поля-для-возврата', массив-колбэков-и-схем() )
register_rest_field( 'tour', 'metaval', array(
'get_callback' => 'get_post_meta_for_api',
'schema' => null,
)
);
}
function get_post_meta_for_api( $object ) {
// получаем ID из массива объекта записи
$post_id = $object['id'];
// возвращаем метаданные записи
return get_post_meta( $post_id );
}

Вот пример ООП:
class MetaDataFetcher{
public function enableAPIroute(){
add_action ('rest_api_init', array($this, 'doRegisterRoutes'));
}
public function doRegisterRoutes(){
register_rest_route(
'yournamespace/vXX',
'fetch-post-meta',
array(
'methods' => array('GET','POST'),
'callback' => array($this, 'returnMetaData'),
// Вам следует реализовать лучшую авторизацию, иначе этот endpoint будет открыт
'permission_callback' => function(){return TRUE;}
)
);
}
public function returnMetaData(){
if (!(isset($_REQUEST['post-id']))){
return "ОШИБКА: Не указан ID поста";
}
$postID = $_REQUEST['post-id'];
$meta = get_post_meta($postID);
$meta = json_encode($meta);
return $meta;
}
}
$MetaDetaFetcher = New MetaDataFetcher;
$MetaDetaFetcher->enableAPIroute();

Я протестировал и использовал то, что кажется мне более простым способом: после регистрации пользовательского типа записи вы также можете зарегистрировать пользовательские мета-поля и сделать их доступными в REST API.
Смотрите register_meta()
register_post_type( 'job_listing', $args ); // в $args вы можете сделать тип записи доступным в REST API
register_meta(
'post', '_phone', [
'object_subtype' => 'job_listing',
'show_in_rest' => true
]
);
