1

I am trying to update the field when post status changes to published. It is getting the values properly but not updating when I check the what update field is returning.

It shows some number.

Please help not sure whether I should use this along with transition_post_status


Update - I have tried below hooks // the action is getting triggered but the fields are not updating

1. publish //works but no update is happening

2. save_post && save_post_l //works but no update is happening.


add_action('transition_post_status', 'updated_to_publish', 10, 3);
function updated_to_publish($new_status, $old_status, $post)
{

    if ($new_status == 'publish')) // I have removed the check for post type 
  {

        $post_id = $post->ID;

        if (get_field('advanced_option_edit_seo', $post_id)) {

            if (defined('WPSEO_VERSION')) {

                $metatitle = get_field('seo_title', $post_id);
                $metadesc = get_field('seo_meta_description', $post_id);
                $metakeywords = get_field('seo_keyword', $post_id);


                update_post_meta($post_id, '_yoast_wpseo_title', $metatitle );
                update_post_meta($post_id, '_yoast_wpseo_metadesc', $metadesc );
                update_post_meta($post_id, '_yoast_wpseo_focuskw', $metakeywords);

            }

        }

    } else {
        return;
    }

}



Update

I was able to solve the issue by using 'wp_insert_post' action . Can I know why other actions failed but 'wp_insert_post' worked?

code that i used for testing

add_action('transition_post_status', 'updated_to_publish', 10, 3);
    function updated_to_publish($new_status, $old_status, $post)
    {

        if (($new_status == 'publish') && ($post->post_type == 'l')) {

            $post_id = $post->ID;

            error_log( var_export( $post_id, 1 ) );

            if (get_field('advanced_option_edit_seo', $post_id)) {


                if (defined('WPSEO_VERSION')) {

                    // ACF field
                    $metatitle    = get_field('seo_title', $post_id);

                     error_log( var_export( $metatitle, 1 ) );

                    $metadesc     = get_field('seo_meta_description', $post_id);

                     error_log( var_export( $metadesc, 1 ) );
                    $metakeywords = get_field('seo_keyword', $post_id);

                     error_log( var_export( $metakeywords, 1 ) );
                    //plugin is activated


                    //old values 

                     $metadesc_old = get_post_meta($post->ID, '_yoast_wpseo_metadesc', true);
                        error_log( var_export( $metadesc_old, 1 ) );
                     $metatitle_old = get_post_meta($post->ID, '_yoast_wpseo_title', true);
                         error_log( var_export( $metatitle_old, 1 ) );
                     $metakeywords_old = get_post_meta($post->ID, '_yoast_wpseo_focuskw', true);
                        error_log( var_export( $metakeywords_old, 1 ) );

                    update_post_meta($post_id, '_yoast_wpseo_title', $metatitle, $metatitle_old);
                       error_log( var_export( $tyone, 1 ) );
                   update_post_meta($post_id, '_yoast_wpseo_metadesc', $metadesc, $metadesc_old);
                       error_log( var_export( $tytwo, 1 ) );
                     update_post_meta($post_id, '_yoast_wpseo_focuskw', $metakeywords, $metakeywords_old);  
                       error_log( var_export( $tythree, 1 ) ); 

                }

            }

        } else {
            return;
        }

        //Do something
    }
