2014-02-09 71 views
1

我正在写一个WordPress插件的不同实例多次,但我不认为这是一个特定的WordPress发出...注册如何调用add_metabox()从类

我的插件定义类。在类的方法中,使用几个add_action()钩子来注册回调(这也是类方法)。

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('foo'); 
new MyClass('bar'); 

换句话说,代码的结果以上是正是我想从以下期待:

// new MyClass('foo'); 
new MyClass('bar'); 

我一直琢磨不透这一点,我的直觉是,这是涉及到$this以及与同一类中有两次回调有关的范围问题。但希望有人比我更聪明可以解释它。

更多信息

这个问题确实出现了被链接到WordPress的注册操作的方式。我目前在Wordpress v3.8.1上,我正在寻找/wp-includes/plugin.php。我看到,当我注册add_action()(行360)的行动时,它基本上只是add_filter()(行82)的包装,它通过调用_wp_filter_build_unique_id()(行774)创建独特的$idx

更多信息2

我我的代码后加var_dump($wp_filter);,我看到了相关行动挂机键下面列出两个实例。所以看起来像 WP知道他们都是有...

更新

我也试过以下,并再次,只有最后的实例有一个效果:

class Foo1 extends MyClass{} 
class Foo2 extends MyClass{} 
class Foo3 extends MyClass{} 

new Foo1('foo1'); 
new Foo2('foo2'); 
new Foo3('foo3'); 

我认为这与我上面的理论矛盾。

UPDATE2

这也不起作用:

MyClass { 

    __construct($foo) { 


    } 

    public function go() { 
     add_action('hook1', array($this, 'method1')); 
     add_action('hook2', array($this, 'method2')); 
    } 

    public function method1() {...} 

    public function method2() {...} 

} 

$foo = new MyClass('foo'); 
$bar = new MyClass('bar'); 
$foo->go(); 
$bar->go(); 

UPDATE3

作为一个全面的检查,我想这和它仍然无法正常工作。唯一的区别在于,以下只有FIRST实例有效。现在我完全困惑。

class MyClass1 { 

    __construct($foo) { 

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

    } 

    public function method1() {...} 

    public function method2() {...} 

} 

class MyClass2 { 

    __construct($foo) { 

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

    } 

    public function method1() {...} 

    public function method2() {...} 

} 

$foo = new MyClass1('foo'); 
$bar - new MyClass2('bar'); 

UPDATE4

我试图@尼哈特的建议,通过$this通过参考...

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

...但只有二审工作(再次)。

下面是完整的原来的插件我写道:

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

} 
+0

为什么你需要在构造中使用这段代码?你可以像'$ worker = new MyClass(); $工人─>的init( '富');'。我认为这应该有所帮助。 –

+0

@DannyChernyavsky代码不必在构造函数中。但我已经尝试了你所建议的模式,但并没有解决问题。我认为这个问题与Wordpress使用'$ this'注册回调的方式有关。 – emersonthis

+0

,添加一个新的方法,如add_wp_actions(),并在那里设置你的动作。在你实例化类像$ aa = new Myclass1(..)之后,把它称为$ aa-> add_wp_actions() – Nihat

回答

0

这里是发生了什么事情:的add_meta_box(),第一参数的ID参数,它是不是真的在the docs解释。原来,这需要是独一无二的,否则后续add_meta_box() s将简单覆盖前一个。这个问题已经无关,与我的插件或对象哈希等

这相当于我在做什么错了(注意第一NULL PARAM):

function _print_field_HTML() { 
    echo "Hello"; 
} 
add_action('add_meta_boxes', function() { add_meta_box(NULL, 'FOO', '_print_field_HTML', 'post'); }); 
add_action('add_meta_boxes', function() { add_meta_box(NULL, 'BAR', '_print_field_HTML', 'post'); }); 

这是作品:

function _print_field_HTML() { 
    echo "Hello"; 
} 
add_action('add_meta_boxes', function() { add_meta_box('A', 'FOO', '_print_field_HTML', 'post'); }); 
add_action('add_meta_boxes', function() { add_meta_box('B', 'BAR', '_print_field_HTML', 'post'); });