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
    }
  • 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 Nov 10 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. – Latheesh V M Villa Nov 10 at 17:27
  • @Milo the issue was with action . every thing works if i use wp_insert_post – Latheesh V M Villa Nov 11 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 Nov 13 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 Nov 14 at 10:49
up vote 1 down vote accepted
+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.

  • 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 2 days ago

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/

New contributor
mithun raval is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.

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

  • 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 – Latheesh V M Villa Nov 12 at 13:27

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.