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 recently created a custom post type, however each time an update is saved the contents of the meta field disappears after a few minutes.

Is this a bug?

<?php

//      CUSTOM POST TYPE 1
add_action('init', 'ootb_tenant_register');

function ootb_tenant_register() {
    $args = array(
        'label' => __('Tenant'),
        'singular_label' => __('Tenant'),
        'public' => true,
        'show_ui' => true,
        'capability_type' => 'post',
        'hierarchical' => false,
        'rewrite' => true,
        'supports' => array('title', 'editor', 'thumbnail')
    );

    register_taxonomy("business", array("tenant"), array(
        "hierarchical" => true, 
        "label" => "Business Type", 
        "singular_label" => "Business", 
        "rewrite" => true)
    );

    register_post_type( 'tenant' , $args );
}


add_action("ootb_admin_init", "ootb_admin_init");
add_action('wp_insert_post_data', 'ootb_save_tenant_options');

function ootb_admin_init(){
    add_meta_box("gallerymeta", "Tenant Directory Data", "ootb_tenant_meta_options", "tenant", "normal", "low");
}

function ootb_tenant_meta_options(){
    global $post;
    $custom = get_post_custom($post->ID);
    $location = $custom["location"][0];
    $shortdesc = $custom["shortdesc"][0];
    $website = $custom["website"][0];
    $email = $custom["email"][0];
    $twitter = $custom["twitter"][0];
    $facebook = $custom["facebook"][0];
    $smallpictureurl = $custom["smallpictureurl"][0];
    $contactname = $custom["contactname"][0];
    $landlinephone = $custom["landlinephone"][0];
    $mobilephone = $custom["mobilephone"][0];
    $largepictureurl = $custom["largepictureurl"][0];
    $picturealttag = $custom["picturealttag"][0];
?>

<div class="form-wrap">

    <div class="form-field">    
        <label for="location">Location :</label>
        <select name="location" style="width: 200px;">
            <option <?php if($location == "Please select...") echo "selected"; ?> value="Please select...">Please select...</option>
            <option <?php if($location == "Out of the Blue Drill Hall") echo "selected"; ?> value="Out of the Blue Drill Hall">Out of the Blue Drill Hall</option>
            <option <?php if($location == "Portobello Powerhouse") echo "selected"; ?> value="Portobello Powerhouse">Portobello Powerhouse</option>
        </select>
        <p>Location of Business</p>
    </div>

    <div class="form-field">
        <label for="shortdesc">Short Description :</label>
        <textarea name="shortdesc"><?php echo $shortdesc; ?></textarea>
        <p>Short description of the business which will appear on the directory homepage.</p>
    </div>

    <div class="form-field">
        <label for="website">Website Address :</label>
        <input name="website" value="<?php echo $website; ?>" />
        <p>Website address including http://www.</p>
    </div>

    <div class="form-field">
        <label for="email">E-mail Address :</label>
        <input name="email" value="<?php echo $email; ?>" />
        <p>Business contact address.</p>
    </div>

    <div class="form-field">
        <label for="twitter">Twitter URL :</label>
        <input name="twitter" value="<?php echo $twitter; ?>" />
        <p>Twitter URL including http://www.</p>
    </div>

    <div class="form-field">
        <label for="facebook">Facebook URL :</label>
        <input name="facebook" value="<?php echo $facebook; ?>" />
        <p>Facebook URL including http://www.</p>
    </div>

    <div class="form-field">
        <label for="smallpictureurl">Small Picture URL :</label>
        <input name="smallpictureurl" value="<?php echo $smallpictureurl; ?>" />
        <p>250 x 250 Picture URL</p>
    </div>

    <div class="form-field">
        <label for="largepictureurl">Large Picture URL :</label>
        <input name="largepictureurl" value="<?php echo $largepictureurl; ?>" />
        <p>500 x 500 Picture URL</p>
    </div>

    <div class="form-field">
        <label for="picturealttag">Picture Alt Tag :</label>
        <input name="picturealttag" value="<?php echo $picturealttag; ?>" />
        <p>Alt tag for both images.</p>
    </div>

    <div class="form-field">
        <label for="contactname">Business contact name :</label>
        <input name="contactname" value="<?php echo $contactname; ?>" />
        <p>Business contact name.</p>
    </div>

    <div class="form-field">
        <label for="landlinephone">Landline Telephone Number :</label>
        <input name="landlinephone" value="<?php echo $landlinephone; ?>" />
        <p>Landline telephone number.</p>
    </div>

    <div class="form-field">
        <label for="mobilephone">Mobile Telephone Number :</label>
        <input name="mobilephone" value="<?php echo $mobilephone; ?>" />
        <p>Mobile telephone number.</p>
    </div>

</div>

<?php
}

