检查SAVE_POST操作上的更新与新POST

时间:2012-04-11 作者:hereswhatidid

是否可以在save\\u post操作中确定是创建新帖子还是更新现有帖子?

11 个回复
最合适的回答,由SO网友:Nicolai Grossherr 整理而成

自WordPress版本3.7起-IIRC-thesave_post 钩子-有关钩子及其用法的更多信息,请访问Code Reference: save_postCodex: 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();
}

SO网友:James Cushing

我执行此检查的方式(在挂钩函数中)是比较发布日期和修改日期(以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秒的差异。

SO网友:hereswhatidid

最后,我只是在设置自定义值之前检查它是否存在。这样,如果它是新创建的帖子,那么自定义值将不存在。

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\');

SO网友:Goran Jakovljevic

使用“更新”参数回答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 );

SO网友:simongcc

我刚刚遇到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
    }
}

SO网友:Nejmeddine Jammeli

这是我在我的网站上使用的一个功能代码,它可以解决与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);

SO网友:Darshan Thanki

您可以为更新代码使用pre\\u post\\u update操作挂钩,并为新的post代码保存\\u post。它在帖子更新之前工作。

SO网友:Qix - MONICA WAS MISTREATED

正如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 事件(这通常是足够的,至少对于我们正在用它做什么)。

SO网友:moraleida

触发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\');
但这尚未测试。=)

SO网友:John112

另一种使用内置函数且不向数据库添加内容的方法将涉及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

SO网友:dan9vu

$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);

结束

相关推荐