Veröffentlichen Sie keine benutzerdefinierte Post-Post, wenn ein Metadatenfeld nicht gültig ist

Ich habe einen benutzerdefinierten Post-Typ (CPT) namens event . Ich habe eine Meta-Box für den Typ mit mehreren Feldern. Ich möchte einige Felder vor der Veröffentlichung einer Veranstaltung validieren. Wenn beispielsweise das Datum eines Ereignisses nicht angegeben ist, möchte ich eine informative Fehlermeldung anzeigen, das Ereignis für die zukünftige Bearbeitung speichern, aber verhindern, dass dieses Ereignis veröffentlicht wird. Ist der ‘ausstehende’ Status für einen CPT-Beitrag ohne alle notwendigen Informationen der richtige Weg, ihn zu behandeln?

Was ist die beste Vorgehensweise bei der validation von CPT-Feldern? Verhindern Sie, dass ein Beitrag veröffentlicht wird, speichern Sie ihn jedoch für die zukünftige Bearbeitung.

Vielen Dank, Dascha

Solutions Collecting From Web of "Veröffentlichen Sie keine benutzerdefinierte Post-Post, wenn ein Metadatenfeld nicht gültig ist"

Sie können den Post davon abhalten, alle zusammen mit kleineren JQuery-Hacks zu speichern und die Felder zu validieren, bevor Sie auf der Client- oder Serverseite mit ajax speichern:

Zuerst fügen wir unser JavaScript hinzu, um das Ereignis submit / publish zu erfassen und es zu verwenden, um unsere eigene Ajax-function vor dem tatsächlichen Senden zu übermitteln:

  add_action('wp_print_scripts','my_publish_admin_hook'); function my_publish_admin_hook(){ if (is_admin()){ ?>  < ?php } } 

dann erstellen wir die function für die eigentliche validation:

 add_action('wp_ajax_my_pre_submit_validation', 'pre_submit_validation'); function pre_submit_validation(){ //simple Security check check_ajax_referer( 'pre_publish_validation', 'security' ); //do your validation here //all of the form fields are in $_POST['form_data'] array //and return true to submit: echo 'true'; die(); //or your error message: echo 'bal bla bla'; die(); } 

Sie können es immer ein wenig ändern, um die validation nur für Ihren Post-Typ my_publish_admin_hook , my_publish_admin_hook function my_publish_admin_hook eine bedingte Überprüfung für Ihren Post-Typ hinzufügen und auf der Client-Seite validieren, aber ich bevorzuge auf der Server-Seite.

Die Methode besteht aus zwei Schritten: erstens eine function zum Speichern Ihrer benutzerdefinierten Metabox-Felddaten (angehängt an save_post) und zweitens eine function zum Lesen des neuen post_meta (das Sie gerade gespeichert haben), Überprüfen und Ändern des Ergebnisses von Speichern nach Bedarf (auch süchtig nach save_post, aber nach dem ersten). Die Validator-function, falls die validation fehlschlägt, ändert den post_status sogar wieder in “pending”, was effektiv verhindert, dass der Post veröffentlicht wird.

Da die save_post-function sehr oft aufgerufen wird, verfügt jede function über Prüfungen, die nur ausgeführt werden, wenn der Benutzer publizieren möchte, und nur für den benutzerdefinierten Post-Typ (mycustype).

Ich füge auch in der Regel einige benutzerdefinierte Nachrichten hinzu, um dem Benutzer zu zeigen, warum sein Beitrag nicht veröffentlicht wurde, aber diese sind ein bisschen kompliziert, hier einzubeziehen …

Ich habe diesen genauen Code nicht getestet, aber es ist eine vereinfachte Version von dem, was ich in großen benutzerdefinierten Post-Typ-Setups getan habe.

 add_action('save_post', 'save_my_fields', 10, 2); add_action('save_post', 'completion_validator', 20, 2); function save_my_fields($pid, $post) { // don't do on autosave or when new posts are first created if ( ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || $post->post_status == 'auto-draft' ) return $pid; // abort if not my custom type if ( $post->post_type != 'mycustomtype' ) return $pid; // save post_meta with contents of custom field update_post_meta($pid, 'mymetafield', $_POST['mymetafield']); } function completion_validator($pid, $post) { // don't do on autosave or when new posts are first created if ( ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || $post->post_status == 'auto-draft' ) return $pid; // abort if not my custom type if ( $post->post_type != 'mycustomtype' ) return $pid; // init completion marker (add more as needed) $meta_missing = false; // retrieve meta to be validated $mymeta = get_post_meta( $pid, 'mymetafield', true ); // just checking it's not empty - you could do other tests... if ( empty( $mymeta ) ) { $meta_missing = true; } // on attempting to publish - check for completion and intervene if necessary if ( ( isset( $_POST['publish'] ) || isset( $_POST['save'] ) ) && $_POST['post_status'] == 'publish' ) { // don't allow publishing while any of these are incomplete if ( $meta_missing ) { global $wpdb; $wpdb->update( $wpdb->posts, array( 'post_status' => 'pending' ), array( 'ID' => $pid ) ); // filter the query URL to change the published message add_filter( 'redirect_post_location', create_function( '$location','return add_query_arg("message", "4", $location);' ) ); } } } 

Fügen Sie für mehrere Metabox-Felder einfach weitere Abschlussmarkierungen hinzu und rufen Sie mehr post_meta ab und führen Sie weitere Tests durch.

Sie müssen Ihren Meta-Feldwert auf Ajax prüfen / validieren, dh wenn der Benutzer auf die Schaltfläche “Veröffentlichen / Aktualisieren” klickt. Hier validiere ich Woocommerce-Produkt mit Meta-Feld “Produktnummer” für leeren Wert.

 add_action('admin_head-post.php','ep_publish_admin_hook'); add_action('admin_head-post-new.php','ep_publish_admin_hook'); function ep_publish_admin_hook(){ global $post; if ( is_admin() && $post->post_type == 'product' ){ ?>  < ?php } } 

Danach fügen Sie eine Ajax-Handler-function hinzu,

 add_action('wp_ajax_ep_pre_product_submit', 'ep_pre_product_submit_func'); function ep_pre_product_submit_func() { //simple Security check check_ajax_referer( 'pre_publish_validation', 'security' ); if ( empty( $_POST['product_number'] ) || empty( $_POST['file_attachment'] ) ) { $data = array( 'message' => __('Please enter part number and specification document.'), ); wp_send_json_error( $data ); } wp_send_json_success(); } 

Wollte nur hinzufügen, dass, um die Post-Variablen zu lesen, mit Bainternet-Lösung, müssen Sie die Zeichenfolge in $_POST['form_data'] mit PHP parse_str function parse_str (nur um einige Forschungszeit zu sparen).

 $vars = parse_str( $_POST['form_data'] ); 

Dann können Sie mit $varname auf jede Variable $varname . Wenn Sie beispielsweise ein Meta-Feld namens “my_meta” haben, würden Sie folgendermaßen darauf zugreifen:

 $vars = parse_str ( $_POST['form_data'] ) if ( $my_meta == "something" ) { // do something }