Skip to main contentSkip to footer

Wishlist Member: Sorting the posts by membership levels

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

PSA: New ransom scam in town

We were threatened with a new ransom extortion message. I haven’t seen this one before, looks like it’s new but already spreading out widely. I’m sharing it here as to remind everyone that even though messages like this can feel scary, they’re fake. Just look at this: Your reputation and…

Excluding protected posts

A site I’m working with has a handful of “protected” posts (password required to view). For various reasons, we don’t want to show these in search results. While there is no excerpt shown, I’d prefer for people to not even know they exist. Relevanssi sees protected posts as public posts……2 ); function rlv_search_exclude_protected( $allow, $post_id ) { $post = get_post( $post_id ); if ( ! empty( $post->post_password ) ) { $allow = false; if ( is_user_logged_in() ) { $allow = true; } } return $allow; } Now protected posts are not shown to searchers who are not logged in….

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