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;
}
quelle
OK, so habe ich es endlich gemacht: ein Ajax-Aufruf einer PHP-Funktion, die die Prüfung durchführt, die irgendwie von dieser Antwort inspiriert ist und einen cleveren Tipp aus einer Frage verwendet, die ich bei StackOverflow gestellt habe . Wichtig ist, ich stelle sicher, dass nur dann, wenn wir die Prüfung veröffentlichen möchten, erfolgt, damit ein Entwurf immer ohne die Prüfung gespeichert werden kann. Dies war letztendlich die einfachere Lösung, um die Veröffentlichung des Beitrags tatsächlich zu verhindern . Es könnte jemand anderem helfen, also habe ich es hier geschrieben.
Fügen Sie zunächst das erforderliche Javascript hinzu:
Dann die Funktion, die die Prüfung übernimmt:
Diese Funktion gibt zurück,
true
ob alles in Ordnung ist, und sendet das Formular, um den Beitrag auf dem normalen Kanal zu veröffentlichen. Andernfalls gibt die Funktion eine Fehlermeldung zurück, die als angezeigt wirdalert()
, und das Formular wird nicht gesendet.quelle
delayed_autosave(); //get data from textarea/tinymce field jQuery('#publish').data("valid", true).trigger('click'); //publish post
Vielen Dank.Ich denke, dass der beste Weg, dies zu tun, nicht darin besteht, die Statusänderung so sehr zu verhindern, wie dies der Fall ist, um sie rückgängig zu machen, wenn dies der Fall ist. Zum Beispiel: Sie haken
save_post
mit einer wirklich hohen Priorität (so dass der Haken sehr spät ausgelöst wird, nämlich nachdem Sie Ihre Meta-Einfügung durchgeführt haben), überprüfen dannpost_status
den gerade gespeicherten Beitrag und aktualisieren ihn auf ausstehend (oder Entwurf oder Was auch immer), wenn es nicht Ihren Kriterien entspricht.Eine alternative Strategie besteht darin, den Haken
wp_insert_post_data
zu setzen, um den post_status direkt zu setzen. Der Nachteil dieser Methode ist meines Erachtens, dass Sie das Postmeta noch nicht in die Datenbank eingefügt haben, sodass Sie es usw. vor Ort verarbeiten müssen, um Ihre Überprüfungen durchzuführen, und es dann erneut verarbeiten müssen, um es einzufügen es in die Datenbank ... die entweder in Leistung oder in Code eine Menge Aufwand werden könnte.quelle
save_post
mit Priorität 1 verbunden, um die Metafelder aus den Metaboxen zu speichern. was Sie dann vorschlagen, ist, einen zweiten Hakensave_post
mit Priorität zu haben, sagen wir 99? Würde dies die Integrität sicherstellen? Was passiert, wenn aus irgendeinem Grund der erste Hook ausgelöst wird, die Metadaten eingefügt und der Beitrag veröffentlicht werden, der zweite Hook jedoch nicht, sodass Sie ungültige Felder erhalten?post_status
All-in-One-Funktion, die von einem einzelnen Anruf ausgeht, auf einen Hook aktualisieren, wenn Sie dies vorziehen.save_post
aber das löst eine Endlosschleife aus.if( get_post_status( $post_id ) == 'publish' )
ist auch das, was Sie verwenden möchten, da Sie die Daten in neu definieren$wpdb->posts
und nicht die Daten in$_POST[]
.Die beste Methode könnte JAVASCRIPT sein:
quelle
Tut mir leid, dass ich Ihnen keine klare Antwort geben kann, aber ich erinnere mich, dass ich in letzter Zeit etwas Ähnliches gemacht habe. Ich kann mich nur nicht genau erinnern, wie. Ich denke , dass ich es vielleicht hätte um über Art und Weise - so etwas wie ich es ein Default - Wert hatte und wenn die Person es nicht geändert hatte nahm ich das so in einer if - Anweisung nach oben ->
if(category==default category) {echo "You didn't pick a category!"; return them to the post creation page; }
leider ist dies nicht eine gerade nach oben Antwort , aber die Hoffnung es hilft ein bisschen.quelle