When using the Payment Manager with GeoDirectory, there is no option to sort listings by price. By default, you can only sort by Featured listing.

For example, if you have 4 prices: Gold, Silver, Bronze and Free, but only 1 is Featured (Gold), when sorting by featured it will show all the featured listing on top (Gold) and all other listings (Silver, Bronze and Free) sorted by last entered regardless of the price.

Many members and potential customers asked if it was possible to sort listings by price package and until now, we always replied that it could be possible, but it would require a complex customization.

Few days ago we had few minutes available, we brainstormed about this and Stiofan (as usual) came up with a brilliant solution.

There is some coding involved, but it is extremely simple and if you follow this tutorial carefully, it’s almost impossible not to make it right the first time. For 1 custom post type and 4 prices it shouldn’t take longer than 10 to 15 minutes.

The tutorial will only cover the default custom post type (Places) and 4 prices (Gold, Silver, Bronze and Free), but it can be easily extended to any situation with multiple CPTs and any number of price packages.

It can also be adapted to existing situation and in this post we also provide a function to update existing listings.

Let’s get started:

1. Create Prices (or gather IDS of your existing prices for our next functions)

As I said we created 4 price packages for this example and you can see them in the screenshot below.

Gold, Silver, Bronze, Free Prices

Free Price = ID 1
Bronze Price = ID 7
Silver Price = ID 6
Gold Price = ID 3

Make sure to take note of the IDs of your prices, because you will have to change them in the function that you will find below.

2. Create an admin only Text custom field with “NUMBER” as Field Data Type.

Go to GeoDirectory >> Place Settings

– Add a Text custom field with “NUMBER” as Field Data Type
– In this example we called it “My Custom Sort”, but you can really name it what you prefer.
– Take note of the HTML variable for later, in our example it is : my_custom_sort (geodir_ will be the prefix)
– Set default value : 4
– Show it for all 4 price packages : Gold, Silver, Bronze and Free
– Show in sidebar : NO
– Is Active : YES
– For Admin use only : YES
– Is required : NO
– Show on listing page / more info tab / as tab in detail page : NO
– Include this field in sort option : ENABLED
– SAVE

Click on this link to see the full screenshot example.

A new custom field called My Custom Sort will appear in the back-end add/edit place form. (If you are logged in as admin you will see it in the front end too.)

3. Add the code below in the functions.php file of your active theme and adjust according to your settings.

First let me explain what the functions do.

The two functions below, will add the sort value by price in the new custom field. The first will do it every time a new listing is saved or an existing listing is updated.

The second is there for convenience in case you have many existing listings to update. You can run it only once and it allows to update all existing listings with the new custom fields at once.

In the first function you will find 2 code snippets containing a number.

A. This one checks for the package ID:

if(isset($post_info['package_id']) && $post_info['package_id']=='1')

B. This one sets the value in the new custom field “geodir_my_custom_sort” (the html variable prefixed by geodir_), if you changed the custom field variable name you will have to change it here (example if your custom field html variable is default, here you will use geodir_default instead of geodir_my_custom_sort).

geodir_save_post_meta($post_id, 'geodir_my_custom_sort','4');

So package ID 1 (which in our case is the free package) will have position 4.

Below is the full snippet that needs to be added to the functions.php of file your active theme for this example.

Please read the comments within the code for more clarity:


// fire the function every time a listing is published or edited 
add_action('geodir_after_save_listing','my_change_custom_field_on_save',10,2);

