Skip to main contentSkip to footer

Someone wanted a way to prioritize posts that are targeting particular Wishlist Member membership level. The basic implementation here is simple: create a relevanssi_hits_filter function that will sort the posts by the level.

There’s a trick to this, though, as Wishlist Member does not provide a way to check the level of one post. There’s a function that will get all the posts on a particular level, though, so we need to come up with a method to get the list once, then use it to check each individual post.

The relevanssi_hits_filter function is simple: it uses array_filter()to get the target posts from the list of all search results, then array_udiff() to get the rest of the posts and then array_merge() to merge the list back together in the correct order.

The filter function for array_filter() calls a function that will return a list of post IDs for the target level posts and uses that check whether a post is on that list or not.

The function that gets the list of post IDs will do that once, and will then just return the list on later calls.

/**
 * Generates the list of posts for the specific membership level.
 *
 * The list is fetched with wlmapi_get_level_posts(), which returns a
 * fairly complicated format. The format is simplified with
 * array_column() to extract just the post IDs. Those are set as
 * array keys with value of true to make lookup faster, as you can then
 * use isset( $array[ $post_ID ] ) instead of slower in_array().
 *
 * @param int $level The membership level.
 *
 * @return array An array of post_ID => true pairs.
 */
function rlv_generate_level_post_list( $level ) {
	global $rlv_wishlist_level_posts;
  
	if ( ! isset( $rlv_wishlist_level_posts[ $level ] ) ) {
		$rlv_wishlist_level_posts[ $level ] = array();
    }

	if ( empty( $rlv_wishlist_level_posts[ $level ] ) ) {
		$results = wlmapi_get_level_posts( $level );

		$rlv_wishlist_level_posts[ $level ] = array_fill_keys(
			array_column( $results['posts']['post'], 'ID' ),
			true
		);
	}

	return $rlv_wishlist_level_posts[ $level ];
}

/**
 * Filter function that returns true if posts is on the specific level.
 *
 * @param WP_Post The post object to check.
 *
 * @return boolean True if post is on the specific level.
 */
function rlv_free_filter( $post ) {
	$free_posts = rlv_generate_level_post_list( 1313127748 );
	return isset( $free_posts[ $post->ID ] );
}

/**
 * Comparison function for array_udiff: post objects are considered
 * equal if they have the same ID.
 *
 * @param WP_Post $a Compared object.
 * @param WP_Post $b Compared object.
 *
 * @return int 0 if the objects are equal, not 0 if not.
 */
function rlv_id_comparison( $a, $b ) {
	return $a->ID - $b->ID;
}

add_filter( 'relevanssi_hits_filter', 'rlv_free_posts_first' );

/**
 * Adjusts the hits so that posts on the specific Wishlist Member level
 * are first in the results.
 *
 * @param array $hits Contains the posts in $hits[0].
 *
 * @return array The $hits array, filtered.
 */
function rlv_free_posts_first( $hits ) {
	$free_posts  = array_filter( $hits[0], 'rlv_free_filter' );
	$other_posts = array_udiff( $hits[0], $free_posts, 'rlv_id_comparison' );
	$hits[0]     = array_merge( $free_posts, $other_posts );

	return $hits;
}

Your account

Not logged in. Log in to see your license details.

Search

Popular Resources

Indexing term slugs
I have a term who name is for, example, Great Blue Trojans. The slug is GBT.I want to be able…
Indexing post slugs
By default, Relevanssi does not index the post slug. It is, however, an easy thing to fix using the relevanssi_content_to_index…
Sorting search results
If you want something else than the default relevancy ranking, you can use orderby and order parameters for the search…

Related Posts:

Comment Section:

Leave a Reply

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

Fill out this field
Fill out this field
Please enter a valid email address.
You need to agree with the terms to proceed