Ich habe einen benutzerdefinierten Post-Typ Event
, der ein benutzerdefiniertes Start- und Enddatum / -uhrzeitfeld enthält (als Metaboxen im Post-Bearbeitungsbildschirm).
Ich möchte sicherstellen, dass ein Event nicht veröffentlicht (oder geplant) werden kann, ohne dass die Daten ausgefüllt sind, da dies Probleme mit den Vorlagen zur Anzeige der Eventdaten verursacht (abgesehen davon, dass dies eine notwendige Voraussetzung ist!). Ich würde jedoch gerne Entwürfe für Veranstaltungen haben, die kein gültiges Datum enthalten, während sie in Vorbereitung sind.
Ich habe überlegt save_post
, ob ich die Überprüfung durchführen soll, aber wie kann ich verhindern, dass der Status geändert wird?
EDIT1: Dies ist der Hook, mit dem ich jetzt das post_meta speichere.
// Save the Metabox Data
function ep_eventposts_save_meta( $post_id, $post ) {
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return;
if ( !isset( $_POST['ep_eventposts_nonce'] ) )
return;
if ( !wp_verify_nonce( $_POST['ep_eventposts_nonce'], plugin_basename( __FILE__ ) ) )
return;
// Is the user allowed to edit the post or page?
if ( !current_user_can( 'edit_post', $post->ID ) )
return;
// OK, we're authenticated: we need to find and save the data
// We'll put it into an array to make it easier to loop though
//debug
//print_r($_POST);
$metabox_ids = array( '_start', '_end' );
foreach ($metabox_ids as $key ) {
$events_meta[$key . '_date'] = $_POST[$key . '_date'];
$events_meta[$key . '_time'] = $_POST[$key . '_time'];
$events_meta[$key . '_timestamp'] = $events_meta[$key . '_date'] . ' ' . $events_meta[$key . '_time'];
}
$events_meta['_location'] = $_POST['_location'];
if (array_key_exists('_end_timestamp', $_POST))
$events_meta['_all_day'] = $_POST['_all_day'];
// Add values of $events_meta as custom fields
foreach ( $events_meta as $key => $value ) { // Cycle through the $events_meta array!
if ( $post->post_type == 'revision' ) return; // Don't store custom data twice
$value = implode( ',', (array)$value ); // If $value is an array, make it a CSV (unlikely)
if ( get_post_meta( $post->ID, $key, FALSE ) ) { // If the custom field already has a value
update_post_meta( $post->ID, $key, $value );
} else { // If the custom field doesn't have a value
add_post_meta( $post->ID, $key, $value );
}
if ( !$value )
delete_post_meta( $post->ID, $key ); // Delete if blank
}
}
add_action( 'save_post', 'ep_eventposts_save_meta', 1, 2 );
EDIT2: und das ist, was ich versuche, um die Post-Daten nach dem Speichern in der Datenbank zu überprüfen.
add_action( 'save_post', 'ep_eventposts_check_meta', 99, 2 );
function ep_eventposts_check_meta( $post_id, $post ) {
//check that metadata is complete when a post is published
//print_r($_POST);
if ( $_POST['post_status'] == 'publish' ) {
$custom = get_post_custom($post_id);
//make sure both dates are filled
if ( !array_key_exists('_start_timestamp', $custom ) || !array_key_exists('_end_timestamp', $custom )) {
$post->post_status = 'draft';
wp_update_post($post);
}
//make sure start < end
elseif ( $custom['_start_timestamp'] > $custom['_end_timestamp'] ) {
$post->post_status = 'draft';
wp_update_post($post);
}
else {
return;
}
}
}
Das Hauptproblem dabei ist ein Problem, das tatsächlich in einer anderen Frage beschrieben wurde : Die Verwendung wp_update_post()
eines save_post
Hakens löst eine Endlosschleife aus.
EDIT3: dachte ich einen Weg , es zu tun, durch Einhaken wp_insert_post_data
statt save_post
. Das einzige Problem ist, dass jetzt die post_status
zurückgesetzt wird, aber jetzt eine irreführende Meldung mit der Aufschrift "Beitrag veröffentlicht" angezeigt wird (durch Hinzufügen &message=6
zur umgeleiteten URL), der Status jedoch auf "Entwurf" gesetzt wird.
add_filter( 'wp_insert_post_data', 'ep_eventposts_check_meta', 99, 2 );
function ep_eventposts_check_meta( $data, $postarr ) {
//check that metadata is complete when a post is published, otherwise revert to draft
if ( $data['post_type'] != 'event' ) {
return $data;
}
if ( $postarr['post_status'] == 'publish' ) {
$custom = get_post_custom($postarr['ID']);
//make sure both dates are filled
if ( !array_key_exists('_start_timestamp', $custom ) || !array_key_exists('_end_timestamp', $custom )) {
$data['post_status'] = 'draft';
}
//make sure start < end
elseif ( $custom['_start_timestamp'] > $custom['_end_timestamp'] ) {
$data['post_status'] = 'draft';
}
//everything fine!
else {
return $data;
}
}
return $data;
}