Skip to content
5 changes: 5 additions & 0 deletions .changelogs/multi-restriction-warning.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
significance: patch
type: changed
links:
- "#2523"
entry: Added support for mutliple membership restriction warning.
89 changes: 59 additions & 30 deletions includes/class.llms.template.loader.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* @package LifterLMS/Classes
*
* @since 1.0.0
* @version 7.4.0
* @version [version]
*/

defined( 'ABSPATH' ) || exit;
Expand Down Expand Up @@ -332,50 +332,79 @@ public function restricted_by_lesson_prerequisite( $info ) {
*
* @since 3.0.0
* @since 3.37.10 Added Flag to print notices when landing on the redirected page.
* @since [version] Added support for multiple memberships warning.
*
* @param array $info Array of restriction info from `llms_page_restricted()`.
* @return void
*/
public function restricted_by_membership( $info ) {

$membership_id = $info['restriction_id'];
$membership_ids = $info['restriction_id'];

// Do nothing if we don't have a membership id.
if ( ! empty( $membership_id ) && is_numeric( $membership_id ) ) {

// Instantiate the membership.
$membership = new LLMS_Membership( $membership_id );
if ( ! empty( $membership_ids ) && ( is_array( $membership_ids ) || is_numeric( $membership_ids ) ) ) {

$msg = '';
$redirect = '';

if ( 'yes' === $membership->get( 'restriction_add_notice' ) ) {
// Check if we're dealing with an array or a numeric for single membership restriction.
if ( ( is_array( $membership_ids ) && 1 === count( $membership_ids ) ) || is_numeric( $membership_ids ) ) {

$msg = $membership->get( 'restriction_notice' );
// Get the membership.
$membership = new LLMS_Membership( is_array( $membership_ids ) ? $membership_ids[0] : $membership_ids );

}
if ( 'yes' === $membership->get( 'restriction_add_notice' ) ) {

$msg = $membership->get( 'restriction_notice' );

// Get the redirect based on the redirect type (if set).
switch ( $membership->get( 'restriction_redirect_type' ) ) {
}

// Get the redirect based on the redirect type (if set).
switch ( $membership->get( 'restriction_redirect_type' ) ) {

case 'custom':
$redirect = $membership->get( 'redirect_custom_url' );
break;

case 'membership':
$redirect = get_permalink( $membership->get( 'id' ) );
break;

case 'page':
$redirect = get_permalink( $membership->get( 'redirect_page_id' ) );
// Make sure to print notices in wp pages.
$redirect = empty( $msg ) ? $redirect : add_query_arg(
array(
'llms_print_notices' => 1,
),
$redirect
);
break;
}
} else {

case 'custom':
$redirect = $membership->get( 'redirect_custom_url' );
break;
$restricted_memberships = '';
$count = 0;
$length = count( $membership_ids );

case 'membership':
$redirect = get_permalink( $membership->get( 'id' ) );
break;
foreach ( $membership_ids as $membership_id ) {

case 'page':
$redirect = get_permalink( $membership->get( 'redirect_page_id' ) );
// Make sure to print notices in wp pages.
$redirect = empty( $msg ) ? $redirect : add_query_arg(
array(
'llms_print_notices' => 1,
),
$redirect
);
break;
$restricted_memberships .= do_shortcode( '[lifterlms_membership_link id="' . $membership_id . '"]' );
$count++;

// Adding `, ` or ` or ` depending on the number of memberships.
if ( $count < $length - 1 ) {
$restricted_memberships .= ', ';
} elseif ( $count === $length - 1 ) {
$restricted_memberships .= __( ' or ', 'lifterlms' );
}
}

// Translators: %s = Membership links.
$msg = sprintf(
__( 'You must belong to one of the following memberships: %s to access this content.', 'lifterlms' ),
$restricted_memberships
);

}

Expand Down Expand Up @@ -700,6 +729,7 @@ public function maybe_prepare_post_content_restriction() {
* @since 3.41.1
* @since 4.0.0 Don't pass by reference because it's unnecessary.
* @since 4.10.1 Fixed incorrect position of `true` in `in_array()`.
* @since [version] Added support for restricted membership IDs array.
*
* @param WP_Post $post Post Object.
* @param WP_Query $query Query object.
Expand Down Expand Up @@ -747,9 +777,8 @@ public function maybe_restrict_post_content( $post, $query ) {

$membership_id = $page_restricted['restriction_id'];

if ( ! empty( $membership_id ) && is_numeric( $membership_id ) ) {

$membership = new LLMS_Membership( $membership_id );
if ( ! empty( $membership_id ) && ( is_array( $membership_id ) || is_numeric( $membership_id ) ) ) {
$membership = new LLMS_Membership( is_array( $membership_id ) ? $membership_id[0] : $membership_id );

if ( 'yes' === $membership->get( 'restriction_add_notice' ) ) {
$msg = $membership->get( 'restriction_notice' );
Expand Down
50 changes: 19 additions & 31 deletions includes/functions/llms.functions.access.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* @package LifterLMS/Functions
*
* @since 1.0.0
* @version 6.5.0
* @version [version]
*/

defined( 'ABSPATH' ) || exit;
Expand Down Expand Up @@ -502,11 +502,12 @@ function llms_is_post_restricted_by_time_period( $post_id, $user_id = null ) {
* @since 3.0.0
* @since 3.16.14 Unknown.
* @since 3.37.10 Call `in_array()` with strict comparison.
* @since [version] Added support for multiple membership restrictions.D
*
* @param int $post_id WP_Post ID.
* @param int|null $user_id Optional. WP User ID (will use get_current_user_id() if none supplied). Default `null`.
* @return bool|int WP_Post ID of the membership if a restriction is found.
* False if no restrictions found.
* @return bool|array Array of WP_Post IDs of the memberships that restrict the post.
* False if no restrictions found.
*/
function llms_is_post_restricted_by_membership( $post_id, $user_id = null ) {

Expand All @@ -528,45 +529,32 @@ function llms_is_post_restricted_by_membership( $post_id, $user_id = null ) {
return false;
}

$memberships = get_post_meta( $post_id, '_llms_restricted_levels', true );
$restricted = get_post_meta( $post_id, '_llms_is_restricted', true );
$memberships = get_post_meta( $post_id, '_llms_restricted_levels', true );
$restricted = get_post_meta( $post_id, '_llms_is_restricted', true );
$restricted_ids = array();

if ( 'yes' === $restricted && $memberships && is_array( $memberships ) ) {

// if no user, return the first membership from the array as the restriction id.
if ( ! $user_id ) {

$restriction_id = array_shift( $memberships );
$student = llms_get_student( $user_id );

if ( ! $student ) {
$restriction_ids = $memberships;
} else {
// loop through the memberships.
foreach ( $memberships as $mid ) {

$student = llms_get_student( $user_id );
if ( ! $student ) {

$restriction_id = array_shift( $memberships );

} else {

// reverse so to ensure that if user is in none of the memberships,
// they'd encounter the same restriction settings as a visitor.
$memberships = array_reverse( $memberships );

// loop through the memberships.
foreach ( $memberships as $mid ) {

// set this as the restriction id.
$restriction_id = $mid;
// set this as the restriction id.
$restriction_ids[] = absint( $mid );

// once we find the student has access break the loop,
// this will be the restriction that the template loader will check against later.
if ( $student->is_enrolled( $mid ) ) {
break;
}
// once we find the student has access break the loop,
// this will be the restriction that the template loader will check against later.
if ( $student->is_enrolled( $mid ) ) {
break;
}
}
}

return absint( $restriction_id );
return $restriction_ids;

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,15 +138,13 @@ public function test_llms_is_post_restricted_by_membership() {

update_post_meta( $post_id, '_llms_restricted_levels', $memberships );
update_post_meta( $post_id, '_llms_is_restricted', 'yes' );

$this->assertEquals( $memberships[0], llms_is_post_restricted_by_membership( $post_id ) );
$this->assertEquals( $memberships[0], llms_is_post_restricted_by_membership( $post_id, $uid ) );
$this->assertEquals( $memberships, llms_is_post_restricted_by_membership( $post_id ) );
$this->assertEquals( $memberships, llms_is_post_restricted_by_membership( $post_id, $uid ) );

$out = llms_is_post_restricted_by_membership( $post_id );
$in = llms_is_post_restricted_by_membership( $post_id, $uid );

$student->enroll( $memberships[1] );
$this->assertEquals( $memberships[1], llms_is_post_restricted_by_membership( $post_id, $uid ) );
$this->assertEquals( $memberships, llms_is_post_restricted_by_membership( $post_id, $uid ) );

}

Expand Down