Why won’t my metabox data save?

Following are the issues that were preventing from the meta values to be saved in both of your save functions.

1. Incorrect post_type checking.
You are checking post type to be of ‘page’ in your save function where as your meta boxes are being displayed on your custom post type of ‘film’.

Your code:

if ( 'page' == $_POST['post_type'] ) { if ( !current_user_can( 'edit_page', $post_id )) { return $post_id; }}

It should be:

if ( 'film' == $_POST['post_type'] ) { if ( !current_user_can( 'edit_page', $post_id )) { return $post_id; }}

2. Incorrect nonce field name.
As @tollmanz pointed out you are checking incorrect field names when checking nonces. The field name in save functions should match the input field name in print meta box functions.

Your code:

if (isset($_POST['reviews-nonce'])){
    if ( !wp_verify_nonce( $_POST['reviews-nonce'], 'reviews-nonce' ) )
        return;
}else{return;}

It should be:

if (isset($_POST['reviews_noncename'])){
    if ( !wp_verify_nonce( $_POST['reviews_noncename'], 'reviews-nonce' ) )
        return;
}else{return;}

For screening nonce your code:

if (isset($_POST['screenings-nonce'])){
    if ( !wp_verify_nonce( $_POST['screenings-nonce'], 'screenings-nonce' ) )
        return;
}else{return;}

It should be:

if (isset($_POST['screenings_noncename'])){
    if ( !wp_verify_nonce( $_POST['screenings_noncename'], 'screenings-nonce' ) )
        return;
}else{return;}

3. Incorrectly saving the meta values.
You were using update_post_meta to store the meta values.

4. Inoccrectly getting meta values.
You were using third parameter in your get_post_meta calls which is to specify to only fetch single meta value, were in your case you need to fetch all meta values.

Your code:

$reviews = get_post_meta($post->ID,'reviews',true); //get any previously saved meta as an array so we can display it

It should be:

$reviews = get_post_meta($post->ID,'reviews'); //get any previously saved meta as an array so we can display it

Your code for screenings:

$reviews = get_post_meta($post->ID,'screenings',true); //get any previously saved meta as an array so we can display it

It should be:

$reviews = get_post_meta($post->ID,'screenings',true); //get any previously saved meta as an array so we can display it

Below is the correct code. The code below should work for you as I have tested it and it worked fine. If it doesn’t work for some reason I will need to look at your complete code.

add_action('save_post', 'save_postdata_dynamic_reviews_metabox' );  
add_meta_box("film-reviews", "Reviews", "print_dynamic_reviews_metabox", "film", "normal", "low");

add_action('save_post', 'save_postdata_dynamic_screenings_metabox' );
add_meta_box("film-screenings", "Reviews", "print_dynamic_screenings_metabox", "film", "normal", "low");
/* Prints the box content */
function print_dynamic_reviews_metabox() {
    global $post;
    // Use nonce for verification

        echo '<input type="hidden" name="reviews_noncename" id="reviews_noncename" value="' . wp_create_nonce( 'reviews-nonce' ) . '" />';
        echo '<div id="meta_inner-reviews">';
        echo '<ol id="reviews-meta">';
    $reviews = get_post_meta($post->ID,'reviews'); //get any previously saved meta as an array so we can display it
    // print_r($reviews);
    $c = 0;
    if( is_array($reviews) ) {
      foreach($reviews as $review ) {
                if (isset($review['review-name']) || isset($review['review-link']) ) {
          echo '
                        <li><span class="remove-review" title="Delete">Remove</span>
                       <label><strong>Review Name/Title:</strong> <input type="text" class="meta-review-name saveddata" name="reviews['.$c.'][review-name]" value="'.$review['review-name'].'" /></label>
                         <label><strong>Review URL:</strong> (don\'t forget the http://) <input type="text" class="meta-review-url saveddata" name="reviews['.$c.'][review-url]" value="'.$review['review-url'].'" /></label>';
                    echo '<span class="remove-review" title="Delete">Remove</span></li>';
          $c = $c +1;
          } // ends if isset $award[album]
        } // ends foreach
            } // ends if (is_array)
        echo '</ol>';
    echo '<span class="add-review">Add New Review</span>';
        ?>
            <script>
                var $ =jQuery.noConflict();
                $(document).ready(function() {
                    var count = <?php echo $c; ?>;
                    $(".add-review").click(function() {
                        count = count + 1;
                        $('#reviews-meta').append('<li><span class="remove-review" title="Delete">Remove</span> <label><strong>Review Name/Title:</strong> <input type="text" class="meta-review-name" name="reviews['+count+'][review-name]" value="" /></label> <label><strong>Review URL:</strong> (don\'t forget the http://) <input type="text" class="meta-review-url" name="reviews['+count+'][review-url]" value="" /></label></li> <span class="remove-review" title="Delete">Remove</span>');
                        return false;
                    });
                    $(".remove-review").live('click', function() {
                        $(this).parent().remove();
                    });
                });
              </script>

     <?php
     echo '</div>'; // ends div#meta_inner
} // ends function print_dynamic_reviews_metabox()


function save_postdata_dynamic_reviews_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 ( 'film' == $_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['reviews_noncename'])){
        if ( !wp_verify_nonce( $_POST['reviews_noncename'], 'reviews-nonce' ) )
            return;
    }else{return;}

    delete_post_meta( $post_id, 'reviews' );
    // OK, we're authenticated: we need to find and save the data
    $reviews = $_POST['reviews'];
    foreach ( $reviews as $review ) {
        add_post_meta($post_id,'reviews',$review);
    }
} // ends function save_postdata_dynamic_reviews_metabox


