如何对同一个类的多个实例使用Add_action

时间:2014-02-09 作者:emersonthis

我正在编写一个插件,它定义了一个要多次调用的类。该类使用add_action 将它自己的方法注册为回调。

class MyClass {

    __construct($foo) {

        add_action(\'hook1\', array($this, \'method1\') );
        add_action(\'hook2\', array($this, \'method2\') );

    }

    public function method1() {...}

    public function method2() {...}

}
这很好用。但当我做两次时,只有第二次起作用。

new MyClass(\'foo\');
new MyClass(\'bar\');
换句话说,上述代码的结果正是我从以下内容中所期望的结果:

// new MyClass(\'foo\');
new MyClass(\'bar\');
似乎第二个实例覆盖了第一个实例。我做错了什么?

我已经检查过了spl_object_hash() 这两种情况都是不同的。

我补充道var_dump($wp_filter); 在我的代码之后,我看到这两个实例都列在相关的操作挂钩键下。所以看起来WP知道他们都在那里。。。

Full code from my complete plugin:

将其粘贴到/wp-content/mu-plugins中的文件中。然后添加/编辑帖子。你should 可以看到两个新的自定义元框“Foo”和“Bar”,但只能看到“Bar”。注释最后一行,以使用类实例的不同组合进行测试。

<?php
/*
Plugin Name: SDP Custom Meta Boxes
Description: Defines a custom meta box framework class.
*/

class SDP_Custom_Field {

  public $name = NULL;
  public $slug = NULL;
  public $prefix = NULL;
  public $post_type = \'post\'; //The type of Write screen on which to show the meta: \'post\', \'page\', \'dashboard\', \'link\', \'attachment\' or \'custom_post_type\'
  public $meta_box_location = \'normal\'; //\'normal\', \'advanced\', or \'side\'
  public $meta_box_priority = \'default\'; //\'high\', \'core\', \'default\' or \'low\'
  public $meta_box_field_type = NULL;

  public function __construct( $custom_field_name, $args=array() ) {
    #set the name
    $this->name = $custom_field_name;

    #set the slug
    if (isset($args[\'slug\'])) {
        $this->slug = $args[\'slug\'];
    } else {
        $slug = strtolower($custom_field_name);
        $slug = str_replace(\' \', \'_\', $slug);
        $this->slug = $slug;      
    }

    #set the meta_box_field_type
    if (isset($args[\'field_type\'])) {
        switch ($args[\'field_type\']) {
            case \'text\':
                $this->meta_box_field_type = \'text\';
                break;
            case \'textarea\':
                $this->meta_box_field_type = \'textarea\';
                break;            
            default:
                $this->meta_box_field_type = \'text\';
                break;
        }

    } else {
        $this->meta_box_field_type = \'text\';
    }

    // add_action( \'add_meta_boxes\', array($this, \'_add_custom_metaboxes\'));
    // add_action( \'save_post\', array($this, \'_save_postdata\'));

    add_action( \'add_meta_boxes\', array(&$this, \'_add_custom_metaboxes\'));
    add_action( \'save_post\', array(&$this, \'_save_postdata\'));

    //var_dump( is_object( array($this, \'_add_custom_metaboxes\') ));

  }

  // public function go() {
  //   add_action( \'add_meta_boxes\', array($this, \'_add_custom_metaboxes\'));
  //   add_action( \'save_post\', array($this, \'_save_postdata\'));
  // }

  #Echo the HTML for this meta box... 
  public function _print_field_HTML( $post ) {

      $value = get_post_meta( $post->ID, $this->slug, true );

      // Add an nonce field so we can check for it later.
      wp_nonce_field( $this->slug.\'_custom_box\', $this->slug.\'_custom_box_nonce\' );


      echo \'<label for="\'.$this->slug.\'">\'.$this->name.\'</label> \';
      echo \'<input type="text" id="\'.$this->slug.\'" name="\'.$this->slug.\'" value="\' . esc_attr( $value ) . \'" size="25" />\';

      //TODO: Add update button
      //TODO: Add delet button
  }

  public function _add_custom_metaboxes() {
      #http://codex.wordpress.org/Function_Reference/add_meta_box
      add_meta_box( NULL, $this->name, array(&$this, \'_print_field_HTML\'), $this->post_type, $this->meta_box_location, $this->meta_box_priority, NULL );
  }




  /**
   * When the post is saved, saves our custom data.
   * @param int $post_id The ID of the post being saved.
   */
  public function _save_postdata( $post_id ) {

    /*
     * We need to verify this came from the our screen and with proper authorization,
     * because save_post can be triggered at other times.
     */

    // Check if our nonce is set.
    if ( ! isset( $_POST[$this->slug.\'_custom_box_nonce\'] ) )
      return $post_id;

    #http://codex.wordpress.org/Function_Reference/wp_nonce_field
    $nonce = $_POST[$this->slug.\'_custom_box_nonce\'];

    // Verify that the nonce is valid.
    if ( ! wp_verify_nonce( $nonce, $this->slug.\'_custom_box\' ) )
        return $post_id;

    // If this is an autosave, our form has not been submitted, so we don\'t want to do anything.
    if ( defined( \'DOING_AUTOSAVE\' ) && DOING_AUTOSAVE ) 
        return $post_id;


      if ( ! current_user_can( \'edit_post\', $post_id ) )
          return $post_id;

    /* OK, its safe for us to save the data now. */

    // Sanitize user input.
    $mydata = sanitize_text_field( $_POST[$this->slug] );

    // Update the meta field in the database.
    update_post_meta( $post_id, $this->slug, $mydata );
  }

}

new SDP_Custom_Field( \'Foo\' );
new SDP_Custom_Field( \'Bar\' );

1 个回复
最合适的回答,由SO网友:fuxia 整理而成

当你打电话的时候add_meta_box() 您必须提供unique ID 作为第一个参数。

考虑这种情况:

add_meta_box( \'foobox\', \'Foo Title\', \'foo_callback\' );
add_meta_box( \'foobox\', \'Bar Title\', \'bar_callback\' );
你会得到Bar Title 现在是metabox,因为它将覆盖第一个。

您需要的是每个框的新ID:

add_meta_box( \'foobox\', \'Foo Title\', \'foo_callback\' );
add_meta_box( \'barbox\', \'Bar Title\', \'bar_callback\' );
尝试从创建ID$custom_field_name 或者使用静态计数器。

除此之外,您还应该在其他两个方面更改代码:

摆脱神的等级,把它分成多个等级:

一个用于输出,一个用于当前。ExampleFix your nonce, 否则,您的插件将在多站点安装时严重损坏。

结束

相关推荐

How to find installed plugins

我一直在寻找WordPress网站上安装的插件列表。虽然我找到了一种方法,“http wp plugins.nse”暴力脚本,但我不知道如何使用这个脚本。如果有人知道任何方法,请分享。