I'm writing a plugin which defines a class that is meant to be called multiple times. The class uses add_action
to register it's own methods as callbacks.
class MyClass {
__construct($foo) {
add_action('hook1', array($this, 'method1') );
add_action('hook2', array($this, 'method2') );
}
public function method1() {...}
public function method2() {...}
}
This works just fine. But when I do it twice, only the second works.
new MyClass('foo');
new MyClass('bar');
In other words, the results of the code above are exactly what I'd expect from the following:
// new MyClass('foo');
new MyClass('bar');
It seems like the second instance overrides the first. What am I doing wrong?
I've checked to make sure that spl_object_hash()
is different for both instances and it is.
I added var_dump($wp_filter);
after my code and I see BOTH instances listed under the relevant action hook key. So it looks like WP knows they are both there...
Full code from my complete plugin:
Paste this into a file in /wp-content/mu-plugins.php and then add/edit a post. You should see two new custom meta boxes "Foo" and "Bar" but you will only see "Bar". Comment in/out the final lines to test with different combinations of instances of the class.
<?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' );