/* Prints the box content */
function print_dynamic_screenings_metabox() {
global $post;
// Use nonce for verification

    echo '<input type="hidden" name="screenings_noncename" id="screenings_noncename" value="' . wp_create_nonce( 'screenings-nonce' ) . '" />';
    echo '<div id="meta_inner-screenings">';
    echo '<ol id="screenings-meta">';
$reviews = get_post_meta($post->ID,'screenings'); //get any previously saved meta as an array so we can display it
// print_r($reviews);
$c = 0;
if( is_array($screenings) ) {
  foreach($screenings as $screening ) {
            if (isset($screening['screening-festival-name']) || isset($screening['screening-festival-date']) ) {
      echo '
                    <li><span class="remove-screening" title="Delete">Remove</span>
                   <label><strong>Festival Name:</strong> <input type="text" class="meta-screening-festival-name saveddata" name="screenings['.$c.'][screening-festival-name]" value="'.$screening['screening-festival-name'].'" /></label>
                     <label><strong>Festival Date:</strong> <input type="text" class="meta-screening-festival-date saveddata" name="screenings['.$c.'][screening-festival-date]" value="'.$screening['screening-festival-date'].'" /></label>';
                echo '<span class="remove-screening" title="Delete">Remove</span></li>';
      $c = $c +1;
      } // ends if isset $award[album]
    } // ends foreach
        } // ends if (is_array)
    echo '</ol>';
echo '<span class="add-screening">Add New Screening</span>';
    ?>
        <script>
            var $ =jQuery.noConflict();
            $(document).ready(function() {
                var count = <?php echo $c; ?>;
                $(".add-screening").click(function() {
                    count = count + 1;
                    $('#screenings-meta').append('<li><span class="remove-screening" title="Delete">Remove</span> <label><strong>Festival Name:</strong> <input type="text" class="meta-screening-festival-name" name="screenings['+count+'][screening-festival-name]" value="" /></label> <label><strong>Festival Date:</strong> <input type="text" class="meta-screening-festival-date" name="screenings['+count+'][screening-festival-date]" value="" /></label> <span class="remove-screening" title="Delete">Remove</span>');
                    return false;
                });
                $(".remove-screening").live('click', function() {
                    $(this).parent().remove();
                });
            });
          </script>

 <?php
 echo '</div>'; // ends div#meta_inner
} // ends function print_dynamic_screenings_metabox()


function save_postdata_dynamic_screenings_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 ( 'film' == $_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['screenings_noncename'])){
        if ( !wp_verify_nonce( $_POST['screenings_noncename'], 'screenings-nonce' ) )
            return;
    }else{return;}

    delete_post_meta( $post_id, 'screenings' );
    // OK, we're authenticated: we need to find and save the data
    $screenings = $_POST['screenings'];
    foreach ( $screenings as $screening ) {
        add_post_meta($post_id,'screenings',$screening);
    }
} // ends function save_postdata_dynamic_reviews_metabox

Leave a Comment