wordpress: problems with meta boxes, nonces and save_post

10. Juni 2014 - PHP, wordpress

If you have created a nice backend user interface in wordpress with meta boxes that add some input fields for additional information to your post and protected them with nonces, you maybe encounter a strange behaviour:
custom menus cannot be saved anymore, likewise pages, likewise custom posts….

The reason is, that your function specified in the action hook doesn’t stick to the rules:
e.g. if you have written (as in my case 🙂 )

add_action( 'save_post', array( $this, 'saveAllCustomFields' ));

function saveAllCustomFields() {
global $post;

if ( !empty($_POST) && check_admin_referer( 'custom_field_creation','custom_fields' ) ) {
if ( !current_user_can( 'edit_post', $post->ID) )  return;
if ( $post->post_type != 'page' && $post->post_type != 'post' )  return;
$this->saveCustomFields($this->customFields1);
}

}

The nonce, created with

wp_nonce_field( 'custom_field_creation','custom_fields' );

for type ‚post‘ will block any other type of post from beeing saved. They simply dont’t know about it.

Changing saveAllCustomFields to

function saveAllCustomFields() {
global $post;
if (!empty($post) && ($post->post_type == 'post')) {
if ( !empty($_POST) && check_admin_referer( 'custom_field_creation','custom_fields' ) ) {
if ( !current_user_can( 'edit_post', $post->ID) )  return;
$this->saveCustomFields($this->customFields1);
}
}
}

will set them free.

Deutsche Zusammenfassung:

Wenn man ein Backend-Userinterface mit Meta-Boxen und  Zusatzfeldern, die durch Nonces abgesichert werden, schreibt, kann es zu – vielleicht zunächst nicht auffallenden – Nebenwirkungen kommen. Andere Post-Typen wie Seiten, BenutzermenĂĽs etc. können plötzlich nicht mehr gesichert werden.

Der Grund dafĂĽr liegt in der Funktion, die man beim zuständigen Action-Hook ’save_post‘ angegeben hat (hier: saveAllCustomFields)

Man muĂź genau darauf achten, dass der Nonce nur bei dem Post-Type ĂĽberprĂĽft wird, fĂĽr den man ihn auch erzeugt hat.
Ansonsten werden alle anderen Post-Types ausgesperrt.