Reputation: 5240
SETUP
I wrote a piece of code in which I created a custom post type and a meta box with aditional information for my custom post type called portfolio. This meta box contains 3 fields, a link field, date field and expertise field, which are stored and saved with that custom post type.
PROBLEM
This whole setup works completely fine when I update my portfolio items (no errors), but as soon as i start to add things in other post types, such as pages, messages and other post types i have defined. I have errors and notices appear everywhere, since it tries to assign the meta box to these post items as well. Although I thought i specificly assigned the Meta Box only to the post type called portfolio, i am affraid i made an error somewhere. See the code.
So when I load up a different posttype i get the notice that it has an undefined index
Notice: Undefined index: dbt_website-link in /home/jellyf1q/public_html/test/webfanatics/wp/wp-content/themes/thewebfanatics/cpt/portfolio.php on line 161
When I save it however, I get a whole lot of errors in one time. Besides the notices, i do get also information has been send to the headers error.
Notice: Undefined index: dbt_website-link in /home/jellyf1q/public_html/test/webfanatics/wp/wp-content/themes/thewebfanatics/cpt/portfolio.php on line 161
Notice: Undefined index: dbt_opleverdatum in /home/jellyf1q/public_html/test/webfanatics/wp/wp-content/themes/thewebfanatics/cpt/portfolio.php on line 161
Notice: Undefined index: dbt_text in /home/jellyf1q/public_html/test/webfanatics/wp/wp-content/themes/thewebfanatics/cpt/portfolio.php on line 161
Warning: Cannot modify header information - headers already sent by (output started at /home/jellyf1q/public_html/test/webfanatics/wp/wp-content/themes/thewebfanatics/cpt/portfolio.php:161) in /home/jellyf1q/public_html/test/webfanatics/wp/wp-admin/post.php on line 197
Warning: Cannot modify header information - headers already sent by (output started at /home/jellyf1q/public_html/test/webfanatics/wp/wp-content/themes/thewebfanatics/cpt/portfolio.php:161) in /home/jellyf1q/public_html/test/webfanatics/wp/wp-includes/pluggable.php on line 1228
ASSUMPTION
With a bit of deduction i figured this has to do with the meta box trying to be applied to all post types. I yet have no clue how to solve this, since I told it already in the code to only use the post type portfolio as I followed the instructions on this tutorial. It does actually follow that instruction, since the custom meta box is only applied to the portfolio CPT, yet something happens in the code what makes it seek for the index of the post variable of the metabox fields.
CODE
I supplied the code under here for the metabox. As you see in the metabox array on line 5, i tell it to assign to the post type portfolio
$prefix = 'dbt_';
$meta_box = array(
'id' => 'meta-portfolio',
'title' => 'Overige informatie',
'page' => 'portfolio',
'context' => 'normal',
'priority' => 'high',
'fields' => array(
array(
'name' => 'Website link',
'desc' => 'De link naar het portfolio item bij onze klant',
'id' => $prefix . 'website-link',
'type' => 'text',
'std' => 'http://'
),
array(
'name' => 'Opleverdatum',
'desc' => 'De opleverdatum van het project',
'id' => $prefix . 'opleverdatum',
'type' => 'text',
'std' => 'dd/mm/yyyy'
),
array(
'name' => 'Expertise',
'desc' => 'De Expertise die is gebruikt binnen het project',
'id' => $prefix . 'text',
'type' => 'text',
'std' => 'Expertise'
)
)
);
add_action('admin_menu', 'portfolio_add_box');
// Add meta box
function portfolio_add_box() {
global $meta_box;
add_meta_box($meta_box['id'], $meta_box['title'], 'portfolio_show_box', $meta_box['page'], $meta_box['context'], $meta_box['priority']);
}
// Callback function to show fields in meta box
function portfolio_show_box() {
global $meta_box, $post;
// Use nonce for verification
echo '<input type="hidden" name="portfolio_meta_box_nonce" value="', wp_create_nonce(basename(__FILE__)), '" />';
echo '<table class="form-table">';
foreach ($meta_box['fields'] as $field) {
// get current post meta data
$meta = get_post_meta($post->ID, $field['id'], true);
echo '<tr>',
'<th style="width:20%"><label for="', $field['id'], '">', $field['name'], '</label></th>',
'<td>';
switch ($field['type']) {
case 'text':
echo '<input type="text" name="', $field['id'], '" id="', $field['id'], '" value="', $meta ? $meta : $field['std'], '" size="30" style="width:97%" />', '<br />', $field['desc'];
break;
case 'textarea':
echo '<textarea name="', $field['id'], '" id="', $field['id'], '" cols="60" rows="4" style="width:97%">', $meta ? $meta : $field['std'], '</textarea>', '<br />', $field['desc'];
break;
case 'select':
echo '<select name="', $field['id'], '" id="', $field['id'], '">';
foreach ($field['options'] as $option) {
echo '<option ', $meta == $option ? ' selected="selected"' : '', '>', $option, '</option>';
}
echo '</select>';
break;
case 'radio':
foreach ($field['options'] as $option) {
echo '<input type="radio" name="', $field['id'], '" value="', $option['value'], '"', $meta == $option['value'] ? ' checked="checked"' : '', ' />', $option['name'];
}
break;
case 'checkbox':
echo '<input type="checkbox" name="', $field['id'], '" id="', $field['id'], '"', $meta ? ' checked="checked"' : '', ' />';
break;
}
echo '</td><td>',
'</td></tr>';
}
echo '</table>';
}
add_action('save_post', 'portfolio_save_data');
// Save data from meta box
function portfolio_save_data($post_id) {
global $meta_box;
// verify nonce
if (isset($_POST['portfolio_meta_box_nonce']) && !wp_verify_nonce($_POST['portfolio_meta_box_nonce'], basename(__FILE__))) {
return $post_id;
}
// check autosave
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return $post_id;
}
// check permissions
if ('page' == $_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;
}
foreach ($meta_box['fields'] as $field) {
$old = get_post_meta($post_id, $field['id'], true);
$new = $_POST[$field['id']];
if ($new && $new != $old) {
update_post_meta($post_id, $field['id'], $new);
} elseif ('' == $new && $old) {
delete_post_meta($post_id, $field['id'], $old);
}
}
}
?>
the code for the custom post type is as following.
add_action('init', 'portfolio_register');
function portfolio_register() {
$labels = array(
'name' => _x('portfolio', 'post type general name'),
'singular_name' => _x('portfolio', 'post type singular name'),
'add_new' => _x('Nieuw', 'portfolio'),
'add_new_item' => __('Nieuw portfolio'),
'edit_item' => __('Edit portfolio'),
'new_item' => __('Nieuw portfolio'),
'view_item' => __('View portfolio'),
'search_items' => __('Search portfolio'),
'not_found' => __('Nothing found'),
'not_found_in_trash' => __('Nothing found in Trash'),
'parent_item_colon' => ''
);
$args = array(
'labels' => $labels,
'public' => true,
'has_archive' => true,
'publicly_queryable' => true,
'show_ui' => true,
'query_var' => true,
'menu_icon' => null,
'rewrite' => array(
'slug' => 'portfolio',
'with_front' => false,
'hierarchical' => true),
'capability_type' => 'post',
'hierarchical' => false,
'menu_position' => null,
'supports' => array('title','editor','thumbnail'),
'menu_icon' => 'dashicons-format-image',
'taxonomies' => array('post_tag')
);
register_post_type( 'portfolio' , $args );
}
Line 161 is refer to this piece of code in the meta box.
foreach ($meta_box['fields'] as $field) {
$old = get_post_meta($post_id, $field['id'], true);
$new = $_POST[$field['id']];
if ($new && $new != $old) {
update_post_meta($post_id, $field['id'], $new);
} elseif ('' == $new && $old) {
delete_post_meta($post_id, $field['id'], $old);
}
}
Upvotes: 0
Views: 705
Reputation: 1477
This hook add_action('save_post', 'portfolio_save_data');
is for saving all posts, pages and custom_post_types, not only for CPT.
So when you add new regular post, for instance, this functions runs also, but there have no metaboxes and such things, somethimes there even no $_POST
.
In your function portfolio_save_data
before check permisions you can do this check:
if ( 'portfolio' !== get_post_type() ) {
return $post_id;
}
So your save runs only in your CPT, otherwise let WP do its things.
Like I mentioned above sometimes sometimes there is no such key 'post_type'
in $_POST, so you can change this line for checking permissions:
if ( isset($_POST['post_type']) && 'page' == $_POST['post_type'])
And last thing, acording to Codex, is better to hook in add_meta_boxes
when you regiter your metaboxes with portfolio_add_box
.
Upvotes: 3