17
  • 1
    you say when i check the what update field is returning it shows some number, that is the ID of the metadata it just inserted, this means it has worked. From the documentation: Return: Meta ID if the key didn't exist, true on successful update, false on failure.
    – Milo
    Commented Nov 10, 2018 at 17:17
  • @Milo But when i check it after updating the meta fields they are empty. Yes but all the update field returns a number(ID). Not sure if i am using correct action.
    – user145078
    Commented Nov 10, 2018 at 17:27
  • @Milo the issue was with action . every thing works if i use wp_insert_post
    – user145078
    Commented Nov 11, 2018 at 22:07
  • 1
    If (you're 100% sure) the fields are not being updated, and you did get to the update_post_meta() part, then some possible causes are: a) the fields are already updated (i.e. new values equal the current values in the database, so update_post_meta() will update nothing); or b) a plugin/code is changing back (or removing) the field values. With the wp_insert_post action, the fields may have yet existed in the post being created/updated; hence that's likely why the update_post_meta() calls work.
    – Sally CJ
    Commented Nov 13, 2018 at 12:20
  • 1
    @LatheeshVMVilla, try using a test field - update_post_meta( $post_id, 'test20181114', 'Test 20181114' ); - and see if the field is being added to the post. If it is, then your code works. PS: In my previous comment, I meant to say "When you tested with the wp_insert_post action".
    – Sally CJ
    Commented Nov 14, 2018 at 10:49

3 Answers 3

1
+50

So I installed the Yoast SEO plugin, and tested your code, and now I can positively say "neither no nor yes, but you could" to this question:

Please help not sure whether I should use this along with transition_post_status

transition_post_status is fired before the wp_insert_post action is fired, and the Yoast SEO plugin is actually saving (adding/updating) all its custom fields via the wp_insert_post action:

// See WPSEO_Metabox::save_postdata() (in wordpress-seo/admin/metabox/class-metabox.php)
add_action( 'wp_insert_post', array( $this, 'save_postdata' ) );

So your code itself works, and the fields do get updated (if the new and current values are not the same and that all the if conditions are met, of course); however the Yoast SEO plugin overrides the value via the WPSEO_Metabox::save_postdata() function, which should answer this question:

I was able to solve the issue by using 'wp_insert_post' action . Can I know why other actions failed but 'wp_insert_post' worked?

Why did I say neither no nor yes, but you could?

Because you can use transition_post_status along with wp_insert_post like so:

add_action( 'transition_post_status', 'do_updated_to_publish', 10, 2 );
function do_updated_to_publish( $new_status, $old_status ) {
    if ( $new_status !== $old_status && 'publish' === $new_status ) {
        add_action( 'wp_insert_post', 'updated_to_publish', 10, 2 );
    }
}

function updated_to_publish( $post_id, $post ) {
    // Remove it; it will be re-added via the do_updated_to_publish() function,
    // if necessary or when applicable.
    remove_action( 'wp_insert_post', 'updated_to_publish', 10, 2 );

    if ( ! defined( 'WPSEO_VERSION' ) || 'l' !== $post->post_type ) {
        return;
    }

    if ( get_field( 'advanced_option_edit_seo', $post_id ) ) {
        // Make your update_post_meta() calls here.
        update_post_meta( $post_id, '_yoast_wpseo_focuskw', 'test' );
        error_log( 'focuskw updated for post #' . $post_id );
    }
}

Tried and tested working with Yoast SEO version 9.1.

1
  • PS: The See WPSEO_Metabox::save_postdata() should be See WPSEO_Metabox::__construct(). Sorry about that. And in the updated_to_publish(), you'd also want to check if $post->post_status is publish, because double-checking is always a good practice. ;)
    – Sally CJ
    Commented Nov 15, 2018 at 1:59
0

try "wpseo_title" Filter for updating wpseo_title.

add_filter('wpseo_title', 'filter_product_wpseo_title');

function filter_product_wpseo_title($title) {
global $post;
$post_id = $post->ID;
        if (get_field('advanced_option_edit_seo', $post_id)) {

            if (defined('WPSEO_VERSION')) {

                $title = get_field('seo_title', $post_id);

            }

        }


    return $title;
}

for more seo data update example: https://yoast.com/wordpress/plugins/seo/api/

1
  • Hello, thanks. Tried but it is not working.
    – user145078
    Commented Nov 11, 2018 at 20:25
0

Your original function relies on the $_POST['post_type'] being set to the appropriate value. As a general rule, you should avoid using global variables - if you use only want the function gives to you, you don't have to think about the contexts in what it should be called.

In this case, that's what's happened. You're function relies on a global variable $_POST['post_type'], and while that works in one 'state' (publishing a post) it doesn't in another (a cron job, updating a post). In short, $_POST['post_type'] isn't always what you think it should be.

The following retrieves the post type from the passed $post variable:

add_action('transition_post_status', 'updated_to_publish', 10, 3);

function updated_to_publish($new_status, $old_status, $post) {

if (($new_status == 'publish') && (get_post_type( $post ) == 'l')) {

    $post_id = $post->ID;

    if (get_field('advanced_option_edit_seo', $post_id)) {

        if (defined('WPSEO_VERSION')) {

           //Code goes here

        }
    }

} else {
    return;
}

}

Visit this link from where I just have copied the answer

1
  • Hello , thanks ..Okay i have removed the check for post type..but now i am still having the problem...transition_post_status does not work, only wp_insert_post works. May be answer to question is why wp_insert_post only works when updating the meta
    – user145078
    Commented Nov 12, 2018 at 13:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.