save_post-Aktion, um den wp_insert_post_data-Filter einzuschließen, Metafeldinformationen zu sammeln und Endlosschleife zu verhindern

Ich versuche, den Titel eines Beitrags zu ändern, aber ich möchte Informationen aus einem Meta-Feld hinzufügen, deren Wert erst nach dem Speichern der Beiträge in der database gespeichert wird. wp_insert_post_data dieser einen Sache funktioniert es gut als wp_insert_post_data Filter.

 // add_filter('wp_insert_post_data', 'tr_change_show_title', 99, 2); function tr_change_show_title($data, $postarr) { if('post' != $data['post_type']) { // don't bother if its an auto-draft, as the post title may not have been completed yet, or in the trash if ( !in_array( $data['post_status'], array( 'auto-draft', 'trash' ) )) $child_ID = $postarr['ID']; // Child post id $parent_ID = get_post_meta($child_ID, "_wpcf_belongs_booking_id", true); // parent ID $post_type = $data['post_type']; if ($post_type == 'show' && get_post_type($parent_ID) == 'booking') { $parent_title = get_the_title($parent_ID); $data['post_title'] = $parent_title; // save the parent title first } if (function_exists('types_render_field')) { //this isn't working as the meta field isn't saved yet $show_time = types_render_field( "show-time", array("post_id"=>"$child_ID", "raw"=>"true") ); if ($show_time){ $data['post_title'] .= ' : ' . $show_time; // Append Show time to title } } $data['post_title'] .= ': show-' . $child_ID; // add the original post id } return $data; } 

Ich habe den Codex und diesen wpse Beitrag gelesen: https://wordpress.stackexchange.com/a/54713/13551 https://codex.wordpress.org/Function_Reference/wp_update_post

