Multiple Random Post Sort Order in Single Query

Hi Friends,

Actually my problem is already solved here

https://wordpress.org/support/topic/order-by-custom-field-strange-problem?replies=11

but that time, i didn't got the entries so i can't check its proper working.

First page is already working fine but the issue is when i visit the 2nd page the entries are also coming in random..

You can see it live here
http://www.ekarnal.com/cats/directory/

I just need simple hack, that list the post orderd by platinum, featured and basic but all of them in their own random order.

Like i have total of 10 Platinum Posts and 5 Featured and 20 Basic Posts

Now first posts to be shows are Platinum But all in random order, then Featured in random order too and then basic in random order.

Please help me out as i need to sort this out ASAP

Thanks

  • Shabir

    Thanks Tyler,

    Actually i have 3 listing types right now with custom field named Platinum, Featured and Basic.

    Its basically a directory and i want to show the listings with the order like Platinum -> Featured -> Basic.

    But we have many posts in these section and we can't provide them an order.

    Every one wants fair deal, so we decided to go with the random order.

    All i need is when a person visit the category, it first shows the Platinum members but in random order and then featured members again with random order and then basic members with random order.

    Hope you understand my question

    Thanks

  • Sybre Waaijer

    Hi @Shabir,

    Might it be possible to split the queries into two where one contains the platinum subscribers and the other will be your random query?
    In other words, remove the $featured_args for the first query and use your current one for the following query and print them in order.

    You can use the post_per_page parameter to show only 3 platinum subscribers on top for example (just like Google does).

    The following example is a fork of the one on the wordpress.org page, but then with only platinum subscribers.
    P.S. I've never used the pre_get_posts function and I'm not even sure where they will be placed, so this is just a guess.

    function my_platinum_post_queries( $query ) {
    	// not an admin page and is the main query
    	if ( !is_admin() && $query->is_main_query() ) {
    		// category and search pages
    		if ( is_category() || is_tag() || is_tax() || is_search() ) {
    			add_filter( 'posts_orderby', 'add_platinum_orderby' );
    		}
    	}
    }
    add_action( 'pre_get_posts', 'my_platinum_post_queries' );
    
    function add_platinum_orderby( $orderby ) {
    	global $wpdb;
    
    	$args = array(
    		'meta_key' => 'listing_type',
    		'fields' => 'ids',
    		'orderby' => 'rand',
    		'posts_per_page' => 3, //only 3 platinum posts
    	);
    
    	if ( is_category() || is_tag() || is_tax() ) {
    		$obj = get_queried_object();
    		$tax_query = array(
    			array(
    				'taxonomy' => $obj->taxonomy,
    				'field' => 'id',
    				'terms' => $obj->term_id,
    			)
    		);
    		$args['tax_query'] = $tax_query;
    	}
    
    	$platinum_args = $args + array( 'meta_value' => 'platinum' );
    
    	$platinum = (array) get_posts( $platinum_args );
    
    	$posts = array_unique( $platinum );
    
    	if ( $posts ) {
    
    		// add custom ordering
    		$sql = ' CASE';
    		$i = count( $posts );
    		foreach ( $posts as $post ) {
    			$sql .= " WHEN $wpdb->posts.ID = $post THEN $i";
    			$i--;
    		}
    		$sql .= ' ELSE 0 END DESC, ';
    
    		$orderby = $sql . $orderby;
    	}
    
    	return $orderby;
    }

    This might not exactly be what you needed but it should be possible to merge your code with mine displayed above. When I have the time I'll try to fix that for you (if it still needs fixing, that is).

  • Sybre Waaijer

    Hi @Shabir

    Unfortunately, I cannot replicate the usage of your the plugin in question - I never really work with taxonomies and categories in general.

    This means I cannot test the plugin D:

    However, that doesn't mean I can't read instructions from http://codex.wordpress.org/Template_Tags/get_posts

    So I'll take another go, please report back if it works or now :slight_smile: (I can't check that myself :slight_frown: ).

    function my_post_queries( $query ) {
    	// not an admin page and is the main query
    	if ( !is_admin() && $query->is_main_query() ) {
    		// category and search pages
    		if ( is_category() || is_tag() || is_tax() || is_search() ) {
    			add_filter( 'posts_orderby', 'add_featured_orderby' );
    		}
    	}
    }
    add_action( 'pre_get_posts', 'my_post_queries' );
    
    function add_featured_orderby( $orderby ) {
    	global $wpdb;
    
    	$args = array(
    		'meta_key' => 'listing_type',
    		'fields' => 'ids',
    /*		'orderby' => 'rand', */ //Removed and overwritten
    /*		'posts_per_page' => -1, */ //Removed and overwritten
    	);
    
    	if ( is_category() || is_tag() || is_tax() ) {
    		$obj = get_queried_object();
    		$tax_query = array(
    			array(
    				'taxonomy' => $obj->taxonomy,
    				'field' => 'id',
    				'terms' => $obj->term_id,
    			)
    		);
    		$args['tax_query'] = $tax_query;
    	}
    
    	$platinum_before_args = $args + array( 'meta_value' => 'platinum', 'posts_per_page' => 3, 'orderby' => 'rand' );
    	$platinum_args = $args + array( 'meta_value' => 'platinum', 'posts_per_page' => -1, 'orderby' => 'rand' );
    	$featured_args = $args + array( 'meta_value' => 'featured', 'posts_per_page' => -1, 'orderby' => 'rand' );
    
    	$platinum_before = (array) get_posts( $platinum_before_args );
    	$platinum = (array) get_posts( $platinum_args );
    	$featured = (array) get_posts( $featured_args );
    
    	$posts = array_unique( array_merge( $platinum, $featured ) );
    
    	if ( $platinum_before ) { //returning platinum posts
    
    		// add custom ordering
    		$sql = ' CASE';
    		$i = count( $platinum_before );
    		foreach ( $platinum_before as $post ) {
    			$sql .= " WHEN $wpdb->posts.ID = $post THEN $i";
    			$i--;
    		}
    		$sql .= ' ELSE 0 END DESC, ';
    
    		$orderby1 = $sql . $orderby;
    	}
    
    	if ( $posts ) { //returning the rest
    
    		// add custom ordering
    		$sql = ' CASE';
    		$i = count( $posts );
    		foreach ( $posts as $post ) {
    			$sql .= " WHEN $wpdb->posts.ID = $post THEN $i";
    			$i--;
    		}
    		$sql .= ' ELSE 0 END DESC, ';
    
    		$orderby2 = $sql . $orderby;
    	}
    
    	return $orderby1 . $orderby2;
    }
  • Shabir

    Hi,

    Right now i m using this code and its perfectly working
    http://www.ekarnal.com/cats/directory/

    function my_post_queries( $query ) {
    	// not an admin page and is the main query
    	if ( !is_admin() && $query->is_main_query() ) {
    		// category and search pages
    		if ( is_category() || is_tag() || is_tax() || is_search() ) {
    			add_filter( 'posts_orderby', 'add_featured_orderby' );
    		}
    	}
    }
    add_action( 'pre_get_posts', 'my_post_queries' );
    
    function add_featured_orderby( $orderby ) {
    	global $wpdb;
    
    	$args = array(
    		'meta_key' => 'listing_type',
    		'fields' => 'ids',
    		'orderby' => 'rand',
    		'posts_per_page' => -1,
    	);
    
    	if ( is_category() || is_tag() || is_tax() ) {
    		$obj = get_queried_object();
    		$tax_query = array(
    			array(
    				'taxonomy' => $obj->taxonomy,
    				'field' => 'id',
    				'terms' => $obj->term_id,
    			)
    		);
    		$args['tax_query'] = $tax_query;
    	}
    
    	$premium_args = $args + array('meta_value' => 'premium');
    	$advanced_args = $args + array('meta_value' => 'advanced');
    	$basic_args = $args + array('meta_value' => 'basic');
    
    	$premium = (array) get_posts( $premium_args );
    	$advanced = (array) get_posts( $advanced_args );
    	$basic = (array) get_posts( $basic_args );
    
    	$posts = array_unique( array_merge( $premium, $advanced, $basic) );
    
    	if ( $posts ) {
    
    		// add custom ordering
    		$sql = ' CASE';
    		$i = count( $posts );
    		foreach ( $posts as $post ) {
    			$sql .= " WHEN $wpdb->posts.ID = $post THEN $i";
    			$i--;
    		}
    		$sql .= ' ELSE 0 END DESC, ';
    
    		$orderby = $sql . $orderby;
    	}
    
    	return $orderby;
    }

    The only problem i am getting is the entries are not properly when i m going to the 2nd page.

    Entries are in Random order, so the few entries which are already on 1st page coming back to the 2nd page..

    I think there is must some thing with the pagination order.

  • Michelle Shull

    Hi, Shabir.

    As Sybre explained in his reply above, what you want will take additional custom work. We're more than happy to help with many WordPress issues, but as a support forum, we're not really equipped to whip up custom plugins.

    The reason you're seeing repeats on your second page is because you've assigned the posts to display at random, so each page (like page one, page two, etc.) will be generating a random list when the page is created. With this awesome method Sybre shared, each post slot is given a post to show randomly, on a post by post basis, so there's a potential for repeats, as there's nothing telling WordPress to remove a post from the list once it's added to a slot. Each subsequent slot on the page would need to query only posts that have not already been randomly selected in order to give you a 100% repeat-free list across multiple pages.

    This might be a great project for our Jobs Board, but it's definitely advanced custom code creation.

    Thanks, Shabir!

  • aristath

    Hello there @Shabir, I hope you're well today!

    I think its not an hard job, We just need to first pull all the IDS of premium Listing and get the posts in random.

    Then do the same thing for Basic and shuffle the IDs and show the results.

    Yes, you're right. That's what you'd have to do... However this is beyond the scope of support we can provide in these forums.
    You can however post a new job in our Jobs Board on https://premium.wpmudev.org/wordpress-development/ so that a skilled developer can do that for you. :slight_smile:

    Cheers,
    Ari.

Thank NAME, for their help.

Let NAME know exactly why they deserved these points.

Gift a custom amount of points.