How can I iterate through all current active woo subscriptions and print the user ID of the user who published the product related to each active subscription (PHP)? I think something like this will give just the subscriptions:
$args = array( 'subscriptions_per_page' => -1, 'post_type' => 'shop_subscription', // WC orders post type
'post_status' => 'wc-active' );
$subscriptions = wcs_get_subscriptions( $args );
The following code will query all active subscriptions to get the author Id (that published the product of the active subscription):
// Get all active subscriptions
$subscriptions = wcs_get_subscriptions( array(
'subscriptions_per_page' => -1,
'subscription_status' => array('active') // Active subscriptions
) );
// 1) Loop through quieried active subscriptions
foreach($subscriptions as $subscription)
{
// 2) Loop through subscription items
foreach( $subscription->get_items() as $item_id => $item )
{
// Get the subscription product author
$author_id = get_post_field ('post_author', $item->get_product_id());
// Display
echo $author_id . '<br>';
}
}
Tested and works.
Related
i'm developing a Woocommerce Booking site for an Hotel, i'm stuck to find the way to have the url 'add to cart" for Woocommerce Booking in a custom loop. could someone please give me a little help whether is with WP_Query or wc_get_products. Any help would be appreciate. thx
To get bookable products from WooCommerce Bookings plugin:
1). Using a WC_Product_Query (see documentation here):
$products = wc_get_products( array(
'status' => 'publish',
'type' => 'booking',
'limit' => -1,
) );
// Loop through an array of the WC_Product objects
foreach ( $products as $product ) {
// Output linked product name (with add to cart url)
echo '<p>' . $product->get_name() . '</p>'; // The product name
}
2). Using a WP_Query (see documentation here):
$query = new WP_Query( array(
'posts_per_page' => -1,
'post_type' => array( 'product' ),
'post_status' => 'publish',
'tax_query' => array( array(
'taxonomy' => 'product_type',
'terms' => array( 'booking' ),
'field' => 'slug',
)),
) );
if ( $query->have_posts() ) :
// Loop through an array of WP_Post objects
while ( $query->have_posts() ) : $query->the_post();
// Get the WC_Product Object (optional)
$product = wc_get_product();
// Output linked product name (with add to cart URL)
echo '<p>' . get_the_title() . '</p>'; // The product name
endwhile;
wp_reset_postdata();
else :
// No post found
echo '<p>' . __("No products found", "woocommerce") . '</p>';
endif;
Both ways works…
Note for add to cart Url on bookable products:
On Bookable products, you mostly can't get the add to cart URL as it involves some choices only possible in single product pages… So when using WC_Product add_to_cart_url() method your get the link to the single product page.
I have been creating a plugin and I am trying to pull all woo commerce subscriptions and the variations within the subscription product into a drop down list.
I have successfully pulled the top level product into the drop down list but for some reason the variations of that product don't display on my list.
Any ideas?
This is the code I believe that is adding the products to the list. Do I need to make changes to the type in order to add the variations to the list and not just the top level product?
// get product list...
$query = new WC_Product_Query( array(
'limit' => -1,
'orderby' => 'date',
'order' => 'DESC',
'return' => 'all',
'type' => array('variable-subscription', 'subscription')
) );
The code below will display all WooCommerce subscription products (simple subscriptions, variable subscription and their subscription available variations:
// Get all Subscription products
$subscription_products = wc_get_products( array(
'type' => array('variable-subscription', 'subscription'),
'limit' => -1,
'orderby' => 'date',
'order' => 'DESC'
) );
if ( ! empty($subscription_products) ):
$html = '<div class="products-dropdown"><select name="products-select" id="products-select">
<option value="">'.__('Choose some other product').'</option>';
foreach( $subscription_products as $product ) {
$html .= '<option value="'.$product->get_id().'">'.$product->get_name().'</option>';
// Get Subscription variation (from variable subscription product)
if( $product->is_type('variable-subscription') ) {
print_pr(($product->get_id(). ' ' . $product->get_name()));
// Loop through subscription variations
foreach( $product->get_children() as $variation_id ) {
// Get the WC_Product_Variation object
$variation = wc_get_product( $variation_id );
// The available subscription variation
if( $variation->variation_is_visible() ) {
$html .= '<option value="'.$variation_id.'">'.$variation->get_name().' (variation)</option>';
}
}
}
}
$html .= '</select><p style="margin-top:1em;">';
$html .= 'Add to cart';
// Output
echo $html . '</p></div>';
endif;
Tested and works.
I am currently developing a WordPress project and I am using WooCommerce with WooCommerce Subscriptions plugin to offer subscriptions to my users. I need help on how to get the quantity of a subscription in PHP.
I am using this code to get subscription but I can not retrieve quantity:
$subscriptions = wcs_get_subscriptions( array(
'customer_id' => get_current_user_id(),
'subscription_status' => 'wc-active',
'order_by' => 'DESC',
'subscriptions_per_page' => - 1
) );
When a user purchases a subscription, the user can select the quantity of subscriptions. So I need to get the value of this field:
Your code is correct and wcs_get_subscriptions() is the right and best way to get customer active subscriptions.
But you have missed a something after your code to get the customer subscription item quantity (code commented):
// Get current customer active subscriptions
$subscriptions = wcs_get_subscriptions( array(
'customer_id' => get_current_user_id(),
'subscription_status' => 'wc-active',
'order_by' => 'DESC',
'subscriptions_per_page' => - 1
) );
if ( count( $subscriptions ) > 0 ) {
// Loop through customer subscriptions
foreach ( $subscriptions as $subscription ) {
// Get the initial WC_Order object instance from the subscription
$order = wc_get_order( $subscription->get_parent_id() );
// Loop through order items
foreach ( $order->get_items() as $item ) {
$product = $item->get_product(); // Get the product object instance
// Target only subscriptions products type
if( in_array( $product->get_type(), ['subscription', 'subscription_variation'] ) ) {
$quantity = $item->get_quantity(); // Get the quantity
echo '<p>Quantity: ' . $quantity . '</p>';
}
}
}
}
Tested and works.
Here is my working code try this
$current_user_id = get_current_user_id();
$customer_subscriptions = get_posts( array(
'numberposts' => -1,
'meta_key' => '_customer_user',
'meta_value' => get_current_user_id(), // Or $user_id
'post_type' => 'shop_subscription', // WC orders post type
'post_status' => 'wc-active' // Only orders with status "completed"
) );
And if you want get all post_status subscription then use this
$customer_subscriptions_for_other_cases = get_posts( array(
'numberposts' => -1,
'meta_key' => '_customer_user',
'meta_value' => get_current_user_id(), // Or $user_id
'post_type' => 'shop_subscription', // WC orders post type
'post_status' => array('wc-on-hold','wc-pending-cancel','wc-active') // Only orders with status "completed"
) );
Thanks
I have an issue with my Woocommerce products. This issue is fixed if I just update the product (edit the product and click in the Update button) with no changes at all.
I have around 2000 products in my site, then I am thinking of doing this using a function in my function.php file.
It should be something like this, I just need the line which update the product.
function update_all_products(){
// getting all products
$products = get_posts( $args );
// Going through all products
foreach ( $products as $key => $value ) {
// the product ID
$product_id = $value->ID;
// update product
update_post_meta...(NEED HELP HERE)...
} //..end foreach
}
// fire the function
update_all_products();
Try the following, that will update your products by 200 each time to avoid problems
(if you have variable products also, the post_type arg will need to be product & product_variation):
add_action( 'woocommerce_loaded', 'update_products_by_x' );
function update_products_by_x(){
$limit = 200;
// getting all products
$products_ids = get_posts( array(
'post_type' => 'product', // or ['product','product_variation'],
'numberposts' => $limit,
'post_status' => 'publish',
'fields' => 'ids',
'meta_query' => array( array(
'key' => '_sync_updated',
'compare' => 'NOT EXISTS',
) )
) );
// Loop through product Ids
foreach ( $products_ids as $product_id ) {
// Get the WC_Product object
$product = wc_get_product($product_id);
// Mark product as updated
$product->update_meta_data( '_sync_updated', true );
$product->save();
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Each time you will browse a page of your site the function will be triggered. processing products by 200 is just more secure and will avoid a timeout or errors.
You can increase that number to 500 for example, setting the $limit to 500
I'm trying to get the price of all products on hold (i.e user has placed order but haven't made a payment) by a user in woocommerce.
I have the following code which detects all products on-hold orders by a user
function get_user_on_hold_product_price() {
global $product, $woocommerce;
// GET USER
$current_user = wp_get_current_user();
// GET USER ON-HOLD ORDERS
$customer_orders = get_posts( array(
'numberposts' => -1,
'meta_key' => '_customer_user',
'meta_value' => $current_user->ID,
'post_type' => 'shop_order',
'post_status' => 'wc-on-hold',
) );
I'm not sure what to do from here to get only the total price of all on-hold orders by the user.
Adding/hooking this function to a shortcode, like this;
add_shortcode('get_on-hold_price', 'get_user_on_hold_product_price')
Thanks
To get the total amount of customer "on-hold" orders using a WC_Order_Query for improved usability and compatibility:
add_shortcode('user_on_hold_total', 'get_user_orders_on_hold_total');
function get_user_orders_on_hold_total() {
$total_amount = 0; // Initializing
// Get current user
if( $user = wp_get_current_user() ){
// Get 'on-hold' customer ORDERS
$on_hold_orders = wc_get_orders( array(
'limit' => -1,
'customer_id' => $user->ID,
'status' => 'on-hold',
) );
foreach( $on_hold_orders as $order) {
$total_amount += $order->get_total();
}
}
return $total_amount;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
To get a formatted total amount replace return $total_amount; by return wc_price($total_amount);
Shortcode usage: [user_on_hold_total]
Related documentation: Woocommerce wc_get_orders() and WC_Order_Query