Answers:
从WordPress版本3.7开始。-IIRC- save_post
钩子-有关钩子及其用法的更多信息,请参见代码参考:save_post
和Codex:save_post
-具有第三个参数$update
,可用于确定该参数。
@param int $ post_ID帖子ID。
@param WP_Post $ post发布对象。
@param bool $ update这是否是正在更新的现有帖子。
注意:
$update
并非总是如此true
-您可以使用以下代码自己查看和测试它。但是,它没有得到很好的记录,可能离最佳命名还很远,因此产生了误导性期望。下面的代码可用于某些调试,并在何时拦截代码执行时进行操作,因为否则您将看不到信息/消息。我认为,欺骗性行为的罪魁祸首是对修订和自动保存的处理-可以将其禁用,但我不建议这样做,也没有对其进行测试。不知道这是否需要Trac Ticket,所以我没有打开过,如果您认为这样,请点击链接并自己完成。除此之外,如评论中所述,如果您有特定问题,请发布新问题。
add_action( 'save_post', 'debug_save_post_update', 10, 3 );
function debug_save_post_update( $ID, $post, $update ) {
echo '<pre>';
print_r( $post ); echo '<br>';
echo '$update == ';
echo $update ? 'true' : 'false';
//conditions
if( ! $update && $post->post_status == "auto-draft" ) {
// applies to new post
echo ' && $post->post_status == "auto-draft"';
//die();
} else if ( ! $update ) {
// applies basically to the (auto saved) revision
//die();
} else {
// applies to updating a published post
// when there is a revision, which is normally the case,
// standard behavior of WordPress, then it is considered
// an update, which is where the confusion sets in
// there are other methods, like checking time or post status
// depending on your use case it might be more appropriate
// to use one of those alternatives
//die();
}
echo '</pre>';
//die();
}
$update
即使是新帖子,该参数也始终为true。所以这个参数没用。不确定它是否曾经奏效,但可以肯定的是,它并没有按照最新版本的wordpress 4.8中所记录的那样工作。
wp_publish_post
,那么可以。但这并不是它在中的用法wp_insert_post
。我已经编写了调试功能,将其添加到答案中。
save_post
钩有总是被设置为TRUE,所以不知道这是什么需要做的与其他挂钩,而不是谈论其他钩子第三个参数。我说的是你答案中的陷阱。这是不正确的。
wp_insert_post()
,wp_publish_post()
。后者仅是将来的职位,$update
并且总是存在true
。否则,在问候wp_insert_post()
,$update
并不总是true
。
我执行此检查的方法(在挂钩函数中)是比较发布日期和修改日期(在GMT中进行标准化)
function check_new_vs_update( $post_id ){
$myPost = get_post($post_id);
$post_created = new DateTime( $myPost->post_date_gmt );
$post_modified = new DateTime( $myPost->post_modified_gmt );
if( abs( $post_created->diff( $post_modified )->s ) <= 1 ){
// New post
}else{
// Updated post
}
}
add_action('save_post', 'check_new_vs_update' );
之所以可行,是因为即使在创建帖子时,该帖子就会附加一个“修改的”日期,该日期与“创建”的日期完全相同,但是无论如何,我们都允许1秒钟的差异,以防在创建该帖子的过程中出现一秒的滴答声该职位。
post_date_gmt
是2019-03-12 01:31:30
和post_modified_gmt
是2019-03-12 01:31:31
。:(
我最终只是在设置前检查自定义值的存在。这样,如果它是新创建的帖子,则自定义值将不存在。
function attributes_save_postdata($post_id) {
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
if (!wp_verify_nonce($_POST['_attributes_noncename'], plugin_basename(__FILE__))) return;
if ('page' == $_POST['post_type']) {
if (!current_user_can('edit_page', $post_id)) return;
} else {
if (!current_user_can('edit_post', $post_id)) return;
}
$termid = get_post_meta($post_id, '_termid', true);
if ($termid != '') {
// it's a new record
$termid = 'update';
} else {
// it's an existing record
}
update_post_meta($post_id, '_termid', $termid);
}
add_action('save_post', 'attributes_save_postdata');
用“更新”参数对ialocin答案的示例:
function save_func($ID, $post,$update) {
if($update == false) {
// do something if its first time publish
} else {
// Do something if its update
}
}
add_action( 'save_post', 'save_func', 10, 3 );
if($update)
要么将新块放在第一位,然后使用if( ! $update )
。后者将使OP进入更好的实践,并且在三元运算符
您可以将pre_post_update操作挂钩用于更新代码,将save_post用于新的邮政编码。它可以在帖子更新之前起作用。
save_post
钩被激发双方在创建时桩和更新(WordPress的有它保存到数据库后)。pre_post_update
在帖子更新时触发,但在帖子更新之前触发-这可能很重要。
正如Darshan Thanki所暗示的(Stephen Harris进一步阐述),您可以利用pre_post_update
自己的优势。
global $___new_post;
$___new_post = true;
add_action(
'pre_post_update',
function() {
global $___new_post;
$___new_post = false;
},
0
);
function is_new_post() {
global $___new_post;
return $___new_post;
}
我之所以使用全局变量,是因为function is_new_post() use ( &$new_post )
在PHP中无效(令人震惊...),因此将该变量拉入函数范围不起作用-因此是全局变量。
请注意,实际上只能在save_post
事件内/ 事件后可靠地使用它(通常就足够了,至少对于我们正在处理的事情而言)。
触发save_post时,有关该帖子的所有信息已经可用,因此理论上您可以使用
function f4553265_check_post() {
if (!get_posts($post_id)) {
// if this is a new post get_posts($post_id) should return null
} else {
// $post_id already exists on the database
}
}
add_action('save_post','f4553265_check_post');
不过,这未经测试。=)
save_post
发布帖子时,该帖子本身已经已经保存到数据库中,因此get_posts
将返回当前帖子。
另一种使用内置函数且不添加数据库的方法将涉及get_post_status()
。
$post_status = get_post_status();
if ( $post_status != 'draft' ) {
//draft
} else {
//not a draft: can be published, pending, etc.
}
但是请注意,如果您计划稍后将状态重新设置为“草稿”,则可能不合适;您的指示将在下次更新帖子时重复。根据上下文,您可能需要考虑可以返回的各种字符串get_post_status()
以构建更合适的方案。
参见Codex中的get_post_status()和发布状态
可能的值为:
- “发布”-已发布的帖子或页面
- “待审核”-帖子待审核
- “草稿”-处于草稿状态的帖子
- “自动草稿”-新创建的帖子,没有内容
- “未来”-将来发布的帖子
- “私人”-对未登录的用户不可见
- '继承'-版本。参见get_children。
- “垃圾箱”-帖子在垃圾箱中。在2.9版中添加。
save_post()
则将首次执行该命令,但是在执行过程中,get_post_status()
它仅返回“发布”状态,而不会返回“草稿”状态。