是否可以在save\\u post操作中确定是创建新帖子还是更新现有帖子?
检查SAVE_POST操作上的更新与新POST
自WordPress版本3.7起-IIRC-thesave_post
钩子-有关钩子及其用法的更多信息,请访问Code Reference: save_post
和Codex: save_post
- 有第三个参数$update
这可以用来确定。
@参数 ;内景 $post\\U ID ;Post ID.参数 ;WP\\U Post $发布 ;Post对象
@参数 ;布尔 $更新 ;这是否是正在更新的现有帖子。
注:
$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();
}
我执行此检查的方式(在挂钩函数中)是比较发布日期和修改日期(以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 );
$diff = $created->diff( $modified );
$seconds_difference = ((($diff->y * 365.25 + $diff->m * 30 + $diff->d) * 24 + $diff->h) * 60 + $diff->i)*60 + $diff->s;
if( $seconds_difference <= 1 ){
// New post
}else{
// Updated post
}
}
add_action(\'save_post\', \'check_new_vs_update\' );
这是因为即使在创建帖子时,帖子也会附加一个“修改”日期,这与“创建”日期完全相同,但如果在创建帖子的过程中出现第二个时间点,我们允许有1秒的差异。最后,我只是在设置自定义值之前检查它是否存在。这样,如果它是新创建的帖子,那么自定义值将不存在。
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\');
使用“更新”参数回答iLocin的示例:
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 );
我刚刚遇到save_post
关于新建和更新。阅读源代码后了解流程。我发现以下方法可能有用。因为之前还没有提到。看看它是否对任何人有用。(测试为核心5.3.3)
创建后的流程大约为:
按Add New(Post)后,$Post=get\\u default\\u Post\\u to\\u edit($Post\\u type,true);将在以下位置调用:get\\u default\\u post\\u to\\u edit()接收参数$create\\u in\\u db=true,因此立即调用wp\\u insert\\u post(),auto-draft
正在创建帖子,即使没有保存,每次单击Add New
, 一auto-draft
创建时,$更新对于发布始终为真。因此,当发布新帖子时,这是真的通过比较new POST和update POST或Repubish POST的$\\u POST对象,显著的区别是值_wp_http_referer
, 新职位是/wp-admin/post-new.php
假设:假设文章是从UI发布/添加的。如果是由其他机制(自定义代码)完成的,则需要调整检查。
add_action( \'save_post\', \'test_save_post_check\', 0, 3 );
function test_save_post_check( $post_ID, $post, $update ) {
// other tests + this
// checking the \'post-new\' position from the \'_wp_http_referer\'
if( strpos( wp_get_raw_referer(), \'post-new\' ) > 0 ) {
// new
} else {
// update
}
}
这是我在我的网站上使用的一个功能代码,它可以解决与save\\u post操作相关的以下两个问题:
在ubdate或insert之间检查问题
通过save\\u post操作两次插入的问题
function save_annonces_callback($post_ID, $post, $update){
$post_type = get_post_type($post_ID);
if ( $post_type === \'annonces\' ){
//this to preventtwice insert by save_post action :)
if (defined(\'DOING_AUTOSAVE\') && DOING_AUTOSAVE ) {
return;
} else {
//check if new post so insert
if( strpos( wp_get_raw_referer(), \'post-new\' ) > 0 ){
//perform insert
}else{
//perform update
}
}
}
}add_action(\'save_post\',\'save_annonces_callback\', 10, 3);
您可以为更新代码使用pre\\u post\\u update操作挂钩,并为新的post代码保存\\u post。它在帖子更新之前工作。
正如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;
}
我之所以使用globals是因为function is_new_post() use ( &$new_post )
在PHP中无效(令人震惊…)因此,将该变量拉入函数范围不起作用——因此是全局变量。请注意,只有在save_post
事件(这通常是足够的,至少对于我们正在用它做什么)。
触发save\\u post时,有关该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\');
但这尚未测试。=)另一种使用内置函数且不向数据库添加内容的方法将涉及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()
构建更合适的场景。参见法典get_post_status() 和Post Status
可能的值包括:
“发布”-已发布的帖子或页面“待定”-帖子正在等待审阅“草稿”-处于草稿状态的帖子“自动草稿”-新创建的帖子,没有内容“未来”-将来要发布的帖子“私有”-未登录的用户看不到“继承”-修订版。请参见get\\u children
自$update
param是无用的,这是我测试的最快方法:
function wpse48678_check_is_post_new($post_id, $post, $update)
{
if (false !== strpos($_POST[\'_wp_http_referer\'], \'post-new.php\')) {
return true; // Or do something else.
} else {
return false; // Or do something else.
}
}
add_action(\'save_post_{$post_type}\', \'wpse48678_check_is_post_new\', 10, 3);