function ootb_save_tenant_options( $post_id ) {
    global $post;   
    //skip auto save
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
        return $post_id;
    }
    //check for you post type only
    if( $post->post_type == "tenant" ) {
            if( isset($_POST['location']) ) { update_post_meta( $post->ID, 'location', $_POST['location'] );}
            if( isset($_POST['shortdesc']) ) { update_post_meta( $post->ID, 'shortdesc', $_POST['shortdesc'] );}
            if( isset($_POST['website']) ) { update_post_meta( $post->ID, 'website', $_POST['website'] );}
            if( isset($_POST['email']) ) { update_post_meta( $post->ID, 'email', $_POST['email'] );}
            if( isset($_POST['twitter']) ) { update_post_meta( $post->ID, 'twitter', $_POST['twitter'] );}
            if( isset($_POST['facebook']) ) { update_post_meta( $post->ID, 'facebook', $_POST['facebook'] );}
            if( isset($_POST['contactname']) ) { update_post_meta( $post->ID, 'contactname', $_POST['contactname'] );}
            if( isset($_POST['smallpictureurl']) ) { update_post_meta( $post->ID, 'smallpictureurl', $_POST['smallpictureurl'] );}
            if( isset($_POST['landlinephone']) ) { update_post_meta( $post->ID, 'landlinephone', $_POST['landlinephone'] );}
            if( isset($_POST['mobilephone']) ) { update_post_meta( $post->ID, 'mobilephone', $_POST['mobilephone'] );}
            if( isset($_POST['largepictureurl']) ) { update_post_meta( $post->ID, 'largepictureurl', $_POST['largepictureurl'] );}
            if( isset($_POST['picturealttag']) ) { update_post_meta( $post->ID, 'picturealttag', $_POST['picturealttag'] );}
    }
}

?>
share|improve this question
add comment

2 Answers

up vote 1 down vote accepted

try this:

//      CUSTOM POST TYPE 1
add_action('init', 'ootb_tenant_register');

    function ootb_tenant_register() {
        $labels = array(
            'name' => _x('Tenants', 'post type general name'),
            'singular_name' => _x('Tenant', 'post type singular name'),
            'add_new' => _x('Add Tenant', 'tenant'),
            'add_new_item' => __('Add New Tenant'),
            'edit_item' => __('Edit Tenant'),
            'new_item' => __('New Tenant'),
            'view_item' => __('View Tenant'),
            'search_items' => __('Search Tenants'),
            'not_found' =>  __('No Tenants found'),
            'not_found_in_trash' => __('No Tenants found in Trash'), 
            'parent_item_colon' => ''
        );

        $args = array(
            'label' => __('Tenant'),
            'labels' => $labels,
            'public' => true,
            'show_ui' => true,
            'capability_type' => 'post',
            'hierarchical' => false,
            'rewrite' => true,
            'supports' => array('title', 'editor', 'thumbnail')
        );

        register_post_type( 'tenant' , $args );

        register_taxonomy("business", array("tenant"), array(
            "hierarchical" => true, 
            "label" => "Business Type", 
            "singular_label" => "Business", 
            "rewrite" => true)
        );
    }

add_action("add_meta_boxes", "ootb_admin_init");
add_action('save_post', 'ootb_save_tenant_options');

function ootb_admin_init(){
    add_meta_box("gallerymeta", "Tenant Directory Data", "ootb_tenant_meta_options", "tenant", "normal", "low");
}


