插件开发:WordPress在更新后处理两次。如何跳过第一个流程?

时间:2011-07-12 作者:Exit

当您创建插件并设置流程功能时,Wordpress将在单击更新按钮后运行插件流程功能两次。我相信第一个过程是针对版本控制(修订)岗位的,第二个过程是针对实际岗位的。

现在,我的过程中有一个插入函数,所以它现在将数据插入两次。

确保在创建修订时不进行处理并且仅在实际的后期处理时进行处理的最佳方法是什么?

* Note: Targeting Wordpress 3.0+ *

示例(完整插件):

<?php
/*
Plugin Name: Something Amazing
Plugin URI: http://www.somewhere.com/
Description: Displays something.
Author: Some guy
Version: 1.0
Author URI: http://www.somewhere.com/
*/
function call_something() {
 return new something();
}
if (is_admin()) add_action(\'load-post.php\',\'call_something\');

class something {

 public function __construct() {
  add_action(\'add_meta_boxes\',array(&$this,\'something_add_boxes\'));
  add_action(\'save_post\',array(&$this,\'something_process\'),1,1);
 }

 public function something_add_boxes() {
  add_meta_box(\'something\',\'Some Thing\',array(&$this,\'something_form\'),\'post\',\'side\',\'default\');
 }

 public function something_form($post,$args) {
  echo \'<p><input type="text" name="somethingnew" /></p>\';
 }

 public function something_process($id) {
  echo \'hey there! I\\\'m going to cause a redirect warning, but you will see this line twice per submit!\';
  //do_something_amazing();
 }
}
?>
也许有一个更好的钩子可以用来处理,它不会写两次?

5 个回复
最合适的回答,由SO网友:Hameedullah Khan 整理而成

@Steve函数hook to save\\u post总是调用两次,Wordpress调用函数hook to save\\u post总是调用两次,因为:

第一次保存后修订NOTE: 如果已使用禁用发布修订define(\'WP_POST_REVISIONS\', false); 然后,当实际的帖子将被保存时,save\\u post挂钩将只被触发一次。

我刚刚测试了以下代码,它按预期工作,echo在something\\u process函数中只运行一次。

NOTE: 我上钩的方式保存了\\u post

<?php
/*
Plugin Name: Something Amazing
Plugin URI: http://www.somewhere.com/
Description: Displays something.
Author: Some guy
Version: 1.0
Author URI: http://www.somewhere.com/
*/
function call_something() {
 return new something();
}
if (is_admin()) add_action(\'load-post.php\',\'call_something\');

class something {

 public function __construct() {
  add_action(\'add_meta_boxes\',array(&$this,\'something_add_boxes\'));
  add_action(\'save_post\',array(&$this,\'something_process\'),1,2);
 }

 public function something_add_boxes() {
  add_meta_box(\'something\',\'Some Thing\',array(&$this,\'something_form\'),\'post\',\'side\',\'default\');
 }

 public function something_form($post,$args) {
  echo \'<p><input type="text" name="somethingnew" /></p>\';
 }

 public function something_process($id, $post_object) {
    // don\'t run the echo if this is an auto save
    if ( defined(\'DOING_AUTOSAVE\') && DOING_AUTOSAVE )
        return;

    // don\'t run the echo if the function is called for saving revision.
    if ( $post_object->post_type == \'revision\' )
        return;

  echo \'hey there! I\\\'m going to cause a redirect warning, but you will see this line twice per submit!\';
  //do_something_amazing();
 }
}
?>

SO网友:Vix

您需要确保您的代码仅在保存帖子时运行,而不是在执行修订或自动保存时运行。

通过执行此操作,检查当前帖子id是否确实是实际帖子,而不是修订或自动保存的帖子(实际帖子将始终返回假值):

if ( is_int( wp_is_post_revision( $id ) ) )
    return;

if( is_int( wp_is_post_autosave( $id ) ) )
    return;

SO网友:Bainternet

您可以通过在函数中进行简单的检查来避免自动保存,例如

if (defined(\'DOING_AUTOSAVE\') && DOING_AUTOSAVE) {
        return \'\';
    }
更新就像我发布的一样,只需将上面的代码片段添加到something_process 功能先于任何其他功能。

SO网友:Caio Alves

在我的插件中,我验证了post的状态是一个修订版。您可以在“something process”函数中执行类似操作。

public function something_process($id, $post) {
    if ($post->post_type == \'revision\') return;
    echo \'hey there! I\\\'m going to cause a redirect warning, but you will see this line twice per submit!\';
    //do_something_amazing();
}
添加if ($post->post_type == \'revision\') return; 第行,您可以“取消”WP上函数的第一次调用。

您还需要对动作挂钩进行第二次更改。只需更改行:

add_action(\'save_post\',array(&$this,\'something_process\'),1,1);
对此:

add_action(\'save_post\',array(&$this,\'something_process\'),1,2);
这样,您就可以在操作“save\\u post”上传递第二个参数$post 变量)

SO网友:bellasys

我听说你在寻找“最好的”方法。。。那要看情况了。代码需要处理定制问题——就像你不会选择凯迪拉克越野一样,你也不会(可能)坐吉普车去歌剧院过夜。

我有一个插件,可以处理在save-on-purpose上运行的两个进程。我使用静态var并有条件地选择要运行的代码。我还使用上面的wp\\u is\\u post\\u revision()函数测试post parent id,并且可以更灵活地根据这些结果定制条件,以满足我的需要。

function complex_meta_update_on_save($id){
$ppid = wp_is_post_revision($id);
(can also employ) if($post_parent_id === false) $ppid = $id;
...set environmentals...

static $tc;
if($tc < 1){
execute conditions essential  for revisions, or preprocess for ppid 
}
//note no else-
i can do stuff here that is ok to duplicate, processing, etc. 

if($tc > 0) {
execute conditions and statements essential for post parents
update custom tables with custom queries, register newly processed taxonomies, et. al. 
keep in mind, on Save hook, post data has been saved in db. My plugin uses special  
metadata that needs to know whether I\'ve got a revision, or the parent. 
update_post_meta($id, $blah);now is ok to use $id in
}
//oh the staticness of it all
$tc++;
}//end function
我不知道这其中有什么好主意,甚至是最好的主意,这正是我所需要的——我不需要管理比编辑和保存更多的钩子。。。有一点很简单。

结束

相关推荐

将目录路径传递给plugins_url()安全吗?

plugins_url() 函数接受插件slug或文件路径来构建URL。我有以下目录结构:/wp-content/mu-plugins/someplugin/css/file.css /wp-content/mu-plugins/someplugin/includes/file.php 我需要建立URL到file.css 在里面file.php. 我不能通过__FILE__ 因为这将是一个层次太深。plugins_url(\'css/file.css\', __FILE__ )