posts_results filter – additional sort, with a meta value, to move posts to the end of the results, with pagination working

Okay, so why doesn’t this work:

The Filter you are using is the posts_results, which is a filter that is applied AFTER the Results are retrieved from the database. Which has the problem that you are describing: Ordering happens on a page-per-page basis.

What you want to do is add an order TO the SQL-Query, so that the order is applied to the complete result and your Locations are retrieved first open, then closed.

The way to do that is to remove the posts_results filter, and then use the pre_get_posts action:

function wpse_420312_order_locations_by_open_closed( $query ) {
    //First we need to check that this is the "main" query and that we're not on a backend page
    if ( $query->is_main_query() && !is_admin() ) {
        $post_type = $query->get('post_type');
        if ( $post_type === 'location' ) {
            //we need to build a meta query. To learn more, look here: https://developer.wordpress.org/reference/classes/wp_meta_query/
            $meta_query = array(
                //to sort by a meta query, we have to name it
                'location_status' => array(
                    //luckily, ACF saved custom fields with their name as the meta_key
                    'key' => 'location_status',
                    //we only want to see locations that have the status information
                    'compare' => 'EXISTS'
                )
            );
            $query->set( 'meta_query', $meta_query );
            //sort by: location Status DESC (first "Open", then "Closed"), then post title ASC
            $query->set( 'orderby', array( 'location_status' => 'DESC', 'title' => 'ASC', 'ID' => 'ASC' ) );
        }
    }
}
add_action( 'pre_get_posts', 'wpse_420312_order_locations_by_open_closed' );

Happy Coding!