Question

I am creating a metabox that loops through all the posts of another CPT: 'product'. The metabox lists all the published products in that CPT, puts them in a table row along with an input box. Each input box has a unique ID based off of the CPT product id.

Most of this code I have added based on other posts, but I am having a problem saving the data. I know that it has to do with my value="", my nonce, and $meta_value, but I am not sure where to go next. Below is the code I have so far:

<?php
add_action('admin_init', 'my_theme_on_admin_init');

function my_theme_on_admin_init() {
    add_meta_box('my_metabox',
    __('Daily Inventory Levels', 'textdomain'),
    'my_metabox_render',
    'location_inventory', 'normal', 'high'
    );
}

function my_metabox_render($post) {
    // using an underscore, prevents the meta variable
    // from showing up in the custom fields section
    global $woocommerce, $post;
    $productsList = new WP_Query( 'post_type=product&post_status=publish');
?>
<div class="inside">
<table class="form-table">
    <input type="hidden" name="inventory_noncename" id="inventory_noncename" value="<?php wp_create_nonce( 'inventory-nonce' ); ?>" />
<?php 
    while ( $productsList->have_posts() ) {
    $productsList->the_post(); 
?>
<tr><td><label for="location_inventory_product-<?php the_ID(); ?>"><?php the_title(); ?></label></td><td><input id="location_inventory_product-<?php the_ID(); ?>" name="location_inventory_product-<?php the_ID(); ?>" cols="40" rows="5" value="<?php echo $meta_key; ?>" /></td></tr>
<?php }
    wp_reset_postdata();
?>
</table>
</div>
<?php
}


/*update on save*/
add_action('save_post', 'save_postdata_dynamic_inventory_metabox' );  
function save_postdata_dynamic_inventory_metabox( $post_id ) {
    // verify if this is an auto save routine.
    // If it is our form has not been submitted, so we dont want to do anything
    if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) {
        return;
    }

    // Check permissions
    if ( 'location_inventory' == $_POST['post_type'] ) { 
        if ( !current_user_can( 'edit_page', $post_id )) { 
            return $post_id; 
        }
    }
    elseif ( !current_user_can( 'edit_post', $post_id )) { 
        return $post_id;
    }

    // verify this came from the our screen and with proper authorization,
    // because save_post can be triggered at other times
    if (isset($_POST['inventory_noncename'])){
            if ( !wp_verify_nonce( $_POST['inventory_noncename'], 'inventory-nonce' ) )
            return;
    } else {
            return;
    }

    // Get the posted data and sanitize it for use as an HTML class.
    $new_meta_value = ( isset( $_POST['location_inventory_product-'.the_ID().''] ) ? sanitize_html_class( $_POST['location_inventory_product-'.the_ID().''] ) : '' );

    // Get the meta key.
    $meta_key = 'location_inventory_product-'.the_ID().'';

    // Get the meta value of the custom field key.
    $meta_value = get_post_meta( $post_id, $meta_key, true );

    // If a new meta value was added and there was no previous value, add it.
    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 );

} // ends function save_postdata_dynamic_reviews_metabox
Était-ce utile?

La solution

Some observations:

1) The hook save_post takes 2 arguments:

add_action( 'save_post', 'save_postdata_dynamic_inventory_metabox', 10, 2 );  

function save_postdata_dynamic_inventory_metabox( $post_id, $post_object ) { }

2) I don't think checking for permissions is necessary (at least, never seen it). Just in case, this is an example of the post_object use:

if ( 'location_inventory' == $post_object->post_type )

3) Short this check:

if ( !isset($_POST['inventory_noncename']) || !wp_verify_nonce( $_POST['inventory_noncename'], 'inventory-nonce' ) )
    return;

4) The use of the_ID() inside the function save_postdata_dynamic_inventory_metabox is wrong. This is only available inside a Loop and you already have $post_id at hand.

5) Finally, and the most important, the way you're handling the $meta_key is wrong. For one, it's not defined inside the function my_metabox_render. Check this Answer for a working example.

Research in this search query to find more examples.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top