18

I'm developing a website in WordPress with WooCommerce. I'm using additionally WC Paid Listings and WooCommerce Subscriptions plugins to handle my work.

The problem is when a user with "subscriber" role with an active subscription login tries to post content every time he/she has to choose a package even if he has an active subscription.

Is there anyone with an idea of how to detect if the user has an active subscription, if it returns true then the step choosing package is skipped?

mujuonly
  • 11,370
  • 5
  • 45
  • 75
Knight
  • 343
  • 1
  • 4
  • 16

2 Answers2

31

Updated (2019)

  • New conditional function using WooCommerce Subscriptions wcs_user_has_subscription().
  • New conditional function using a much lighter code version (SQL query).
  • Original enhanced conditional function based on an improved WP_Query.

The following custom conditional functions have an optional argument $user_id (a defined user_id) and will return true when the current user (or a defined user) has active subscriptions.

So this can be done now using 3 different ways (that do the same thing):

1) Using WooCommerce Subscriptions dedicated conditional function wcs_user_has_subscription():

function has_active_subscription( $user_id='' ) {
    // When a $user_id is not specified, get the current user Id
    if( '' == $user_id && is_user_logged_in() ) 
        $user_id = get_current_user_id();
    // User not logged in we return false
    if( $user_id == 0 ) 
        return false;

    return wcs_user_has_subscription( $user_id, '', 'active' );
}

2) The same thing with a much lighter SQL query (added on March 2019):

function has_active_subscription( $user_id=null ) {
    // When a $user_id is not specified, get the current user Id
    if( null == $user_id && is_user_logged_in() ) 
        $user_id = get_current_user_id();
    // User not logged in we return false
    if( $user_id == 0 ) 
        return false;

    global $wpdb;

    // Get all active subscriptions count for a user ID
    $count_subscriptions = $wpdb->get_var( "
        SELECT count(p.ID)
        FROM {$wpdb->prefix}posts as p
        JOIN {$wpdb->prefix}postmeta as pm 
            ON p.ID = pm.post_id
        WHERE p.post_type = 'shop_subscription' 
        AND p.post_status = 'wc-active'
        AND pm.meta_key = '_customer_user' 
        AND pm.meta_value > 0
        AND pm.meta_value = '$user_id'
    " );

    return $count_subscriptions == 0 ? false : true;
}

Code goes in function.php file of your active child theme (or theme) or also in any plugin file.


3) The original enhanced code, that will also do the same:

function has_active_subscription( $user_id=null ) {
    // When a $user_id is not specified, get the current user Id
    if( null == $user_id && is_user_logged_in() ) 
        $user_id = get_current_user_id();
    // User not logged in we return false
    if( $user_id == 0 ) 
        return false;

    // Get all active subscriptions for a user ID
    $active_subscriptions = get_posts( array(
        'numberposts' => 1, // Only one is enough
        'meta_key'    => '_customer_user',
        'meta_value'  => $user_id,
        'post_type'   => 'shop_subscription', // Subscription post type
        'post_status' => 'wc-active', // Active subscription
        'fields'      => 'ids', // return only IDs (instead of complete post objects)
    ) );

    return sizeof($active_subscriptions) == 0 ? false : true;
}

Code goes in function.php file of your active child theme (or theme) or also in any plugin file.


Update of usage:

1) USAGE for the current user:

if( has_active_subscription() ){ // Current user has an active subscription 
    // do something … here goes your code

    // Example of displaying something
    echo '<p>I have active subscription</p>';
}

2) USAGE for a defined user ID:

if( has_active_subscription(26) ){ // Defined User ID has an active subscription 
    // do something … here goes your code

    // Example of displaying something
    echo '<p>User ID "26" have an active subscription</p>';
}

This code is tested and it works


Related answers:

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
  • Thanks to Loic it seems the codes working but the problem is when i redirect the page the following error appear Warning: Cannot modify header information - headers already sent by (output started at /home2/xxx/xxxx/wp-content/themes/jobsdojo/header.php:13) in /home2/xxx/public_html/quickextra/wp-includes/pluggable.php on line 1174. please one more tip can help – Knight Feb 23 '17 at 08:56
  • Thanks @ Loic TheAztec what i tried to overide the package-selection.php – Knight Feb 23 '17 at 14:36
  • This code is helpful but beware of implementation if you have large post meta table. It will conduct a full table scan due to lack of index. I just fixed a site that copy/pasted this & had to modify it to set & check a session variable if they had an active subscription & check the user id was not 0 before calling get_posts. They were calling this on pages to display premium content whether a user was logged in or not. get_current_user_id will always return 0 if not logged in. Site was experiencing 2k selects/sec & after my changes optimized to 200/sec. I also added index for meta key/value. – mtg169 Mar 20 '19 at 02:44
  • @mtg169 Thank you (that was an old answer)… I have updated the function code with some enhancements and added 2 other different ways: a much lighter code version *(using a SQL query)* and another one based on wcs_user_has_subscription() WooCommerce Subscriptions conditional function. – LoicTheAztec Mar 20 '19 at 04:18
8

Use wcs_user_has_subscription()

$has_sub = wcs_user_has_subscription( '', '', 'active' );

if ( $has_sub) {
    // User have active subscription
}
LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
phpsmashcode
  • 874
  • 8
  • 16