Les fonctions de post-sauvegarde sont en conflit lors de leur ajout au hook d’action save_post.
2 types de publication personnalisés avec 2 méta-boîtes personnalisées différentes (une pour chaque type de publication).
J'inclus seulement le code pour l'une des boîtes à méta. L'autre est très similaire et chacun fonctionne bien séparément mais pas ensemble.
function c3m_video_meta() {
add_meta_box('_c3m_video_embed', __('Enter Video Embed Code In the Box Below') , 'c3m_video_embed', 'video', 'normal', 'low');
}
function c3m_video_embed($post) {
global $post;
wp_nonce_field(__FILE__,'video_nonce');
$embed-code = get_post_meta($post->ID, '_embed-code', true);
echo '<input type="text" name="_embed-code" value=""' . $embed-code . '" class="widefat" />' ;
}
function c3m_save_video_meta( $post_id , $post ) {
if ( !wp_verify_nonce( $_POST [ 'video_nonce' ], __FILE__ ) ) { return $post ->ID;
}
if ( !current_user_can( 'edit_post' , $post ->ID )) return $post ->ID;
$c3m_video_embed-code [ '_embed-code' ] = $_POST [ '_embed-code' ];
foreach ( $c3m_video_embed-code 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( 'admin_menu' , 'c3m_video_meta' );
add_action( 'save_post' , 'c3m_save_video_meta' , 1, 2);
C’est très bien et fonctionne bien, mais lorsque j’ajoute une autre méta-boîte à un type de message différent et que j’utilise une fonction similaire (nom de fonction, nom de clé et clé différents) lorsque le message est sauvegardé, j’obtiens cette erreur:
Avis: Index non défini: _embed-code dans /Applications/MAMP/htdocs/wordpress/wp-content/plugins/ieew-custom-functions/ieew-custom-functions.php à la ligne 181
Avertissement: impossible de modifier les informations d'en-tête - en-têtes déjà envoyés par (sortie démarrée à /Applications/MAMP/htdocs/wordpress/wp-content/plugins/ieew-custom-functions/ieew-custom-functions.php:181) dans/Applications/MAMP/htdocs/wordpress/wp-includes/pluggable.php à la ligne 897
Le _embed-code non défini est lors de l'enregistrement de la publication qui ne contient pas la variable _embed-code.
Comme les messages d'erreur sont inversés en fonction du type de message que j'essaie de sauvegarder, cela me porte à croire que les deux (2 différentes) fonctions de sauvegarde sont ajoutées à l'action save_post. Ils sont également ajoutés lors de la sauvegarde d'un message normal. Si je n'utilise que l'une des fonctions de sauvegarde, il n'y a pas d'erreur lors de la sauvegarde d'un message normal.
Plutôt que cette question étant une question "Corriger mon code" , je préférerais que la réponse contienne le comment et le pourquoi d'ajouter des méta-boîtes personnalisées et d'utiliser les différents nonce. méthodes. Bien sûr, je pourrais utiliser le plug-in More Fields, mais je préférerais connaître le meilleur moyen d'accomplir la personnalisation de l'écran de post-édition avec des types de contenu personnalisés.
J'ai utilisé ce même code et cette même méthode pour ajouter plusieurs méta-boîtes à un seul type d'article personnalisé et cela a toujours fonctionné correctement.
Après quelques recherches supplémentaires, j'ai constaté que:
add_meta_box
à admin_menu
, elle devrait être reliée à add_meta_boxes
update_post_meta
dans la fonction de sauvegarde.wp_nonce_field
, les données peuvent être effacées à l'aide de esc_attr
et strip_tags
global $post
sur la fonction de sauvegardeadd_action( 'add_meta_boxes', 'c3m_sponsor_meta' );
function c3m_sponsor_meta() {
add_meta_box( 'c3m_sponsor_url', 'Sponsor URL Metabox', 'c3m_sponsor_url', 'sponsor', 'side', 'high' );
}
function c3m_sponsor_url( $post ) {
$sponsor_url = get_post_meta( $post->ID, '_sponsor_url', true);
echo 'Please enter the sponsors website link below';
?>
<input type="text" name="sponsor_url" value="<?php echo esc_attr( $sponsor_url ); ?>" />
<?php
}
add_action( 'save_post', 'c3m_save_sponsor_meta' );
function c3m_save_sponsor_meta( $post_id ) {
global $post;
if( $post->post_type == "sponsor" ) {
if (isset( $_POST ) ) {
update_post_meta( $post_ID, '_sponsor_url', strip_tags( $_POST['sponsor_url'] ) );
}
}
}
add_action( 'add_meta_boxes', 'c3m_video_meta' );
function c3m_video_meta() {
add_meta_box( 'c3m_video_embed_code', 'Video Embed Code Meta Box', 'c3m_video_embed_code', 'video', 'normal', 'high' );
}
function c3m_video_embed_code( $post ) {
$embed_code = get_post_meta( $post->ID, '_embed_code', true);
echo 'Please enter the video embed code below';
?>
<input type="text" name="embed_code" value="<?php echo esc_attr( $embed_code ); ?>" />
<?php
}
add_action( 'save_post', 'c3m_save_video_meta' );
function c3m_save_video_meta( $post_id ) {
global $post;
if( $post->post_type == "video" ) {
if (isset( $_POST ) ) {
update_post_meta( $post_ID, '_embed_code', strip_tags( $_POST['embed_code'] ) );
}
}
}
Au lieu d'utiliser wp_nonce_field, les données peuvent être nettoyées à l'aide de esc_attr et strip_tags
Je ne suis pas la logique d'échapper des données au lieu d'utiliser un nonce? L'exemple donné sur wordpress.org utilise un nonce pour vérifier l'intention et échappe également aux données avant de les insérer. comment ces deux choses sont-elles liées?
vous ne devriez pas avoir besoin de Global Post, vous pouvez certainement le passer dans la fonction.
j'avais 2 actions save_post différentes, une pour l'édition rapide et une pour une metabox sur le même type de message et je les ai combinées pour me débarrasser des notices d'index non définies concernant mes différents nonces comme les 2 éléments couvraient les mêmes données, j’utilisais le même nom non générateur.
de toute façon, je considérerais de combiner vos fonctions save_post dans 1 ... OR en vérifiant le type de message avant de vérifier le nonce.
add_action( 'save_post' , 'c3m_save_meta' , 20, 2); //moved priority to later. you had priority 1 so is possible that WP actions were happening after your code
function c3m_save_meta( $post_id , $post ) {
// 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 $post_id;
//don't save if only a revision
if ( $post->post_type == 'revision' ) return $post_id;
// Check permissions
if ( 'page' == $post->post_type ) {
if ( !current_user_can( 'edit_page', $post_id ) ) return $post_id;
} else {
if ( !current_user_can( 'edit_post', $post_id ) ) return $post_id;
}
//save video post meta
if( $post->post_type == "video" && wp_verify_nonce( $_POST [ 'video_nonce' ], __FILE__ )) {
if (isset( $_POST['_embed_code'] ) ) {
update_post_meta( $post_ID, '_embed_code', esc_attr( $_POST['embed_code'] ) );
}
}
//save sample bacon post meta
if( $post->post_type == "bacon" && wp_verify_nonce( $_POST [ 'bacon_nonce' ], __FILE__ )) {
if (isset( $_POST['_bacon_code'] ) ) {
update_post_meta( $post_ID, '_bacon_code', esc_attr( $_POST['bacon_code'] ) );
}
}
}
ou vous pouvez utiliser le même nom de nonce pour les deux métaboxes. Je ne peux pas commenter sur la sécurité de cette opération, mais cela me semble correct car WP semble faire la même chose avec _wpnonce dans les modes d'édition rapide et normal. WP ne semble pas non plus avoir un nonce distinct pour chaque metabox.
function c3m_save_meta( $post_id , $post ) {
if(!wp_verify_nonce( $_POST [ 'c3m_nonce' ], __FILE__ )) return $post_id; //change both nonces to name=c3m_nonce
// 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 $post_id;
//don't save if only a revision
if ( $post->post_type == 'revision' ) return $post_id;
// Check permissions
if ( 'page' == $post->post_type ) {
if ( !current_user_can( 'edit_page', $post_id ) ) return $post_id;
} else {
if ( !current_user_can( 'edit_post', $post_id ) ) return $post_id;
}
//save video post meta
if( $post->post_type == "video") {
if (isset( $_POST['_embed_code'] ) ) {
update_post_meta( $post_ID, '_embed_code', esc_attr( $_POST['embed_code'] ) );
}
}
//save sample bacon post meta
if( $post->post_type == "bacon" && wp_verify_nonce( $_POST [ 'bacon_nonce' ], __FILE__ )) {
if (isset( $_POST['_bacon_code'] ) ) {
update_post_meta( $post_ID, '_bacon_code', esc_attr( $_POST['bacon_code'] ) );
}
}
}