私は投稿のタイトルを変更しようとしていますが、私は投稿が既に保存されるまでその値がデータベースに保存されないメタフィールドからの情報を含めたいと思います。これ以外にwp_insert_post_data
フィルタとしてはうまく機能しています。
// 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;
}
私はコーデックスを読んだ、そしてこのwpseの投稿: https://wordpress.stackexchange.com/a/54713/13551https://codex.wordpress.org/Function_Reference/wp_update_post
私が理解していることは、無限ループはリスクであるということです。これを避けるために、私達は私達の仕事の核心部分の前後にsave_post
のフックを解除してから再度フックします。私は次のことを思いついたが、なぜImがまだ無限ループに陥っているのか全く理解していない。
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');
}
}
tr_change_show_title
を関数自体の内側のフィルタにフックすると、無限ループになる可能性があります。関数内のアクションやフィルタを削除/追加するものはすべて削除する必要があります。代わりに、投稿データを更新する必要があるかどうかを確認してください。あなたのケースでは、タイトルがあなたが望む値を持っているかどうか、新しい値で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 );
}
}
}
}
メタフィールドが保存または更新された後にその関数を実行することについて心配しています。メタフィールドが投稿を編集しているフォームにある場合は、他のメタフィールドと同様にメタフィールド値にアクセスできます。とにかく、メタフィールドが保存/更新されたことを確認したい場合は、updated_{$meta_type}_meta
の代わりにsave_post
アクションフックを使用することができます。利点として、このアクションフックでは、現在のメタ値(もしあれば)に直接アクセスできます。
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 );
}
}
}
}
この問題に対する私のアプローチは、wp_insert_post_dataフィルター・フックの$ _POST [metabox_id]から直接「生の」メタデータにアクセスすることです。このアプローチは、投稿が完全にメタデータから生成され、毎回再レンダリングする必要がある私のプロジェクトに適していることを認めます。タフな人はそれが便利だと思うかもしれません。
@ cybmetaの貢献に関しては、Typesプラグインが私たちに曲線を投げかけているのかもしれないと思います。
彼はあなたが(少なくともこの文脈では)無限ループを作らずにsave_post
のところにフィルタを追加することができないという点で正しいです。
私はメタフィールドの値にアクセスしようとしていたので、updated_post_meta
に対する彼の提案は適切かもしれませんが、フックが実行されたときにメタキーが利用できなかったのでうまくいきませんでした。これもまた、Typesがカスタムフィールドを設定する方法の問題です。
最後に私は私の最初のアプローチを修正しました。型からの影響に関係なく、以下は投稿のタイトルをsave_post
の時点で変更し、メタフィールドの値を組み込んで、無限ループを防止する実用的な例です。 save_post
はチェーン内の最後のアクションであるため、他のすべてのデータベース変更の後に実行する必要があります。したがって、WP_Post Object
にはメタフィールド値、および前のフィルタまたはアクションによるすべての変更が含まれると確信できます。私のメタフィールドから最新の情報が欲しくなかったら、wp_insert_post_data
による単純なフィルタリングで十分でしょう。
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);
}
}
}
}
}
興味深いことに save_post_<post_type>
はsave_post
がメタから最新の値を取得していない直前に実行されます。どちらかのフィールド。