问题
I have quite a complex problem to solve which has baffled me for the last day or so.
Basically, I have two custom post types 'Sessions' and 'Recipes'. These are showing fine in the backend of WordPress.
Attached to the session are several meta boxes, 'Introduction Video', 'Session video', 'Goals', 'Fitness Level' and 'Featured Recipes'.
The 'Featured Recipes' meta box is special, as in it queries the WordPress database to get all posts within the 'recipe' custom post type and then use these values to populate a select box.
Now as you can see from the screen shot attached, the select box for the recipe custom post type is pulling through the correct items and ID's, and it also saves the data and pulls back the correct selection and associates it with the correct post ID for the 'session' post type. Great!
The problem arises with the other fields within the post, they seem to be using the first recipe ID as the value for pulling through the data for each field, rather than the 'session' custom post type ID.
Now I can get this to work by writing various while loops based on specific query arguments but that creates another issue. The data is saved in the correct place but it uses the first 'session' cpt ID to pull back the data for all posts.
Now, I believe it is something to do with the 'recipe' meta box creation, as as soon as you remove this function and it's related functions from the functions.php file, everything works as it should.
I think I should be using for loops instead of while loops, I'm going to try this now.
Hopefully some of you PHP gurus out there will be able to point me in the right direction. I've included both my functions.php file and a screen shot from the admin. Cheers.
<?php
add_action( 'init', 'tfp_session_cpt' );
function tfp_session_cpt() {
register_post_type( 'session',
array(
'labels' => array(
'name' => __( 'Sessions' ),
'singular_name' => __( 'Session' )
),
'public' => true,
'has_archive' => true,
)
);
}
add_action( 'init', 'tfp_recipe_cpt' );
function tfp_recipe_cpt() {
register_post_type( 'recipe',
array(
'labels' => array(
'name' => __( 'Recipes' ),
'singular_name' => __( 'Recipe' )
),
'public' => true,
'has_archive' => true,
)
);
}
/*add_action( 'init', 'tfp_tip_cpt' );
function tfp_tip_cpt() {
register_post_type( 'tip',
array(
'labels' => array(
'name' => __( 'Tips' ),
'singular_name' => __( 'Tip' )
),
'public' => true,
'has_archive' => true,
)
);
}*/
add_action( 'add_meta_boxes', 'tfp_add_introduction_video' );
add_action( 'add_meta_boxes', 'tfp_add_session_video' );
add_action( 'add_meta_boxes', 'tfp_add_goals' );
add_action( 'add_meta_boxes', 'tfp_add_levels' );
add_action( 'add_meta_boxes', 'tfp_add_recipes' );
/*add_action( 'add_meta_boxes', 'tfp_add_tips' );*/
add_action( 'save_post', 'tfp_save_introduction_video');
add_action( 'save_post', 'tfp_save_session_video');
add_action( 'save_post', 'tfp_save_goals');
add_action( 'save_post', 'tfp_save_levels');
add_action( 'save_post', 'tfp_save_recipes');
/*add_action( 'save_post', 'tfp_save_tips');*/
function tfp_add_introduction_video() {
add_meta_box('tfp_introduction_video', 'Introduction Video', 'tfp_introduction_video_html', 'session');
}
function tfp_add_session_video() {
add_meta_box('tfp_session_video', 'Session Video', 'tfp_session_video_html', 'session');
}
function tfp_add_goals() {
$types = array ('session');
foreach ($types as $type) {
add_meta_box('tfp_goals', 'Goals', 'tfp_goals_html', $type);
}
}
function tfp_add_levels() {
add_meta_box('tfp_levels', 'Fitness Levels', 'tfp_levels_html', 'session');
}
function tfp_add_recipes() {
add_meta_box('tfp_recipes', 'Select a Featured Recipe', 'tfp_recipes_html', 'session', 'side');
}
function tfp_add_tips() {
add_meta_box('tfp_tips', 'Tips', 'tfp_tips_html', 'session', 'side');
}
function tfp_introduction_video_html($post) {
// Nonce field for some validation
wp_nonce_field( plugin_basename( __FILE__ ), 'session' );
global $post;
$introductionVideo = get_post_meta( $postID, 'introduction_video_embed_code', true );
echo $post->ID;
?>
<label for="introduction_video_embed_code">YouTube Embed Code</label>
<textarea class="large-text code" id="introduction_video_embed_code" name="introduction_video_embed_code" value="<?php echo $introductionVideo; ?>"><?php echo get_post_meta( $post->ID, 'introduction_video_embed_code', true ); ?></textarea>
<?php }
function tfp_session_video_html($post) {
// Nonce field for some validation
wp_nonce_field( plugin_basename( __FILE__ ), 'session' );
global $post;
$sessionVideo = get_post_meta( $post->ID, 'session_video_embed_code', true ); ?>
<?php echo $post->ID; ?>
<label for="session_video_embed_code">YouTube Embed Code</label>
<textarea class="large-text code" id="session_video_embed_code" name="session_video_embed_code" value="<?php echo $sessionVideo; ?>"><?php echo $sessionVideo; ?></textarea>
<?php }
function tfp_goals_html($post) {
// Nonce field for some validation
wp_nonce_field( plugin_basename( __FILE__ ), 'session' );
$goals = get_post_meta( $post->ID, 'goals', true ); ?>
<?php echo $post->ID; ?>
<label for="weight_loss">
<input type="checkbox" name="goal[]" id="weight_loss" value="Weight Loss" <?php if (in_array('Weight Loss', $goals)) echo "checked='checked'"; ?> />
<?php _e("Weight Loss"); ?>
</label>
<br />
<label for="improve_fitness">
<input type="checkbox" name="goal[]" id="improve_fitness" value="Improve Fitness" <?php if (in_array('Improve Fitness', $goals)) echo "checked='checked'"; ?> />
<?php _e("Improve Fitness"); ?>
</label>
<br />
<label for="improve_health">
<input type="checkbox" name="goal[]" id="improve_health" value="Improve Health" <?php if (in_array('Improve Health', $goals)) echo "checked='checked'"; ?> />
<?php _e("Improve Health"); ?>
</label>
<br />
<?php }
function tfp_levels_html($post) {
// Nonce field for some validation
wp_nonce_field( plugin_basename( __FILE__ ), 'session' );
$levels = get_post_meta( $post->ID, 'levels', true ); ?>
<?php echo $post->ID; ?>
<label for="beginner">
<input type="checkbox" name="level[]" id="beginner" value="Beginner" <?php if (in_array('Beginner', $levels)) echo "checked='checked'"; ?> />
<?php _e("Beginner"); ?>
</label>
<br />
<label for="advanced">
<input type="checkbox" name="level[]" id="advanced" value="Advanced" <?php if (in_array('Advanced', $levels)) echo "checked='checked'"; ?> />
<?php _e("Advanced"); ?>
</label>
<br />
<?php }
function tfp_recipes_html($post) {
// Nonce field for some validation
wp_nonce_field( plugin_basename( __FILE__ ), 'session' );
global $post;
$recipes = get_post_meta( $post->ID, 'recipe_name', true );
$recipeArgs = array(
'post_type' => 'recipe'
);
$recipeQuery = new WP_Query($recipeArgs); ?>
<?php echo $post->ID; ?>
<select name="recipe_names" id="recipes">
<option value="null">Select a Featured Recipe</option>
<?php while ( $recipeQuery->have_posts() ) : $recipeQuery->the_post(); ?>
<option id="<?php echo $post->ID; ?>" value="<?php the_title(); ?>" <?php $title = get_the_title(); if($recipes == $title) echo "selected='selected'";?>><?php the_title(); ?></option>
<?php endwhile; ?>
</select>
<?php }
/*function tfp_tips_html($post) {
// Nonce field for some validation
wp_nonce_field( plugin_basename( __FILE__ ), 'session' );
global $post;
$tipArgs = array(
'post_type' => 'tip'
);
$tipQuery = new WP_Query($tipArgs); ?>
<?php echo $post->ID; ?>
<?php while ( $tipQuery->have_posts() ) : $tipQuery->the_post();
$tipID = 'tip_' . $post->ID;
$tips = get_post_meta( $post->ID, $tipID, true );?>
<?php echo $tipID; ?>
<label for="<?php echo $tipID; ?>">
<input type="checkbox" name="<?php echo $tipID; ?>" id="<?php echo $tipID; ?>" value="1" <?php if ($tips == 1) echo "checked='checked'"; ?> />
<?php the_title(); ?>
</label>
<br />
<?php endwhile;
}*/
function tfp_save_introduction_video($post_id) {
if ( !current_user_can( 'edit_post', $post_id ) ) { return false; }
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return $post_id;
}
update_post_meta($post_id, 'introduction_video_embed_code', $_POST['introduction_video_embed_code']);
}
function tfp_save_session_video($post_id) {
if ( !current_user_can( 'edit_post', $post_id ) ) { return false; }
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return $post_id;
}
update_post_meta($post_id, 'session_video_embed_code', $_POST['session_video_embed_code']);
}
function tfp_save_goals($post_id) {
if ( !current_user_can( 'edit_post', $post_id ) ) { return false; }
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return $post_id;
}
update_post_meta($post_id, 'goals', $_POST['goal']);
}
function tfp_save_levels($post_id) {
if ( !current_user_can( 'edit_post', $post_id ) ) { return false; }
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return $post_id;
}
update_post_meta($post_id, 'levels', $_POST['level']);
}
function tfp_save_recipes($post_id) {
if ( !current_user_can( 'edit_post', $post_id ) ) { return false; }
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return $post_id;
}
update_post_meta($post_id, 'recipe_name', $_POST['recipe_names']);
}
/*function tfp_save_tips($post) {
if ( !current_user_can( 'edit_post', $post_id ) ) { return false; }
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return $post_id;
}
if ( ! wp_verify_nonce( $_POST['custom_post_type'], plugin_basename(__FILE__) ) ) return;
global $post;
$tipArgs = array(
'post_type' => 'tip'
);
$tipQuery = new WP_Query($tipArgs);
while ( $tipQuery->have_posts() ) : $tipQuery->the_post();
$tipID = 'tip_' . $post->ID;
update_post_meta($post->ID, $tipID, $_POST[$tipID]);
endwhile;
}*/
// Extra user profile fields, specifically goal and fitness level checkboxes and radio buttons
add_action( 'show_user_profile', 'gaf_user_profile_fields' );
add_action( 'edit_user_profile', 'gaf_user_profile_fields' );
// Function to generate field HTML
function gaf_user_profile_fields( $user ) { ?>
<h3><?php _e("Goals and Fiteness Level", "blank"); ?></h3>
<table class="form-table">
<tr>
<th scope="row"><?php _e("Goals"); ?></th>
<td>
<fieldset>
<legend class="screen-reader-text">
<span><?php _e("Goals"); ?></span>
</legend>
<?php $single = true; ?>
<?php $goals = get_user_meta( $user->ID, 'goals', $single ); ?>
<label for="weight_loss">
<input type="checkbox" name="goal[]" id="weight_loss" value="Weight Loss" <?php if (in_array('Weight Loss', $goals)) echo "checked='checked'"; ?> />
<?php _e("Weight Loss"); ?>
</label>
<br />
<label for="improve_fitness">
<input type="checkbox" name="goal[]" id="improve_fitness" value="Improve Fitness" <?php if (in_array('Improve Fitness', $goals)) echo "checked='checked'"; ?> />
<?php _e("Improve Fitness"); ?>
</label>
<br />
<label for="improve_health">
<input type="checkbox" name="goal[]" id="improve_health" value="Improve Health" <?php if (in_array('Improve Health', $goals)) echo "checked='checked'"; ?> />
<?php _e("Improve Health"); ?>
</label>
<br />
</fieldset>
</td>
</tr>
<tr>
<?php $fitnessLevel = get_the_author_meta('fitness_level', $user->ID); ?>
<th scope="row"><?php _e("Fitness Level"); ?></th>
<td>
<fieldset>
<legend class="screen-reader-text">
<span><?php _e("Fitness Level"); ?></span>
</legend>
<input class="tog" type="radio" name="fitness_level" value="beginner" <?php if ($fitnessLevel == 'beginner') { ?>checked="checked"<?php } ?> /><label>Beginner</label>
<br />
<input class="tog" type="radio" name="fitness_level" value="advanced" <?php if ($fitnessLevel == 'advanced') { ?>checked="checked"<?php } ?> /><label>Advanced</label>
<br />
</fieldset>
</td>
</tr>
</table>
<?php }
// Function and actions to save the data from the fields
add_action( 'personal_options_update', 'save_gaf_user_profile_fields' );
add_action( 'edit_user_profile_update', 'save_gaf_user_profile_fields' );
function save_gaf_user_profile_fields( $user_id ) {
if ( !current_user_can( 'edit_user', $user_id ) ) { return false; }
update_user_meta( $user_id, 'goals', $_POST['goal'] );
update_user_meta( $user_id, 'fitness_level', $_POST['fitness_level'] );
}
?>
[EDIT]
I'm certainly getting closer with this function but it's not quite right as it's pulling through the same title.
function tfp_recipes_html($post) {
// Nonce field for some validation
wp_nonce_field( plugin_basename( __FILE__ ), 'session' );
$recipeArgs = array(
'post_type' => 'recipe'
);
$recipeQuery = get_posts($recipeArgs);
$recipeName = get_post_meta( $post->ID, 'recipe_name', true );
$recipeTitle[] = get_query_var('name');
echo $recipeTitle;
?>
<select name="recipe_names" id="recipes">
<option value="null">Select a Featured Recipe</option>
<?php foreach ( $recipeQuery as $recipe ) : setup_postdata($recipeQuery); ?>
<option id="<?php echo $recipe->ID; ?>" value="<?php echo $recipeTitle; ?>" <?php if($recipeName == $recipeTitle) echo "selected='selected'";?>><?php echo $recipeName; ?></option>
<?php endforeach; ?>
</select>
<?php }
回答1:
OK Guys, I solved my issue using the following function.
function tfp_recipes_html($post) {
// Nonce field for some validation
wp_nonce_field( plugin_basename( __FILE__ ), 'session' );
global $post;
$recipeArgs = array(
'post_type' => 'recipe'
);
$recipes = get_posts($recipeArgs);
$recipeName = get_post_meta( $post->ID, 'recipe_name', true );
?>
<select name="recipe_names" id="recipes">
<option value="null">Select a Featured Recipe</option>
<?php foreach ( $recipes as $recipe ) : setup_postdata($recipe); ?>
<option id="<?php echo $recipe->ID; ?>" value="<?php $recipeTitle = $recipe->post_title; echo $recipeTitle; ?>" <?php if($recipeName == $recipeTitle) echo "selected='selected'";?>><?php echo $recipeTitle; ?></option>
<?php endforeach; ?>
</select>
<?php }
Though now I'm having another issue saving another custom metabox. The function to add the metabox is:
function tfp_tips_html($post) {
// Nonce field for some validation
wp_nonce_field( plugin_basename( __FILE__ ), 'session' );
global $post;
echo $post->ID;
$tipArgs = array(
'post_type' => 'tip'
);
$tips = get_posts($tipArgs);
$tipData = get_post_meta( $post->ID, $tipID, true );
foreach ( $tips as $tip ) : setup_postdata($tip);
$tipID = 'tip_' . $tip->ID; ?>
<label for="<?php echo $tipID; ?>">
<input type="checkbox" name="<?php echo $tipID; ?>" id="<?php echo $tipID; ?>" value="1" <?php if ($tipData == 1) echo "checked='checked'"; ?> />
<?php $tipTitle = $tip->post_title; echo $tipTitle; ?>
</label>
<br />
<?php endforeach;
}
Similar to the recipe function except this adds checkboxes each with a specific ID. Now the function to save it is:
function tfp_save_tips($post_id) {
if ( !current_user_can( 'edit_post', $post_id ) ) { return false; }
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return $post_id;
}
if ( ! wp_verify_nonce( $_POST['custom_post_type'], plugin_basename(__FILE__) ) ) return;
global $tipID;
add_post_meta($post->ID, $tipID, $_POST[$tipID], true) or update_post_meta($post->ID, $tipID, $_POST[$tipID]);
}
The problem is it's not saving the data, and is going to a blank page.
[EDIT]
OK, I have the data saving, as well as the checkboxes being checked correctly when you go back to the post. The only issue is it's posting to a blank page, which is no good. Needs to refresh the editor.
The function 'm now using is:
function tfp_save_tips($post_id) {
if ( !current_user_can( 'edit_post', $post_id ) ) { return false; }
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return $post_id;
}
if ( ! wp_verify_nonce( $_POST['session'], plugin_basename(__FILE__) ) ) return;
$tipArgs = array(
'post_type' => 'tip'
);
$tips = get_posts($tipArgs);
foreach ( $tips as $tip ) : setup_postdata($tip);
$tipID = 'tip_' . $tip->ID;
endforeach;
add_post_meta($post_id, $tipID, $_POST[$tipID], true) or update_post_meta($post_id, $tipID, $_POST[$tipID]);
}
来源:https://stackoverflow.com/questions/12744150/custom-post-type-id-issue-when-querying-other-post-types