How to force function to run as the last one when saving the post?

I don’t know how to force this function to run as the last function after all other save things from WP are executed.

This is my current code in my plugin:

Read More
add_action( 'save_post', 'do_custom_save' ); 
function do_custom_save( $post_id ) { 


    // No auto saves 
    if( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return; 

    // make sure the current user can edit the post 
    if( ! current_user_can( 'edit_post' ) ) return;

    // assure the post type
    if ( ! get_post_type($post_id) == 'post' ) return;


    $latitude  = $_POST['rw_company_latitude'];
    $longitude = $_POST['rw_company_longitude'];
    $zoom      = '6';

    $lat_lon_zoom = $latitude . ', ' . $longitude . ', ' . $zoom ;

    update_post_meta($post_id, 'company_map', $lat_lon_zoom );


}

How to force this code to be executed and saved the mixed variable as the last thing? After all the other saving and updating is done.

Because right now it’s updated ok, but then again rewritten by the value from original map field $_POST[‘company_map’]. I need to somehow tell WP that this function should run as the last function when performing saving/updating post stuff.

How to do that?

Related posts

2 comments

  1. add_action has a priority parameter which is 10 by default, you can increase that to load your function late.

    Change add_action( 'save_post', 'do_custom_save' );

    to

    add_action( 'save_post', 'do_custom_save', 100 );

    Now the priority is to set to 100 and will load quite late and will allow other function associated to load before this function is executed.

    For more details check the function reference for add_action.

  2. Maruti Mohanty’s suggestion is not bad, but it will fail. There are many core actions with a higher priority:

    • wp-admin/menu.php:

      add_action('admin_menu', '_add_themes_utility_last', 101);
      
    • wp-includes/admin-bar.php:

      add_action( 'wp_footer', 'wp_admin_bar_render', 1000 );
      
    • wp-includes/canonical.php

      add_action( 'template_redirect', 'wp_redirect_admin_locations', 1000 );
      
    • wp-includes/class-wp-admin-bar.php:

      add_action( 'admin_bar_menu', 'wp_admin_bar_add_secondary_groups', 200 );
      
    • wp-includes/class-wp-customize-manager.php:

      add_action( 'wp_redirect_status', array( $this, 'wp_redirect_status' ), 1000 );
      add_action( 'shutdown', array( $this, 'customize_preview_signature' ), 1000 );
      
    • wp-includes/widgets.php:

      add_action( 'widgets_init', array( $this, '_register_widgets' ), 100 );
      

    And plugins and themes can use a higher priority too.

    So you have to inspect the current filter or action in $GLOBALS['wp_filter'], find the highest key and add something. Be aware, a priority could be a string, because it is an array key:

    The key can either be an integer or a string.

    So let’s make a function get_latest_priority() as a tool:

    /**
     * Get the highest needed priority for a filter or action.
     *
     * If the highest existing priority for filter is already PHP_INT_MAX, this
     * function cannot return something higher.
     *
     * @param  string $filter
     * @return number|string
     */
    function get_latest_priority( $filter )
    {
        if ( empty ( $GLOBALS['wp_filter'][ $filter ] ) )
            return PHP_INT_MAX;
    
        $priorities = array_keys( $GLOBALS['wp_filter'][ $filter ] );
        $last       = end( $priorities );
    
        if ( is_numeric( $last ) )
            return PHP_INT_MAX;
    
        return "$last-z";
    }
    

    Use this function lately. Wait until most other code has registered its callback. To do that, hook into your desired action first with a priority 0, get the highest priority you need, and then register the real callback:

    add_action( 'save_post', 'register_custom_save', 0 ); 
    
    function register_custom_save() 
    {
        add_action( 
            'save_post', 
            'do_custom_save',
            get_latest_priority( current_filter() ),
            2 
        ); 
    }
    

Comments are closed.