0

我想向 WordPress 网站添加新帖子,并使用 WordPress 4.7 REST API 和客户端的 JSON-Tool "" 设置未来的bash发布日期curljq我已将 basic-auth 插件添加到 WordPress,以便我可以使用这种类型的身份验证。

我最初是这样上传帖子的:

curl -s --location --basic --user 'name:password' \
     --url "https://<server>/wp-json/wp/v2/posts" \
     -d "title=Testpost" -d "content=This is a new post." | \
jq -r '"id: \(.id), date: \(.date), status: \(.status), title: \(.title.raw)"'

> id: 45, date: 2017-02-07T10:10:31, status: draft, title: Testpost

好的,这正如预期的那样。让我们看看更改帖子是否有效:

curl -s --location --basic --user 'name:password' \
     --url "https://<server>/wp-json/wp/v2/posts/45" \
     -d "title=Other title" | \
jq -r '"date: \(.date), status: \(.status), title: \(.title.raw)"'

> date: 2017-02-07T10:20:32, status: draft, title: Other title

好的,工作。

现在我想在下午 3 点发布帖子(" curl" 参数缩小,因为它们没有改变):

curl ... "/wp-json/wp/v2/posts/45" \
     -d "date=2017-02-07T15:00:00" | \
jq -r '"id: \(.id), date: \(.date), status: \(.status)"'

> id: 45, date: 2017-02-07T10:29:32, status: draft

没有。日期更改为发出请求的时间,而不是请求的发布日期。好的,也许状态“待定”?

curl ... "/wp-json/wp/v2/posts/45" \
     -d "status=pending" -d "date=2017-02-07T15:00:00" | \
jq -r '"id: \(.id), date: \(.date), status: \(.status)"'

> id: 45, date: 2017-02-07T10:36:24, status: pending

好吧,状态设置为“待定”,但日期仍然是错误的。也许明确地将状态设置为“未来”?

curl ... "/wp-json/wp/v2/posts/45" \
     -d "status=future" -d "date=2017-02-07T15:00:00" | \
jq -r '"id: \(.id), date: \(.date), status: \(.status)"'

> id: 45, date: 2017-02-07T10:36:48, status: publish

什么???这里发生了什么?现在,该帖子以当前日期发布。正是我不想拥有的。

但是,如果我现在用已发布的帖子重新发出相同的请求

curl ... "/wp-json/wp/v2/posts/45" \
     -d "status=future" -d "date=2017-02-07T15:00:00" | \
jq -r '"id: \(.id), date: \(.date), status: \(.status)"'

> id: 45, date: 2017-02-07T16:00:00, status: future

......它完成了这项工作 - 至少在某种程度上。不知何故,时间被解释为 UTC,但最终帖子被正确设置为“未来”状态。

问题 1:如何在首先发布的情况下使帖子进入这种状态?

问题 2:为什么日期被解释为 UTC?不就是“ date_gmt”吗?

我在这里想念什么?

4

1 回答 1

3

好的,我想我得到了状态的东西(问题 1)。

解决方案:

private您可以通过将发布状态设置为中间来将发布日期更改为将来的某个日期。以下两个命令将草稿的发布日期更改为将来的某个时间点,而不会过早发布:

curl ... "/wp/v2/posts/45" -d "status=private"
curl ... "/wp/v2/posts/45" -d "status=future" -d "date=2017-02-07T15:00:00"

解释:

好的,这是为什么呢?这是 WordPress 核心的一个功能,它阻止了预期的操作。让我们深入研究一下:

REST API 在下面实现wp-includes/rest-api/endpoints。对于处理帖子,代码是class-wp-rest-posts-controller.php. 从第 670 行开始处理更新帖子update_item()(在 WP 4.7.2 中)。

该功能并没有做那么多。主要是调用wp_update_post()WordPress 核心。该方法在 中实现wp-includes/post.php,从第 3534 行开始(原文如此!)。

在方法开始后不久,我们发现了麻烦的代码行:

// Drafts shouldn't be assigned a date unless explicitly done so by the user.
if ( isset( $post['post_status'] ) &&
     in_array($post['post_status'], array('draft', 'pending', 'auto-draft')) &&
     empty($postarr['edit_date']) &&
     ('0000-00-00 00:00:00' == $post['post_date_gmt']) )
        $clear_date = true;
else
        $clear_date = false;

这就是问题所在:这里检查的所有数据都是帖子已经存储的信息。即使我future通过 REST API 使用更新请求传输新状态,也不会在此位置对其进行评估。$clear_date仅根据数据库中的信息设置。由于我们的帖子是作为草稿插入的,并且所有其他条件也都匹配,因此它总是会true导致方法将所有更新删除到日期字段的更远一些行。因此,只要帖子的状态是或之一draft,就无法更改帖子的发布日期。核心只是用它认为“正确”的方式覆盖对发布日期的所有预期更改。pendingauto-draft

如本回复开头所述,解决方案是将帖子的状态中间更改为private. 该状态既不会触发任何发布操作,也不会出现在wp_update_posts(). 因此,我们可以在第二步中更改日期 - 然后还更新状态以便发布帖子。

我觉得这毕竟是一个错误。在我看来,关键部分wp_update_post()应该考虑更新的新发布状态,如果新状态是(至少)其中之一,则保持新日期不变publishedor future

于 2017-02-07T17:28:43.740 回答