Question

I'm trying to create a metabox, it should be nice and easy but I'm getting it wrong. It pertains to a tour custom post, and adding the price in for that tour:

So initially I create this custom post type (this works):

register_post_type( 'tours',
            array(
                'labels' => array(
                    'name' => __( 'Tours' ),
                    'singular_name' => __( 'Tour' ),
                    'add_new' => 'Add New Tour Instance',
                    'add_new_item' => 'Add New Tour Instance',
                    'edit' => 'Edit',
                    'edit_item' => 'Edit Tour Instance',
                    'new_item' => 'New Tour Instance',
                    'view' => 'View',
                    'view_item' => 'View Tour Instance',
                    'search_items' => 'Search Tour Instances',
                    'not_found' => 'No Tour Instances found',
                    'not_found_in_trash' => 'No Tour Instances found in Rubbish',
                    'parent' => 'Parent Tour Instance'
                ),
            'public' => true,
            'supports' => array( 'title', 'editor', 'thumbnail'),
            'taxonomies' => array( '' ),
            //'menu_icon' => plugins_url( 'images/image.png', __FILE__ ),
            'capability_type' => 'post',
            'rewrite' => array("slug" => "tours") // Permalinks format
            )
        );

Then I create the box itself (this also works):

add_action( 'admin_init', 'tour_meta' );
        function tour_meta() {
            add_meta_box(
                'tours_meta_box',
                'Tour Price',
                'display_tours_price_meta_box',
                'tours',
                'side',
                'high'
            );
        }

Now, within the overall function, I then try to get the detail and save it:

function display_tours_price_meta_box() {
            global $post;
            // Noncename needed to verify where the data originated
            echo '<input type="hidden" name="tourmeta_noncename" id="tourmeta_noncename" value="' . 
            wp_create_nonce( plugin_basename(__FILE__) ) . '" />';

            // Get the price data if its already been entered
            $price = get_post_meta($post->ID, '_price', true);
            echo 'Add the total cost for this tour here, do not include monetary characters like £ or $';
            echo '<input type="text" name="_price" ' . $price  . '" class="widefat" />';
        }
        function save_tours_meta($tour_id, $tour) {
            if ( !wp_verify_nonce( $_POST['tourmeta_noncename'], plugin_basename(__FILE__) )) {
            return $post->ID;
            }
            // Is the user allowed to edit the post or page?
            if ( !current_user_can( 'edit_post', $post->ID ))
                return $post->ID;

            $tour_meta['_price'] = $_POST['_price'];

            // Add values of $tour_meta as custom fields
            foreach ($tour_meta as $key => $value) {
                if( $post->post_type == 'revision' ) return;
                $value = implode(',', (array)$value);
                if(get_post_meta($post->ID, $key, FALSE)) {
                    update_post_meta($post->ID, $key, $value);
                } else {
                    add_post_meta($post->ID, $key, $value);
                }
                if(!$value) delete_post_meta($post->ID, $key);
            }
        }
        add_action('save_post', 'save_tours_meta', 1, 2);

The actual box appears, and the information is echo'd. However it does not save. I haven't the foggiest why. It must pertain to my last function, but I don't understand what is going wrong.

Thanks

Was it helpful?

Solution

You should better simplify your saving process like this :

    function save_tours_meta($post_id) {
        if ( !wp_verify_nonce( $_POST['tourmeta_noncename'], plugin_basename(__FILE__) ))       {
        // You don't need to return anything
        return;
        }
        // Is the user allowed to edit the post or page?
        if ( !current_user_can( 'edit_post', $post_id ) && !isset($_POST['_price']))
            return;

        // If you just have 1 value
        update_post_meta($post_id, '_price', $_POST['_price']);
    }

Just notice that the update_post_meta function will update the post meta or create it if it doesn't exist so don't bother usind add_post_meta.

OTHER TIPS

I think it's your arguments. You declare the function as

function save_tours_meta($tour_id, $tour) {

but you're using (eg) $post->ID. $post in this case isn't the global variable, but the function argument. Try using $tour->ID or just $tour_id instead.

A couple of other (unrelated) things:

  1. You can call update_post_meta() and it'll add the key if it doesn't exist, so you can remove your if statement (just reducing the lines of code).
  2. Your "revision" check should return the post ID (and can be moved outside your loop)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top