Forums › Forums › Search & Filter Pro › Multiple forms on one page + search analytics
- This topic has 15 replies, 3 voices, and was last updated 6 years, 8 months ago by Ross.
-
Ross Moderator(Private) March 28, 2018 at 5:51 pm #168826
Hi Liam
I had a look (and was surprised that you could add an
orderby
with random seed to the query object so easily)! You learn something new every day!Anyway, I tested the code you were using and it mostly seemed correct – but I had some trouble getting it working.
I realised, in this scenario, using our filter
sf_edit_query_args
was the wrong filter to use, because it is called several times (once for the main query, and again, while generating our filters) – which probably meant your seed being continually reset, or reset 3 times in 1 page load.— As a side note, the whole purpose of this filter we use is so that any modification you do to the query, is also reflected in the filter counts…
However, in this case, ordering the results will have no effect on the filter counts, so its not necessary and we can go ahead and use
pre_get_posts
.Using your code, and some I’ve found online, I think I’ve managed to successfully do this:
session_start(); add_filter( 'pre_get_posts', 'sf_sort_random_seed', 200, 2 ); function sf_sort_random_seed( $query ) { if( !is_admin() && $query->is_main_query() ) { //$query->set( 'posts_per_page', 1 ); // testing //grab the ID from the query_vars $sfid = 0; if(isset($query->query_vars['search_filter_id'])) { $sfid = $query->query_vars['search_filter_id']; } if($sfid==27339||$sfid==27361) { // Reset seed on load of initial archive page $sf_paged = 0; if(isset($_GET['sf_paged'])){ $sf_paged = $_GET['sf_paged']; } if( $sf_paged == 0 || $sf_paged == 1 ) { if( isset( $_SESSION['seed'] ) ) { unset( $_SESSION['seed'] ); } } // Get seed from session variable if it exists $seed = false; if( isset( $_SESSION['seed'] ) ) { $seed = $_SESSION['seed']; } // Set new seed if none exists if ( ! $seed ) { $seed = rand(); $_SESSION['seed'] = $seed; } // Inject the order into the query $query->set( 'orderby', 'RAND(' . $seed . ')' ); } } return $query; }
This seems to be working for me anyway! Just watchout when using sessions, I’ve heard many cases of them not working in WP, and needing to use transients instead.
Let me know if it works!
Thanks
Anonymous(Private) March 29, 2018 at 3:36 am #168910Thanks Ross!
I had a feeling the supplied filter was not going to work. I tested your version of the function and was unable to get it working. I realised that I hadn’t yet attempted to do this with transients! I completely forgot about them, havent used them in years. My main problem was getting getting session/cookie data to work so this presented a new avenue to explore.
I rewrote your function using transients and was immediately able to get it reading and writing properly. I was then able to debug why the function still wasn’t working and realised the injected orderby var was being ignored. I realised that pre_get_posts will have no effect on the posts order because the posts_orderby action will override it after that.
So! I restructured the function that modifies the pre_get_posts query and use it to filter the posts_orderby variable after that. voila! I did some testing and so far its working on all fronts. This works with or without ajax and works with my original setup of having 2 forms on a single page for the same archive.
Feel free to share with anyone that wants to preserve pagination with random ordering:
function sf_pre_posts( $query ){ if( !is_admin() && $query->is_main_query() ) { $sfid = 0; if(isset($query->query_vars['sfid'])) { $sfid = $query->query_vars['sfid']; } if($sfid==27339||$sfid==27361) { add_filter('posts_orderby', 'sf_order_random_seed'); } } else { remove_filter('posts_orderby', 'sf_order_random_seed'); } } add_action( 'pre_get_posts', 'sf_pre_posts', 200, 2 ); function sf_order_random_seed( $orderby ) { // Reset seed on load of initial archive page $sf_paged = 0; if(isset($_GET['sf_paged'])){ $sf_paged = $_GET['sf_paged']; } // Detect first page of results if( $sf_paged == 0 || $sf_paged == 1 ) { if( get_transient( 'rand_trans' ) ) { // delete transient if it exists delete_transient( 'rand_trans' ); } } // Get seed from transient if it exists $seed = false; if( get_transient('rand_trans') ) { $seed = get_transient( 'rand_trans' ); } // Set new seed and transient if none exists if ( ! $seed ) { $seed = rand(); set_transient( 'rand_trans', $seed, 60*60*12 ); } // Setup orderby statement $orderby = 'RAND('.$seed.')'; return $orderby; }
Thanks you both for the feedback and good tips, really appreciate it.
Cheers,
Josh.Ross Moderator(Private) March 29, 2018 at 2:44 pm #168982Hi Josh!
It’s strange, I would have never thought putting the
random(seed)
in the query using->set
would work, and by the sounds of it, that’s why you went with theposts_orderby
filter (which is also the method I found when googling).However, it actually seemed to worked fine for me, most odd.
Thanks for sharing anyway – this is something I will likely include in an upcoming version of S&F.
Best
Ross Moderator(Private) March 29, 2018 at 4:56 pm #168999Hi Josh
I’ve just thought of a problem with your logic.
When saving $_SESSION variables, these are personalised to each visitor so would work as expected.
However, the transient you are using is global – it has one name for every user. This means, when another user visits page 1 of results, your seed will be reset, causing problems for another visitor on page 2 etc.
I can’t remember how exactly, but there is a way to use transients like sessions, so every visitor gets their own key generated – I think WooCommerce and others do something similar but I’m afraid I can’t think of how off the top of my head.
Anyway thought I’d give you a headsup on that as it just popped into my head.
Thanks
-
AuthorPosts