With Paid Membership Pro (PMPro) plugin, you can restrict certain products for certain membership levels. But by default, when a member visits shop, they can still see those restricted products, which they were not supposed to see. We will avoid that using woocommerce_product_query
action hook, by modifying the default WooCommerce query.
/**
* Get all page/post/custom post type ID based on pmpro membership level
*/
function careless_get_pmpro_member_pages( $user_level ) {
global $wpdb;
$page_ids = array();
$sql = "SELECT page_id FROM $wpdb->pmpro_memberships_pages WHERE membership_id = $user_level";
$results = $wpdb->get_results( $sql, ARRAY_A );
if ( $results ) {
foreach ( $results as $result ) {
$page_ids[] = $result['page_id'];
}
}
return $page_ids;
}
/**
* Modify default WooCommerce query
*/
function careless_maintain_membership_restriction_for_woo_products_shop_page( $query ) {
//avoid for admin users - admin should have access to all - if you don't need this, simply remove this portion
if( current_user_can( 'manage_options' ) ){
return $query;
}
//get membership level of current user
$membership_level = pmpro_getMembershipLevelForUser();
if ( !$membership_level ) {//doesn't have any active membership level
$page_ids = array( 1 );//set some unavailable id as product id, to show no product at all
} else {//user is active member
//get page (page/post/product) ids for the membership level of current user
$page_ids = careless_get_pmpro_member_pages( $membership_level->ID );
}
//modify woocommerce query - to only show products for current user membership level
$query->set( 'post__in', $page_ids );
$query->set( 'ignore_sticky_posts', true );//avoid sticky posts!
}
add_action( 'woocommerce_product_query', 'careless_maintain_membership_restriction_for_woo_products_shop_page' );
Code goes in the functions.php
file of your active theme.