function ootb_tenant_meta_options(){
    global $post;
    $custom = get_post_custom($post->ID);
    $location = $custom["location"][0];
    $shortdesc = $custom["shortdesc"][0];
    $website = $custom["website"][0];
    $email = $custom["email"][0];
    $twitter = $custom["twitter"][0];
    $facebook = $custom["facebook"][0];
    $smallpictureurl = $custom["smallpictureurl"][0];
    $contactname = $custom["contactname"][0];
    $landlinephone = $custom["landlinephone"][0];
    $mobilephone = $custom["mobilephone"][0];
    $largepictureurl = $custom["largepictureurl"][0];
    $picturealttag = $custom["picturealttag"][0];
?>

<div class="form-wrap">

    <div class="form-field">    
        <label for="location">Location :</label>
        <select name="location" style="width: 200px;">
            <option <?php if($location == "Please select...") echo "selected"; ?> value="Please select...">Please select...</option>
            <option <?php if($location == "Out of the Blue Drill Hall") echo "selected"; ?> value="Out of the Blue Drill Hall">Out of the Blue Drill Hall</option>
            <option <?php if($location == "Portobello Powerhouse") echo "selected"; ?> value="Portobello Powerhouse">Portobello Powerhouse</option>
        </select>
        <p>Location of Business</p>
    </div>

    <div class="form-field">
        <label for="shortdesc">Short Description :</label>
        <textarea name="shortdesc"><?php echo $shortdesc; ?></textarea>
        <p>Short description of the business which will appear on the directory homepage.</p>
    </div>

    <div class="form-field">
        <label for="website">Website Address :</label>
        <input name="website" value="<?php echo $website; ?>" />
        <p>Website address including http://www.</p>
    </div>

    <div class="form-field">
        <label for="email">E-mail Address :</label>
        <input name="email" value="<?php echo $email; ?>" />
        <p>Business contact address.</p>
    </div>

    <div class="form-field">
        <label for="twitter">Twitter URL :</label>
        <input name="twitter" value="<?php echo $twitter; ?>" />
        <p>Twitter URL including http://www.</p>
    </div>

    <div class="form-field">
        <label for="facebook">Facebook URL :</label>
        <input name="facebook" value="<?php echo $facebook; ?>" />
        <p>Facebook URL including http://www.</p>
    </div>

    <div class="form-field">
        <label for="smallpictureurl">Small Picture URL :</label>
        <input name="smallpictureurl" value="<?php echo $smallpictureurl; ?>" />
        <p>250 x 250 Picture URL</p>
    </div>

    <div class="form-field">
        <label for="largepictureurl">Large Picture URL :</label>
        <input name="largepictureurl" value="<?php echo $largepictureurl; ?>" />
        <p>500 x 500 Picture URL</p>
    </div>

    <div class="form-field">
        <label for="picturealttag">Picture Alt Tag :</label>
        <input name="picturealttag" value="<?php echo $picturealttag; ?>" />
        <p>Alt tag for both images.</p>
    </div>

    <div class="form-field">
        <label for="contactname">Business contact name :</label>
        <input name="contactname" value="<?php echo $contactname; ?>" />
        <p>Business contact name.</p>
    </div>

    <div class="form-field">
        <label for="landlinephone">Landline Telephone Number :</label>
        <input name="landlinephone" value="<?php echo $landlinephone; ?>" />
        <p>Landline telephone number.</p>
    </div>

    <div class="form-field">
        <label for="mobilephone">Mobile Telephone Number :</label>
        <input name="mobilephone" value="<?php echo $mobilephone; ?>" />
        <p>Mobile telephone number.</p>
    </div>

</div>

<?php

    // Use nonce for verification
    wp_nonce_field( plugin_basename( __FILE__ ), 'wpse28341' );

}


function ootb_save_tenant_options( $post_id ) {
    global $post;   

    //skip auto save
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
        return $post_id;
    }

    // Use nonce for verification
    if ( !wp_verify_nonce( $_POST['wpse28341'], plugin_basename( __FILE__ ) ) )
        return;

    //check for you post type only
    if( $post->post_type == "tenant" ) {
            if( isset($_POST['location']) ) { update_post_meta( $post->ID, 'location', $_POST['location'] );}
            if( isset($_POST['shortdesc']) ) { update_post_meta( $post->ID, 'shortdesc', $_POST['shortdesc'] );}
            if( isset($_POST['website']) ) { update_post_meta( $post->ID, 'website', $_POST['website'] );}
            if( isset($_POST['email']) ) { update_post_meta( $post->ID, 'email', $_POST['email'] );}
            if( isset($_POST['twitter']) ) { update_post_meta( $post->ID, 'twitter', $_POST['twitter'] );}
            if( isset($_POST['facebook']) ) { update_post_meta( $post->ID, 'facebook', $_POST['facebook'] );}
            if( isset($_POST['contactname']) ) { update_post_meta( $post->ID, 'contactname', $_POST['contactname'] );}
            if( isset($_POST['smallpictureurl']) ) { update_post_meta( $post->ID, 'smallpictureurl', $_POST['smallpictureurl'] );}
            if( isset($_POST['landlinephone']) ) { update_post_meta( $post->ID, 'landlinephone', $_POST['landlinephone'] );}
            if( isset($_POST['mobilephone']) ) { update_post_meta( $post->ID, 'mobilephone', $_POST['mobilephone'] );}
            if( isset($_POST['largepictureurl']) ) { update_post_meta( $post->ID, 'largepictureurl', $_POST['largepictureurl'] );}
            if( isset($_POST['picturealttag']) ) { update_post_meta( $post->ID, 'picturealttag', $_POST['picturealttag'] );}
    }
}

