Created
April 10, 2023 11:04
-
-
Save ipokkel/9fdd5d9f6c03103d7b1c2b416d4584ed to your computer and use it in GitHub Desktop.
Prevent users from checking out for a level they already have, unless the level is expiring soon and the user can renew.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Prevent users from checking out for a level they already have, | |
* unless the level is expiring soon and the user can renew. | |
* | |
* You can add this recipe to your site by creating a custom plugin | |
* or using the Code Snippets plugin available for free in the WordPress repository. | |
* Read this companion article for step-by-step directions on either method. | |
* https://www.paidmembershipspro.com/create-a-plugin-for-pmpro-customizations/ | |
*/ | |
// Warn the user if they already have a membership level in the checkout levels. | |
function my_pmpro_checkout_set_message_has_level() { | |
global $current_user, $pmpro_level, $pmpro_checkout_level_ids, $pmpro_msg, $pmpro_msgt; | |
// bail if not active user. | |
if ( ! is_user_logged_in() || ! pmpro_hasMembershipLevel() || ! empty( $pmpro_msg ) ) { | |
return; | |
} | |
$checkout_levels = array(); | |
// get the checkout levels | |
if ( ! empty( $pmpro_checkout_level_ids ) ) { | |
$checkout_levels = $pmpro_checkout_level_ids; | |
} elseif ( ! empty( $pmpro_level ) ) { | |
$checkout_levels = array( $pmpro_level->id ); | |
} | |
// get all membership level ids for user | |
$user_levels = pmpro_getMembershipLevelsForUser( $current_user->ID ); | |
$user_level_ids = array(); | |
foreach ( $user_levels as $user_level ) { | |
$user_level_ids[] = $user_level->id; | |
} | |
// get the checkout level ids matching the user's membership level ids | |
$has_levels = array_intersect( $user_level_ids, $checkout_levels ); | |
// bail if user does not have a membership level in the checkout levels | |
if ( empty( $has_levels ) ) { | |
return; | |
} | |
// Let's let the user know they already have the level. | |
if ( empty( $pmpro_msg ) ) { | |
foreach ( $has_levels as $has_level ) { | |
// get the array key for the user_levels where have level matches the object->id | |
$key = array_search( $has_level, array_column( $user_levels, 'id' ) ); | |
$level = $user_levels[ $key ]; | |
// Skip if if the user is renewing an expiring level. | |
if ( pmpro_isLevelExpiringSoon( $level ) || pmpro_isLevelFree( $level ) ) { | |
continue; | |
} | |
// Set the message. | |
/* translators: %s: membership level name */ | |
$alert_message = sprintf( __( 'You are already a member of the <strong>%s</strong> membership level.', 'paid-memberships-pro' ), $level->name ); | |
pmpro_setMessage( $alert_message, 'pmpro_error' ); | |
break; | |
} | |
} | |
} | |
add_action( 'pmpro_checkout_after_parameters_set', 'my_pmpro_checkout_set_message_has_level' ); | |
// Prevent users from registering for the same level they already have, unless the level is expiring soon and the user can renew. | |
function my_pmpro_same_level_registration_checks( $okay ) { | |
global $pmpro_level, $wpdb, $current_user; | |
// bail if things are not okay | |
if ( ! $okay || ! is_user_logged_in() ) { | |
return $okay; | |
} | |
$level_id = $pmpro_level->id; | |
// check if user has a membership level and if they do that it isn't expiring soon. | |
if ( pmpro_hasMembershipLevel( $level_id ) && ! pmpro_isLevelExpiringSoon( $level_id ) ) { | |
pmpro_setMessage( 'You already have this membership level.', 'pmpro_error' ); | |
$okay = false; | |
} | |
return $okay; | |
} | |
add_action( 'pmpro_registration_checks', 'my_pmpro_same_level_registration_checks' ); | |
// Filter the levels array to remove levels the user already has, unless the level is expiring soon and the user can renew. | |
function my_pmpro_levels_array_filter( $levels ) { | |
global $current_user; | |
// bail if user does not have a membership level already. | |
if ( ! pmpro_hasMembershipLevel() ) { | |
return $levels; | |
} | |
// get all membership level ids for user | |
$user_levels = pmpro_getMembershipLevelsForUser( $current_user->ID ); | |
$user_level_ids = array(); | |
foreach ( $user_levels as $user_level ) { | |
// add the level id to the array if the level is an expiring level and is not expiring soon. | |
if ( ! pmpro_isLevelExpiringSoon( $user_level ) ) { | |
$user_level_ids[] = $user_level->id; | |
} | |
} | |
// Bail if the user does not have active levels. | |
if ( empty( $user_level_ids ) ) { | |
return $levels; | |
} | |
// remove the levels the user already has from the levels array if it isn't expiring soon. | |
foreach ( $levels as $key => $level ) { | |
if ( in_array( $level->id, $user_level_ids, true ) ) { | |
unset( $levels[ $key ] ); | |
} | |
} | |
return $levels; | |
} | |
add_filter( 'pmpro_levels_array', 'my_pmpro_levels_array_filter' ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
To block only specific level IDs see - https://gist.github.com/ipokkel/8a44ce3ce7f31e84c1f789878a21a703