Was ich verstehe ist, dass eine Endlosschleife ein Risiko ist. Um dies zu vermeiden, haken wir die save_post vor und nach der Arbeit ab. Ich habe mir folgendes ausgedacht, verstehe aber nicht ganz, warum ich immer noch in eine Endlosschleife laufe.

 add_action( 'save_post', 'tr_save_post_show_title', 99 ); function tr_save_post_show_title($post_ID){ if ( !wp_is_post_revision( $post_ID ) ) { // do nothing if a revision // Prevent infinite loop remove_action('save_post', 'tr_save_post_show_title'); // Add our filter add_filter('wp_insert_post_data', 'tr_change_show_title', 99, 2); write_log(array( 'ID' => $post_ID)); // Re-save the post this time with filter wp_update_post( array( 'ID' => $post_ID), true ); // true for error catching // Catch errors if (is_wp_error($post_id)) { $errors = $post_id->get_error_messages(); foreach ($errors as $error) { write_log($error); } } // re-hook the save_post action add_action('save_post', 'tr_save_post_show_title'); } } 

Solutions Collecting From Web of "save_post-Aktion, um den wp_insert_post_data-Filter einzuschließen, Metafeldinformationen zu sammeln und Endlosschleife zu verhindern"

Sie tr_change_show_title den tr_change_show_title an einen Filter innerhalb der function selbst, der eine Endlosschleife bilden kann. Alle Aktionen zum Entfernen / Hinzufügen von Inhalten und Filter in den functionen sollten gelöscht werden. Prüfen Sie stattdessen, ob die Postdaten aktualisiert werden sollen oder nicht. In Ihrem Fall sollten Sie überprüfen, ob der Titel den gewünschten Wert hat oder nicht, wenn Sie wp_update_post mit dem neuen Wert wp_update_post :

 add_action( 'save_post', 'tr_save_post_show_title', 99, 2 ); function tr_save_post_show_title( $post_ID, $post ){ if ( !wp_is_post_revision( $post_ID ) ) { // do nothing if a revision $meta = get_post_meta($post_ID, "your-meta-key", true ); if( $meta != '' ) { $desired_title = "Whatever you want as title"; // Check the title value to check if it should be modified if( $post->post_title != $desired_title ) { $post->post_title = $desired_title; wp_update_post( $post, true ); } } } } 

Sie sind besorgt, diese function auszuführen, nachdem ein Metafeld gespeichert / aktualisiert wurde. Wenn das Metafeld in der Form ist, in der Sie den Post bearbeiten, können Sie wie jedes andere Metafeld auf den Metafeldwert zugreifen. Wie auch immer, wenn Sie sicher sein wollen, dass das Meta-Feld gespeichert / aktualisiert wurde, können Sie den updated_{$meta_type}_meta Aktions-Hook anstelle von save_post ; Als Vorteil haben Sie in diesem Aktions-Hook direkten Zugriff auf den aktuellen Meta-Wert (falls vorhanden):

 add_action( 'updated_post_meta', 'tr_save_post_show_title', 99, 4 ); function tr_save_post_show_title( $meta_id, $object_id, $meta_key, $meta_value ) { if ( $meta_key == 'the_meta_key_here' && $meta_value != '' && $object_id && ! wp_is_post_revision( $object_id ) ) { //write_log(array( 'ID' => $post_id )); // Get post data $post = get_post( $object_id ); if( $post ) { $desired_title = 'Combine here the $post->post_title with $meta_value as you desire.'; // Check the title value to check if it should be modified if( $post->post_title != $desired_title ) { $post->post_title = $desired_title; wp_update_post( $post ); } } } } 

In Bezug auf @ Cybmetas Beitrag denke ich, dass das Typ-Plugin uns einen Curveball casting könnte.

Er hat save_post , dass Sie (zumindest in diesem Zusammenhang) keinen Filter an der Stelle von save_post ohne eine save_post zu erzeugen.

Als ich versuchte, auf den Wert eines Meta-Felds updated_post_meta mag sein Vorschlag für ” updated_post_meta ” angemessen sein, schien aber nicht zu funktionieren, da der Meta-Schlüssel beim updated_post_meta des updated_post_meta nicht verfügbar war. Dies könnte wiederum ein Problem bei der Art sein, wie Typen benutzerdefinierte Felder einrichten.

Am Ende habe ich meinen ursprünglichen Ansatz korrigiert. Ungeachtet des Einflusses von Typen ist das Folgende ein funktionierendes Beispiel für das Ändern eines save_post an der Stelle von save_post , das Einbeziehen des Wertes eines Meta-Felds und das Verhindern einer Endlosschleife. Da save_post die letzte Aktion in der Kette ist, sollte sie nach allen anderen databaseänderungen ausgeführt werden. Daher sollten Sie sich ziemlich sicher sein, dass das WP_Post Object alle Meta-Feldwerte und alle von vorherigen Filtern oder Aktionen vorgenommenen Änderungen enthält. Wenn ich nicht aktuelle Informationen aus meinen Meta-Feldern haben wollte, hätte eine einfache Filterung über wp_insert_post_data genügt.

 add_action('save_post', 'tr_save_post_show_title', 99, 2); function tr_save_post_show_title ($post_ID, $post) { if($post->post_type == 'show' && !in_array($post -> post_status, array('auto-draft', 'revision', 'trash'))) { // don't bother if our CPT post is an auto-draft, a revision or in the trash $parent_ID = get_post_meta($post_ID, "_wpcf_belongs_booking_id", true); // Types relationship $current_title = $post -> post_title; // Get current post title saved in DB $post_showtime = get_post_meta($post_ID, "wpcf-show-time", true ); // our custom meta field if ($post_showtime == ''){ $post_showtime = 'To be confirmed'; } if ($parent_ID && get_post_type($parent_ID) == 'booking') { // Check to see if Types a parent relationship has been assigned. $show_post_title = get_the_title($parent_ID); // get the id of the parent post if ($show_post_title != ''){ $show_post_title .= ': ' . $post_showtime; } } else if (!$parent_ID){ // when a parent is not assigned $show_title = "Show not yet assigned to venue: " . $post_showtime; } if ($current_title != $show_post_title ){ // The current title does not match what we would like it to be // Prevent infinite loop remove_action('save_post', 'tr_save_post_show_title'); // Re-save the post with our new title wp_update_post( array( 'ID' => $post_ID, 'post_title' => $show_post_title ), false ); // true for error catching // re-hook the save_post action add_action('save_post', 'tr_save_post_show_title', 99, 2); // Catch any errors with our custom logging function http://goo.gl/P9HbcK if (is_wp_error($post_ID)) { $errors = $post_id->get_error_messages(); foreach ($errors as $error) { write_log($error); } } } } } 

Interessanterweise hat save_post_ , der kurz vor save_post nicht die neuesten Werte aus dem Meta-Feld bekommen.

Mein Ansatz für dieses Problem ist der direkte Zugriff auf “rohe” Metadaten von $ _POST [metabox_id] in wp_insert_post_data Filter Hook. Ich gebe zu, dass dieser Ansatz eher für mein Projekt geeignet ist, bei dem Beiträge vollständig aus Metadaten generiert werden und jedes Mal neu gerendert werden müssen. Tough jemand könnte es nützlich finden.