Widersprüchliche save_post-functionen beim Übergeben der Post-ID und Speichern von benutzerdefinierten Meta-Boxen für verschiedene Post-Typen

Postsave-functionen stehen miteinander in Konflikt, wenn sie zum Aktionshaken save_post hinzugefügt werden.

2 verschiedene benutzerdefinierte Post-Typen mit 2 verschiedenen (einer für jeden Post-Typ) benutzerdefinierten Meta-Boxen.

Ich schließe nur den Code für 1 der Metaboxen ein. Der andere ist sehr ähnlich und jeder funktioniert separat, aber nicht zusammen.

Die callbackfunktion ‘register_metabox_cb’:

function c3m_video_meta() { add_meta_box('_c3m_video_embed', __('Enter Video Embed Code In the Box Below') , 'c3m_video_embed', 'video', 'normal', 'low'); } 

Hinzufügen des Meta-Felds zum Post-Bearbeitungsbildschirm:

 function c3m_video_embed($post) { global $post; wp_nonce_field(__FILE__,'video_nonce'); $embed-code = get_post_meta($post->ID, '_embed-code', true); echo '' ; } 

Die Speicherfunktion:

  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 ); } } 

Die Aktion hakt:

add_action( 'admin_menu' , 'c3m_video_meta' );

add_action( 'save_post' , 'c3m_save_video_meta' , 1, 2);

Das ist gut und schön und funktioniert, aber wenn ich eine andere Meta-Box zu einem anderen Post-Typ hinzufügen und eine ähnliche function (andere functionsname, Nonce-Name und Schlüssel) verwenden, wenn der Beitrag gespeichert wird, bekomme ich diesen Fehler:

Hinweis: Undefinierter Index: _embed-code in /Applications/MAMP/htdocs/wordpress/wp-content/plugins/ieew-custom-functions/ieew-custom-functions.php in Zeile 181

Warnung: Header-Informationen können nicht geändert werden – Header, die bereits gesendet wurden (Ausgabe gestartet unter /Applications/MAMP/htdocs/wordpress/wp-content/plugins/ieew-custom-functions/ieew-custom-functions.php:181) in / Applications / MAMP / htdocs / wordpress / wp-includes / Pluggable.php in Zeile 897

Der undefinierte _embed-Code ist beim Speichern des Posts, der die Variable _embed-code nicht enthält.

Da die Fehlermeldungen umgekehrt sind, je nachdem, welchen Post-Typ ich versuche zu speichern, führt das zu der Annahme, dass beide (2 verschiedene) Speicherfunktionen zur save_post-Aktion hinzugefügt werden. Sie werden auch beim Speichern eines normalen Posts hinzugefügt. Wenn ich nur eine der Speicherfunktionen verwende, gibt es beim Speichern eines normalen Posts keine Fehler.

Anstatt dass diese Frage eine “Fix My Code” -Frage ist, würde ich lieber die Antwort enthalten, wie und warum benutzerdefinierte Meta-Boxen hinzugefügt werden und die verschiedenen Nonce-Methoden verwendet werden. Natürlich könnte ich das More Fields-Plugin verwenden, aber ich würde lieber lernen, wie man den Post-Edit-Bildschirm mit benutzerdefinierten Inhaltstypen anpasst.

Ich habe denselben Code und dieselbe Methode verwendet, um mehrere Meta-Felder zu einem einzelnen benutzerdefinierten Post-Typ hinzuzufügen, und es hat immer gut funktioniert.

Solutions Collecting From Web of "Widersprüchliche save_post-functionen beim Übergeben der Post-ID und Speichern von benutzerdefinierten Meta-Boxen für verschiedene Post-Typen"

Nach einigen weiteren Recherchen fand ich Folgendes:

  • Anstatt die function admin_menu add_meta_box zu admin_menu , sollte sie in add_meta_boxes
  • Verwenden update_post_meta anstelle der foreach-Schleife die function update_post_meta für die Speicherfunktion
  • Anstatt das wp_nonce_field die Daten mit esc_attr und strip_tags
  • Um die Post-ID an die function zum Speichern der Meta-Box zu übergeben, müssen Sie die zusätzliche $ post-Variable nicht einfügen
  • Sie müssen einen bedingten Status für den Post-Typ in der Speicherfunktion hinzufügen
  • Sie müssen global $post mit der Speicherfunktion aufrufen

Der neue und viel einfachere Code zum Hinzufügen beider Meta-Boxen:

 add_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'; ?>  < ?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'; ?>  < ?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'] ) ); } } } 

Anstatt das wp_nonce_field zu verwenden, können die Daten mit esc_attr und strip_tags bereinigt werden

Ich folge nicht der Logik des Entweichens von Daten anstelle der Verwendung einer Nonce? Das auf wordpress.org angegebene Beispiel verwendet eine Nonce, um die Absicht zu überprüfen, und entkommt auch den Daten, bevor es eingefügt wird. Wie hängen diese beiden Dinge zusammen?

Sie sollten nicht global $ post benötigen, Sie können es definitiv in die function übergeben.

Ich hatte 2 verschiedene save_post-Aktionen, eine für die schnelle Bearbeitung und eine für eine Metabox auf dem gleichen Post-Typ und ich endete damit, sie zu kombinieren, um nicht definierte Index-Nachrichten über meine verschiedenen Nonces loszuwerden. Da die 2 Items die gleichen Daten enthielten, verwendete ich denselben Nonce-erzeugenden Namen.

Wie auch immer, ich würde in Erwägung ziehen, Ihre save_post-functionen in 1 … ODER eine Überprüfung des Post-Typs zu kombinieren, bevor Sie die Nonce überprüfen.

 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'] ) ); } } } 

oder Sie könnten den gleichen Nonce-Namen für beide Metaboxen verwenden. Ich kann die Sicherheit davon nicht kommentieren, aber scheint mir in Ordnung zu sein, da WP scheinbar dasselbe mit _wpnonce sowohl im Schnellbearbeitungsmodus als auch im normalen Bearbeitungsmodus macht. WP scheint auch kein separates Nonce für jede Metabox zu haben.

 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'] ) ); } } }