I have a Wordpress website with Woocommerce and Woocommerce Subscription plugins.
I need to write some PHP script that will check if a user has active subscription status.
From the database, I would like to get information: user id, status (if it's active - if payment was made and the subscription was renewed), end date of subscription...
The problem is that I don't even know where subscription info is saved?
Can somebody write me a snippet of code, that includes a query that will give me a list of users that subscribed, with the necessary information mentioned earlier?
I will post an update with code later, for now, I just need help with query and guidance where to look in the database tables.
I think what you meant is you want to access the Wordpress/Woocommerce Subscriptions API from a PHP file within your Wordpress installation. To do this I think the following will help:
Create a folder in wp-content/plugins called woocommerce-subscriptions-status-checker
Create a file called woocommerce-subscriptions-status-checker.php inside the above new folder.
Add this code in the file:
/*
Plugin Name: Woocommerce Subscriptions Status Checker
Plugin URI: http://www.XXXXXX.com
Description: XXXXXXXXX
Author: XXXXXX
Version: 2.0
Author URI: http://www.XXXXX.com
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
class WC_Subscriptions_Status_Checker {
function __construct() {
// Avoids the function firing if we are in wp-admin backend
if ( !is_admin() ) {
// Fires on every page load after WordPress, all plugins, and the theme are fully loaded and instantiated
add_action( 'wp-loaded', array( $this, 'check_current_user' ) );
}
}
function check_current_user() {
// Check if user is even logged in, if not exit
if ( !is_user_logged_in() ) return;
$current_user = wp_get_current_user(); // get current WP_User
$user_id = $current_user->ID; // get user id
$is_subscription = wcs_user_has_subscription( $user_id ); // check if user has subscription
if ( $is_subscription )
{
$subscriptions = wcs_get_users_subscriptions( $user_id ); // get array of all subscriptions
// Check if there is one subscription or multiple subscriptions per user
if ( count( $subscriptions ) > 1 ) {
// Example if you wanted to loop through all subscriptions, in the case of the user having multiple subscriptions
foreach ( $subscriptions as $sub_id => $subscription ) {
if ( $subscription->get_status() == 'active' ) {
// Do something
}
}
} else { // Only 1 subscription
$subscription = reset( $subscriptions ); // gets first and only value
if ( $subscription->get_status() == 'active' ) {
// Do something
}
}
}
}
}
new WC_Subscriptions_Status_Checker();
Visit the plugins section of wp-admin and Activate your new plugin.
Here is my solution (not saying that it's the best, but for me, it solved the problem that I had).
Code in function.php (WP child theme)
add_action('init','getWPuser');
function getWPuser(){
$current_user = wp_get_current_user();
return $current_user;
}
Custom website
Code in my custom site that needs information about the user.
require_once '../wp-load.php';
require_once '../wp-content/themes/h-code-child/functions.php';
require_once '../wp-includes/pluggable.php';
require_once '../wp-blog-header.php';
$current_user = getWPuser();
Saving user ID information.
$logged_user_id = $current_user->ID;
Checking on specific subscription if it's active.
$has_free = wcs_user_has_subscription( $logged_user_id, $product_id, 'active' );
You can try Woocommerce REST API.
https://docs.woocommerce.com/document/woocommerce-rest-api/
Basically, Woocommerce provide a restful API to access the data and interact with the ecommerce system outside of the traditional woocommerce workflow.
Related
We are using the "User Switching" plugin and I am looking to add an element or a simple bit of text (Placed by Rep: YES) to the WooCommerce Order details which identifies if the order was placed by the customer or by a sales rep that logged in as the customer. This can be achieved with the current_user_switched() function like so:
if ( function_exists( 'current_user_switched' ) ) {
$switched_user = current_user_switched();
if ( $switched_user ) {
// User is logged in and has switched into their account.
// $switched_user is the WP_User object for their originating user.
}
}
But I am stuck on how to add the additional code that would show the actually element on the order details. Hope you can help.
I'm using WooCommerce: Disable Date on Edit Orders anwer code
According to this only applies to admin, how about for only shop manager?
I wonder is there any way where I can disable on edit 'Order created & 'Customer:'? for shop manager only?
Because the code provided does not work for me and only apply to admin. The way I'm doing is using plugin 'Simple Custom CSS and JS' and add accordingly using the code provided. But it doesn't work.
Is there any tips or code that can be directly be added to functions.php?
As in the post provided to disable edit on 'order created', how about for 'Customer:'? which is right below the 'Status'.
First create js file in your active parent/child theme
Add the code:
jQuery(function($) {
$('.order_data_column .date-picker').attr("disabled", true);
$('.order_data_column .hour').attr("disabled", true);
$('.order_data_column .minute').attr("disabled", true);
$('.wc-customer-user select').attr("disabled", true);
});
In your functions.php file add this:
function prevent_editing_shop_order_fields( $current_screen ) {
$user = wp_get_current_user();
if ( 'shop_order' == $current_screen->post_type && 'post' === $current_screen->base && isset( $user->roles[0] ) && $user->roles[0] == 'shop_manager' ) {
// Fix accordingly with your file
wp_enqueue_script('myscript', get_stylesheet_directory_uri().'/assets/js/scripts.js',array('jquery'));
}
}
add_action( 'current_screen', 'prevent_editing_shop_order_fields' );
$user->roles[0] == 'shop_manager' - is a condition to check if current user is shop_manager role
I have used stripe plugin and gravity form for payment in my WordPress site. Subscription payment transaction is working. Now I want to cancel auto renewal after one payment. I have used this code in my functions.php. I have added the
my feed name $feed_names = array( 'Stripe Feed 1' ); and set the count if ( $count == 1 ) { but its not working. I cant understand how to solve this? I have not used any other code of gravity form in functions.php.
LINK
add_action( 'gform_post_add_subscription_payment', function ( $entry ) {
if ( rgar( $entry, 'payment_status' ) == 'Active' ) {
$feed = gf_stripe()->get_payment_feed( $entry );
$feed_name = rgars( $feed, 'meta/feedName' );
$feed_names = array( 'Stripe Feed 1' ); // update this line
if ( in_array( $feed_name, $feed_names ) ) {
global $wpdb;
$count = $wpdb->get_var( $wpdb->prepare( "SELECT count(id) FROM {$wpdb->prefix}gf_addon_payment_transaction WHERE lead_id=%d", $entry['id'] ) );
if ( $count == 1 ) { // update this line
$result = gf_stripe()->cancel( $entry, $feed );
gf_stripe()->log_debug( "gform_post_add_subscription_payment: Cancelling subscription (feed #{$feed['id']} - {$feed_name}) for entry #{$entry['id']}. Result: " . print_r( $result, 1 ) );
}
}
}
} );
Stripe Feeds Name
Yes, this code is OK but I don't know where is your issue. I have a suggestion which is you can check the table {$wpdb->prefix}gf_addon_payment_transaction has been added data successfully while Subscription going on if your data has been added successfully then this add-on hook will work otherwise not because the table is empty.
How you check the data?
It's very easy you can just open up your database's table & check data exists or not.
You can check your Stripe add-on log for seeing what's going on.
Could try the following third-party add-on
You can check these necessary links
Creating a Stripe Feed
logging-and-debugging
theme/plugin conflict test
Note:
When testing you'll need to wait a day before cancelling the subscription to give Stripe time to capture the subscription payment and send the webhook.
I think will help.
I have a Wordpress Memberships website that is built on WooCommerce with WooCommerce Memberships plugin to restrict certain pages to members only.
Some of those pages are "drip-fed"... ie. Access to those pages opens 3 days after purchase, etc. I have set this up in WooMemberships.
I am trying to simply do a PHP conditional check to see if the current user has access to a certain page.
I have found this code piece in the docs: wc_memberships_is_post_content_restricted()
However, I have been unable to make it work.
Is there a code snippet which will basically do a PHP IF statement on whether the current user has access to a certain page (using page ID)?
eg:
if ( current_user_has_access(page_ID) ) { DO SOMETHING } else { DON'T }
Thanks.
I'm not sure if this helps but here is my take on it. I first go through all of the users active membership and then I check the content $rules to see if the restricted plans are a part of the users membership plans (in_array)
function can_user_access_content($user_id,$post_id){
//check if there's a force public on this content
if(get_post_meta($post_id,'_wc_memberships_force_public',true)=='yes') return true;
$args = array( 'status' => array( 'active' ));
$plans = wc_memberships_get_user_memberships( $user_id, $args );
$user_plans = array();
foreach($plans as $plan){
array_push($user_plans,$plan->plan_id);
}
$rules = wc_memberships()->get_rules_instance()->get_post_content_restriction_rules( $post_id );
foreach($rules as $rule){
if(in_array($rule->get_membership_plan_id(), $user_plans)){
return true;
}
}
return false;
}
Usage would be something like:
if(can_user_access_content(get_current_user_id(),$post->ID)){
//do whatever here
}
I'm dealing with the same issue at StoryMoment.com (we produce audio + eBook story series for kids).
This is how I've dealt with it. I use the following in a page template to show or hide page elements based on access. The wc_memberships_view_delayed_post_content would change based on the type of content.
You can see the other options in the file:
class-wc-memberships-capabilities.php
<?php
$has_access = current_user_can( 'wc_memberships_view_delayed_post_content', $post->ID );
if ($has_access) {
//do something
} else {
//do something else
}
?>
You will have to Replace (in the conditions):
$page_id by your page ID number (for example: is_page(42))
$membership_plan by the slug of the plan ('plan_slug') or related post ID.
The conditions:
wc_memberships_is_post_content_restricted($page_id) => true if $page_id is retracted.
is_page($page_id) => true if is actual $page_id.
wc_memberships_is_user_active_member( $membership_plan ) => true actual user is an active member for this $membership_plan plan. In that case the access to the page is granted by the suscription plan of the user.
You can remove some of the conditions, if not needed, and fine tune for your needs.
if( wc_memberships_is_post_content_restricted() && is_page($page_id) && wc_memberships_is_user_active_member( $membership_plan ) ) {
// do something
} else {
// don't
}
--- Update ---
The only function related to restriction and (or) time access are:
1) wc_memberships_restrict( $content, $membership_plans, $delay, $exclude_trial ) just like shortcode [wcm_restrict] (so not useful)…
2) wc_memberships_get_user_access_time( $user_id, $target, $action, $gmt ): Parameters
$user_id // for a logged 'user ID'
$target : array('post' => id, 'product' => id) // content_type and content_id
$action : 'view' or 'purchase' // Type of access (products only)<br>
$gmt => : true or false // (selection of the time zone)
// Returns user access start timestamp (in site timezone) for content or a product
Reference: WooCommerce Memberships Function Reference
On the WooCommerce My Account page I am trying to hide a couple of the sections based on the user role.
At the moment, all people who register directly with the WooCommerce registration form are assigned user role 'Customer'. However, only users with role 'Employer' are actually able to make purchases... so effectively I want to hide the My Addresses section to users who are 'Customers'.
Any ideas if I can do this with a function?
Miro
This is possible easily with templates.
Add this function in your functions.php file so you can reuse it:
function isEmployer(){
$currentUser = wp_get_current_user();
return in_array('employer', $currentUser->roles);
}
Grab the my-account.php template from woocommerce > templates > myaccount and copy over to your theme's WooCommerce directory (YOURTHEME > woocommerce > myaccount).
From there go to line 36. THIS is where the address gets loaded in.
Wrap the address with a PHP if statement like so:
<?php if( isEmployer() ){
wc_get_template( 'myaccount/my-address.php' )
}?>
You would need to override the my-account.php template in your theme and then wrap the call to the address template in some conditional logic. Specifically current_user_can() which checks for WordPress capabilities.
<?php
if( current_user_can( 'place_order' ) ){
wc_get_template( 'myaccount/my-address.php' );
} ?>
Ideally, you would do this based on a capability that the Employer role has that the Customer role does not, but in the worst case you could use the role name à la current_user_can('employer')
Update 2021-02-16
Given the restructuring of my-account.php that is no longer the ideal template to modify and I believe you could remove sections entirely via hooks/filters without overriding a template.
5.0 is out right now, and I would probably filter woocommerce_account_menu_items to remove items from the account menu navigation. And then for security purposes remove the callback from the endpoint too... As an example this adds the address content to the address endpoint: add_action( 'woocommerce_account_edit-address_endpoint', 'woocommerce_account_edit_address' );
So to update my example, if you want to completely remove the Edit Addresses tab for certain users, you could use the following snippet to 1. remove the item from the My Account navigation and 2. completely disable that endpoint.
/**
* Conditionally remove address menu item from My Account.
*
* #param array $items the My Account menu items
* #return array
*/
function so_31342804_remove_address_from_my_account_menu( $items ) {
// Remove menu item for users without certain capability.
if( ! current_user_can( 'place_order' ) ) {
unset( $items['edit-address'] );
}
return $items;
}
add_filter( 'woocommerce_account_menu_items', 'so_31342804_remove_address_from_my_account_menu' );
/**
* Conditionally remove address endpoint from My Account area.
*
* #param array $items the My Account menu items
* #return array
*/
function so_31342804_remove_address_endpoint( $endpoints ) {
// Remove endpoint content for users without certain capability.
if( ! current_user_can( 'place_order' ) ) {
unset( $endpoints['edit-address'] );
}
return $endpoints;
}
add_filter( 'woocommerce_get_query_vars', 'so_31342804_remove_address_endpoint' );