// this is the function that will set the correct value in the my_custom_sort custom field
function my_change_custom_field_on_save($post_id, $post_info){

  //Checks for package ID 1, the free price in our example
  if(isset($post_info['package_id']) && $post_info['package_id']=='1'){

  //set position number 4 in geodir_my_custom_sort for the free price
    geodir_save_post_meta($post_id, 'geodir_my_custom_sort','4');

  //Checks for package ID 7, the bronze price in our example
  }elseif(isset($post_info['package_id']) && $post_info['package_id']=='7'){

  //set position number 3 in geodir_my_custom_sort for the bronze price
    geodir_save_post_meta($post_id, 'geodir_my_custom_sort','3');

  //Checks for package ID 6, the silver price in our example
  }elseif(isset($post_info['package_id']) && $post_info['package_id']=='6'){

  //set position number 2 in geodir_my_custom_sort for the silver price
    geodir_save_post_meta($post_id, 'geodir_my_custom_sort','2');

  //Checks for package ID 3, the gold price in our example
  }elseif(isset($post_info['package_id']) && $post_info['package_id']=='3'){

  //set position number 1 in geodir_my_custom_sort for the gold price
    geodir_save_post_meta($post_id, 'geodir_my_custom_sort','1');

  }

}

//this is the function to update all existing listings at once. It won't do anything until we call it from within a template.
function my_change_custom_field_on_save_existing() {

global $wpdb;

//set position 4 for free price on custom field geodir_my_custom_sort 
$wpdb->query("UPDATE `wp_geodir_gd_place_detail` SET `geodir_my_custom_sort`=4 WHERE `package_id`=1");

//set position 3 for bronze price on custom field geodir_my_custom_sort  
$wpdb->query("UPDATE `wp_geodir_gd_place_detail` SET `geodir_my_custom_sort`=3 WHERE `package_id`=7");

//set position 2 for silver price on custom field geodir_my_custom_sort 
$wpdb->query("UPDATE `wp_geodir_gd_place_detail` SET `geodir_my_custom_sort`=2 WHERE `package_id`=6");

//set position 1 for gold price on custom field geodir_my_custom_sort 
$wpdb->query("UPDATE `wp_geodir_gd_place_detail` SET `geodir_my_custom_sort`=1 WHERE `package_id`=3");

}

If we have existing listings, we need to call the second function from within a template to make it run once.

To do this, we need to go to Appearance >> Editor and select the 404.php template of our theme. If you are running a child theme, probably you won’t see a 404.php template. In that case make sure to select the parent theme from the option: Select theme to edit.

All you need to add is :

<?php my_change_custom_field_on_save_existing(); ?>

update existing listings

Now visit a non existing page of your website, example:

yousite.com/avlrhgahajanfkjnad

This will return a 404 page, run our function and update all existing listings.

###IMPORTANT###

Remember to delete

<?php my_change_custom_field_on_save_existing(); ?>

from your 404.php template after running it once, or everytime someone lands on a 404 page of your website, the function will run again. It will make no damage, but if you have a lot of listings it could take time to run and slow down your website.

4. Set the new custom field as default sorting option.

Go to GeoDirectory >> Place Settings >> Sorting Option.

You will find the new My Custom Sort option available in the left box: Available sorting options for Place listing and search results

Double click on it to activate it and move it in the right box. Once on the right box, double click on it again to open up it’s settings options.

– Select Ascending : Enable Set as default sort.
– Is active : Yes

new default sort

At this point we will see our listings sorting by price in both listings pages and search (whenever a keyword or location isn’t searched).

final result

This sorting method can only be applied to GeoDirectory Listings pages, not widgets.

5 thoughts on “How to sort listings by price

  1. Hi Stiofan, I have applied the technique you outlined above to our site at https://dinnerdata.co.uk.

    If we search leaving fields clear, it isn’t returning the sort order using custom sort, I think I might be missing something obvious but perhaps you can help point me in the right direction.

    We have included the code in the functions.php you outline above, modified it for our larger list of packages, and run it via the modified 404 page, and it seems to have worked fine, so I think it is a setting to do with displaying results.

    Look forward to any pointer you can provide please.

  2. Hello all, here every one is sharing such knowledge, therefore it’s nice to read this
    webpage, and I used to go to see this webpage every
    day.

Leave a Reply

Your email address will not be published. Required fields are marked *

Share This