Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save ipokkel/9fdd5d9f6c03103d7b1c2b416d4584ed to your computer and use it in GitHub Desktop.
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.
<?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' );
@ipokkel
Copy link
Author

ipokkel commented Sep 8, 2023

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment