2014-02-09 23 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'); });