Given a custom URL like:


I'm trying to catch the URL and add the user_id to a custom post meta field.

My code looks like:

function add_user_to_tvt(){

    $post_id = $_GET['post_id'];
    $user_id = $_GET['user_id'];

    $current_members = get_post_meta( absint( $post_id ), '_pmc_members', true );
    $current_members[] = $user_id;
    $unique = array_unique( $current_members );

    $value = update_post_meta( absint( $post_id ), '_pmc_members', $unique );

    if ( false === $value ){
        $message = 'You were not added. Please contact an administrator';
        $success = false;
    } else {
        $message = 'You were added to the team. Refresh the page to see your name.';
        $success = true;

    $values = array(
        'success' => $success,
        'message' => $message,

    return (array) $values;

} // add_user_to_tvt

add_action( 'init', 'add_user_to_tvt' );

The problem is that when I open a new tab and put in the URL update_post_meta returns false and so the feedback given to the user is that it failed even though, it did in fact update.

If I refresh that same page with the URL sitting in the browser, update_post_meta returns the expected value and the proper feedback is returned to the user.

Yes I am handling the fact that update_post_meta returns false if the current value and the value you're trying to update are the same. We don't even call the function above if the value already exists.

Update so it seems that this does work as expected and return the values properly if we delay the check till the template_redirect action. In which case, things work for me now (woohoo) but I've always caught URL and such via the 'init' hook.

Should we not be doing that?

Update: I realize init doesn't pass $post_id or $user_id. This is a simplified version of the code that doesn't work. We catch these 2 values and pass it to the function above. I just moved the 'catch' inside the function to keep things short.

  • init is way to early. Try template_include or similar – Pieter Goosen Apr 14 '15 at 16:25
  • And why is that the place to do this versus init? What portion of the WordPress lifecycle is needed? – curtismchale Apr 14 '15 at 16:28
  • 1
    Probably not related to your problem, but init doesn't pass $post_id or $user_id to the callback, so if you're not using WP_DEBUG you're probably missing some function call errors. Same with expecting the $_GET vars to be there on every load. – NateWr Apr 14 '15 at 16:29
  • Yup @NateWr I know that. I don't rely on init, this is just making it simple for StackExchange to see. – curtismchale Apr 14 '15 at 16:31
  • 1
    The comment by @NateWr is why init won't work here. The post object has not yet being set when init fires. By the time template_include (you can also use template_redirect here which is more preferable, was a bit to hasty here) fires, the post object has been set up and the main query has run – Pieter Goosen Apr 14 '15 at 16:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.