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; }