Seems to work fine, When adding a metabox you should use add_meta_boxes hook and you should really use nonce

share|improve this answer
    
Bainternet, this is brilliant, thank you. Would you mind talking me through the changes to $labels = array and the logic behind using nonce? –  toomanyairmiles Sep 13 '11 at 23:23
add comment

You have many, many problems here.

  1. Your functions names are way too generic, especially the one you've named admin_init. You need to prefix them with something unique to prevent namespace collisions.

  2. Instead of adding an action to admin_init, you can register a metabox callback when registering your custom post type by adding 'register_meta_box_cb' => 'myprefix_tenant_add_metabox' to your $args array.

  3. There is no singular_label in the register_post_type accepted arguments. labels will accept an array with quite a few labels in it: http://codex.wordpress.org/Function_Reference/register_post_type#Arguments

  4. Your metabox should really contain a nonce field for security. Your metabox save code should check the nonce, check to make sure the user has permissions to be editing that post before saving, and sanitize the user's entries. For sanitizing, see http://codex.wordpress.org/Data_Validation. For an example of nonces and checking permissions, see http://codex.wordpress.org/Function_Reference/add_meta_box

  5. Your select menu is trying to compare against something called type, which you have not set in your initial pull of the metadata and is not in your save code. If all your code for saving and retrieving is the same, use an array with all the keys and a foreach loop to save yourself typing and error checking.

  6. It's spelled "tenant".

I'm not sure which or if any of these is the source of your issue that it is erasing the extra data, but I'd fix these up first to eliminate those potential problems.

Edit:

Here's an example of adding the proper labels array to your post type registration:

function ootb_tenant_register() {
    $labels = array(
        'name' => _x('Tenants', 'post type general name'),
        'singular_name' => _x('Tenant', 'post type singular name'),
        'add_new' => _x('Add Tenant', 'tenant'),
        'add_new_item' => __('Add New Tenant'),
        'edit_item' => __('Edit Tenant'),
        'new_item' => __('New Tenant'),
        'view_item' => __('View Tenant'),
        'search_items' => __('Search Tenants'),
        'not_found' =>  __('No Tenants found'),
        'not_found_in_trash' => __('No Tenants found in Trash'), 
        'parent_item_colon' => ''
    );

    $args = array(
        'label' => __('Tenant'),
        'labels' => $labels,
        'public' => true,
        'show_ui' => true,
        'capability_type' => 'post',
        'hierarchical' => false,
        'rewrite' => true,
        'supports' => array('title', 'editor', 'thumbnail')
    );

    register_post_type( 'tenant' , $args );

    register_taxonomy("business", array("tenant"), array(
        "hierarchical" => true, 
        "label" => "Business Type", 
        "singular_label" => "Business", 
        "rewrite" => true)
    );
}
share|improve this answer
    
Thanks for this, admin_init is actually a wordpress thing codex.wordpress.org/Plugin_API/Action_Reference/admin_init as is singular_label wordpress.org/support/topic/…, the spelling of Tennant (as in David) is an in joke. The fault with the select menu turned out to be that for= and name= have to match the $variable in the form to work. But thankyou for the tip about nonces, but I still have problems saving. Hey ho... –  toomanyairmiles Sep 13 '11 at 13:39
    
admin_init is indeed a hook, but you shouldn't name your function that. singular_label is a part of the array that the labels argument should have (which you are missing), not the register_post_type args array. –  helenhousandi Sep 13 '11 at 14:38
    
I did try renaming all 3 instances of admin_init to ootb_admin_init but doing so causes the whole meta box to disappear. I've updated the code above. Also what am I missing from the –  toomanyairmiles Sep 13 '11 at 15:20
    
You only needed to change two of the admin_init instances. One of them is the actual WordPress hook that's named admin_init, which you needed to leave alone. That would be this line: add_action("ootb_admin_init", "ootb_admin_init");. The first ootb_admin_init should just be admin_init. Will update my answer with an example of the labels shortly. –  helenhousandi Sep 13 '11 at 17:29
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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