Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I've written a simple bit of code (cobbled together from various tutorials around the web) that creates a simple meta-box (called 'Subheading') and removes the custom fields from the admin area.

It all works fine - until I place the code inside a class. Once I do this, the meta-box stops saving to the database. I suspected it was because I need to define some arguments for the constructor to take, but anything I try fails. I cannot figure out what is going wrong, so any help would be greatly appreciated! Here is the code:

class MySubBoxClass 
{  
    function __construct()
    {
        add_action( 'add_meta_boxes', array( $this, 'meta_box_add' ) );      //Hooks meta_box_add() onto the add_meta_boxes hook                                                                
        add_action( 'save_post', array( $this, 'save_meta_box', 10, 2 ) );   //Hooks save_meta_box() onto the save_post hook                                                                          
        add_action('admin_init', array( $this, 'remove_custom_meta_boxes') );//Hooks remove_custom_meta_boxes() onto admin_init  
    }

    public function meta_box_add()    //Function that triggers the add_meta_box() Wordpress function 
    {
        add_meta_box( 'meta-box-id', 'SUBHEADING', array($this, 'html_form_func'), 'post', 'normal', 'high' );  
        //Adds meta box with HTML id "meta-box" to the admin panel in the edit posts screen  
        //Calls the add_meta_box_cb_function() which creates the HTML form (see below)  
    }


    public function html_form_func( $object ) //Creates the HTML form and outputs its value if it has one   
    {  
        wp_nonce_field( basename( __FILE__ ), 'meta_box_nonce' );

        <label><input type="text" name="subheading" id="meta-box-input" size="144" value="<?php echo get_post_meta( $object->ID, 'subheading', true ); ?>" /></label>        
    }

    public function save_meta_box( $post_id, $post ) 
    {
        //Verifies the nonce before proceeding.
        if ( !isset( $_POST['meta_box_nonce'] ) || !wp_verify_nonce( $_POST['meta_box_nonce'], basename( __FILE__ ) ) )
            return $post_id;

        //Gets the post type object
        $post_type = get_post_type_object( $post->post_type );


        //Assigns '$new_meta_value' variable the value that was newly submitted through the HTML form input named 'subheading' 
        $new_meta_value = ( isset( $_POST['subheading'] ) ? esc_attr( $_POST['subheading'] ) : '' );

        //Assigns'$meta_key' variable the value 'subheading'  
        $meta_key = 'subheading';

        //Assigns $meta_value variable the value of the custom field (identified by the key '$meta_key') that is currently 
        //associated with that post 
        $meta_value = get_post_meta( $post_id, $meta_key, true );

        //If a new meta value was added and the previous meta value had no value (== ''), add the new meta value
        if ( $new_meta_value && $meta_value == '' )
            add_post_meta( $post_id, $meta_key, $new_meta_value, true );

        //If the new meta value does not match the old value, update it
        elseif ( $new_meta_value && $new_meta_value != $meta_value )
            update_post_meta( $post_id, $meta_key, $new_meta_value );

        //If there is no new meta value but an old value exists, delete it
        //elseif ( $new_meta_value == '' && $meta_value )
        //delete_post_meta( $post_id, $meta_key, $meta_value );
    }

    public function remove_custom_meta_boxes() 
    {
        remove_meta_box('postcustom','post','normal');
        remove_meta_box('postcustom','page','normal');
    }
}

$MySubBoxClass = new MySubBoxClass;
share|improve this question

closed as too localized by kaiser, toscho Mar 11 '13 at 14:35

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.If this question can be reworded to fit the rules in the help center, please edit the question.

    
Have you checked the return value of wp_verify_nonce()? –  kaiser Mar 11 '13 at 13:20
    
In the 'save' action there is a wrong bracket. It should read: add_action( 'save_post', array( $this, 'save_meta_box'), 10, 2 ); –  t f Mar 11 '13 at 13:26

1 Answer 1

up vote 1 down vote accepted

Enable the magic method __construct

You have to change the following line

$MySubBoxClass = new MySubBoxClass;

Into

$MySubBoxClass = new MySubBoxClass();

This way the __construct() magic method will be used.
The add_action methods aren't called now.

Error in html_form_func( $object )

Change

public function html_form_func( $object ) //Creates the HTML form and outputs its value if it has one   
{  
    wp_nonce_field( basename( __FILE__ ), 'meta_box_nonce' );

    <label><input type="text" name="subheading" id="meta-box-input" size="144" value="<?php echo get_post_meta( $object->ID, 'subheading', true ); ?>" /></label>        
}

Into

public function html_form_func( $object ) //Creates the HTML form and outputs its value if it has one   
{  
    wp_nonce_field( basename( __FILE__ ), 'meta_box_nonce' );
    ?>
    <label><input type="text" name="subheading" id="meta-box-input" size="144" value="<?php echo get_post_meta( $object->ID, 'subheading', true ); ?>" /></label>
    <?php
}

Object methods by reference

Change

function __construct()
  {
  add_action( 'add_meta_boxes', array( $this, 'meta_box_add' ) );      //Hooks meta_box_add() onto the add_meta_boxes hook                                                                

  add_action( 'save_post', array( $this, 'save_meta_box', 10, 2 ) );   //Hooks save_meta_box() onto the save_post hook                                                                          

  add_action('admin_init', array( $this, 'remove_custom_meta_boxes') );//Hooks remove_custom_meta_boxes() onto admin_init  
  }

Into

function __construct()
{
    add_action( 'add_meta_boxes', array( &$this, 'meta_box_add' ) );        //Hooks meta_box_add() onto the add_meta_boxes hook                                                                
    add_action( 'save_post', array( &$this, 'save_meta_box', 10, 2 ) );     //Hooks save_meta_box() onto the save_post hook                                                                          
    add_action( 'admin_init', array( &$this, 'remove_custom_meta_boxes' ) );//Hooks remove_custom_meta_boxes() onto admin_init  
}

If you use object methods in add_action you have to use &$this to use $this in reference.

share|improve this answer
    
This doesn't happen for me, at least on PHP 5.3: the constructor is always called, () or no –  djb Mar 11 '13 at 13:19
    
Hi Mike, cheers for your reply. I tried that but it still won't save for me! –  Nathan Mar 11 '13 at 13:21
1  
and this one array( $this, 'save_meta_box', 10, 2 ) –  Jesse Mar 11 '13 at 13:23
    
Hi Mike, in my original code I do drop out of PHP to create the HTML before going back in to PHP (exactly like you have suggested). I had to change the code to post it here because it was breaking the code into two separate code boxes and wasn't displaying the line of HTML. Apologies for not mentioning this in my original post. –  Nathan Mar 11 '13 at 13:31
    
Oh, no problem mate. I do hope that the other things I mentioned help you. –  Mike Madern Mar 11 '13 at 13:34

Not the answer you're looking for? Browse other questions tagged or ask your own question.