无法显示来自 Wordpress REST API 自定义端点的自定义字段

Can't display custom field from Wordpress REST API custom endpoint

我正在使用 Wordpress Rest API 将内容从 Wordpress 网站导入 PHP 应用程序。 这并不复杂,只是一个包含 post 列表的主页和个人 post 的页面。

我在 API 响应中添加了一些字段,特别是用于获取 post 中插入的第一张图片的 url。

这是这部分的代码:

add_action('rest_api_init', function () {
    register_rest_field('post', 'post_images', array(
        'get_callback'    => 'get_first_image',
        'update_callback' => null,
        'schema'          => null
    ));
});

function get_first_image($obj, $name, $request)
{
    $images = get_attached_media('image', $obj['id']);
    $imagesArray = (array) $images;
    reset($imagesArray);
    $firstImageId = current($imagesArray)->ID;
    $imageSrc = wp_get_attachment_image_url($firstImageId);
    return $imageSrc;
}

当我在主页中列出 post 时它工作正常,但在个人 post 页面中该字段为空。我能想到的唯一解释是我有一个用于单个 posts:

的自定义端点
function post_by_slug(WP_REST_Request $request)
{
    $postSlug = $request->get_param('post_slug');
    $lang     = $request->get_param('my_lang');
    $myPost   = get_page_by_path($postSlug, OBJECT, 'post');
    $targetPostId   = apply_filters('wpml_object_id', $myPost->ID, 'post',
        false, $lang);
    $targetPost     = get_post($targetPostId);
    $postController = new \WP_REST_Posts_Controller($targetPost->post_type);
    $response       = $postController->prepare_item_for_response($targetPost,
        $request);

    return rest_ensure_response($response);
}

add_action('rest_api_init', function () {
    register_rest_route('pc/v1',
        "/post-slug/(?P<post_slug>\S+)/(?P<my_lang>\w+)", [
            'methods'  => 'GET',
            'callback' => 'post_by_slug',
            'args'     => [
                'post_slug' => 'required',
                'my_lang'   => 'required'
            ]
        ]);
});

在我的应用程序中,我这样称呼它:

$client = new Client([
    'base_uri' => 'http://example.com/wp-json/pc/v1/',
    'headers' => [
        'Content-Type' => 'application/json',
        "Accept" => "application/json",
    ],
    'verify' => false,
]);

var_dump(json_decode($client->get("post-slug/$slug/$lang")
                             ->getBody()->getContents()));

奇怪的是,直接从浏览器访问同一个端点我可以正确看到所有字段。我是不是漏掉了什么不对劲的东西?

只是回答我自己的问题,因为我发现是什么导致端点在我的浏览器中正常工作,但在通过 Guzzle 访问时却没有。

问题是我是以管理员身份登录的,所以我用来管理网站上多种语言的 WPML 插件设置了这个 cookie:

wp-wpml_current_admin_language_d41d8cd98f00b204e9800998ecf8427e:"de"

所以问题与这个插件有关,我实际上在 post_by_slug 函数中使用了它。 不知何故,像我在这里那样指定语言是不够的,或者只是为了不同的目的,不确定:

$targetPostId   = apply_filters('wpml_object_id', $myPost->ID, 'post', false, $lang);

我可以找到两个解决方案:

1) 使用插件 switch_lang() 方法显式设置语言:

function post_by_slug(WP_REST_Request $request) {
  global $sitepress;
  $postSlug = $request->get_param('post_slug');
  $lang = $request->get_param('my_lang');
  $sitepress->switch_lang($lang);

2) 更改 guzzle GET 请求以将语言作为查询参数传递,这似乎自动与插件一起工作:

$response = $client->get("post-slug/$slug", ['query' => ['lang' => $lang]])->getBody()->getContents();

我意识到这是一个非常具体的问题,但也许它会对其他人有所帮助。