Get custom fields values in filter on wp_insert_post_data

Hi all, thanks for reading.


Environment :

Read More

WordPress + Advanced Custom Fields plugin


Problem :

I have searched for hours now and I can’t seem to find the correct syntax to do the following:

When posting a new post, get custom field value in order to automatically replace the title of the post by that value. Example: I create a post and set ’10am’ in my ‘time’ custom field. The title of the post is automatically replaced by ’10am’.


Example:

So I’m adding a filter with the following :

add_filter('wp_insert_post_data', 'change_title') ;

function change_title($data)

{

    $time = XXX ; // How should I get this custom field value ?

    $new_title = 'Topic created at'.$time ;

    $data['post_title'] = $time ;

    return $data;

}

It must be very simple but I have tried every function available on both WP and the plugin’s documentations. I would be very thankful if anyone passing by gave me the solution.

Thanks in advance !

Related posts

Leave a Reply

4 comments

  1. Tweak to Riadh’s accepted answer (would add as a comment but haven’t got enough rep yet):

    As documented in the WordPress Codex wp_update_post includes the save_post hook so calling wp_update_post() inside the save_post hook creates an infinite loop. To avoid this, unhook then rehook your function like so:

    add_action('save_post', 'change_title');
    
    function change_title($post_id) {
        $time = get_field('time',$post_id);
        $post_title = 'Topic created at '. $time;
    
        // unhook this function so it doesn't loop infinitely
        remove_action('save_post', 'change_title');
    
        // update the post, which calls save_post again
        wp_update_post(array('ID' => $post_id, 'post_title' => $post_title));
    
        // re-hook this function
        add_action('save_post', 'change_title');
    }    
    
  2. You can actually access the global $_POST variable for your field value , but i guess you can do it in a cleaner way by using the save_post action to update your post’s title, eg:

    add_action('save_post', 'change_title');
    
    function change_title($post_id) {
        $time = get_field('time',$post_id);
        $post_title = 'Topic created at '. $time;
    
        // unhook this function so it doesn't loop infinitely
        remove_action('save_post', 'change_title');
    
        // update the post, which calls save_post again
        wp_update_post(array('ID' => $post_id, 'post_title' => $post_title));
    
        // re-hook this function
        add_action('save_post', 'change_title');
    }  
    

    assuming that your ACF fieldname is “time”.

    Edit: Updated the answer as per Mark Chitty’s answer.

  3. You may try this

    add_filter( 'wp_insert_post_data', 'change_title', '99', 2 );
    
    function change_title($data , $postarr){
    
        $custom_field = 'custom_filed_name';
        $post_id = $postarr['ID'];
        $time = get_post_meta( $post_id, $custom_field, true );
    
        // Now you have the value, do whatever you want
    }
    
  4. Advanced Custom Fields creates a ‘field key’ for each custom field that is created. I was able to refer to this key value when trying to access the custom fields. The field key value can be found by viewing page source when viewing the post type within the WordPress admin section.

    Look for data-field-key. You will see a value similar to data-field-key="field_5847b00820f13" in the page source. Use this value when accessing the value in the $postarr argument in the wp_insert_post_data filter. The custom fields will be in a nested array named fields within the $postarr argument.

    Alternatively, the field key value can be located by navigating to the Advanced Custom Fields / Export option from within the admin section. Once you are on the export page for Advanced Custom Fields, select the export to PHP option and you will see the value in the resulting PHP code.

    In the example below, I am concatenating two Advanced Custom Fields and updating the post_title in the $data array returned from the function.

    The result is that the post_title value will be saved to the database via the built in WordPress save post logic.

    add_filter('wp_insert_post_data', 'slb_set_title', '99', 2);
    
    function slb_set_title ($data, $postarr){
      if($data['post_type']==='slb_subscriber'){
        $data['post_title'] = $postarr['fields']['field_5847b00820f13'] .' '.       
        $postarr['fields']['field_5847b03f20f14'];
      }
    return $data;
    }