Skip Navigation

[Resolved] Need help refining filters for a "Suggested Properties" View

This support ticket is created 4 years, 3 months ago. There's a good chance that you are reading advice that it now obsolete.

This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.

Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.

Sun Mon Tue Wed Thu Fri Sat
- 7:00 – 14:00 7:00 – 14:00 7:00 – 14:00 7:00 – 14:00 7:00 – 14:00 -
- 15:00 – 16:00 15:00 – 16:00 15:00 – 16:00 15:00 – 16:00 15:00 – 16:00 -

Supporter timezone: Europe/London (GMT+01:00)

This topic contains 2 replies, has 2 voices.

Last updated by jeleenC 4 years, 3 months ago.

Assisted by: Nigel.

Author
Posts
#1435685
Suggested-Properties.JPG

Tell us what you are trying to do? I have created a "Suggested Properties" view using Toolset. There are two main parameters that should be met for a property to be considered related: location (taxonomy) and price (custom field). I have attached a screenshot of how I set up the filters.

Here is an example of a single property listing with its "Suggested Properties" below: hidden link

As you can see, the price matching is off.

This would have been acceptable if there are truly no other properties that match the criteria, but as you can see on this page, there are plenty that match the location AND price: hidden link

Can you suggest a solution to this, maybe a refinement to the filters I am using?

Ideally, all suggested properties would come from the same location (taxonomy), sorted by how similar their price is to the current property. Otherwise, it will be the top 3 properties with the same price.

I was initially thinking of filtering by location and sorting by price based on how close it is to the current price, but that option is not available (only ascending and descending)

Thanks in advance!

#1436007

Nigel
Supporter

Languages: English (English ) Spanish (Español )

Timezone: Europe/London (GMT+01:00)

The Query Filters that you can add are determined by the underlying WP_Query Class that WordPress uses to retrieve posts from the database.

You can see the available parameters here: https://developer.wordpress.org/reference/classes/wp_query/#custom-field-post-meta-parameters

You can use comparisons such as equals or greater than, and in your case you've tried to use LIKE which is actually for string matches. There isn't really anything for the use case you describe.

What you really need is to work with the orderby parameters (https://developer.wordpress.org/reference/classes/wp_query/#order-orderby-parameters) where you order by difference from the price of the current post, disregarding sign.

Again, there isn't anything very helpful there. You can only sort by the custom field values, not by some dynamic calculation using the custom field value (e.g. INT(50000 - meta_value) to order the posts by those closest to 50,000).

So, although the request appears simple enough, the implementation is actually quite complex, because of how the underlying WordPress queries work.

You can use the API hook 'wpv_filter_query_post_process' to test and manipulate the View query results before they are output so that you can manually re-order the results and limit as required.

I prepared some sample code you can test on your site. It assumes you have a View created to display these posts, which should only include a Query Filter for the taxonomy, not for the price, and which should contain no setting to limit the number of returned posts.

Then you can try adding the following PHP code (at Toolset > Settings > Code Snippets):

/**
 * Re-order View results 
 */
add_filter( 'wpv_filter_query_post_process', 'ts_closest_items', 10, 3 );
function ts_closest_items( $query_args, $view_settings, $view_id ){

    /** SETTINGS */
    $view_ids = array( 123 ); // update with IDs of Views to apply to
    $field = 'wpcf-max-price'; // slug of comparison custom field with Types 'wcpf-' prefix
    $limit = 3; // how many posts to return

    if ( in_array( $view_id, $view_ids ) ) {

        global $post;
        $base_value = get_post_meta( $post->ID, $field, true );
        $results = $query_args->posts;
    
        foreach ($results as $result) {
            $value = get_post_meta( $result->ID, $field, true );
            $result->value_diff = abs($base_value - $value);
        }
        usort( $results, "custom_cmp" );
        
        $query_args->posts = array_slice( $results, 0, $limit );
        $query_args->found_posts = $limit;
        $query_args->post_count = $limit;
    }

    return $query_args;
}

function custom_cmp($a, $b) {
    if ($a->value_diff == $b->value_diff) {
        return 0;
    }
    return ($a->value_diff > $b->value_diff) ? 1 : -1;
}

You will need to edit the first few lines for the ID of the View(s), the field you want to compare, and the number of posts which should be returned.

Let me know how you get on.

#1437735

My issue is resolved now. Thank you!

This ticket is now closed. If you're a WPML client and need related help, please open a new support ticket.