我想在WordPress网站上添加一个新帖子,并使用WordPress 4.7 REST API和bash
,curl
和JSON-Tool“{{1}来设置将来的发布日期“在客户端。我已经为WordPress添加了basic-auth插件,以便我可以使用这种类型的身份验证。
我最初上传这样的帖子:
jq
好的,这是预期的。让我们看看是否更改帖子:
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
好的,有效。
现在我想在下午3点发布帖子(“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
”参数缩小,因为它们不会改变):
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
......它完成了这项工作 - 至少在某种程度上如此。不知何故,时间被解释为UTC,但最后帖子被正确地设置为“未来”状态。
问题1:如何在没有首次发布帖子的情况下将帖子置于此状态
问题2:为什么日期被解释为UTC?那不是“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
”吗?
我在这里缺少什么?
答案 0 :(得分:2)
好的,我认为我得到了状态(问题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
。更新帖子由第{6}行(在WP 4.7.2中)update_item()
处理。
这个功能没那么多。主要是,它在WordPress核心中调用wp_update_post()
。该方法在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;
这就是问题所在:此处检查的所有数据都是帖子的已存储的信息。即使我通过REST API使用我的更新请求传输新状态future
,也不会在此处对其进行评估。 $clear_date
仅由数据库中的信息设置。并且,由于我们的帖子作为草稿插入而所有其他条件也匹配,因此它始终为true
,这导致该方法将某些行的所有更新都删除到日期字段。因此,只要帖子的状态是draft
,pending
或auto-draft
之一,就无法更改帖子的发布日期。核心只是将所有预期的更改覆盖到发布日期,并且感觉“正确”。
在本回复开头写的解决方案是将帖子的状态中间更改为private
。该状态既不会触发任何发布操作,也不会出现在wp_update_posts()
的“特殊处理列表”中。因此,我们可以在第二步中更改日期 - 然后还更新状态,以便发布帖子。
我觉得这毕竟是一个错误。在我看来,wp_update_post()
的关键部分应该考虑更新的新帖子状态,如果新状态是(至少)published
或{{1}中的一个,则保持新日期不变}}