Support

Account

Home Forums Bug Reports Hooking in save_post_{$post->post_type} and update_field

Solved

Hooking in save_post_{$post->post_type} and update_field

  • I’ve read almost every topic named similar to “update_field() not working blah blah” and the only solution that worked for me, isn’t actually a solution…

    But let me be more specific… I have a custom post type, and have hooked into save_post_{$post->post_type} to do some data retrieval from another website, and then save that data to the appropriate custom fields of my custom post type…

    The whole procedure goes like this: You click on Add New, and then in the Content box, you only type an ID… You hit the Publish button, and my code does all the magic behind the scenes, where it fetches the data based on the ID you typed in $post->post_content, and then updates the custom fields…

    The relevant part of the code that does that is this:

                $data = unserialize($data);
    
                $text = $post_id . "\n\n" . print_r($post, true) . "\n" . print_r($data, true) . "\n\n\n"; // THIS IS JUST A CONTROL TEXT WRITTEN TO A TEMP TXT TO MONITOR THE HOOK'S FUNCTIONALITY
    
                foreach ($data as $key => $value) {
                    if ($key != 'movie_genre' && $key != 'movie_poster') {
                        if ($value == 'n/a') {
                            $value = 'Unretrieved element';
                        }
    
                        $text .= $key . ' - functions exists: ' . function_exists('update_field') . "\n\n"; // THIS IS JUST A CONTROL TEXT WRITTEN TO A TEMP TXT TO MONITOR THE HOOK'S FUNCTIONALITY
    
                        $text .= update_field($key, $value, $post_id). "\n\n"; // THIS IS THE UPDATE_FIELD() AND I'M TAKING LOGGING THE RETURNED VALUE TO THE SAME TEMP TXT TO MONITOR THE RESULT
                    }
                }

    An extract from the logging TXT for an action like this, reads the following:

    movie_release - functions exists: 1
    
    1
    
    movie_synopsis - functions exists: 1
    
    1
    
    movie_language - functions exists: 1
    
    1
    
    movie_runtime - functions exists: 1
    
    1
    
    movie_cast - functions exists: 1
    
    1
    
    movie_director - functions exists: 1
    
    1
    
    movie_writer - functions exists: 1
    
    1
    
    movie_awards - functions exists: 1
    
    1

    So, what I get from the above is that indeed update_field exists at the point of hooking, and also it succeeds in updating the fields. The problem is that when the whole post save finishes its job, the fields are empty…

    I’ve read MANY solutions… In a post, this fantastic guy – @hube2 – suggested to set the priority to a higher value than 10… Done that… Set it to 20, still my data isn’t there…

    Another guy here https://support.advancedcustomfields.com/forums/topic/update_field-is-not-working/ said that

    wp_safe_redirect( admin_url('/post.php?post='. $post_id .'&action=edit') ); fixed his problem. In my case this didn’t work either…

    The only think that DID work was a simple die(); after the updating loop…

    Of course this led my page to go blank once the updating was finished, so I had to reload the page, but indeed this was the first time that I saw my data there in their respective custom fields…

    So, although this didn’t actually fix my situation, it was the biggest confirmation at least that my code works…

    Now, something obviously overwrites my data… Has anyone figured out what is that thing that overwrites the data on those numerous, similar cases that are open in this community?

  • Actually, after taking a look at the WP code reference of wp_safe_redirect() it is specifically advised that wp_safe_redirect() should almost always be followed by an exit; command…

    Well this was enough to fix my problem.

    Of course this isn’t a proper fix, that would essentially stop the data data overwriting from happening, but it’s a workaround that at least solves my problem…

    If anyone has any proper fix/suggestion, please let me know!

  • I think I found out (as an educated guess) what is happening… I’m hooking into WP’s stock save_post_{$post->post_type}

    But somewhere in there, ACF’s similar hook point fires up and tries to update the fields I’ve already updated in my own hook, with the values of the respective input fields (which are effectively empty) thus replacing my fields with an empty string…

    I somehow need to remove/prevent from within my hook ACF’s hook from firing up… How do I do that? I suppose remove_action(‘acf/save_post’) won’t be enough…

  • OK, after two days I finally found what was going on… Well, I was inspired by this post in WP reference (such a precious place of knowledge)…

    As I said in the first post, I used the do_action( “save_post_{$post->post_type}”, int $post_ID, WP_Post $post, bool $update ) hook point. And according to the post above, this hook fires before the generic do_action( ‘save_post’, int $post_ID, WP_Post $post, bool $update ), so what I was saving in my hook point (in regard to the ACF fields) was overwritten when the generic hook was firing…

    So I used the generic one instead, and did a check where this was true $post->post_type == ‘movie’

    That was all that was needed! No need priority settings, nothing… Just this was enough to solve my problem!!! Amazing!

  • @princeofabyss sorry for not replying to this sooner, but when saving any post that has acf fields on it you should actualy use the acf/save_post hook with a priority > 10. This ensures that any changes you make happen after ACF has run. ACF runs with a default priority of 10 on the generic save_post hook and if you use the default priority as well it will be a tossup as to which will happen first. This has a lot to do with when the actions are added and that has to do with the load order of files and this load order can change in some cases.

Viewing 5 posts - 1 through 5 (of 5 total)

You must be logged in to reply to this topic.